Re: Objects, methods, attributes, properties, and other related frobnitzes
Dan Sugalski wrote: At 2:06 PM + 2/19/03, Peter Haworth wrote: On Fri, 14 Feb 2003 15:56:25 -0500, Dan Sugalski wrote: I got clarification. The sequence is: 1) Search for method of the matching name in inheritance tree 2) if #1 fails, search for an AUTOLOAD 3) if #2 fails (or all AUTOLOADs give up) then do MM dispatch Shouldn't we be traversing the inheritance tree once, doing these three steps at each node until one works, rather doing each step once for the whole tree. MM dispatch probably complicates this, though. No, you have to do it multiple times. AUTOLOAD is a last-chance fallback, so it ought not be called until all other chances have failed. If my derived class has an autoloaded method which overrides the base class' method, I don't want the base class method to be called, just because parrot does things in a peculiar order. Well, I know it's the same order that perl5 does things, but it's still peculiar. If you prototype the sub but AUTOLOAD the body it'll work OK. newbie to perl6; I've just joined this mailing list How about two AUTO subroutines? An AUTOPROTO method, which will return the prototype of the subroutine being looked for. If it returns undef, then we know to keep looking up the inheritance tree. If it doesn't return undef, cache the prototype (just as if someone had created a stub for that subroutine with that prototype), and then call AUTOLOAD. There are a number of benefits of doing it this way: 1/ Just a single traversal of the inheritance tree. 2/ More than one class can have an AUTOLOAD. 2a/ No need for $self-NEXT::AUTOLOAD(_) 3/ If perl6 allows $coderef = someclass.can('somemethod'), similar to perl5's UNIVERSAL::can, then this will work right even if somemethod *would* be autoloaded, but hasn't been created yet, or if the AUTOLOAD method chooses not to cache a subroutine for it. (.can would would search the inheritance tree (once), and call AUTOPROTO as needed, but would not call AUTOLOAD) Item (2) is perhaps the most important, since none of the other things in this thread seem to address it. /newbie -- $;=qq qJ,krleahciPhueerarsintoitq;sub __{0 my$__;s ee substr$;,$,++$__%$,--,1,qq;;;ee; $__2__}$,=22+$;=~y yiy y;__ while$;;print
Re: Objects, methods, attributes, properties, and other related frobnitzes
Andy Wardley wrote: Dan Sugalski wrote much sense, including these gems: [snip] Code must be able to fetch a handle on a particular method for later calling By this I presume you mean that the handle would be frozen to the method as it was when then handle was fetched? If you later re-define the method, the handle would remain pointing at the original method, not the new one. Or not? Redefining methods is almost (but not quite) as evil as altering inheritance trees (at least wrt to it's effect on caching methods). Consider the following perl5 code: { package MyClass; sub SomeMethod { 12 } } my $methodref = MyClass-can(SomeMethod); *MyClass::SomeMethod = sub { return 42 }; print MyClass-SomeMethod(), \n; print MyClass-$methodref(), \n; I suppose if perl6's equivilant of 'can' returns a string, such as MyClass::SomeMethod, then it might work as you want it to... but that would produce one extra level of indirection; would it be worth it? -- $;=qq qJ,krleahciPhueerarsintoitq;sub __{0 my$__;s ee substr$;,$,++$__%$,--,1,qq;;;ee; $__2__}$,=22+$;=~y yiy y;__ while$;;print
Re: [perl #21276] [PATCH] formatting fix for docs/dev/rx.dev
Cal Henderson (via RT) wrote: # New Ticket Created by Cal Henderson # Please include the string: [perl #21276] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt2/Ticket/Display.html?id=21276 hi, this patch fixes some formatting issues that cause docs/dev/rx.dev to incorrectly display code snippets and to have no title. it also adds a missing B tag. Thanks, applied. leo
Re: [perl #21301] [PATCH] life.pasm
Leon Brocard (via RT) wrote: # New Ticket Created by Leon Brocard # Please include the string: [perl #21301] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt2/Ticket/Display.html?id=21301 This little patch changes the life.pasm in examples/assembly/ to use a small spaceship instead. Thanks, applied. leo
Re: Using imcc as JIT optimizer
Leopold Toetsch wrote: - do register allocation for JIT in imcc - use the first N registers as MAPped processor registers The [RFC] imcc calling conventions didn't get any response. Should I take this fact as an implict yep, fine? Here is again the relevant part, which has implications on register renumbering, used for JIT optimization: =head1 Parrot calling conventions (NCI) Proposed syntax: $P0 = load_lib libname $P1 = dlfunc $P0, funcname, signature .nciarg z # I5 .nciarg y # I6 .nciarg x # I7 ncicall $P1 # r = funcname(x, y, z) .nciresult r A code snippet like: set I5, I0 dlfunc P0, P1, func, ii invoke set I6, I5 now comes out as: set ri1, ri0 dlfunc P0, P1, func, ii invoke set ri0, ri1 which is clearly not, what pdd03 is intending. For plain PASM at least the .nciarg/.nciresult are necessary, to mark these parrot registers as fix and to have some hint for imcc, that dlfunc is actually using these registers. So there are some possibilities: - disable register renumbering for all compilation units, where a Binvoke is found - do it right, i.e. implement above (or a similar) syntax and rewrite existing code leo
Re: Objects, methods, attributes, properties, and other related frobnitzes
Dan Sugalski wrote: At 12:06 AM -0500 2/21/03, Benjamin Goldberg wrote: Andy Wardley wrote: Dan Sugalski wrote much sense, including these gems: [snip] Code must be able to fetch a handle on a particular method for later calling By this I presume you mean that the handle would be frozen to the method as it was when then handle was fetched? If you later re-define the method, the handle would remain pointing at the original method, not the new one. Or not? Redefining methods is almost (but not quite) as evil as altering inheritance trees (at least wrt to it's effect on caching methods). So? This is perl, it happens with some frequency, and other languages we'll be running (like Ruby) do it rather more than perl does. Doesn't matter if we like it or not, it's going to happen so we deal with it. There are optimization tricks we can use, but they need to be behind-the-scenes tricks and not affect language semantics. I haven't said that we should rule out method redefinition... I am, however, saying that we should handle it no worse than (and preferably better than) perl5 does it. My bit of example code was merely to demonstrate that UNIVERSAL::can() from perl5 clearly has the problem that Andy Wardley worries about wrt freezing to a particular definition... Thus, it *may* be a good idea to *not* provide a user-code-level means of obtaining method handles, or else it will likely have the same problem as perl5's -can(). In other words, I'm agreeing with you -- any method-handle-obtaining-for-caching should be entirely behind the scenes, where we can easily keep track of whether a cached handle is still valid. -- $;=qq qJ,krleahciPhueerarsintoitq;sub __{0 my$__;s ee substr$;,$,++$__%$,--,1,qq;;;ee; $__2__}$,=22+$;=~y yiy y;__ while$;;print
invoke
The invoke op is bothering me -- namely, it disturbs me that it implicitly operates on P0. I know that P0 is the correct register to use according to pdd03, but I dislike having it be implicit. The user is required to set the rest of the pdd03 conventions up manually, so I don't see any need for invoke to be different. And it makes it much more clear what registers are being used if you have to pass in a PMC as an argument. So would anyone mind if I eliminated the zero-arg invoke op in favor of a one-arg invoke that takes a single PMC? (I may also have situations where I don't need to follow pdd03, and it would be more convenient to use a different register.)
stabs support
First -- wow, thanks! I tried out the stabs stuff for the JIT yesterday, and it's really helpful to be able to step through PASM code from within emacs's gud mode. I had one problem, though -- whenever stepping over a keyed op (eg set I0, P0[3]), gdb fails to recognize that it reaches any more lines and instead runs the whole thing to completion and exits. If I did 'si' twice to step two machine instructions whenever I was about to execute a keyed op, then I could go back to stepping normally and it would find things correctly. That .stabs data is correct -- the keyed op and the following ops (and all others) had the correct offsets associated with them. I still don't have a home network connection anymore, so I couldn't download the gdb source to figure out what was going on. But I remember noticing that gdb prints out the current PASM line number after that second 'si' on the keyed op. Anyone else having this problem? (Anyone have a better workaround?) In my local copy (currently locked away on my home hard drive, so I can't post it from here at work), I also added stabs entries for all the PMC registers (in addition to the current S, I, and N registers.) You can see the PMC's data fields and type. It looks something like: (gdb) p P0 (PMC*) 0xdeadbeef (gdb) p *P0 { vtable = 0xdeadbeef, pobj = { u = { int_val = 17, pmc_val = 0x17 }, flags = 381741 } } (gdb) p *P0-vtable { base_type = PerlArray } (I added an enumeration for the PMC types). I probably have the exact data structures all wrong, but it looks something like that. Oh, and I suspect I may be able to use an external type reference to avoid defining all of these things. I haven't tried that yet. And I'd just like to say that stabs is a mess. Is DWARF2 any better? (My poor disconnected computer doesn't have any documentation on it, so I couldn't try it out.)
Helpful emacs gud/perldb debugging tool
Here's a silly little tool that I've used for a long time to help debug various programs. I just added perl support to it, so I thought I'd announce it in case anyone got some use out of it. To use it, save it into your $PATH somewhere. Then, instead of running ./someapplication args..., run debug ./someapplication args... instead. If someapplication is a compiled binary other than perl, it will bring up an emacs window with gdb running the application within it. If someapplication is either perl or an executable perl script, it will bring up an emacs window running perldb with the application loaded (and it also chdirs to the correct path, instead of perldb's usual annoying behavior). There are some environment variables that you can use to control whether the application will be running under GDB when the window pops up (the default), or whether it will just set the arguments and give you a chance to run it yourself. Read the source for details. Note that this won't help much if you're debugging something that exec's the thing you really want to debug, but you can usually work around that by changing the exec to put debug in front of the actual command. This, in fact, is the killer application for this script, since it will then pop up windows no matter how deeply buried the interesting invocation is, and the whole environment should be set up nicely. If you're trying to use this, or perldb in general, to debug the perl6 driver program, watch out -- perl6 uses *massive* amounts of stack space, so to get anything useful you'll probably need to set the max stack depth to 1000 instead of the default 100. BEGIN { $DB::deep = 1000 } should do it, I think. (Once again, my notes on that are at home.) Let me know if you find this useful, or think I'm stupid for not knowing a much nicer way of doing this. #!/bin/bash -f # This script opens up an emacs window with the given program running # under a debugger, all automagic-like. # # Usage: debug program args... # # Various environment variables can affect the operation. Let's see... # $DBG : set to qr/EXPRESSION/ to only fire up emacs for programs # that match the given regex. # $GDB_INITFILE : gdb will execute this file when it starts up. # There are better ways of doing this, you know. # $GDB_INITSTRING : execute the given gdb command at startup. # $GDB_INTERACTIVE : set this to any nonempty value to have gdb # pause before running the program. # # Most of those options don't work or aren't relevant for the perl # debugger. COMMAND=$(echo $1 | perl -lpe 's!//!/!g') shift # Check whether we should skip debugging this invocation # (if DBG is set to qr/something/ that doesn't match the command line) if perl -e '$args=join( ,ARGV); print MATCHING $ENV{DBG} AGAINST $args\n; if ($ENV{DBG} !~ /^qr/) { exit(1); } else { $match=eval $ENV{DBG}; exit(($args =~ $match) ? 1 : 0); }' $COMMAND $*; then exec $COMMAND $* fi function debug_perl () { CWD=`pwd` exec emacs --eval (progn (perldb \perl $*\) (insert-string \chdir('$CWD')\) (comint-send-input)) } if [ $COMMAND = perl ]; then debug_perl $* elif file $COMMAND | grep perl script; then debug_perl $COMMAND $* fi # Set the arguments INIT_EVAL=(insert-string \set args $*\) (comint-send-input) (insert-string \cd $(pwd)\) (comint-send-input) # If env var GDB_INITFILE set, load it into gdb on startup if [ ! x$GDB_INITFILE = x ]; then echo Loading init file $GDB_INITFILE 2 INIT_EVAL=$INIT_EVAL (insert-string \source $GDB_INITFILE\) (comint-send-input) fi # If env var GDB_INITSTRING set, give it to gdb if [ ! x$GDB_INITSTRING = x ]; then echo Sending gdb command $GDB_INITSTRING 2 INIT_EVAL=$INIT_EVAL (insert-string \$GDB_INITSTRING\) (comint-send-input) fi # If env var GDB_INTERACTIVE or DBG eq 'wait', let the user run the gdb session if [ x$GDB_INTERACTIVE = x ] [ ! x$DBG = xwait ]; then echo Running gdb immediately 2 INIT_EVAL=$INIT_EVAL (insert-string \run\) (comint-send-input) echo INIT_EVAL=$INIT_EVAL fi exec emacs --eval (progn (gdb \gdb $COMMAND\) $INIT_EVAL) # Copyright (c) 2002-3 by Steve Fink. All rights reserved. # # You may do anything you want with this script, as long as you don't # use it to directly or indirectly cause harm to any mythical # creatures. Only real creatures may be harmed by the running of this # script. Oh, and you can't remove my copyright notice either, no # matter how much you mutate the script itself. # # But if you're nice, you'll properly document all the funky options, # clean it up, and send it back to me at [EMAIL PROTECTED] And you seem # like a really nice person to me.
Re: [RFC] imcc calling conventions
On Feb-18, Leopold Toetsch wrote: =head1 Stack calling conventions Arguments are Bsaved in reverse order onto the user stack: .arg y # save args in reversed order .arg x call _foo #(r, s) = _foo(x,y) .local int r .local int s .result s # restore results in reversed order .result r # [1] and return values are Brestored in reversed order from there. The subroutine is responsible for preserving registers. .sub _foo# sub foo(int a, int b) saveall .param int a .param int b ... .return pl # return (pl, mi) .return mi # [1] restoreall ret .end My immediate reaction to this (okay, I really saw this before in perl6-generated code) is why don't the values from .return and restoreall get mixed up? You may want to add a brief description of the kazillion different stacks that Parrot uses. There are six, I think: 1. The user stack -- holds a stack of unions, so entries can be int/float/pmc/string 2. The control stack -- holds return addresses 3. The int register stack -- holds frames of 32 ints each 4. The float register stack 5. The string register stack 6. The pmc register stack I think this has been discussd before, but are we all okay with this callee-save-everything policy? At the very least, I'd be tempted to add a bitmasked saveall/restoreall pair to reduce the amount of cache thrashing. (saveall 0b00100110) It just seems odd that you have to either save all 32 of one of the types of registers, or to save selected ones onto a different stack. But it *is* simpler to copy over the entire register file to a stack frame, I guess. Taking that farther, I've always liked systems that divide up the registers into callee-save, caller-save, and scratch (nobody-save?) Maybe that's just me. And I vaguelly recall that there was some discussion I didn't follow about how that interferes with tail-call optimization. (To me, tail call optimization == replace recursive call with a goto to the end of the function preamble) Or, as another stab at the same problem, does Parrot really need 32*4 registers? I keep thinking we might be better off with 16 of each type. But maybe I'm just grumbling. [It's nice to have a net connection again!]
Re: IMCC's bsr handling
[Apologies if you receive this twice, but my messages from work haven't been going through, so I'm resending everything now that I have my home net connection back.] On Sat, Feb 08, 2003 at 12:19:35PM +0100, Leopold Toetsch wrote: Steve Fink wrote: bsr $I0 It will complain that it can't fixup the label '$I0'. I can't imagine, how to get a correct CFG with these kind of register jump instructions. They are too low level, lacking any hint where they might jump to. When we want these kind of branches, then they must be more high level, defining all possible branch targets, e.g. like a switch statement. My specific use is in implementing regexes (I guess I should say rules). It is now possible to store anonymous rules or references to named rules in variables, and invoke the rules within a regex. If you're qualifying those invocations with * or + or whatever, then the setup/teardown code is going to be called many, many times, so it would be nice to minimize it. But because it's not constant, it will boil down to either bsr $I0 or invoke. I would like to be able to put the code implementing those anonymous rules into the current compilation unit (they'll be acting like closures and referring to local vars, but I'd rather avoid a full-blown closure when possible.) I think all that means that I *can* specify a set of labels that the instruction might jump to, and guarantee that if it jumps to anywhere else that it won't affect any registers. For now, I'm prototyping using a heavyweight mechanism. If that gets to be too unwieldy, maybe I'll take a look at implementing something like bsr $I0 = _label1 | _label2 | REGISTER_PRESERVING_LOCATION (Ignore the syntax!). It's only needed for imcc, right? (I wouldn't need to propagate it through to the JIT or anything, would I?) I'm not really sure whether I'll end up needing any of this anway. It may be just too unpredictable where things can go to, and I'll have to suffer with the heavyweight approach. How is invoke handled? Is it assumed to always use the full PDD06 calling conventions?
Re: XML within parrot?
At 2:07 PM -0800 2/17/03, Tupshin Harper wrote: I've been a parrot lurker for quite some time, and I've recently wanted to start participating in some way. One idea that came to mind was to port a language I wrote a while back which is an XML-relational converter. Call it XTOR(XML to Relational for lack of imagination). Think of it as analogous to XSL, but for converting XML data to row/column data in completely arbitrary(and sometimes quite capricious) ways. The problem(s) is that the language itself is written in XML (as is XSL), and therefore anything that processes it has to have an XML engine available. Just out of curiosity (I know, this is old) have you looked at examples/assembly/xml_parser.pasm? Might not be enough, but it is there. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, methods, attributes, properties, and other related frobnitzes
At 6:24 PM -0500 2/20/03, Mark Jason Dominus wrote: Dan Sugalski [EMAIL PROTECTED]: At 2:06 PM + 2/19/03, Peter Haworth wrote: On Fri, 14 Feb 2003 15:56:25 -0500, Dan Sugalski wrote: I got clarification. The sequence is: 1) Search for method of the matching name in inheritance tree 2) if #1 fails, search for an AUTOLOAD 3) if #2 fails (or all AUTOLOADs give up) then do MM dispatch Shouldn't we be traversing the inheritance tree once, doing these three steps at each node until one works, rather doing each step once for the whole tree. MM dispatch probably complicates this, though. No, you have to do it multiple times. AUTOLOAD is a last-chance fallback, so it ought not be called until all other chances have failed. Pardon me for coming in in the middle, but it seems to me that only one traversal should be necessary. The first traversal can accumulate a temporary linked list of AUTOLOAD subroutines. If the first traversal locates an appropriate method, the linked list is discarded. If no appropriate method is found, control is dispatched to the AUTOLOAD subroutine at the head of the list, if there is one; if the list is empty the MM dispatch is tried. Fair enough--in practice we can do a single traversal, but conceptually we need to do multiple traversals. More importantly we can't check for method then AUTOLOAD then MMD in each class in turn up the hierarchy, which is what I think the original suggestion was. (Though I may have misinterpreted, of course) If A isa B, we certainly wouldn't want to call A's AUTOLOAD on a method before we looked to see if B had a concrete instance of that method. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, methods, attributes, properties, and other related frobnitzes
At 12:06 AM -0500 2/21/03, Benjamin Goldberg wrote: Andy Wardley wrote: Dan Sugalski wrote much sense, including these gems: [snip] Code must be able to fetch a handle on a particular method for later calling By this I presume you mean that the handle would be frozen to the method as it was when then handle was fetched? If you later re-define the method, the handle would remain pointing at the original method, not the new one. Or not? Redefining methods is almost (but not quite) as evil as altering inheritance trees (at least wrt to it's effect on caching methods). So? This is perl, it happens with some frequency, and other languages we'll be running (like Ruby) do it rather more than perl does. Doesn't matter if we like it or not, it's going to happen so we deal with it. There are optimization tricks we can use, but they need to be behind-the-scenes tricks and not affect language semantics. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Using imcc as JIT optimizer
At 12:09 PM +0100 2/20/03, Leopold Toetsch wrote: Starting from the unbearable fact, that optimized compiled C is still faster then parrot -j (in primes.pasm), I did this experiment: - do register allocation for JIT in imcc - use the first N registers as MAPped processor registers This sounds pretty interesting, and I bet it could make things faster. The one thing to be careful of is that it's easy to get yourself into a position where you spend more time optimizing the code you're JITting than you win in the end. You also have to be very careful that you don't reorder things, since there's not enough info in the bytecode stream to know what can and can't be moved. (Which is something we need to deal with in IMCC as well) -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Configure.pl --cgoto=0 doesn't work
On Thu, Feb 20, 2003 at 09:45:49PM -0500, Simon Glover wrote: On Thu, 20 Feb 2003, Simon Glover wrote: On Thu, 20 Feb 2003, Nicholas Clark wrote: If I perl Configure.pl --cgoto=0 make all test then the build fails with: The problem is that an ifdef in jit/i386/jit_emit.h is defining JIT_CGP based on whether or not the compiler is GCC, and not on whether HAS_COMPUTED_GOTO is defined. The attached patch fixes this, but I'm not sure if the __GCC__ bit is still necessary. Leo? OK, let's try this again, with the _correct_ spelling this time... Thanks, applied. Nicholas Clark
Re: Configure.pl --cgoto=0 doesn't work
On Fri, Feb 21, 2003 at 08:34:05AM +0100, Leopold Toetsch wrote: Nicholas Clark wrote: If I perl Configure.pl --cgoto=0 make all test then the build fails with: We need to sort out different cases: 1) $cc doesn't have computed goto 2) user doesn't want to build core_ops_cg.c Case 1) shouldn't matter, as the CGP core is only called from JIT/i386/gnucc Case 2) should disable only core_ops_cg.c but not core_ops_cgp.c But surely we'd also like a flag to disable core_ops_cgp.c but leave core_ops_cg.c? How many cores are there now? Is there a way to make a modular flag system that lets people configure any arbitrary combination that they wish to build? And an easy way for the tinderbox machines to build all applicable, and run tests for each built core in turn? Nicholas Clark
Re: Using imcc as JIT optimizer
Dan Sugalski wrote: At 12:09 PM +0100 2/20/03, Leopold Toetsch wrote: Starting from the unbearable fact, that optimized compiled C is still faster then parrot -j (in primes.pasm), I did this experiment: - do register allocation for JIT in imcc - use the first N registers as MAPped processor registers This sounds pretty interesting, and I bet it could make things faster. The one thing to be careful of is that it's easy to get yourself into a position where you spend more time optimizing the code you're JITting than you win in the end. I don't think so. Efficiency of JIT code depends very much on register save/restore instructions. imcc does a full parrot register life analysis, and knows when e.g. I17 is rewritten and thus can assign the same register for it, that some ins above I5 had. Current JIT code is looking at parrot registers and emits save/loads to get processor registers in sync, which is the opposite of: The proposal is, to map the top N used parrot regs to physical processor registers. This means: imcc emits instructions to get parrot registers up to date and not vv. The code is already in terms of processor regs. You also have to be very careful that you don't reorder things, since there's not enough info in the bytecode stream to know what can and can't be moved. (Which is something we need to deal with in IMCC as well) Yep. So, I'm trying to get *all* needed info's into the bytecode stream/into the op_info/or as a hack in imcc. See e.g. [RFC] imcc calling conventions. Please remember times where I started digging into parrot and core.ops: the in/out/inout definition of P-registers. These issues are *crucial* for a language *compiler*. If perl6 or any other language should run *efficiently*, imcc has to be a compiler with all needed info at hand and not a plain PASM assembler. leo