parrotcode: running | |
Contents | Documentation |
Parrot - running
$Revision$
This document describes Parrot's command line options.
parrot [-options] <file> [arguments ...]
"parrot -d 0ffff ..."
. Note: If the argument is separated by whitespace from the -d switch, it has to start with a number.-Op
.-o
or --output-pbc
. Run the program from the compiled in-memory image. If two -r
options are given, the .pbc file is read from disc and run. This is mainly needed for tests.-v
shows which files are worked on and prints a summary over register usage and optimization stats per compilation unit. With two -v
switches, parrot
prints a line per individual processing step too. -O0 no optimization (default)
-O1 optimizations without life info (e.g. branches)
-O same
-O2 optimizations with life info
-Op rewrite I and N PASM registers most used first
-Ot select fastest runcore (default with -O1 and -O2)
-Oc turns on the optional/experimental tail call optimizations
$ parrot -E t/op/macro_10.pasm
$ parrot -E t/op/macro_10.pasm | parrot -- -
These options select the runcore, which is useful for performance tuning and debugging. See "About runcores" for details.
slow, bounds bounds checking core (default)
fast fast core (no bounds checking, profiling, or tracing)
switch switch core
cgp computed goto-predereferenced core
cgoto computed goto core
jit JIT core
cgp-jit computed goto-predereferenced core with JIT
switch-jit switch core with JIT
exec exec core (uses JIT at compile time to generate native code)
trace bounds checking core w/ trace info (see 'parrot --help-debug')
gcdebug performs a full GC run before every op dispatch (good for
debugging GC problems)
parrot --help-debug
for available flag bits.parrot --help-debug
for available flag bits.parrot --help-debug
for available flag bits.If the file ends in .pbc it will be interpreted immediately.
If the file ends in .pasm, then it is parsed as PASM code. Otherwise, it is parsed as PIR code. In both cases, it will then be run, unless the -o
flag was given.
If the file
is a single dash, input from stdin
is read.
Optional arguments passed to the running program as ARGV. The program is assumed to know what to do with these.
If JIT debugging is enabled (e.g. via --parrot-debug 04
), the following additional output files are generated:
F<file.stabs.s> stabsfile for the program
F<file.o> object file with debug information
F<EVAL_n> source of C<compile> op number I<n>
F<EVAL_n.stabs.s> stabsfile for this block
F<EVAL_n.o> object file with debug information
See docs/jit.pod for further information.
The runcore (or runloop) tells Parrot how to find the C code that implements each instruction. Parrot provides more than one way to do this, partly because no single runcore will perform optimally on all architectures (or even for all problems on a given architecture), and partly because some of the runcores have specific debugging and tracing capabilities.
In the default "slow" runcore, each opcode is a separate C function. That's pretty easy in pseudocode:
slow_runcore( op ):
while ( op ):
op = op_function( op )
check_for_events()
The GC debugging runcore is similar:
gcdebug_runcore( op ):
while ( op ):
perform_full_gc_run()
op = op_function( op )
check_for_events()
Of course, this is much slower, but is extremely helpful for pinning memory corruption problems that affect GC down to single-instruction resolution. See http://www.oreillynet.com/onlamp/blog/2007/10/debugging_gc_problems_in_parro.html for more information.
The trace and profile cores are also based on the "slow" core, doing full bounds checking, and also printing runtime information to stderr.
The switched core eschews these tiny op functions in favor of cases in a large switch statement:
switch_runcore( op ):
while ( op ):
switch *op:
case NOP:
...
case STORE:
...
...
Depending on the C compiler implementation, this may be faster than function calling. On older systems, it may fail to compile altogether.
The computed-goto ("cgoto") runcore avoids the overhead of function calls by jumping directly to the address where each opcode's function starts. The computed-goto-prederef ("CGP") core takes this one step further by replacing opcode numbers in the bytecode with those opfunc addresses. See "Predereferencing" in docs/glossary.pod for a fuller explanation.
Finally, the JIT runcore uses the "slow" core, but also creates and jumps to JIT-compiled native code for supported opcodes. "cgp-jit" and "switched-jit" are variations that use the CGP or switched core but run JIT code when possible.
Command Line Action Output
---------------------------------------------
parrot x.pir run
parrot x.pasm run
parrot x.pbc run
-o x.pasm x.pir ass x.pasm
-o x.pasm y.pasm ass x.pasm
-o x.pbc x.pir ass x.pbc
-o x.pbc x.pasm ass x.pbc
-o x.pbc -r x.pasm ass/run pasm x.pbc
-o x.pbc -r -r x.pasm ass/run pbc x.pbc
-o x.o x.pbc obj
... where the possible actions are:
run ... yes, run the program
ass ... assemble sourcefile
obj .. produce native (ELF) object file for the EXEC subsystem
Yes.
main.c
Leopold Toetsch lt@toetsch.at
|