30 Jul 2010
Planet Parrot
parrot.org: The extra pointer has to go.
I reached the midterms mostly as scheduled, and NFG is pretty much feature complete now. There's still some stuff to do here and there, but the 'big ticket' items are done. So, I have been looking at what needs to be done before the gsoc_nfg branch can be merged back into trunk. And that means giving a hard look at all of the places where I've cut corners and see if they can be made better. It's mostly minor stuff, like leaving out a cast, or not paying attention to const mismatches in a few places. Most of it is just a matter of code cleanup. Until you see the extra pointer I added to string headers.
30 Jul 2010 10:37pm GMT
29 Jul 2010
Planet Parrot
Patrick Michaud: Rakudo Star - an "early adopter" distribution of Perl 6
On behalf of the Rakudo and Perl 6 development teams, I'm happy to announce the July 2010 release of "Rakudo Star", a useful and usable distribution of Perl 6. The tarball for the July 2010 release is available from http://github.com/rakudo/star/downloads.
Rakudo Star is aimed at "early adopters" of Perl 6. We know that it still has some bugs, it is far slower than it ought to be, and there are some advanced pieces of the Perl 6 language specification that aren't implemented yet. But Rakudo Perl 6 in its current form is also proving to be viable (and fun) for developing applications and exploring a great new language. These "Star" releases are intended to make Perl 6 more widely available to programmers, grow the Perl 6 codebase, and gain additional end-user feedback about the Perl 6 language and Rakudo's implementation of it.
In the Perl 6 world, we make a distinction between the language ("Perl 6") and specific implementations of the language such as "Rakudo Perl". "Rakudo Star" is a distribution that includes release #31 of the Rakudo Perl 6 compiler [1], version 2.6.0 of the Parrot Virtual Machine [2], and various modules, documentation, and other resources collected from the Perl 6 community. We plan to make Rakudo Star releases on a monthly schedule, with occasional special releases in response to important bugfixes or changes.
Some of the many cool Perl 6 features that are available in this release of Rakudo Star:
- Perl 6 grammars and regexes
- formal parameter lists and signatures
- metaoperators
- gradual typing
- a powerful object model, including roles and classes
- lazy list evaluation
- multiple dispatch
- smart matching
- junctions and autothreading
- operator overloading (limited forms for now)
- introspection
- currying
- a rich library of builtin operators, functions, and types
- an interactive read-evaluation-print loop
- Unicode at the codepoint level
- resumable exceptions
There are some key features of Perl 6 that Rakudo Star does not yet handle appropriately, although they will appear in upcoming releases. Thus, we do not consider Rakudo Star to be a "Perl 6.0.0" or "1.0" release. Some of the not-quite-there features include:
- nested package definitions
- binary objects, native types, pack and unpack
- typed arrays
- macros
- state variables
- threads and concurrency
- Unicode strings at levels other than codepoints
- pre and post constraints, and some other phasers
- interactive readline that understands Unicode
- backslash escapes in regex <[...]> character classes
- non-blocking I/O
- most of Synopsis 9
- perl6doc or pod manipulation tools
In many places we've tried to make Rakudo smart enough to inform the programmer that a given feature isn't implemented, but there are many that we've missed. Bug reports about missing and broken features are welcomed.
See http://perl6.org/ for links to much more information about Perl 6, including documentation, example code, tutorials, reference materials, specification documents, and other supporting resources.
Rakudo Star also bundles a number of modules; a partial list of the modules provided by this release include:
- Blizkost - enables some Perl 5 modules to be used from within Rakudo Perl 6
- MiniDBI - a simple database interface for Rakudo Perl 6
- Zavolaj - call C library functions from Rakudo Perl 6
- SVG and SVG::Plot - create scalable vector graphics
- HTTP::Daemon - a simple HTTP server
- XML::Writer - generate XML
- YAML - dump Perl 6 objects as YAML
- Term::ANSIColor - color screen output using ANSI escape sequences
- Test::Mock - create mock objects and check what methods were called
- Math::Model - describe and run mathematical models
- Config::INI - parse and write configuration files
- File::Find - find files in a given directory
- LWP::Simple - fetch resources from the web
These are not considered "core Perl 6 modules", and as module development for Perl 6 continues to mature, future releases of Rakudo Star will likely come bundled with a different set of modules. Deprecation policies for bundled modules will be created over time, and other Perl 6 distributions may choose different sets of modules or policies. More information about Perl 6 modules can be found at http://modules.perl6.org.
Rakudo Star also contains a draft of a Perl 6 book -- see "docs/UsingPerl6-draft.pdf" in the release tarball.
The development team thanks all of the contributors and sponsors for making Rakudo Star possible. If you would like to contribute, see http://rakudo.org/how-to-help, ask on the perl6-compiler@perl.org mailing list, or join us on IRC #perl6 on freenode.
Rakudo Star releases are created on a monthly cycle or as needed in response to important bug fixes or improvements. The next planned release of Rakudo Star will be on August 24, 2010.
[1] http://github.com/rakudo/rakudo
[2] http://parrot.org/
29 Jul 2010 12:28pm GMT
28 Jul 2010
Planet Parrot
Andrew Whitworth: Kakapo and Parrot-Linear-Algebra
Parrot's 2.6 release is out and now everybody is holding their breath in anticipation of the new Rakudo Star release tomorrow. I'm still fighting with my own release project: Kakapo.Kakapo got broken pretty severely when Parrot was changed to no longer store methods in namespaces, and I have been unable in several weeks to make it work again. Austin has been busy with other projects during this time too, so it's been me by my lonesome to try and get this thing working again.
The problems are three-fold: First, Austin's plan for Kakapo was ambitious and the framework does a hell of a lot of things, not all of which I fully understand. Second, NQP and P6object have progressed in some significant ways since Kakapo was originally inked out, and much of the workaround code that Austin wrote to bypass some missing features no longer seems necessary. Third, we have this issue with methods not working nicely with NameSpaces anymore, which makes all of Kakapo's method-injection logic break.Without method injection happening, and happening early enough, all the code in Kakapo which relies on the new methods is broken.
Tene put together a patch for NQP which allows methods marked "our" to be stored in NameSpaces again. This should simplify some of the new logic in Kakapo though I've been too busy in the past few days to test it. Hopefully this patch of his represents a large portion of the fix to get Kakapo working again. I doubt it will be everything that's necessary, but it will be a nice start.
Without working Kakapo I haven't done any work whatsoever on Parrot-Linear-Algebra. PLA uses Kakapo to implement all it's unit tests, and I'm happy enough with the new testing framework that I do not want to move it to use anything besides Kakapo. In the worst case I would consider trying to break out a testing sub-framework from Kakapo if we can't fix the entire framework, but I haven't gotten to that point yet and likely won't have the time for it in the near future. I would much rather fix the framework as a whole first, and then maybe talk about splitting out the unit test stuff into a separate sub-library later, if I still feel like that's a beneficial path to take.
What I would really like to be doing is getting back into PLA development. I had hoped to get some wrappers together to make it work with Rakudo Star, but without working tests I haven't cut a suitable release and without a release it won't be included in the Rakudo Star bundle anyway.
My hope is that within the next few days I can get Kakapo working again. At least I need it working enough that I can get the unit tests for PLA going. With Tene's fix, some hard work, and some trial-and-error I think it will be possible.
28 Jul 2010 10:00pm GMT
parrot.org: Documentation and information collection
Tutorial to learn the basics of the PIR syntax and beginner's introduction to Parrot
NQP - Not Quite Perl
The target Lorito
28 Jul 2010 2:14am GMT
27 Jul 2010
Planet Parrot
Khairul: Method madness
Well, the past two weeks haven't been very productive. Other than the usual addition of tests, I'm slightly stuck on how I'm approaching instrumenting methods and this post is meant to be a sounding board.
In Parrot, methods of a class can be defined in a few ways. First is by defining a sub in a namespace with the same name as the class and annotating the sub with :method. Second is through the use of the addmethod op. Lastly, it seems all PMCs are classes and PMCs can define methods in C. So at the very least, methods can be either Sub or NCI instances (or rather, invokables), and through the use of the addmethod op, an invokable can be a method to more than one class. So the past week I added support to instrument methods of a class, raising an event whenever any instances of the class invokes the method. What I did not foresee was that due to the ability to "share" methods, an event would also be raised for another class that did not instrument the "shared" method. And this unintended consequence is further exacerbated when the instances themselves are instrumented (I added the ability to instrument on a per-object basis too, although it seems like it's not working too well now).
So a step back to reflect is in order. I would need to:
- Keep a list of classes and instances that instrument any given method.
- When the method is invoked, check the invocant against this list and raise the event if required.
- The invocant can be found in the CURRENT_CONTEXT (I think)
It sounds like a plan, albeit not very fleshed out. Time to find out if it works.
27 Jul 2010 10:06pm GMT
25 Jul 2010
Planet Parrot
parrot.org: Cleaning up and speeding up optimizations with Tree::Optimizer
After a false start earlier this week, I've begun implementing something like LLVM's PassManager. It can be found in the pass-manager branch of my project's git repository.
Today, I'm going to talk about adding optimizations to compilers using my GSoC project without Tree::Optimizer and with it. Note that most of the features of Tree::Optimizer that I describe here are not yet implemented.
25 Jul 2010 4:10am GMT
23 Jul 2010
Planet Parrot
parrot.org: Green Threads: A Classic Example
Now that I have green threads basically working with the API functionality I discussed in my last blog post, I've been working on coming up with tests/examples that clearly demonstrate both how green threads in Parrot work and that they work as advertised. With that goal in mind, this blog post is about a classic concurrent programming example: The Sieve of Eratosthenes.
23 Jul 2010 4:18am GMT
21 Jul 2010
Planet Parrot
parrot.org: Parrot 2.6.0 "Red-rumped" supported release.
What we call the beginning is often the end And to make an end is to make a beginning. The end is where we start from. -T. S. Eliot, Four Quartets
On behalf of the Parrot team, I'm happy to announce Parrot 2.6.0
"Red-rumped." Parrot (http://parrot.org/) is a virtual machine aimed
at running all dynamic languages.
Parrot 2.6.0 is available on Parrot's FTP site, or follow the
download instructions at http://parrot.org/download. For those who would like to
develop on Parrot, or help develop Parrot itself, we recommend using Subversion
21 Jul 2010 3:53am GMT
18 Jul 2010
Planet Parrot
parrot.org: The uneventful mid-term week and the future of PAST/Tree Optimization
This has been an uneventful week in my GSoC work.
Parrot's 2.6 release is Tuesday, and I've taken on the task of updating Squaak to modern NQP-rx prior to it. Because of that and my GSoC midterm evaluations, I haven't spent much time hacking on Tree::Pattern or on optimizations using it this week. I plan to finish working on Squaak tonight or tomorrow, commit my fixes to trunk, and finally get back to work on my GSoC project. I'm a little behind schedule now because of that, but I plan to work hard on optimization for the rest of GSoC.
18 Jul 2010 11:07pm GMT
Jonathan Worthington: Last Post
Well, on use.perl.org, anyway. I'd like to thank those who run this place for doing so, as it's been the place I've blogged about my Perl 6 stuff for the last couple of years. However, I've found the user experience of WordPress a lot more enjoyable - it was great for the Perl 6 Advent Calendar - and figure I'll blog more if I more enjoy doing so.
So, from now you'll be able to read my Rakudo news and other Perl 6 related ramblings from my shiny new blog. For those reading through Planet Six, no action required - I'll arrange for my new blog to be aggregated there.
See you over there.
18 Jul 2010 2:58am GMT
15 Jul 2010
Planet Parrot
parrot.org: Green Threads: The Task API
Now that I have pre-emptive task switching between green threads basically working, I need to figure out what the API to interact with them wants to look like. Additionally, I need to clean up this scheduler thing that I've mauled in order to make the API and terminology consistent.
15 Jul 2010 12:32am GMT
12 Jul 2010
Planet Parrot
Khairul: Week 7: Refactor refactor
Done this week:
- Added in generator scripts.
cotto suggested it would be a good idea to put the scripts I used to generate the stubs in tools/build, so that got done. That done, I added a way to get at the parameters passed to the vtable and GC functions. The example below show's what I mean:
test-invoke.pir.sub '' :anon :load :init load_bytecode 'Instrument/InstrumentLib.pbc' .end .sub main :main .param pmc args $S0 = shift args $P0 = new ['Instrument'] $P2 = get_hll_global ['Instrument';'Event'], 'Class' $P1 = $P2.'new'() $P1.'callback'('class_handler') $P1.'inspect_class'('Sub') $P1.'inspect_vtable'('invoke') $P0.'attach'($P1) $S0 = args[0] $P0.'run'($S0, args) .end .sub class_handler .param pmc data $I0 = data['line'] $P0 = data['parameters'] $I1 = $P0 $P1 = $P0[1] print 'Line: ' print $I0 print ' with ' print $I1 say ' parameters.' print 'address: ' say $P1 .endtest-script.pir
.sub main :main test() say 'Done' .end .sub test say 'Invoke!' .endWhich yields the following output:
Line: 3 with 2 parameters. address: 0 Line: 25 with 2 parameters. address: 1006b0050 Invoke! Done
Along the way, I discovered a small bug in src/pmc/pointer.pmc, in line 162:
return Parrot_sprintf_c(INTERP, "%s", PARROT_POINTER(SELF)->pointer);
Subtle, innocuous looking code, until you realise that it's supposed to print an address, not a string.
- Partially implemented Instrument::Event::Class
The code above shows that it is somewhat working. What is missing is instrumenting methods, removing the hooks, and instrumenting dynamically loaded classes. - Massive refactoring of InstrumentGC and InstrumentVtable
Both InstrumentGC and InstrumentVtable work pretty much the same way. So by refactoring the common code out into InstrumentStubBase, most of the remaining code in InstrumentGC and InstrumentVtable are generated by the scripts tools/build/gen_gc_stubs.pl and tools/build/gen_vtable_stubs.pl. Refactoring the code was somewhat in the back of my mind, and cotto also mentioned it in last week's meeting with him. Trying to complete Instrument::Event::Class was the thing that spurred this refactoring, as I found out more and more how similar both InstrumentGC and InstrumentVtable is. Along with the refactoring, I took a step back and reevaluated how my mappings for various items were done, well, that got changed too. So did the event dispatcher, again. - Not as massive refactoring of EventDispatcher
So this is the second week that EventDispatcher got refactored again. So now it can pass events such as Class::Sub::vtable::main::invoke, so that's category, class name, vtable, vtable group and the item itself, which is more flexible that the previous case which was to split it into 3 components.
What did not get done was most of last week's goals. I got sidetracked into refactoring and ended up not doing the goals. Furthermore, I found out that I need to take into account inheritance when instrumenting the vtable. As an example, EventHandler extends Sub, so when I instrument Sub's vtable, the stub entries got imported into EventHandler, leading to fireworks that I least expected. Ah well, at least while figuring it out I discovered how to use XCode's debugger on parrot. So long command line gdb! And good riddance.
Goals this week will be to complete last week's goals, since this week, week 8 is supposed to be code review, and most of that got covered last week.
12 Jul 2010 5:55pm GMT
parrot.org: Tail-call elimination and moving to github
My main goals this week have been getting a tail-call elimination optimization to work in NQP-rx and moving my GSoC project to an external repository to make it easier for other projects to use it. Both of these goals have been successful. You can find the tail-call elimination optimization here. My GSoC project can now be found on github or installed via Plumage with ./plumage install tree-optimizations.
12 Jul 2010 6:15am GMT
10 Jul 2010
Planet Parrot
Andrew Whitworth: Lorito: A Design
Cotto has been putting together a really great checklist for Lorito, the new microcoding approach that the Parrot developers are hoping to implement soon. The first step on the checklist, creating a proper compiler for our ops code DSL is already complete. Today at #parrotsketch Allison also mentioned some things about Lorito, and how we should start focusing more effort on it. I, for one, am very happy about that.
In this post I'm going to play architect and spell out a vision for Lorito. At the very least, this will be a good play-excercise. I don't expect everybody to like all the things I say here, but I do expect this post to generate some thought and discussion.
On the ground floor, Lorito needs to be able to do what C code does now. Actually, it really needs to be able to do much of what the underlying hardware machine does now. C is just a useful abstraction over the hardware, one that people are familiar with. What we don't want to be doing is creating our own ABI, or creating new low-level calling conventions or anything like that. Those kinds of problems are already resolved and if we want to be able to tap into the myriad of existing libraries we will want to stay compatible with existing conventions.
We want Lorito to interact with raw integers and pointers, including pointer dereferences and pointer arithmetic. This is important so that we can easily work with C-level arrays and pointers. I can't think of a modern architecture where pointers and integers are different sizes and are treated differently, but I can't say I'm familiar with every architecture in current use. I don't foresee any huge problems with creating an opset that works transparently with integers and pointers. We also want Lorito to be able to call C-level functions, including indirect calls through a function pointer. There's no hard requirement yet stated that Lorito needs to be binary compatible with compiled C code, but I think we can all agree that such would be a major benefit. In fact, if we had a utility that could compile Lorito directly into C code, that would be the best intermediate step we could take. As I will discuss next, such a tool would make the conversion of Parrot to using Lorito easier in the long run. We probably don't want Lorito-to-C conversion to be a permanent part of our build, but it does get us moving now.
The PASM ops are currently written in C. If Lorito does everything that C can do, eventually they could all be rewritten in Lorito instead. That raises the interesting idea that groups of Lorito ops can be composed into more complex higher-level ops. PASM then becomes little more than a set of predefined convenience compositions, though it certainly does not represent the complete set of possible compositions. Dynops would just be custom predefined Lorito compositions and, since they wouldn't be defined in machine-code libraries, their definitions could be included directly in bytecode for later use.
In fact, while we are moving down this though path, we get to the idea that we could identify repeated patterns of Lorito ops at compile time, and define custom compositions on the fly. This allows us to compress packfiles for size without really adding all the overhead of general-purpose compression algorithms. When optimizing code, if we can apply an optimization to any composed op, even those identified on the fly, those optimizations can be immediately used anywhere the composition op is. This allows us to prune branches out of the parse tree when optimizing quickly.
Any language for which a compiler exists to convert it to Lorito can be considered an "overlay" language for Lorito. We can then use any overlay language any place where we can use Lorito. For instance, if NQP is converted to output Lorito (and composition ops) directly, we can then use NQP to define all the PASM ops, all the core PMCs, and several parts of Parrot's core. That would be quite the turnaround from how NQP is used currently.
Conversely, almost any C code can be rewritten in Lorito, so long as we have a step in the build to preprocess Lorito back into valid C code. In fact, I see no reason why we cannot interleave code written in both languages, in a manner analogous to how the Q:PIR construct allows PIR code to be written in NQP source. If we had a preprocessor that scanned code files and converted Lorito ops into equivalent C code line-by-line, we could start slowly rewriting much of Parrot, if not all of it, in Lorito. Then, once we have converted all the code over that we need, we could change the build process to convert those code files to bytecode instead of machine code, and run large parts of Parrot's code through the runcore.
Alternatively, instead of writing core code in Lorito directly, we could write core code in any Lorito overlay language. NQP comes to mind here.
The huge benefit to be had is that if user programs are written in a Lorito overlay, and Parrot itself is written primarily in Lorito or an overlay, our eventual JIT can record traces across the API boundary, and optimize hot sections of the Parrot core on the fly at runtime.
Here ends the part of the blog post concerned with overarching architecture discussions. Let's get down to the nitty-gritty details.
Lorito is going to want some basic arithmetic operations: addition, subtraction, multiplication and division on integers (pointers) and floating point numbers. We're also going to want modulus, address-of (C &) and pointer dereference (C unary *) for integer/pointer types, int-to-float and float-to-int cast operations. Logical operations are probably essential as well: and, or, xor, not. Logical inversion (C unary !) would probably be necessary as well. Assuming we can find a way to share ops for int/pointer and float operands (which I doubt we can do in an elegant way), that's still about 20 ops we're going to want to even perform basic manipulations on numbers. I can't imagine any modern, robust, mature virtual machine which doesn't perform these operations readily.
On top of basic mathematical operations, we're going to need some important operations for calling subroutines: Passing and retrieving arguments, calling subroutines, returning with values. I don't know how low-level Lorito intends to get, but let's face the reality of the world: Hardware machines are stack-based. Every library function we want to call is probably going to be passing arguments on the system stack. If we want to be defiant and call these ops "pass_arg" and "retrieve_arg" to hide the fact that Parrot is using the system stack, that's fine by me. The "stacks are evil" mantra, while occasionally misguided, is definitely firmly ingrained in Parrot culture.
In a minimalist world, the only ops we would really need are ops to call functions with passed arguments. We could implement every other op as a huge library of functions to call. Of course this would be extremely sub-optimal, but it does open a new possible avenue: Any operation which is sufficiently uncommon could be turned into a function call instead of having a dedicated op. We could encapsulate the call in a composite op. There are lots of options here, we have to weigh the desire to have a smaller op set against the need to have ready access to a huge myriad of low-level operations.
Having ops to do basic ops is necessary but not sufficient. I don't think we can sit back on our laurels and be happy with an op set that only does a subset of what C can do. That's worthless. Parrot needs to provide access to it's PMC and STRING types, and also to its interpreter. We want ops to load registers with values from the constants table in the bytecode file. We want to treat PMCs and STRINGs as opaque pointers at the user-level. They aren't like other pointers which can be manipulated, they are GCable objects that Parrot treats specially. We don't, for instance, want to be passing a PMC pointer willy-nilly to an arithmetic operation. We also don't want such a mistake to imply a call to one of the addition VTABLEs.
That said, we want to be able to get the VTABLE structure from a PMC, introspect information about that, and be able to call the various VTABLE interface functions there without having to calculate pointer offsets. This might make a good use of composite ops, where we can still do the pointer derefs in Lorito, but hide the nonsense behind some PASM-levle composite ops. We already have most of these ops already, but I think we're going to want to rework some of them. We definitely need to radically reduce the number of VTABLE interface functions, or else interacting with all of them from Lorito will be extremely ungainly.
So far as we are talking about a major redesign of the system, maybe it's time to start considering an idea chromatic has been talking about with making all vtables into methods so we can share a common lookup mechanism, common dispatch mechanism, common MMD behaviors, common inheritance behaviors, etc. That's not a bad idea, but we either need dramatic improvements to PCC performance, or we need to create a PCC fast-path for calls which are made without constructing a call object and without doing too many marshalling operations to get arguments where they need to be.
In fact, on a tangentially-related topic, I definitely think PCC should have a fast-path for functions which do not participate in MMD and which have fixed argument lists containing only positional args (no :optional, no :slurpy, no :named, no :call_sig, etc). This is, I think, an extremely common case and there are plenty of optimizations to be had here if we want them.
To round out the low-level opset, we need ops to move data between registers, between registers and memory, and maybe even ops to move data between memory locations directly, without moving them to a register first.
That's my conception for Lorito: probably 64 ops or less, a capability to add composite ops, treating PASM as a series of common composite ops, and the ability to write low-level code interchangably in C or Lorito. I think this plan for it provides a great development path without too many abrupt stops or course changes. We are quickly going to find ourselves in desperate need of a robust, modern JIT. We are going to be able to move to a proper precise GC since all the Lorito code will be using Parrot's registers to store working values, not relying on stack space which will need to be traced.
I am highly interested in hearing what other people have to say about Lorito, and what changes Parrot should be considering so long as we are writing this blank check for a massive refactor.
10 Jul 2010 10:42pm GMT
05 Jul 2010
Planet Parrot
Khairul: Week 6: Vtable madness
Done the past week:
- Finished up instrumenting GC.
GC events are now fully instrumented, with the exception of the following 3 functions (is_blocked_mark, is_blocked_sweep, get_gc_info). An example of how to use this is shown below:
gc_do_gc_mark.pir:.sub '' :anon :init :load load_bytecode 'Instrument/InstrumentLib.pbc' .end .sub 'main' :main .param pmc args $S0 = shift args # Create an Instrument::Event::GC object. $P0 = get_hll_global ['Instrument';'Event'], 'GC' $P1 = $P0.'new'() $P1.'callback'('do_gc_mark_callback') $P1.'inspect'('do_gc_mark') $P2 = new ['Instrument'] $P2.'attach'($P1) $S0 = args[0] $P2.'run'($S0, args) .end .sub 'do_gc_mark_callback' .param pmc data $I0 = data['line'] $S0 = data['file'] $S1 = data['type'] print '(' print $S1 print ') at line ' print $I0 print ' in file ' say $S0 .endgc_sample.pir:
.sub main :main meh() sweep 1 collect say "End main" .end .sub meh $P0 = new ['Hash'] $I0 = 0 LOOP: $P0 = new ['String'] inc $I0 unless $I0 > 1 goto LOOP sweep 1 collect say "End" .endRunning the command: "./parrot gc_do_mark_sweep.pir gc_sample.pir" will yield the following output:
(do_gc_mark) at line 19 in file gc_sample.pir End (do_gc_mark) at line 4 in file gc_sample.pir End main
- Refactored EventDispatcher.
Previously, my implementation of EventDispatcher only allows registered handlers for specific events, such as 'Instrument::Event::GC::administration::do_gc_mark'. With the implementation of InstrumentGC, this design was rather inadequate, as I found out when I wanted to register a handler for all GC events, or a certain subset of GC events.So refactoring and changing the internals of EventDispatcher came as a natural consequence of that. For what I wanted to do, I found that splitting the event type into 3 parts, namely Category, Group and Specific would do nicely for all cases that I could think of. To give an example, 'GC::allocate::allocate_pmc_header'. If I'm only interested in the specific event, I can just register a handler for 'GC::allocate::allocate_pmc_header'. If I'm only interested in events in the 'allocate' group, I can register a handler for 'GC::allocate'. Similarly, for all GC events, I can register a handler for 'GC'.
Thinking ahead for what I want to do in week 7, this dovetails nicely with Classes. As an example, 'Class::ResizablePMCArray::push', 'Vtable::ResizablePMCArray::push_pmc'. On hindsight, maybe refactoring it again to handle more levels would be better, as looking above for the Vtable example, adding 1 more level would allow catching of push_* vtable entries as a group, ie. 'Vtable::ResizablePMCArray::push::push_pmc'.
- Added tests for EventDispatcher.
Rather self-explanatory. - Added tests for InstrumentGC.
Rather self-explanatory too. - Initial cut of InstrumentVtable.
As of now, all vtable entries have a working stub that can be attached and removed at will. What is missing is getting the information about the arguments to the vtable entry. As an example, VTABLE_push_pmc(INTERP, obj, pmc), currently, only the information 'push_pmc' can be obtained, with obj and pmc on the way. As an example:vtable_push_pmc.pir
.sub '' :anon :load :init load_bytecode 'Instrument/InstrumentLib.pbc' .end .sub main :main .param pmc args $S0 = shift args $P0 = new ['Instrument'] $P1 = new ['InstrumentVtable'], $P0 $P2 = $P0['eventdispatcher'] # Register a handler $P3 = get_global 'class_handler' $P2.'register'('Class', $P3) # Instrument push_pmc of class ResizablePMCArray $P1.'attach_to_class'('ResizablePMCArray') $P1.'insert_vtable_hook'('push_pmc') $S0 = args[0] $P0.'run'($S0, args) .end .sub class_handler .param pmc data $I0 = data['line'] print 'Line: ' say $I0 .endvtable_test.pir
.sub main :main $I0 = 0 LOOP: if $I0 > 5 goto DONE $P0 = new ['ResizablePMCArray'] $P1 = box $I0 push $P0, $P1 inc $I0 goto LOOP DONE: say 'Done' .endRunning the command: "./parrot vtable_push_pmc.pir vtable_test.pir" yields the following output:
Line: -1 Line: 8 Line: 8 Line: 8 Line: 8 Line: 10 Line: 10 Line: 10 Line: 10 Line: 10 Line: 10 Done
Since I have not implemented the appropriate Instrument::Event class for Vtable events, the code in 'vtable_push_pmc.pir' is rather lower-level than I would have preferred. But it will do for now.
With that, this week I would like to:
- Finish up InstrumentVtable
- Implement the Instrument::Event class
- Add a way to get at the vtable arguments
- Documentation + Tests
- Do InstrumentClass, InstrumentObject
- Build on InstrumentVtable to add support for methods.
- Add ability to instrument a single object.
- Start on user documentation.
There is currently no tutorial or anything on how to use the framework. Write something to show the simple stuff, instrumenting the ops.
05 Jul 2010 6:27pm GMT
04 Jul 2010
Planet Parrot
parrot.org: Seven days of PIRATE and Tree::Pattern hacking
Last week, I generalized PAST::Pattern to Tree::Pattern. This week, I put that to use.
04 Jul 2010 9:52am GMT