The MMTk Test Harness
Overview
The MMTk harness is a debugging tool. It allows you to run MMTk with a simple client - a simple Java-like scripting language - which can explicitly allocate objects, create and delete references, etc. This allows MMTk to be run and debugged stand-alone, without the entire VM, greatly simplifying initial debugging and reducing the edit-debug turnaround time. This is all accessible through the command line or an IDE such as eclipse.
Running the test harness
The harness can be run standalone or via Eclipse (or other IDE).
Standalone
ant mmtk-harness java -jar target/mmtk/mmtk-harness.jar <script-file> [options...]
There is a collection of sample scripts in the MMTk/harness/test-scripts directory.
In Eclipse
ant mmtk-harness-eclipse-project
Define a new run configuration with main class org.mmtk.harness.Main.
You can configure eclipse to display vmmagic values (Address/ObjectReference/etc) using their toString method through the Eclipse -> Preferences... -> Java -> Debug -> Detail Formatters menu. The simplest option is to check the boxto use toString 'As the label for all variables'.
Test harness options
Options are passed to the test harness as 'keyword=value' pairs. The standard MMTk options that are available through JikesRVM are accepted (leave off the "-X:gc:"), as well as the following harness-specific options:
| Option |
Meaning |
|---|---|
| plan | The MMTk plan class. Defaults to org.mmtk.plan.marksweep.MS |
| collectors | The number of concurrent collector threads (default: 1) |
| initHeap | Initial heap size |
| maxHeap | Maximum heap size (default: 64 pages) |
| trace | Debugging messages from the MMTk Harness. Trace options include
|
| gcEvery | Force frequent GCs. Options are
|
Basics
The language has two types: integer and object. Objects are allocated
with the 'alloc' statement, and have a specified number of pointers and
nonpointers (integers). Variables are declared 'c' style, and are optionally
initialized at declaration.
Object fields are referenced using syntax like "tmp.int[5]" or "tmp.object[i*3]",
ie like a struct of arrays of the appropriate types.
Syntax
script ::= method...
method ::= ident "(" { type ident { "," type ident}... ")" "{" statement... "}"
statement ::=
"if" "(" expr ")" block { "elif" "(" expr ")" block } [ "else" block ]
| "while "(" expr ")" block
| [ [ type ] ident "=" ] "alloc" "(" expr "," expr [ "," expr ] ")" ";"
| [ ident "=" ] "hash" "(" expr ")" ";"
| "gc" "(" ")"
| "spawn" "(" ident [ "," expr ]... ")" ";"
| type ident [ "=" expr ] ";"
| lvalue "=" expr ";"
lvalue ::= ident "=" expr ";"
| ident "." type "[" expr "]"
type ::= "int" | "object"
expr ::= expr binop expr
| unop expr
| "(" expr ")"
| ident
| ident "." type "[" expr "]"
| int-const
| intrinsic
intrinsic ::= "alloc" "(" expr "," expr ["," expr] ")
| "(" expr ")"
| "gc " "(" ")"
binop ::= "+" | "-" | "*" | "/" | "%" | "&&" | "||" | "==" | "!="
unop ::= "!" | "-"