From: <rg...@us...> - 2008-06-27 06:48:21
|
Revision: 14595 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14595&view=rev Author: rgarner Date: 2008-06-26 23:48:15 -0700 (Thu, 26 Jun 2008) Log Message: ----------- MMTk harness: - Allow procedures to return values - Add a command-line selectable trace mechanism - Add "GC Stress" command-line option Modified Paths: -------------- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Harness.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Mutator.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Alloc.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Assignment.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Call.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Empty.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Env.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/GC.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/IfStatement.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Method.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/ObjectValue.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Sequence.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Spawn.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/StackFrame.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Statement.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/StoreField.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/WhileStatement.java rvmroot/trunk/MMTk/harness/src-generated/org/mmtk/harness/lang/parser/Parser.jj rvmroot/trunk/MMTk/harness/test-scripts/README rvmroot/trunk/build.xml Added Paths: ----------- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Return.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/ReturnException.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Trace.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/options/GcEvery.java rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/options/Trace.java rvmroot/trunk/MMTk/harness/test-scripts/lang/recursive2.script Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Harness.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Harness.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Harness.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -15,10 +15,12 @@ import java.util.ArrayList; import org.mmtk.harness.options.Collectors; +import org.mmtk.harness.options.GcEvery; import org.mmtk.harness.options.HarnessOptionSet; import org.mmtk.harness.options.InitHeap; import org.mmtk.harness.options.MaxHeap; import org.mmtk.harness.options.Plan; +import org.mmtk.harness.options.Trace; import org.mmtk.harness.vm.*; import org.mmtk.utility.heap.HeapGrowthManager; @@ -44,6 +46,12 @@ /** Option for the maximum heap size */ public static MaxHeap maxHeap = new MaxHeap(); + /** Trace options */ + public static Trace trace = new Trace(); + + /** GC stress options */ + public static GcEvery gcEvery = new GcEvery(); + /** * Start up the harness, including creating the global plan and constraints, * and starting off the collector threads. @@ -59,6 +67,8 @@ for(String arg: args) { if (!options.process(arg)) newArgs.add(arg); } + trace.apply(); + gcEvery.apply(); MMTkThread thread = new MMTkThread((new Runnable() { public void run() { Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Mutator.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Mutator.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/Mutator.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -15,6 +15,8 @@ import java.util.ArrayList; import org.mmtk.harness.lang.Env; +import org.mmtk.harness.lang.Trace; +import org.mmtk.harness.lang.Trace.Item; import org.mmtk.harness.vm.ActivePlan; import org.mmtk.harness.vm.ObjectModel; import org.mmtk.plan.MutatorContext; @@ -395,7 +397,7 @@ check(refCount >= 0, "Non-negative reference field count required"); check(dataCount >= 0, "Non-negative data field count required"); ObjectReference result = ObjectModel.allocateObject(context, refCount, dataCount, doubleAlign); - if (Env.TRACE) System.err.println("alloc(" + refCount + ", " + dataCount + ", " + doubleAlign + ") returned [" + result + "]"); + Trace.trace(Item.ALLOC,"alloc(" + refCount + ", " + dataCount + ", " + doubleAlign + ") returned [" + result + "]"); return result; } } Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Alloc.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Alloc.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Alloc.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -12,9 +12,21 @@ */ package org.mmtk.harness.lang; +import org.mmtk.vm.Collection; +import org.mmtk.vm.VM; import org.vmmagic.unboxed.ObjectReference; public class Alloc implements Expression { + /** GC stress - GC on every allocation */ + private static boolean gcEveryAlloc = false; + + /** + * GC stress - GC after every allocation + */ + public static void setGcEveryAlloc() { + gcEveryAlloc = true; + } + /** Number of reference fields */ private final Expression refCount; /** Number of data fields */ @@ -35,21 +47,44 @@ * Perform the allocation by calling MMTk. */ public Value eval(Env env) { - Value refCountVal = refCount.eval(env); - env.gcSafePoint(); + int refCountVal = evalInt(env, refCount, "Number of reference fields must be an integer"); + int dataCountVal = evalInt(env,dataCount, "Number of data fields must be an integer"); + boolean doubleAlignVal = evalBoolVal(env, doubleAlign, "DoubleAlign must be a boolean"); - Value dataCountVal = dataCount.eval(env); - env.gcSafePoint(); + ObjectReference object = env.alloc(refCountVal, dataCountVal, doubleAlignVal); + if (gcEveryAlloc) VM.collection.triggerCollection(Collection.EXTERNAL_GC_TRIGGER); + return new ObjectValue(object); + } - Value doubleAlignVal = doubleAlign.eval(env); - env.gcSafePoint(); + /** + * Evaluate a boolean expression, type-check and return a boolean + * @param env + * @param doubleAlign2 + * @param message + * @return + */ + private boolean evalBoolVal(Env env, Expression doubleAlign2, String message) { + Value doubleAlignVal = doubleAlign2.eval(env); - env.check(refCountVal.type() == Type.INT, "Number of reference fields must be an integer"); - env.check(dataCountVal.type() == Type.INT, "Number of data fields must be an integer"); - env.check(doubleAlignVal.type() == Type.BOOLEAN, "DoubleAlign must be a boolean"); + env.check(doubleAlignVal.type() == Type.BOOLEAN, message); - ObjectReference object = env.alloc(refCountVal.getIntValue(), dataCountVal.getIntValue(), doubleAlignVal.getBoolValue()); + boolean doubleAlignBool = doubleAlignVal.getBoolValue(); + env.gcSafePoint(); + return doubleAlignBool; + } - return new ObjectValue(object); + /** + * Evaluate an int expression, type-check and return an int + * @param env + * @param doubleAlign2 + * @param message + * @return + */ + private int evalInt(Env env, Expression refCount2, String message) { + Value refCountVal = refCount2.eval(env); + env.check(refCountVal.type() == Type.INT, message); + int refCountInt = refCountVal.getIntValue(); + env.gcSafePoint(); + return refCountInt; } } Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Assignment.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Assignment.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Assignment.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -32,7 +32,7 @@ /** * Perform the assignment. */ - public void exec(Env env) { + public void exec(Env env) throws ReturnException { env.top().set(slot, expr.eval(env)); } } Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Call.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Call.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Call.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -13,12 +13,14 @@ package org.mmtk.harness.lang; import java.util.List; + +import org.mmtk.harness.lang.Trace.Item; import org.mmtk.harness.lang.parser.MethodTable; /** * A call to a method. */ -public class Call implements Statement { +public class Call implements Statement, Expression { /** Method table */ private final MethodTable methods; /** Method name */ @@ -38,9 +40,41 @@ /** * Run this statement. */ - public void exec(Env env) { + public void exec(Env env) throws ReturnException { Method method = methods.get(methodName); + Value[] values = evalParams(env); + popTemporaries(env, values); + method.exec(env, values); + } + + /** + * Call as an expression + */ + @Override + public Value eval(Env env) { + Method method = methods.get(methodName); + + Value[] values = evalParams(env); + + if (Trace.isEnabled(Item.CALL)) { + System.out.printf("Call %s(",methodName); + for (int i=0; i < values.length; i++) { + System.out.printf("%s%s",values[i].toString(),i == values.length-1 ? ")\n" : ", "); + } + } + popTemporaries(env, values); + // No GC safe points between here and when everything is saved in the callee's stack + return method.eval(env, values); + } + + /** + * Evaluate method parameters, ensuring that temporaries are gc-safe between + * each evaluation. + * @param env + * @return + */ + private Value[] evalParams(Env env) { Value[] values = new Value[params.size()]; for(int i=0; i < params.size(); i++) { values[i] = params.get(i).eval(env); @@ -48,13 +82,19 @@ env.pushTemporary(values[i]); env.gcSafePoint(); } + return values; + } - // No GC safe points between here and when everything is saved in the callee's stack + /** + * Pop all temporaries off the stack + * @param env + * @param values + */ + private void popTemporaries(Env env, Value[] values) { for(int i=params.size() - 1; i >= 0; i--) { env.popTemporary(values[i]); } - method.exec(env, values); + } - env.gcSafePoint(); - } + } Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Empty.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Empty.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Empty.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -24,6 +24,6 @@ /** * Execute the empty statement (do nothing) */ - public void exec(Env env) { + public void exec(Env env) throws ReturnException { } } Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Env.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Env.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Env.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -16,11 +16,16 @@ import org.mmtk.harness.Mutator; import org.mmtk.plan.TraceLocal; +import org.mmtk.vm.Collection; +import org.mmtk.vm.VM; /** * An execution environment */ public class Env extends Mutator { + + private static boolean gcEverySafepoint = false; + /** * The stack */ @@ -45,13 +50,21 @@ this.body = body; } + public static void setGcEverySafepoint() { + gcEverySafepoint = true; + } + /** * Thread.run() */ @Override public void run() { begin(); - body.exec(this); + try { + body.exec(this); + } catch (ReturnException e) { + // Ignore return values on thread exit + } end(); } @@ -99,6 +112,14 @@ } } + @Override + public boolean gcSafePoint() { + if (gcEverySafepoint) VM.collection.triggerCollection(Collection.EXTERNAL_GC_TRIGGER); + return super.gcSafePoint(); + } + + + /** * Push a temporary value to avoid GC errors for objects held during expression evaluation. * Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/GC.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/GC.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/GC.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -28,7 +28,7 @@ /** * Trigger a garbage collection */ - public void exec(Env env) { + public void exec(Env env) throws ReturnException { VM.collection.triggerCollection(Collection.EXTERNAL_GC_TRIGGER); } } Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/IfStatement.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/IfStatement.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/IfStatement.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -40,7 +40,7 @@ * to true, then execute the corresponding statement. If all evaluate * to false, and there is an 'extra' statement, execute it. */ - public void exec(Env env) { + public void exec(Env env) throws ReturnException { Iterator<Statement> stmtIter = stmts.iterator(); for (Expression cond : conds) { Value condVal = cond.eval(env); Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Method.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Method.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Method.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -17,7 +17,7 @@ /** * A method is a set of variable declarations followed by a statement. */ -public class Method implements Statement { +public class Method implements Statement, Expression { /** The name of this block */ private final String name; /** Number of parameters */ @@ -40,7 +40,7 @@ /** * Execute the statements in the method. */ - public void exec(Env env) { + public void exec(Env env) throws ReturnException { exec(env, new Value[] {}); } @@ -57,6 +57,43 @@ public void exec(Env env, Value...values) { StackFrame frame = new StackFrame(decls); env.push(frame); + setParams(env, values); + env.gcSafePoint(); + /* values could be trashed from here down ... */ + try { + body.exec(env); + } catch (ReturnException e) { + // Ignore return values + } + env.gcSafePoint(); + env.pop(); + } + + public Value eval(Env env) { + return eval(env, new Value[] {}); + } + + /** + * Execute the statements in the method (with passed parameters). + */ + public Value eval(Env env, Value...values) { + StackFrame frame = new StackFrame(decls); + env.push(frame); + setParams(env, values); + env.gcSafePoint(); + /* values could be trashed from here down ... */ + try { + body.exec(env); + } catch (ReturnException e) { + env.gcSafePoint(); + env.pop(); + return e.getResult(); + } + env.check(false, "method didn't return a value"); + return null; + } + + private void setParams(Env env, Value... values) { env.check(values.length == params, "Invalid number of parameters"); for(int i=0; i<values.length; i++) { Type expected = env.top().getType(i); @@ -64,9 +101,5 @@ env.check(expected == actual, "Method " + name + " parameter " + i + " expected " + expected + " found " + actual); env.top().set(i, values[i]); } - env.gcSafePoint(); - body.exec(env); - env.gcSafePoint(); - env.pop(); } } Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/ObjectValue.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/ObjectValue.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/ObjectValue.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -12,6 +12,7 @@ */ package org.mmtk.harness.lang; +import org.mmtk.harness.lang.Trace.Item; import org.mmtk.plan.TraceLocal; import org.vmmagic.unboxed.ObjectReference; @@ -19,14 +20,20 @@ * Expression consisting of a simple object value */ public class ObjectValue extends Value { + /** Hand out unique IDs for object variables */ + private static int last_id = 0; + /** The reference to the heap object */ private ObjectReference value; + /** A unique ID for this object value */ + private final int id; + /** * Construct an initially null object value */ public ObjectValue() { - this.value = ObjectReference.nullReference(); + this(ObjectReference.nullReference()); } /** @@ -43,12 +50,15 @@ */ public ObjectValue(ObjectReference value) { this.value = value; + this.id = last_id++; } /** * Copy the value from the given new value. */ public void copyFrom(Value newValue) { + Trace.trace(Item.OBJECT, "copy %d(%s) from %d(%s)", id, value.toString(), + ((ObjectValue)newValue).id, newValue.toString()); this.value = newValue.getObjectValue(); } Added: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Return.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Return.java (rev 0) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Return.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -0,0 +1,29 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Common Public License (CPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/cpl1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.harness.lang; + +public class Return implements Statement { + + private final Expression expr; + + public Return(Expression expr) { + this.expr = expr; + } + + @Override + public void exec(Env env) throws ReturnException { + Value val = expr.eval(env); + throw new ReturnException(val); + } + +} Property changes on: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Return.java ___________________________________________________________________ Name: svn:mime-type + text/plain Added: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/ReturnException.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/ReturnException.java (rev 0) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/ReturnException.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -0,0 +1,28 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Common Public License (CPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/cpl1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.harness.lang; + +class ReturnException extends Exception { + private final Value result; + + public ReturnException(Value result) { + super(); + this.result = result; + } + + Value getResult() { + return result; + } + + private static final long serialVersionUID = 0; +} Property changes on: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/ReturnException.java ___________________________________________________________________ Name: svn:mime-type + text/plain Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Sequence.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Sequence.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Sequence.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -40,7 +40,7 @@ /** * Execute the statements in sequence */ - public void exec(Env env) { + public void exec(Env env) throws ReturnException { for (Statement s : stmts) { s.exec(env); env.gcSafePoint(); Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Spawn.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Spawn.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Spawn.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -38,7 +38,7 @@ /** * Run this statement. */ - public void exec(Env env) { + public void exec(Env env) throws ReturnException { Value[] values = new Value[params.size()]; for(int i=0; i < params.size(); i++) { values[i] = params.get(i).eval(env); Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/StackFrame.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/StackFrame.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/StackFrame.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -37,7 +37,7 @@ * Declare a variable in a given slot */ public void declare(Declaration d) { - values[d.slot] = d.initial; + values[d.slot] = d.initial.clone(); names[d.slot] = d.name; } Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Statement.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Statement.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Statement.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -19,6 +19,7 @@ /** * Execute the statement, possibly with side-effects on the environment. + * @throws ReturnException as the result of a 'return' statement */ - void exec(Env env); + void exec(Env env) throws ReturnException; } Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/StoreField.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/StoreField.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/StoreField.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -42,7 +42,7 @@ * Evaluate the field index expression, and then the value expression. * Store the result into the appropriate field. */ - public void exec(Env env) { + public void exec(Env env) throws ReturnException { Value fieldVal = index.eval(env); env.gcSafePoint(); Value assignVal = value.eval(env); Added: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Trace.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Trace.java (rev 0) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Trace.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -0,0 +1,43 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Common Public License (CPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/cpl1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.harness.lang; + +import java.util.EnumSet; + +public class Trace { + public enum Item { ALLOC, CALL, OBJECT } + + private static EnumSet<Item> enabled = EnumSet.noneOf(Item.class); + + static { + //enable(Item.ALLOC); + } + + public static void enable(String item) { + enable(Item.valueOf(item)); + } + + public static void enable(Item item) { + enabled.add(item); + } + + public static boolean isEnabled(Item item) { + return enabled.contains(item); + } + + public static void trace(Item item, String pattern, Object...args) { + if (isEnabled(item)) { + System.out.printf("["+item+"] "+pattern+"%n",args); + } + } +} Property changes on: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/Trace.java ___________________________________________________________________ Name: svn:mime-type + text/plain Modified: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/WhileStatement.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/WhileStatement.java 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/lang/WhileStatement.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -30,7 +30,7 @@ this.body = body; } - public void exec(Env env) { + public void exec(Env env) throws ReturnException { while (cond.eval(env).getBoolValue()) { body.exec(env); env.gcSafePoint(); Added: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/options/GcEvery.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/options/GcEvery.java (rev 0) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/options/GcEvery.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -0,0 +1,49 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Common Public License (CPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/cpl1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.harness.options; + +import org.mmtk.harness.Harness; +import org.mmtk.harness.lang.Alloc; +import org.mmtk.harness.lang.Env; + +/** + * Number of collector threads. + */ +public final class GcEvery extends org.vmutil.options.EnumOption { + /** + * Create the option. + */ + public GcEvery() { + super(Harness.options, "GcEvery", + "MMTk Harness gc-stress", + new String[] { "NONE", "ALLOC", "SAFEPOINT" }, 0); + } + + public void apply() { + switch(getValue()) { + case 0: + break; + case 1: + Env.setGcEverySafepoint(); + case 2: + Alloc.setGcEveryAlloc(); + break; + } + } + + /** + * Only accept non-negative values. + */ + protected void validate() { + } +} Property changes on: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/options/GcEvery.java ___________________________________________________________________ Name: svn:mime-type + text/plain Added: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/options/Trace.java =================================================================== --- rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/options/Trace.java (rev 0) +++ rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/options/Trace.java 2008-06-27 06:48:15 UTC (rev 14595) @@ -0,0 +1,46 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Common Public License (CPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/cpl1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.harness.options; + +import org.mmtk.harness.Harness; + +/** + * Number of collector threads. + */ +public final class Trace extends org.vmutil.options.EnumOption { + /** + * Create the option. + */ + public Trace() { + super(Harness.options, "Trace", + "Harness debugging trace options", + new String[] { "none", "CALL", "ALLOC", "OBJECT" }, 0); + } + + public void apply() { + switch(getValue()) { + case 0: + break; + default: { + org.mmtk.harness.lang.Trace.enable(values[getValue()]); + break; + } + } + } + + /** + * Only accept non-negative values. + */ + protected void validate() { + } +} Property changes on: rvmroot/trunk/MMTk/harness/src/org/mmtk/harness/options/Trace.java ___________________________________________________________________ Name: svn:mime-type + text/plain Modified: rvmroot/trunk/MMTk/harness/src-generated/org/mmtk/harness/lang/parser/Parser.jj =================================================================== --- rvmroot/trunk/MMTk/harness/src-generated/org/mmtk/harness/lang/parser/Parser.jj 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/src-generated/org/mmtk/harness/lang/parser/Parser.jj 2008-06-27 06:48:15 UTC (rev 14595) @@ -73,8 +73,10 @@ < HASH: "hash" > | < IF : "if" > | < INT : "int" > | + < NULL : "null" > | < OBJECT : "object" > | < PRINT : "print" > | + < RETURN : "return" > | < SPAWN : "spawn" > | < TID : "tid" > | < WHILE : "while" > @@ -145,8 +147,10 @@ Statement stmt; String name; int params = 0; + Type retType; } { + (retType=type())? name=ident() <LPAREN> ( declaration1(methods, symbols) { params++; } ( <COMMA> declaration1(methods, symbols) { params++; } )* )? <RPAREN> @@ -188,7 +192,8 @@ stmt=whileLoop(methods, symbols) | stmt=print(methods, symbols) <SEMICOLON> | stmt=assertTrue(methods, symbols) <SEMICOLON> | - stmt=callMethod(methods, symbols) <SEMICOLON> ) + stmt=callMethod(methods, symbols) <SEMICOLON> | + stmt=returnStmt(methods, symbols) <SEMICOLON> ) { return stmt; } } @@ -202,9 +207,9 @@ List<Statement> stmts = new ArrayList<Statement>(); } { - <IF> <LPAREN> cond=expression(symbols) { conds.add(cond); } <RPAREN> + <IF> <LPAREN> cond=expression(methods,symbols) { conds.add(cond); } <RPAREN> stmt=statements(methods, symbols) { stmts.add(stmt); } - ( <ELIF> <LPAREN> cond=expression(symbols) { conds.add(cond); } <RPAREN> + ( <ELIF> <LPAREN> cond=expression(methods,symbols) { conds.add(cond); } <RPAREN> stmt=statements(methods, symbols) { stmts.add(stmt); })* ( <ELSE> stmt=statements(methods, symbols) { stmts.add(stmt); } )? { return new IfStatement(conds,stmts); } @@ -219,8 +224,8 @@ Expression expr; } { - <ASSERT> <LPAREN> cond=expression(symbols) - ( <COMMA> expr=expression(symbols) + <ASSERT> <LPAREN> cond=expression(methods,symbols) + ( <COMMA> expr=expression(methods,symbols) { exprs.add(expr); } )+ <RPAREN> { return new Assert(cond, exprs); } @@ -234,7 +239,7 @@ Statement body; } { - <WHILE> <LPAREN> cond=expression(symbols) <RPAREN> + <WHILE> <LPAREN> cond=expression(methods,symbols) <RPAREN> body=statements(methods, symbols) { return new WhileStatement(cond,body); } } @@ -252,8 +257,9 @@ } { name=declaration1(methods, symbols) - ( <ASSIGN> expr=expression(symbols) - { return new Assignment(symbols.getLocation(name), expr); } + ( ( <ASSIGN> expr=expression(methods,symbols) + { return new Assignment(symbols.getLocation(name), expr); } + ) )? { return new Empty(); } } @@ -265,15 +271,22 @@ */ String declaration1(MethodTable methods, SymbolTable symbols) : { String name; + Type type; } { - ( <INT> name=ident() - { symbols.declare(name,Type.INT); } | - <OBJECT> name=ident() - { symbols.declare(name,Type.OBJECT); }) - { return name; } + type=type() name=ident() + { symbols.declare(name,type); + return name; + } } +Type type() : { +} +{ + <INT> { return Type.INT; } | + <OBJECT> { return Type.OBJECT; } +} + /* * Assign a value to a variable */ @@ -282,8 +295,8 @@ Expression expr; } { - name=ident() <ASSIGN> expr=expression(symbols) - { return new Assignment(symbols.getLocation(name), expr); } + name=ident() <ASSIGN> expr=expression(methods,symbols) + { return new Assignment(symbols.getLocation(name),expr); } } /* @@ -296,9 +309,8 @@ } { name=ident() - <DOT> ( <INT> { type = Type.INT;} | - <OBJECT> { type = Type.OBJECT;}) - <LBRACKET> index=expression(symbols) <RBRACKET> <ASSIGN> rVal=expression(symbols) + <DOT> type = type() + <LBRACKET> index=expression(methods,symbols) <RBRACKET> <ASSIGN> rVal=expression(methods,symbols) { return new StoreField(symbols.getLocation(name), type, index, rVal); } } @@ -312,24 +324,9 @@ { return new GC(); } } -/* - * Allocate an object. - */ -Expression alloc(SymbolTable symbols) : { - Expression refCount, dataCount; - Expression doubleAlign = new BoolValue(false); -} -{ - <ALLOC> <LPAREN> - refCount=expression(symbols) <COMMA> - dataCount=expression(symbols) - ( <COMMA> doubleAlign=expression(symbols) )? - <RPAREN> - { return new Alloc(refCount, dataCount, doubleAlign); } -} -/* - * Allocate an object. +/** + * Procedure call, as a statement */ Statement callMethod(MethodTable methods, SymbolTable symbols) : { String name; @@ -338,9 +335,9 @@ } { name=ident() <LPAREN> - ( p=expression(symbols) + ( p=expression(methods,symbols) { params.add(p); } - ( <COMMA> p=expression(symbols) + ( <COMMA> p=expression(methods,symbols) { params.add(p); } )* )? @@ -348,8 +345,19 @@ { return new Call(methods, name, params); } } +/** + * Return a value from a method + */ +Statement returnStmt(MethodTable methods, SymbolTable symbols) : { + Expression e; +} +{ + <RETURN> e=expression(methods,symbols) + { return new Return(e); } +} + /* - * Allocate an object. + * Create a new thread */ Statement spawn(MethodTable methods, SymbolTable symbols) : { String name; @@ -358,9 +366,9 @@ } { <SPAWN> <LPAREN> name=ident() - ( <COMMA> p=expression(symbols) + ( <COMMA> p=expression(methods,symbols) { params.add(p); } - ( <COMMA> p=expression(symbols) + ( <COMMA> p=expression(methods,symbols) { params.add(p); } )* )? @@ -373,9 +381,9 @@ Expression expr; } { - <PRINT> <LPAREN> expr=expression(symbols) + <PRINT> <LPAREN> expr=expression(methods,symbols) { exprs.add(expr); } - ( <COMMA> expr=expression(symbols) + ( <COMMA> expr=expression(methods,symbols) { exprs.add(expr); } )* <RPAREN> { return new PrintStatement(exprs); } @@ -383,112 +391,176 @@ /******************************************************************************* * Arithmetic expressions + * + * Complicated slightly by the fact that we don't (currently) have a mechanism + * for enumerating temporaries at GC time. Therefore, method calls as expressions + * can only occur at the top level of an expression. */ -Expression expression(SymbolTable symbols) : { +Expression expression(MethodTable methods, SymbolTable symbols) : { Expression e1,e2; } { - e1=expr1(symbols) - ( <SC_OR> e2=expression(symbols) + e1=expr1(methods,symbols) + ( <SC_OR> e2=expression(methods,symbols) { return new BinaryExpression(e1, Operator.OR, e2); } | - <SC_AND> e2=expression(symbols) + <SC_AND> e2=expression(methods,symbols) { return new BinaryExpression(e1, Operator.AND, e2); } )? { return e1; } } -Expression expr1(SymbolTable symbols) : { +Expression expr1(MethodTable methods, SymbolTable symbols) : { Expression e; } { - <BANG> e=expr1(symbols) + <BANG> e=expr1(methods,symbols) { return new UnaryExpression(Operator.NOT,e); } | - <MINUS> e=expr1(symbols) + <MINUS> e=expr1(methods,symbols) { return new UnaryExpression(Operator.MINUS,e); } | - e=expr2(symbols) { return e; } + e=expr2(methods,symbols) { return e; } } -Expression expr2(SymbolTable symbols) : { +Expression expr2(MethodTable methods, SymbolTable symbols) : { Expression e1,e2; } { - e1=expr3(symbols) - ( <LT> e2=expr3(symbols) + e1=expr3(methods,symbols) + ( <LT> e2=expr3(methods,symbols) { return new BinaryExpression(e1,Operator.LT,e2); } | - <GT> e2=expr3(symbols) + <GT> e2=expr3(methods,symbols) { return new BinaryExpression(e1,Operator.GT,e2); } | - <LE> e2=expr3(symbols) + <LE> e2=expr3(methods,symbols) { return new BinaryExpression(e1,Operator.LE,e2); } | - <GE> e2=expr3(symbols) + <GE> e2=expr3(methods,symbols) { return new BinaryExpression(e1,Operator.GE,e2); } | - <EQ> e2=expr3(symbols) + <EQ> e2=expr3(methods,symbols) { return new BinaryExpression(e1,Operator.EQ,e2); } | - <NE> e2=expr3(symbols) + <NE> e2=expr3(methods,symbols) { return new BinaryExpression(e1,Operator.NE,e2); } )? { return e1; } } -Expression expr3(SymbolTable symbols) : { +Expression expr3(MethodTable methods, SymbolTable symbols) : { Expression e1,e2; } { - e1=expr4(symbols) - ( <PLUS> e2=expr3(symbols) + e1=expr4(methods,symbols) + ( <PLUS> e2=expr3(methods,symbols) { return new BinaryExpression(e1,Operator.PLUS,e2); } | - <MINUS> e2=expr3(symbols) + <MINUS> e2=expr3(methods,symbols) { return new BinaryExpression(e1,Operator.MINUS,e2); } )? { return e1; } } -Expression expr4(SymbolTable symbols) : { +Expression expr4(MethodTable methods, SymbolTable symbols) : { Expression e1,e2; } { - e1=expr5(symbols) - ( <STAR> e2=expr4(symbols) + e1=expr5(methods,symbols) + ( <STAR> e2=expr4(methods,symbols) { return new BinaryExpression(e1,Operator.MULT,e2); } | - <SLASH> e2=expr4(symbols) + <SLASH> e2=expr4(methods,symbols) { return new BinaryExpression(e1,Operator.DIV,e2); } | - <REM> e2=expr4(symbols) + <REM> e2=expr4(methods,symbols) { return new BinaryExpression(e1,Operator.REM,e2); } )? { return e1; } } -Expression expr5(SymbolTable symbols) : { +Expression expr5(MethodTable methods, SymbolTable symbols) : { Expression e, index; String id; + Type type; +} +{ + /* constants of various types */ + e=constant() { return e; } | + + /* intrinsic functions */ + e=intrinsic(methods,symbols) { return e; } | + + /* An expression in parentheses */ + <LPAREN> e=expression(methods,symbols) <RPAREN> + { return e; } | + + /* Field dereference */ + ( id=ident() + (<DOT> type = type() + <LBRACKET> index=expression(methods,symbols) <RBRACKET> + { return new LoadField(symbols.getLocation(id), type, index); } | + + e=callExpr(id,methods,symbols) { return e; } )? + + /* Variable substitution */ + { return new Variable(symbols.getLocation(id)); } + ) +} + +Expression constant() : { int i; boolean b; String s; - Type type; -} -{ - id=ident() - <DOT> ( <INT> { type = Type.INT;} | - <OBJECT> { type = Type.OBJECT;} ) - <LBRACKET> index=expression(symbols) <RBRACKET> - { return new LoadField(symbols.getLocation(id), type, index); } | - id=ident() - { return new Variable(symbols.getLocation(id)); } | +} { + /* Null constant */ + <NULL> + { return new ObjectValue(); } | + + /* Integer constant */ i=integer() { return new IntValue(i); } | + + /* boolean constant */ b=bool() { return new BoolValue(b); } | + + /* String constant */ s=string() - { return new StringValue(s); } | - e=alloc(symbols) - { return e; } | + { return new StringValue(s); } +} + +/** + * Procedure call, as an expression + */ +Expression callExpr(String name, MethodTable methods, SymbolTable symbols) : { + List<Expression> params = new ArrayList<Expression>(); + Expression p; +} +{ + <LPAREN> + ( p=expression(methods,symbols) + { params.add(p); } + ( <COMMA> p=expression(methods,symbols) + { params.add(p); } + )* + )? + <RPAREN> + { return new Call(methods, name, params); } +} + + +Expression intrinsic(MethodTable methods, SymbolTable symbols) : { + Expression e,refCount,dataCount,doubleAlign = new BoolValue(false); +} +{ + /* Thread ID */ <TID> <LPAREN> <RPAREN> { return new ThreadId(); } | - <HASH> <LPAREN> e=expression(symbols) <RPAREN> - { return new Hash(e); } | - <LPAREN> e=expression(symbols) <RPAREN> - { return e; } + + /* Hash code */ + <HASH> <LPAREN> e=expression(methods,symbols) <RPAREN> + { return new Hash(e); } | + + <ALLOC> <LPAREN> + refCount=expression(methods,symbols) <COMMA> + dataCount=expression(methods,symbols) + ( <COMMA> doubleAlign=expression(methods,symbols) )? + <RPAREN> + { return new Alloc(refCount, dataCount, doubleAlign); } } + /*************************************************************************** * Utility rules */ @@ -530,4 +602,4 @@ } { t=<STRING_LITERAL> { s = t.toString(); return s.substring(1, s.length() - 1); } -} \ No newline at end of file +} Modified: rvmroot/trunk/MMTk/harness/test-scripts/README =================================================================== --- rvmroot/trunk/MMTk/harness/test-scripts/README 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/MMTk/harness/test-scripts/README 2008-06-27 06:48:15 UTC (rev 14595) @@ -37,7 +37,12 @@ | ident | ident "." type "[" expr "]" | int-const + | intrinsic +intrinsic ::= "alloc" "(" expr "," expr ["," expr] ") + | "(" expr ")" + | "gc " "(" ")" + binop ::= "+" | "-" | "*" | "/" | "%" | "&&" | "||" | "==" | "!=" unop ::= "!" | "-" Added: rvmroot/trunk/MMTk/harness/test-scripts/lang/recursive2.script =================================================================== --- rvmroot/trunk/MMTk/harness/test-scripts/lang/recursive2.script (rev 0) +++ rvmroot/trunk/MMTk/harness/test-scripts/lang/recursive2.script 2008-06-27 06:48:15 UTC (rev 14595) @@ -0,0 +1,60 @@ +main() { + object tree = insert(null,10); + tree = insert(tree,5); + tree = insert(tree,6); + tree = insert(tree,4); + tree = insert(tree,11); + tree = insert(tree,4); + tree = insert(tree,3); + tree = insert(tree,7); + tree = insert(tree,1); + tree = insert(tree,2); + tree = insert(tree,0); + tree = insert(tree,12); + tree = insert(tree,13); + tree = insert(tree,14); + tree = insert(tree,15); + printTree(tree); +} + +object insert(object tree, int value) { + if (tree == null) { + //print("insert leaf"); + object result = alloc(2,1); + result.int[0] = value; + return result; + } + assert(tree != null, "tree is null"); + assert(!(tree == null), "tree is null"); + + if (tree.int[0] == value) { + //print("unchanged"); + return tree; + } elif (value < tree.int[0]) { + //print("insert left ",tree); + object result = alloc(2,1); + result.object[0] = insert(tree.object[0],value); + result.object[1] = tree.object[1]; + result.int[0] = tree.int[0]; + return result; + } else { + //print("insert right"); + object result = alloc(2,1); + result.object[0] = tree.object[0]; + result.object[1] = insert(tree.object[1],value); + result.int[0] = tree.int[0]; + return result; + } +} + + +printTree(object tree) { + if (tree == null) { + return 6; + } + object left = tree.object[0]; + object right = tree.object[1]; + printTree(left); + print(tree.int[0]); + printTree(right); +} Modified: rvmroot/trunk/build.xml =================================================================== --- rvmroot/trunk/build.xml 2008-06-27 05:24:21 UTC (rev 14594) +++ rvmroot/trunk/build.xml 2008-06-27 06:48:15 UTC (rev 14595) @@ -1957,7 +1957,7 @@ <formatter type="xml" tofile="${build.dir}/checkstyle/report.xml"/> <fileset dir="rvm/src" includes="**/*.java"/> <fileset dir="rvm/src-generated" includes="**/*.java"/> - <fileset dir="MMTk" includes="**/*.java"/> + <fileset dir="MMTk" includes="**/*.java" excludes="harness/src-generated/**/*.java"/> <fileset dir="common/vmmagic" includes="**/*.java"/> <fileset dir="common/options" includes="**/*.java"/> <fileset dir="libraryInterface/Common" includes="**/*.java"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |