JonathanWorthington's Friends' Journals
http://use.perl.org/~JonathanWorthington/journal/friends/
JonathanWorthington's Friends' use Perl Journalsen-ususe Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners.2012-01-25T02:18:42+00:00pudgepudge@perl.orgTechnologyhourly11970-01-01T00:00+00:00JonathanWorthington's Friends' Journalshttp://use.perl.org/images/topics/useperl.gif
http://use.perl.org/~JonathanWorthington/journal/friends/
Todays Vienna.pm TechSocial
http://use.perl.org/~leo/journal/35038?from=rss
<p>We had another TechSocial Meeting in Vienna - taking place on 1st monday of every month. First Willy showed using Perl for emulating heavy (really tons of) hardware - very impressive. Second talk by <a href="http://use.perl.org/~domm/journal/">domm</a> was an intro to Perl 5.10.</p><p>The pub (remember Tech<b>Scocial</b>) did e.g. provide 'Perlhuhnbrust' on the menue, but we didn't ask if it were of the 5.10 persuasion.</p><p>The smart match operator lead to immediate discussion, whether there exists a 'not-smart-operator' or rather a 'smart-not-operator' or their combination:</p><blockquote><div><p> <code>
$foo !~~<nobr> <wbr></nobr>/bar/; # not smart aka dumb match<br>
</code></p></div>
</blockquote><p>Would this maybe match every <code>chicken</code> or rather not?</p><blockquote><div><p> <code>
$foo ~!~<nobr> <wbr></nobr>/bar/; # smart no match<br>
$foo !~!~<nobr> <wbr></nobr>/bar/; # no dumb match<br>
</code></p></div>
</blockquote><p>... which immediately lead to a discussion of the orthogonality of the <code>not</code> operator, which generally was considered as very important. E.g. is this valid syntax, and what does it mean:</p><blockquote><div><p> <code>
not my $var;
</code></p></div>
</blockquote><p>Semantically it's a promise not to use this variable in that scope. But perl has a different POV</p><blockquote><div><p> <code>
$ perl -Mstrict -Mwarnings -le'not my $var'<br>
Useless use of not in void context at -e line 1.
</code></p></div>
</blockquote><p>OTOH<nobr> <wbr></nobr>...</p><blockquote><div><p> <code>
$ perl -Mstrict -Mwarnings -le'print not my $beer'<br>
1<br> <br>
$ perl -Mstrict -Mwarnings -le'print ! my $beer'<br>
1
</code></p></div>
</blockquote><p>... there are some 'true' items, which aren't your beer. But<nobr> <wbr></nobr>...</p><blockquote><div><p> <code>
$ perl -Mstrict -Mwarnings -le'print $_->ignore for not our @beer'<br>
Can't call method "ignore" without a package or object reference at -e line 1.</code></p></div>
</blockquote><p>... you can't actually ignore all of them.</p>leo2007-12-03T22:59:45+00:00journalP3 - Parrot Presentation Program
http://use.perl.org/~leo/journal/30955?from=rss
<p>As outlined in the previous journal entry, I'm writing a new presentation tool using Parrot. It now has hit the parrot svn repository.</p><p>A basic presentation (written in html) about P3 itself can be found <a href="http://svn.perl.org/parrot/trunk/apps/p3/p3p.html">
here</a> (sorry - the svn server is delivering this as text/plain).
</p>leo2006-09-10T19:57:30+00:00journalParrot can do AJAX too!
http://use.perl.org/~leo/journal/30902?from=rss
<p>Above subject is shamelessy stolen from Jonathan, who has used it on IRC. Anyway, I got bored by doing my presentations with</p><blockquote><div><p> <code>
$<nobr> <wbr></nobr>./parrot slpod.imc yapc.pod
</code></p></div> </blockquote><p>... or some such. I wrote the predecessor of that at YAPC::EU::2003 during lunch break and the slides at dinner (no, that isn't a joke) and it caused a lot of fun at these days.</p><p>But in recent times all has to be <strong>AJAX</strong>, hasn't it? Alas, I started hacking <i>examples/io/httpd.pir</i> to support a CGI GET request, which is invoking Parrot subroutines, and put together 60 lines of JavaScript dealing mainly with keyboard requests to navigate between slide pieces and to send <strong>XMLHttpRequest</strong>s. The <i>XML</i> thingy is totally optional, don't be afraid, plain text messages or html snippets are working fine too - and that's what the next slide presentation program will use.</p><p>Given that your GET request delivers a valid HTML snippet, and you got e.g. <tt><div id="answer"></div></tt> on your html page, then all you need to fill this with contents is mainly this JavaScript two-liner:</p><blockquote><div><p> <code>
var x = document.getElementById('answer');<br>
x.innerHTML = req.responseText;
</code></p></div> </blockquote><p>That's almost it. I'll put together a working example in the parrot repo during the next days.</p>leo2006-09-05T22:41:06+00:00journalYAPC::EU::2006 Parrot BOF
http://use.perl.org/~leo/journal/30880?from=rss
<p>About 10 (more or less) parrots flocked together in the lobby of Jury's Inn Hotel at Wednesday. The topics were:</p><ul>
<li>Parrot on VMS (VAX). The <a href="http://vaxman.de/">Vaxman</a> and Martin, who has already sent a patch to p6i, are hopefully continuing this story.</li><li>JIT for the x86_64 architecture</li><li>Perl5 continuations. I discussed parrot's implemenation and some implications mainly with Nick.</li><li>Parrot interfaces. Allison and me went through a more flexible concept extending the current static vtable layout.</li></ul>leo2006-09-04T15:50:36+00:00journalParrot: if vs. unless
http://use.perl.org/~leo/journal/28727?from=rss
<p>Parrot provides two opcodes to branch on the truthness of a
register: <code>if</code> and <code>unless</code>. It looks
like that it's just a matter of taste, which one to use. Is it
really?</p><p>Not with modern CPUs with branch prediction rules and
with JIT code inside tight inner loops. Below are two versions
of the ackermann function, one written with <code>if</code>
and one using <code>unless</code>. (If you are missing the
loop in the code, well, that's coming from tailcall
optimization, turned on with <code>-Oc</code>.)</p><p>
<code>
$ cat ack-if.pir<br><nobr> <wbr></nobr>.sub ack<br>
.param int x<br>
.param int y<br>
if x goto a1<br>
inc y<br>
.return (y)<br>
a1:<br>
if y goto a2<br>
dec x<br>
.return ack(x, 1)<br>
a2:<br>
dec y<br>
y = ack(x, y)<br>
dec x<br>
.return ack(x, y)<br><nobr> <wbr></nobr>.end<br>
</code>
</p><p>
<code>
$ cat ack-unless.pir<br><nobr> <wbr></nobr>.sub ack<br>
.param int x<br>
.param int y<br>
unless x goto a1<br>
unless y goto a2<br>
dec y<br>
y = ack(x, y)<br>
dec x<br>
.return ack(x, y)<br>
a1:<br>
inc y<br>
.return (y)<br>
a2:<br>
dec x<br>
.return ack(x, 1)<br><nobr> <wbr></nobr>.end<br>
</code>
</p><p>And here are the timings of both with<nobr> <wbr></nobr><code>./parrot -Oc -Cj ack-xx.pir 12</code>
on an AMD X2@2000: </p><p> <code>
ack-if 2.9 s<br>
ack-unless 2.4 s</code> </p><p>Branches with positive branch offsets (downwards) are considered to be likely
not taken, that is the fall-through case is the default one. As there are a lot
more positive numbers than the one zero, the <code>unless</code> is the better choice
here (for some CPUs, YMMV). Well, that's at least my
conclusion for now. But there is another issue: branch
alignment. I've not yet experimented with
different label alignments, but I know that alignment can
cause timing differences like above too.</p>leo2006-02-18T21:12:58+00:00journalParrot -Ofun
http://use.perl.org/~leo/journal/28623?from=rss
<p>Heureka - from the -Ofun department</p><p>Or - running the ackermann function (and possibly other recursive
functions) really fast.</p><p> <code>$ time<nobr> <wbr></nobr>./parrot -Oc -C ack.pir 11<br>
Ack(3, 11) = 16381<br>
<br>
real 0m0.567s<br>
user 0m0.559s<br>
sys 0m0.008s<br>
</code> </p><p> <code>$ time<nobr> <wbr></nobr>./ack 11<br>
Ack(3,11): 16381<br>
<br>
real 0m0.980s<br>
user 0m0.978s<br>
sys 0m0.002s<br>
</code> </p><p>The latter is optimized C code. Parrot is recompiling (or will do when that's finished) statically known and simple PIR code to native machine code via it's JIT system.</p><p>See also a recent post on perl6-internals.</p>leo2006-02-08T16:56:09+00:00journalParrot 0.4.1 "Foghorn Leghorn" Released!
http://use.perl.org/~leo/journal/28283?from=rss
<p>Numerous folks contributing more than 640 revisions were helping to create a more powerful <a href="http://en.wikipedia.org/wiki/Foghorn_Leghorn">bird</a>
err <a href="http://www.parrotcode.org/">parrot</a>.
</p><p>Thanks all!</p>leo2006-01-08T16:11:26+00:00journalParrot 0.4.0 "Luthor" Released!
http://use.perl.org/~leo/journal/27855?from=rss
<p>Numerous people have contributed to another major release of <a href="http://www.parrotcode.org/">Parrot</a>: 0.4.0 'Luthor' is out - thanks to all.
</p><p>The release name is of course not related to <a href="http://www.forbes.com/home/lists/2005/11/29/forbes-fictional-rich_cx_mn_de_05fict15land.html">this article</a>, but comes from our brand new <a href="http://svn.perl.org/parrot/trunk/docs/pdds/pdd20_lexical_vars.pod">lexical stuff</a>.
</p>leo2005-12-04T16:53:28+00:00journal"The Continuation Bug" is gone
http://use.perl.org/~leo/journal/27504?from=rss
<p>Today I've checked in the final fix for one of the longest
outstanding bugs inside Parrot.</p><p>A short recap:</p><p>Having first-class continuation objects is one of the design
goals of Parrot. A lot of HLLs support continuations with some
special syntax and with continuations in the core a lot of HLL
control structures and features like exceptions can be implemented easily.
</p><p>But there was a problem with continuations.
Continuations can change the CFG (control flow graph) of a
program in such a way that there are suddenly loops, where the
register allocation code isn't (and can't be) aware of it.</p><p>The following code piece from a test provided by <a href="http://www.bofh.org.uk/">Piers</a> revealed the whole
problem:</p><p> <code>
arr1 = "[1, 3, 5]"<br>
arr2 = "[1, 5, 9]"<br>
x = choose(arr1)<br>
y = choose(arr2)<br>
if (x * y != 15)<br>
fail = find_lex "fail"<br>
fail()</code>
</p><p>To the register allocator this looks like a linear control flow,
which is just executed once (there is no loop outside of that code
snippet). But actually the <code>choose</code> closures are capturing
their continuations and are backtracking through the call to the
<code>fail</code> function. We suddenly have a loop going from
<code>fail()</code> to one of the <code>choose()</code> function
call returns. The code that the register allocator should have been
considering would be something like this:</p><p> <code>
arr1 = "[1, 3, 5]"<br>
arr2 = "[1, 5, 9]"<br>
choose_again_1: # label actually in front of function return<br>
x = choose(arr1)<br>
choose_again_2:<br>
y = choose(arr2)<br>
if (x * y != 15)<br>
fail = find_lex "fail"<br>
fail()<br>
goto choose_again_1 or _2</code> </p><p>This implies that the registers
of the variables <code>x, y, arr2</code> can't be reused for example to
assign a register to the <code>fail</code> variable. But exactly this
has happened and the code really "fail"ed.</p><p>There were some (IMHO) impractical proposals to fix this, like
refetching all variables from lexicals all the time (and don't use
native integers and numbers because these aren't lexicals) but the
real fix for this is now in: that is - just don't reallocate
the registers used by lexicals and non-volatile variables to other
variables like temporaries.</p><p>That's the reason for variable-sized register frames and, well, some
lack of visible progress of Parrot development for some time.</p>leo2005-11-07T23:24:35+00:00journalParrot 0.3.1 "Wart" Released!
http://use.perl.org/~leo/journal/27487?from=rss
<p>After more than 400 revisions within one month the next release of Parrot has arrived on <a href="http://www.cpan.org/authors/id/L/LT/LTOETSCH/parrot-0.3.1.tar.gz">CPAN</a>.</p><p>Thanks to all providing patches and help us with developing <a href="http://www.parrotcode.org/">Parrot</a>.</p>leo2005-11-06T13:54:32+00:00journalParrot 0.3.0 "Alex" Released!
http://use.perl.org/~leo/journal/26960?from=rss
<p>With a lot of help (Robrt, clkao, svk - many thanks) the branch got merged back to trunk and is now released as Parrot 0.3.0. The official announce should make it to the front page soon.</p>leo2005-10-01T15:48:48+00:00journalCalling conventions - a comparison
http://use.perl.org/~leo/journal/26303?from=rss
<p>I've now compared old calling conventions with the new one by
checking bytecode size, executed amount of opcodes, and the timings
of one of the benchmarks.</p><p>I've used the suduku solver and the oo5 benchmark. The latter
does 1 million attribute accesses via a method call, comprising
a typical example of OO code.</p><p>The numbers were achieved by running<tt>
<br>$<nobr> <wbr></nobr>./parrot -o sudoku.pbc examples/assembly/sudoku.pir<br>
$<nobr> <wbr></nobr>./pdump sudoku.pbc | grep size<br>
$<nobr> <wbr></nobr>./parrot -p sudoku.pbc<br>
</tt>
and by
<tt>$<nobr> <wbr></nobr>./parrot -p examples/benchmarks/oo5.imc</tt> or <tt>-C </tt>.
</p><p>Here are the results:</p><blockquote><div><p> <tt>
old new<br>
Sudoku codesize 5764 3442<br>
Sudoku ops -p 911973 793967<br>
oo5 ops -p 22501832 10503606<br>
oo5 time -C 7.5s 4.9s<br>
</tt></p> </div></blockquote><p>The new calling code reduces code size and executed opocdes
significantly, which goes up to a factor of two for the benchmark.
There is also a non-trivial speedup albeit no attempts were done yet to
optimze the new code for speed.</p>leo2005-08-16T14:13:57+00:00journalSlow progress
http://use.perl.org/~leo/journal/25683?from=rss
<p>Two GC bugs (one in my branch, one in both trunk and the branch) slowed down further progress in finishing the calling convention changes. But these bugs are fixed now, and <a href="http://use.perl.org/~coke/journal/">Coke</a> can finish hunting his own in partcl<nobr> <wbr></nobr>;-)</p><p>In return for endless debug sessions, I compared <tt>oo5.imc</tt> and <tt>oo6.imc</tt> from <tt>examples/benchmarks</tt> - these (premature) results are promising: around half of the opcodes saved and more then 20% speedup. These two benchmarks test attribute accessor functions, where the call overhead is considerable.</p>leo2005-07-13T21:27:04+00:00journalContinuations and return context
http://use.perl.org/~leo/journal/25626?from=rss
<p> <b>A correction foremost</b> </p><p>A remark WRT the paragraph mentioning type checking
in my <a href="http://use.perl.org/~leo/journal/25491">first
ewaa journal</a>. It was caused by me
misinterpreting the type conversion specs in <a href="http://svn.perl.org/parrot/trunk/docs/pdds/pdd03_calling_conventions.pod">pdd03</a>. We are
now doing full type conversion, which makes argument
passing strictly positional. That's very likely the
expectation of our <a href="http://svn.perl.org/parrot/trunk/docs/req/model_users.pod">users</a> anyway. In the old scheme calling a
subroutine:</p><p> <code>foo(pmc b, str a) # pseudosyntax to denote argument
types</code> </p><p>just worked, despite the sub was defined as:</p><p><nobr> <wbr></nobr><code>.sub foo<br><nobr> <wbr></nobr>.param str a<br><nobr> <wbr></nobr>.param pmc b</code>
</p><p>Looks weird, but was really used, probably more by
accident then for some good reason. Now you get the first
argument converted to a string and the second as a new
string PMC.</p><p> <b>Continuations and return context</b> </p><p>As Dan describes in his <a href="http://www.sidhe.org/~dan/blog/archives/000423.html">blog</a>,
there is not much difference between a subroutine call and
the invocation of a continuation. Both can return results to
the caller. A nice example provided by <a href="http://www.bofh.org.uk/">Piers</a> from Parrot's <a href="http://svn.perl.org/parrot/trunk/t/op/gc.t">tests</a>
(yeah, number 13) contains something like:</p><p> <code>x = choose([1, 3, 5])<br>
y = choose([1, 5, 9])<br>
if (x * y != 15)<br>
fail()</code>
</p><p>Above is vastly simplified, because the <i>choose</i>
function calls capture their continuations and call a
<i>try</i> closure that either backtracks via the saved
<i>fail </i> hook or delivers the next item from the passed
in choices array. Anyway the interesting thing (for a proper
implementation of continuations) is, that there are
mupltiple continuations that like to return either the next
<i>x</i> or <i>y</i>, when invoked indirectly via the
<i>fail</i> function. These continuations are not only
returning to different program locations they are also
returning different results.</p><p>In the source we got this line:</p><p> <code>our_cc($P3) # $P3 being one of the next choices</code> </p><p>where eventually the next result for <i>choose</i> is
to be returned to the main program. It looks like a plain
subroutine call, but invokes the passed in continuation and
ends up, where one of the <i>choose</i> calls had left off.</p><p>This means that creating a full continuation still needs
to copy the context structure (which contains also the current
return results location). A return continuation
can just contain a pointer to the refered context.</p><p>After having implemented this all now, the rather
complicated tests (p6rules, streams), which are using
continuations as well as coroutines are passing within my
branch (I didn't look at other failing tests yet, but just
converting explicit register usage for call setup to new
conventions should fix almost all). These tests are of
course passing in Parrot svn trunk true, but now (for the
most common case of invoking a return continuation) no
context is copied at all, it's just a matter of putting the pointer
of the captured context into the interpreter.</p><p>The official way to do <i>call/cc</i> is still
unchanged, it's:</p><p>
<code><nobr> <wbr></nobr>.include "interpinfo.pasm"<br>
cc = interpinfo<nobr> <wbr></nobr>.INTERPINFO_CURRENT_CONT</code>
</p><p>This usually means that you need a helper subroutine,
where you capture the continuation (and pass it along
somewhere for later usage), it's OTOH a well defined usage of
continuations in e.g. <i>scheme</i>. When things are
settling, I'm sure that we can provide some shortcuts for
capturing continuations inside the same sub (or context)
too.</p><p>And implementing <i>want</i> or similar is of course
simple now, as the <i>get_results</i> opcode is emitted
before the subroutine invocation, and is therefore available
for plain function returns as well as for continuations that
return a result. Both can return what the caller
<i>want</i>s, because the information is present in the
context.</p>leo2005-07-10T21:17:06+00:00journal360 KByte and done
http://use.perl.org/~leo/journal/25552?from=rss
<p>Well, the <tt>svn diff</tt> got bigger a bit and operation is now that far consolidated that I've committed it to a new branch <tt>branches/leo-ctx5</tt>, so that @all can investigate it and start helping to get it finished soon.</p>leo2005-07-06T21:40:12+00:00journal160 KBytes and still counting
http://use.perl.org/~leo/journal/25532?from=rss
<p>Well, 160 Kbytes are my diffs now against Parrot svn HEAD. And still no chance to check it in, without blocking $others, because too much still is failing.</p><p>Done:</p><ul>
<li> <code>r = foo(a, b)</code> translates now to new call scheme opcodes, as well as<nobr> <wbr></nobr><code>.param</code> and<nobr> <wbr></nobr><code>.returns()</code> stuff. Just tossed 460 lines in <i>imcc/pcc.c</i> and added 20 new. Works fine.</li><li>Converted the NCI generation code to the new scheme too.</li><li>Running Parrot Subs from C code now also uses new conventions</li></ul><p>Overall it looks like that calling PASM/PASM is by far simpler now, but PASM/C (<i>NCI</i>) and C/PASM (<i>runops_fromc_*</i>) interfaces use slightly more code lines. OTOH we get now strict type checking and conversions to and from PMCs, which wasn't in the old scheme.
I can very well imagine that we don't want to call C code w/o argument verification anyway.</p>leo2005-07-05T19:35:51+00:00journalContext patch is getting ready
http://use.perl.org/~leo/journal/25512?from=rss
<p>Wrote a second context allocation strategy today.
Just malloc/free backed by a free list. Works fine, except
that it seems to reveal a very likely unrelated GC bug, which
I'm still chasing.</p><p>Yesterday was <a href="http://xrl.us/gnie">"Somehow Olympia"</a> (German text) here in Herrnbaumgarten. We had a lot of fun
for example watching "towel throwing for politicians".</p>leo2005-07-04T20:11:05+00:00journalParrot Calling Conventions
http://use.perl.org/~leo/journal/25491?from=rss
<b>WWCPD: Calling Conventions</b>
<p>The original design was not only rather <a href="http://www.sidhe.org/~dan/blog/archives/000413.html">heavyweight</a>,
it was also incomplete and a bit blurry. It was lacking
support for MMD argument signatures, return value context,
typechecking, and so on.</p><p>I'll try do describe some reasons, why we changed calling conventions
to use a <a href="http://svn.perl.org/parrot/trunk/docs/pdds/pdd03_calling_conventions.pod">
new abstract scheme</a>. The major change is that all the
argument passing is now done by dedicated opcodes, which
allows any later implementation and adaption under the hood
without changing the ABI of the <a href="http://www.parrotcode.org/">Parrot VM</a>.</p><p>
<b>MMD Signatures</b>
</p><p>A function call:</p><p>
<code> foo(Px, Iy)</code>
</p><p>was translated to these argument-related opcodes (function
lookup and call opcodes omitted for brevity):</p><p>
<code> set I0, 1 # prototyped call<br>
set I1, 1 # 1 INT argument<br>
set I2, 0 # 0 STR arguments<br>
set I3, 1 # 1 PMC argument<br>
set I4, 0 # 0 NUM arguments<br>
set P5, Px # get PMC argument<br>
set I5, Iy # get INT argument<br>
set S0, "foo" # function name</code>
</p><p>A lot of opcodes to dispatch, but takes almost no time with
the JIT runtime. Fine so far. Another function call:</p><p>
<code> foo(Ix, Py)</code>
</p><p>produced exactly the same call register setup - these two
function calls can not be discerned when, it comes to multi
method dispatch.</p><p>Now the first argument setup just translates to:</p><p>
<code> set_args "(0b10,0)", Px, Iy</code>
</p><p>and the second is:</p><p>
<code> set_args "(0,0b10)", Ix, Py</code>
</p><p>Thus we not only saved 7 opcode dispatches per function
call, we got a clear type information of the caller's
arguments including the argument order. You don't have to
set these type bits yourself, the assembler does it
according to the passed arguments, so just writing: </p><p>
<code> set_args "(0,0)", Ix, Py</code>
</p><p>works fine.</p><p>
<b>Type checking</b>
</p><p>In the old scheme you could happily call a function
with:</p><p>
<code> foo(Px, Iy)</code>
</p><p>which was defined as:</p><p>
<code><nobr> <wbr></nobr>.sub foo<br><nobr> <wbr></nobr>.param float n<br><nobr> <wbr></nobr>.param string s</code>
</p><p>The<nobr> <wbr></nobr>.param was just translated to:</p><p>
<code> foo:<br>
set Nx, N5 # get 1st NUM param into n<br>
set Sy, I5 # get 1st STR param into s</code>
</p><p>Due to the register usage of argument passing the function
would have picked up whatever happens to be in registers N5
and S5 and would run - probably not long though. A possible
"solution" would have been to force all compilers and Parrot
hackers to emit code to first verify the passed arguments.
That's of course another bunch of opcodes, bulky and
error-prone. Now the function defines precisely what it
awaits:</p><p>
<code><nobr> <wbr></nobr>.sub foo<br>
get_params "(0b11,0b1)", Nx, Sy</code>
</p><p>Again the type bits are filled in by the assembler. But
during the call sequence, the argument passing code can
verify the types (and counts) of arguments and parameters.
Conversions to and from PMC parameters are specified and
done automatically. Mismatches are reported by an
exception.</p><p>
<b>Implicit register usage</b>
</p><p>The central mechanism of a function call in the old scheme
was just the plain argumentless opcode:</p><p>
<code> invoke</code>
</p><p>It would pick up whatever happens to be in P1 and uses it as
the continuation of the call. P2 was defined to be the
invocant, if it's a method call. And so on - and it call's
whatever is in P0. That's per se fine, if all code writers
and compilers strictly use this convention and don't forget
to NULLify registers that shouldn't be used for the call,
but it's a major PITA for the assembler, which ought to
track the control flow for proper register allocation: is the
invoke a function call, a yield, a return from a function?
Well it's not defined, it could be everything. Not a few
lines inside imcc are trying to track down the usage of invoke
opcodes to do the right thing. You can imagine that this
does not contribute to clear code.</p><p>
<b>Method invocant</b>
</p><p>The old call scheme demanded that the invocant is passed
out-of-band in P2. It's also only available in functions
declared as methods by a special <i>interpinfo</i> call. This
doesn't really match our major target languages, where the
invocant just happens to be the first param of a method.</p><p>Calling a function as a method or vice versa would have
needed to shift PMC arguments down or up to get everything
into the registers that the callee expects.</p><p>
<b>Return value context</b>
</p><p>The old scheme had no provision for specifying, what and how
many return results the caller expects. Now the
<i>get_results</i> opcode is emitted before the actual function
call, so that a function return has a chance to return what
the caller <i>want</i>s.</p><p>
<b>Future and optimization</b>In the old scheme the lower 16 registers of each kind
were volatile (each function return could set these
registers). This implies that you usually have to move
registers from the preserved area into the lower half,
during the call sequence registers are moved into the
callee's lower half, from where another round through all
parameters would have placed everything in the preserved
area. This are three passes over all arguments - hardly to
avoid in the general case.</p><p>The old call scheme reserved 4*16 registers just for
function calls and returns. This accounts for 320 bytes (on
a 32-bit machine) that have to be allocated per call to pass
e.g. just one word argument to an one-liner function or an
attribute accessor method.</p><p>Ok, we are not doing optimzation now - that's fine. But the
old calling scheme would have prevented all future
optimizations that will be needed. You can't do any
optimizations later when the call scheme is carved in stone
and just reserves half of the register resources for
itself.</p><p>---<br>WWCPD<nobr> <wbr></nobr>... why we change(d) parrot's design</p>leo2005-07-03T11:46:19+00:00parrot