# HG changeset patch # User Christian Humer # Date 1377634132 -7200 # Node ID f406557f1a0dd881ff9906856e3824a373893af6 # Parent efe58aa92f86fa1a20e7258afa86750282764694# Parent 58b72cc1710906c644b3b67ea624493541c8d269 Merge. diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Tue Aug 27 22:08:52 2013 +0200 @@ -309,7 +309,7 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase().apply(graph, context); - new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); + new PartialEscapePhase(false).apply(graph, context); } private void compareGraphs(final String snippet, final String referenceSnippet) { @@ -332,7 +332,7 @@ } new DeadCodeEliminationPhase().apply(graph); canonicalizer.apply(graph, context); - new PartialEscapePhase(false, canonicalizer).apply(graph, context); + new PartialEscapePhase(false).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); canonicalizer.apply(graph, context); diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Tue Aug 27 22:08:52 2013 +0200 @@ -43,7 +43,6 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase().apply(graph, context); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - new EarlyReadEliminationPhase(canonicalizer).apply(graph, context); + new EarlyReadEliminationPhase().apply(graph, context); } } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Tue Aug 27 22:08:52 2013 +0200 @@ -236,7 +236,7 @@ HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); - new PartialEscapePhase(iterativeEscapeAnalysis, new CanonicalizerPhase(true)).apply(graph, context); + new PartialEscapePhase(iterativeEscapeAnalysis).apply(graph, context); Assert.assertEquals(1, graph.getNodes(ReturnNode.class).count()); ReturnNode returnNode = graph.getNodes(ReturnNode.class).first(); if (expectedConstantResult != null) { diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Tue Aug 27 22:08:52 2013 +0200 @@ -245,7 +245,6 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase().apply(graph, context); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - new PartialEscapePhase(false, true, canonicalizer).apply(graph, context); + new PartialEscapePhase(false, true).apply(graph, context); } } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Tue Aug 27 22:08:52 2013 +0200 @@ -164,7 +164,7 @@ new DeadCodeEliminationPhase().apply(graph); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); canonicalizer.apply(graph, context); - new PartialEscapePhase(false, canonicalizer).apply(graph, context); + new PartialEscapePhase(false).apply(graph, context); for (MergeNode merge : graph.getNodes(MergeNode.class)) { merge.setStateAfter(null); diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Tue Aug 27 22:08:52 2013 +0200 @@ -81,7 +81,7 @@ } if (PartialEscapeAnalysis.getValue()) { - appendPhase(new PartialEscapePhase(true, canonicalizer)); + appendPhase(new PartialEscapePhase(true)); } if (OptConvertDeoptsToGuards.getValue()) { diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Tue Aug 27 22:08:52 2013 +0200 @@ -47,7 +47,7 @@ appendPhase(new LockEliminationPhase()); if (OptReadElimination.getValue()) { - appendPhase(new EarlyReadEliminationPhase(canonicalizer)); + appendPhase(new EarlyReadEliminationPhase()); } if (OptFloatingReads.getValue()) { diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Tue Aug 27 22:08:52 2013 +0200 @@ -159,18 +159,22 @@ } public void trackInputChange(NodeChangedListener inputChangedListener) { + assert this.inputChanged == null; this.inputChanged = inputChangedListener; } public void stopTrackingInputChange() { + assert inputChanged != null; inputChanged = null; } public void trackUsagesDroppedZero(NodeChangedListener usagesDroppedZeroListener) { + assert this.usagesDroppedZero == null; this.usagesDroppedZero = usagesDroppedZeroListener; } public void stopTrackingUsagesDroppedZero() { + assert usagesDroppedZero != null; usagesDroppedZero = null; } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Tue Aug 27 22:08:52 2013 +0200 @@ -121,12 +121,10 @@ private NodeUsagesList usages; private Node predecessor; private int modCount; - private final NodeClass nodeClass; public Node() { this.graph = null; this.id = INITIAL_ID; - nodeClass = NodeClass.get(getClass()); } protected int id() { @@ -241,7 +239,7 @@ } public final NodeClass getNodeClass() { - return nodeClass; + return NodeClass.get(getClass()); } private boolean checkReplaceWith(Node other) { diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Aug 27 22:08:52 2013 +0200 @@ -25,38 +25,104 @@ import java.lang.reflect.*; import java.util.*; import java.util.Map.Entry; +import java.util.concurrent.*; import com.oracle.graal.graph.Graph.DuplicationReplacement; +import com.oracle.graal.graph.Node.Input; +import com.oracle.graal.graph.Node.IterableNodeType; +import com.oracle.graal.graph.Node.Successor; import com.oracle.graal.graph.Node.Verbosity; -public class NodeClass extends FieldIntrospection { +/** + * Lazily associated metadata for every {@link Node} type. The metadata includes: + * + */ +public final class NodeClass extends FieldIntrospection { - public static final NodeClass get(Class c) { - NodeClass clazz = (NodeClass) allClasses.get(c); - if (clazz != null) { - return clazz; + /** + * Maps {@link Class} values (for {@link Node} types) to {@link NodeClass} values. + * + * Only a single Registry instance can be created. If a runtime creates a specialized registry, + * it must do so before the class initializer of {@link NodeClass} is executed. + */ + public static class Registry { + + private static Registry instance; + + /** + * Gets the singleton {@link Registry} instance, creating it first if necessary. + */ + static synchronized Registry instance() { + if (instance == null) { + return new Registry(); + } + return instance; + } + + protected Registry() { + assert instance == null : "exactly one registry can be created"; + instance = this; } - /* - * Using putIfAbsent doesn't work here, because the creation of NodeClass needs to be - * serialized. (the NodeClass constructor looks at allClasses, and it also uses the static - * field nextIterableId) - * - * The fact that ConcurrentHashMap.put and .get are used should make the double-checked - * locking idiom work, since it internally uses volatile. + /** + * @return the {@link NodeClass} value for {@code key} or {@code null} if no such mapping + * exists */ + protected NodeClass get(Class key) { + return (NodeClass) allClasses.get(key); + } - synchronized (allClasses) { - clazz = (NodeClass) allClasses.get(c); - if (clazz == null) { - clazz = new NodeClass(c); - NodeClass oldClass = (NodeClass) allClasses.putIfAbsent(c, clazz); - assert oldClass == null; + /** + * Same as {@link #get(Class)} except that a {@link NodeClass} is created if no such mapping + * exists. The creation of a {@link NodeClass} must be serialized as + * {@link NodeClass#NodeClass(Class)} accesses both {@link FieldIntrospection#allClasses} + * and {@link NodeClass#nextIterableId}. + *

+ * The fact that {@link ConcurrentHashMap#put} {@link ConcurrentHashMap#get} are used should + * make the double-checked locking idiom work in the way {@link NodeClass#get(Class)} uses + * this method and {@link #get(Class)}. + */ + final synchronized NodeClass make(Class key) { + NodeClass value = (NodeClass) allClasses.get(key); + if (value == null) { + value = new NodeClass(key); + Object old = allClasses.putIfAbsent(key, value); + assert old == null; + registered(key, value); } - return clazz; + return value; + } + + /** + * Hook for a subclass to be notified of a new mapping added to the registry. + * + * @param key + * @param value + */ + protected void registered(Class key, NodeClass value) { + } } + private static final Registry registry = Registry.instance(); + + /** + * Gets the {@link NodeClass} associated with a given {@link Class}. + */ + @SuppressWarnings("unchecked") + public static NodeClass get(Class c) { + Class key = (Class) c; + NodeClass value = registry.get(key); + if (value != null) { + return value; + } + return registry.make(key); + } + static final int NOT_ITERABLE = -1; private static final Class NODE_CLASS = Node.class; @@ -77,7 +143,7 @@ private final int iterableId; private int[] iterableIds; - public NodeClass(Class clazz) { + private NodeClass(Class clazz) { super(clazz); assert NODE_CLASS.isAssignableFrom(clazz); diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Aug 27 22:08:52 2013 +0200 @@ -153,7 +153,7 @@ */ @Test public void test5() throws Exception { - test("test5Snippet", useG1GC() ? 9 : 4); + test("test5Snippet", useG1GC() ? 1 : 0); } public static Object test5Snippet() throws Exception { @@ -262,17 +262,17 @@ } else { barriers = graph.getNodes(SerialWriteBarrier.class).count(); } - Assert.assertTrue(barriers == expectedBarriers); + Assert.assertEquals(expectedBarriers, barriers); for (WriteNode write : graph.getNodes(WriteNode.class)) { if (useG1GC()) { if (write.getBarrierType() != BarrierType.NONE) { - Assert.assertTrue(write.successors().count() == 1); + Assert.assertEquals(1, write.successors().count()); Assert.assertTrue(write.next() instanceof G1PostWriteBarrier); Assert.assertTrue(write.predecessor() instanceof G1PreWriteBarrier); } } else { if (write.getBarrierType() != BarrierType.NONE) { - Assert.assertTrue(write.successors().count() == 1); + Assert.assertEquals(1, write.successors().count()); Assert.assertTrue(write.next() instanceof SerialWriteBarrier); } } @@ -281,10 +281,10 @@ for (ReadNode read : graph.getNodes(ReadNode.class)) { if (read.getBarrierType() != BarrierType.NONE) { if (read.location() instanceof ConstantLocationNode) { - Assert.assertTrue(((ConstantLocationNode) (read.location())).getDisplacement() == referentOffset()); + Assert.assertEquals(referentOffset(), ((ConstantLocationNode) (read.location())).getDisplacement()); } Assert.assertTrue(useG1GC()); - Assert.assertTrue(read.getBarrierType() == BarrierType.PRECISE); + Assert.assertEquals(BarrierType.PRECISE, read.getBarrierType()); Assert.assertTrue(read.next() instanceof G1ReferentFieldReadBarrier); } } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue Aug 27 22:08:52 2013 +0200 @@ -194,9 +194,7 @@ compilerToVm = toVM; compilerToGpu = toGPU; vmToCompiler = toCompiler; - config = new HotSpotVMConfig(); - compilerToVm.initializeConfiguration(config); - config.check(); + config = new HotSpotVMConfig(compilerToVm); // Set some global options: if (config.compileTheWorld) { diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Aug 27 22:08:52 2013 +0200 @@ -22,11 +22,17 @@ */ package com.oracle.graal.hotspot; +import java.lang.reflect.*; + +import com.oracle.graal.hotspot.bridge.*; import com.sun.management.HotSpotDiagnosticMXBean; + import sun.management.ManagementFactoryHelper; /** - * Used to communicate configuration details, runtime offsets, etc. to Graal upon compileMethod. + * Used to access native configuration details. + * + * All non-static, public fields in this class are final so that they can be compiled as constants. */ public final class HotSpotVMConfig extends CompilerObject { @@ -34,7 +40,9 @@ private final HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); - HotSpotVMConfig() { + HotSpotVMConfig(CompilerToVM c2vm) { + c2vm.initializeConfiguration(this); + assert check(); } /** @@ -91,10 +99,28 @@ } } + // Using systenm properties ensures the Java source compilers can never + // optimize away an access to a config field + private static final boolean UNINITIALIZED_BOOLEAN = Boolean.getBoolean("graal.config.uninitializedBoolean"); + private static final long UNINITIALIZED_LONG = Long.getLong("graal.config.uninitializedLong", 0L); + private static final int UNINITIALIZED_INT = Integer.getInteger("graal.config.uninitializedInt", 0); + + private static int getUninitializedInt() { + return UNINITIALIZED_INT; + } + + private static long getUninitializedLong() { + return UNINITIALIZED_LONG; + } + + private static boolean getUninitializedBoolean() { + return UNINITIALIZED_BOOLEAN; + } + // os information, register layout, code generation, ... - public boolean cAssertions; + public final boolean cAssertions = getUninitializedBoolean(); public final boolean windowsOs = System.getProperty("os.name", "").startsWith("Windows"); - public int codeEntryAlignment; + public final int codeEntryAlignment = getUninitializedInt(); public final boolean verifyOops = getVMOption("VerifyOops", false); public final boolean ciTime = getVMOption("CITime"); public final int compileThreshold = getVMOptionInt("CompileThreshold"); @@ -110,17 +136,17 @@ public final boolean useAESIntrinsics = getVMOption("UseAESIntrinsics"); public final boolean useCRC32Intrinsics = getVMOption("UseCRC32Intrinsics"); public final boolean useG1GC = getVMOption("UseG1GC"); - public long gcTotalCollectionsAddress; + public final long gcTotalCollectionsAddress = getUninitializedLong(); // Compressed Oops related values. - public boolean useCompressedOops = getVMOption("UseCompressedOops"); - public boolean useCompressedKlassPointers = getVMOption("UseCompressedKlassPointers"); - public long narrowOopBase; - public int narrowOopShift; + public final boolean useCompressedOops = getVMOption("UseCompressedOops"); + public final boolean useCompressedKlassPointers = getVMOption("UseCompressedKlassPointers"); + public final long narrowOopBase = getUninitializedLong(); + public final int narrowOopShift = getUninitializedInt(); public final int logMinObjAlignment = (int) (Math.log(getVMOptionInt("ObjectAlignmentInBytes")) / Math.log(2)); - public long narrowKlassBase; - public int narrowKlassShift; - public int logKlassAlignment; + public final long narrowKlassBase = getUninitializedLong(); + public final int narrowKlassShift = getUninitializedInt(); + public final int logKlassAlignment = getUninitializedInt(); // CPU capabilities public final int useSSE = getVMOptionInt("UseSSE"); @@ -132,127 +158,127 @@ /** * The offset of the mark word in an object's header. */ - public int markOffset; + public final int markOffset = getUninitializedInt(); /** * The offset of the hub (i.e. Klass*) in an object's header. */ - public int hubOffset; + public final int hubOffset = getUninitializedInt(); /** * The offset of the _prototype_header field in a Klass. */ - public int prototypeMarkWordOffset; + public final int prototypeMarkWordOffset = getUninitializedInt(); /** * The offset of the _subklass field in a Klass. */ - public int subklassOffset; + public final int subklassOffset = getUninitializedInt(); /** * The offset of the _next_sibling field in a Klass. */ - public int nextSiblingOffset; + public final int nextSiblingOffset = getUninitializedInt(); /** * The offset of the array length word in an array object's header. */ - public int arrayLengthOffset; + public final int arrayLengthOffset = getUninitializedInt(); /** * The offset of the _length field in an Array metaspace object (see array.hpp). */ - public int metaspaceArrayLengthOffset; + public final int metaspaceArrayLengthOffset = getUninitializedInt(); /** * The offset of the _data field in an Array metaspace object (see array.hpp). */ - public int metaspaceArrayBaseOffset; + public final int metaspaceArrayBaseOffset = getUninitializedInt(); /** * The offset of the _super_check_offset field in a Klass. */ - public int superCheckOffsetOffset; + public final int superCheckOffsetOffset = getUninitializedInt(); /** * The offset of the _secondary_super_cache field in a Klass. */ - public int secondarySuperCacheOffset; + public final int secondarySuperCacheOffset = getUninitializedInt(); /** * The offset of the _secondary_supers field in a Klass. */ - public int secondarySupersOffset; + public final int secondarySupersOffset = getUninitializedInt(); /** * The offset of the _init_state field in an instanceKlass. */ - public int klassStateOffset; + public final int klassStateOffset = getUninitializedInt(); /** * The value of instanceKlass::fully_initialized. */ - public int klassStateFullyInitialized; + public final int klassStateFullyInitialized = getUninitializedInt(); /** * The value of objArrayKlass::element_klass_offset(). */ - public int arrayClassElementOffset; + public final int arrayClassElementOffset = getUninitializedInt(); /** * The value of JavaThread::tlab_top_offset(). */ - public int threadTlabTopOffset; + public final int threadTlabTopOffset = getUninitializedInt(); /** * The value of JavaThread::tlab_end_offset(). */ - public int threadTlabEndOffset; + public final int threadTlabEndOffset = getUninitializedInt(); /** * The value of JavaThread::threadObj_offset(). */ - public int threadObjectOffset; + public final int threadObjectOffset = getUninitializedInt(); /** * The value of JavaThread::osthread_offset(). */ - public int osThreadOffset; + public final int osThreadOffset = getUninitializedInt(); /** * The value of OSThread::interrupted_offset(). */ - public int osThreadInterruptedOffset; + public final int osThreadInterruptedOffset = getUninitializedInt(); /** * The value of markOopDesc::unlocked_value. */ - public int unlockedMask; + public final int unlockedMask = getUninitializedInt(); /** * The value of markOopDesc::biased_lock_mask_in_place. */ - public int biasedLockMaskInPlace; + public final int biasedLockMaskInPlace = getUninitializedInt(); /** * The value of markOopDesc::age_mask_in_place. */ - public int ageMaskInPlace; + public final int ageMaskInPlace = getUninitializedInt(); /** * The value of markOopDesc::epoch_mask_in_place. */ - public int epochMaskInPlace; + public final int epochMaskInPlace = getUninitializedInt(); /** * The value of markOopDesc::biased_lock_pattern. */ - public int biasedLockPattern; + public final int biasedLockPattern = getUninitializedInt(); /** * Identity hash code value when uninitialized. */ - public int uninitializedIdentityHashCodeValue; + public final int uninitializedIdentityHashCodeValue = getUninitializedInt(); /** * Offset of the _pending_exception field in ThreadShadow (defined in exceptions.hpp). This @@ -260,83 +286,83 @@ *

* NOTE: This is not the same as {@link #threadExceptionOopOffset}. */ - public int pendingExceptionOffset; + public final int pendingExceptionOffset = getUninitializedInt(); /** * Offset of the pending deoptimization field. */ - public int pendingDeoptimizationOffset; + public final int pendingDeoptimizationOffset = getUninitializedInt(); /** * Mark word right shift to get identity hash code. */ - public int identityHashCodeShift; + public final int identityHashCodeShift = getUninitializedInt(); /** * Offset of _access_flags in a metaspace Method object. */ - public int methodAccessFlagsOffset; + public final int methodAccessFlagsOffset = getUninitializedInt(); /** * JVM_ACC_QUEUED defined in accessFlags.hpp and used for marking a Method object as queued for * compilation. */ - public int methodQueuedForCompilationBit; + public final int methodQueuedForCompilationBit = getUninitializedInt(); /** * Offset of _intrinsic_id in a metaspace Method object. */ - public int methodIntrinsicIdOffset; + public final int methodIntrinsicIdOffset = getUninitializedInt(); /** * Offset of _max_locals in a metaspace Method object. */ - public int methodMaxLocalsOffset; + public final int methodMaxLocalsOffset = getUninitializedInt(); /** * Offset of _constMethod in a metaspace Method object. */ - public int methodConstMethodOffset; + public final int methodConstMethodOffset = getUninitializedInt(); /** * Offset of _max_stack in a metaspace ConstMethod object. */ - public int constMethodMaxStackOffset; + public final int constMethodMaxStackOffset = getUninitializedInt(); /** * Offset of _constants in a metaspace ConstMethod object. */ - public int constMethodConstantsOffset; + public final int constMethodConstantsOffset = getUninitializedInt(); /** * Offset of _pool_holder in a metaspace ConstantPool object. */ - public int constantPoolHolderOffset; + public final int constantPoolHolderOffset = getUninitializedInt(); /** * Value of extra_stack_entries() in method.hpp. */ - public int extraStackEntries; + public final int extraStackEntries = getUninitializedInt(); /** * Value of JVM_ACC_HAS_FINALIZER in accessFlags.hpp. */ - public int klassHasFinalizerFlag; + public final int klassHasFinalizerFlag = getUninitializedInt(); /** * The value of JavaThread::is_method_handle_return_offset(). */ - public int threadIsMethodHandleReturnOffset; + public final int threadIsMethodHandleReturnOffset = getUninitializedInt(); /** * Bit pattern that represents a non-oop. Neither the high bits nor the low bits of this value * are allowed to look like (respectively) the high or low bits of a real oop. */ - public long nonOopBits; + public final long nonOopBits = getUninitializedLong(); - public long verifyOopCounterAddress; - public long verifyOopMask; - public long verifyOopBits; + public final long verifyOopCounterAddress = getUninitializedLong(); + public final long verifyOopMask = getUninitializedLong(); + public final long verifyOopBits = getUninitializedLong(); /** * Offset of the _exception_oop field in Thread (defined in thread.hpp). This field is used to @@ -345,207 +371,216 @@ *

* NOTE: This is not the same as {@link #pendingExceptionOffset}. */ - public int threadExceptionOopOffset; + public final int threadExceptionOopOffset = getUninitializedInt(); - public int threadExceptionPcOffset; - public long cardtableStartAddress; - public int cardtableShift; - public long safepointPollingAddress; - public boolean isPollingPageFar; + public final int threadExceptionPcOffset = getUninitializedInt(); + public final long cardtableStartAddress = getUninitializedLong(); + public final int cardtableShift = getUninitializedInt(); + public final long safepointPollingAddress = getUninitializedLong(); + public final boolean isPollingPageFar = getUninitializedBoolean(); /** * G1 Collector Related Values. */ - public int g1CardQueueIndexOffset; - public int g1CardQueueBufferOffset; - public int logOfHRGrainBytes; - public int g1SATBQueueMarkingOffset; - public int g1SATBQueueIndexOffset; - public int g1SATBQueueBufferOffset; + public final int g1CardQueueIndexOffset = getUninitializedInt(); + public final int g1CardQueueBufferOffset = getUninitializedInt(); + public final int logOfHRGrainBytes = getUninitializedInt(); + public final int g1SATBQueueMarkingOffset = getUninitializedInt(); + public final int g1SATBQueueIndexOffset = getUninitializedInt(); + public final int g1SATBQueueBufferOffset = getUninitializedInt(); /** * The offset of the _java_mirror field (of type {@link Class}) in a Klass. */ - public int classMirrorOffset; + public final int classMirrorOffset = getUninitializedInt(); - public int runtimeCallStackSize; + public final int runtimeCallStackSize = getUninitializedInt(); /** * The offset of the _modifier_flags field in a Klass. */ - public int klassModifierFlagsOffset; + public final int klassModifierFlagsOffset = getUninitializedInt(); /** * The offset of the _access_flags field in a Klass. */ - public int klassAccessFlagsOffset; + public final int klassAccessFlagsOffset = getUninitializedInt(); /** * The offset of the _layout_helper field in a Klass. */ - public int klassLayoutHelperOffset; + public final int klassLayoutHelperOffset = getUninitializedInt(); /** * Bit pattern in the klass layout helper that can be used to identify arrays. */ - public int arrayKlassLayoutHelperIdentifier; + public final int arrayKlassLayoutHelperIdentifier = getUninitializedInt(); /** * The offset of the _componentMirror field in an ArrayKlass. */ - public int arrayKlassComponentMirrorOffset; + public final int arrayKlassComponentMirrorOffset = getUninitializedInt(); /** * The offset of the _super field in a Klass. */ - public int klassSuperKlassOffset; + public final int klassSuperKlassOffset = getUninitializedInt(); /** * The offset of the injected klass field in a {@link Class}. */ - public int klassOffset; + public final int klassOffset = getUninitializedInt(); /** * The offset of the injected array klass field in a {@link Class}. */ - public int arrayKlassOffset; + public final int arrayKlassOffset = getUninitializedInt(); /** * The offset of the injected graal_mirror field in a {@link Class}. */ - public int graalMirrorInClassOffset; + public final int graalMirrorInClassOffset = getUninitializedInt(); /** * The offset of the _method_data field in a metaspace Method. */ - public int methodDataOffset; + public final int methodDataOffset = getUninitializedInt(); - public int nmethodEntryOffset; - public int methodCompiledEntryOffset; - public int basicLockSize; - public int basicLockDisplacedHeaderOffset; - public long tlabIntArrayMarkWord; - public long heapEndAddress; - public long heapTopAddress; - public int threadTlabStartOffset; - public int threadTlabSizeOffset; - public int threadAllocatedBytesOffset; - public int threadLastJavaSpOffset; - public int threadLastJavaPcOffset; + public final int nmethodEntryOffset = getUninitializedInt(); + public final int methodCompiledEntryOffset = getUninitializedInt(); + public final int basicLockSize = getUninitializedInt(); + public final int basicLockDisplacedHeaderOffset = getUninitializedInt(); + public final long tlabIntArrayMarkWord = getUninitializedLong(); + public final long heapEndAddress = getUninitializedLong(); + public final long heapTopAddress = getUninitializedLong(); + public final int threadTlabStartOffset = getUninitializedInt(); + public final int threadTlabSizeOffset = getUninitializedInt(); + public final int threadAllocatedBytesOffset = getUninitializedInt(); + public final int threadLastJavaSpOffset = getUninitializedInt(); + public final int threadLastJavaPcOffset = getUninitializedInt(); /** * This value is only valid on AMD64. */ - public int threadLastJavaFpOffset; + public final int threadLastJavaFpOffset = getUninitializedInt(); /** * This value is only valid on SPARC. */ - public int threadJavaFrameAnchorFlagsOffset; + public final int threadJavaFrameAnchorFlagsOffset = getUninitializedInt(); - public int threadObjectResultOffset; - public int tlabRefillWasteLimitOffset; - public int tlabRefillWasteIncrement; - public int tlabAlignmentReserve; - public int tlabSlowAllocationsOffset; - public int tlabFastRefillWasteOffset; - public int tlabNumberOfRefillsOffset; + public final int threadObjectResultOffset = getUninitializedInt(); + public final int tlabRefillWasteLimitOffset = getUninitializedInt(); + public final int tlabRefillWasteIncrement = getUninitializedInt(); + public final int tlabAlignmentReserve = getUninitializedInt(); + public final int tlabSlowAllocationsOffset = getUninitializedInt(); + public final int tlabFastRefillWasteOffset = getUninitializedInt(); + public final int tlabNumberOfRefillsOffset = getUninitializedInt(); public final boolean tlabStats = getVMOption("TLABStats"); - public int klassInstanceSizeOffset; - public boolean inlineContiguousAllocationSupported; - public long arrayPrototypeMarkWord; - public int layoutHelperLog2ElementSizeShift; - public int layoutHelperLog2ElementSizeMask; - public int layoutHelperElementTypeShift; - public int layoutHelperElementTypeMask; - public int layoutHelperElementTypePrimitiveInPlace; - public int layoutHelperHeaderSizeShift; - public int layoutHelperHeaderSizeMask; - public int layoutHelperOffset; + public final int klassInstanceSizeOffset = getUninitializedInt(); + public final boolean inlineContiguousAllocationSupported = getUninitializedBoolean(); + public final long arrayPrototypeMarkWord = getUninitializedLong(); + public final int layoutHelperLog2ElementSizeShift = getUninitializedInt(); + public final int layoutHelperLog2ElementSizeMask = getUninitializedInt(); + public final int layoutHelperElementTypeShift = getUninitializedInt(); + public final int layoutHelperElementTypeMask = getUninitializedInt(); + public final int layoutHelperElementTypePrimitiveInPlace = getUninitializedInt(); + public final int layoutHelperHeaderSizeShift = getUninitializedInt(); + public final int layoutHelperHeaderSizeMask = getUninitializedInt(); + public final int layoutHelperOffset = getUninitializedInt(); // methodData information - public int methodDataOopDataOffset; - public int methodDataOopTrapHistoryOffset; - public int dataLayoutHeaderSize; - public int dataLayoutTagOffset; - public int dataLayoutFlagsOffset; - public int dataLayoutBCIOffset; - public int dataLayoutCellsOffset; - public int dataLayoutCellSize; - public final int bciProfileWidth = getVMOption("BciProfileWidth", 2); // develop flag; might -// change + public final int methodDataOopDataOffset = getUninitializedInt(); + public final int methodDataOopTrapHistoryOffset = getUninitializedInt(); + public final int dataLayoutHeaderSize = getUninitializedInt(); + public final int dataLayoutTagOffset = getUninitializedInt(); + public final int dataLayoutFlagsOffset = getUninitializedInt(); + public final int dataLayoutBCIOffset = getUninitializedInt(); + public final int dataLayoutCellsOffset = getUninitializedInt(); + public final int dataLayoutCellSize = getUninitializedInt(); + + // develop flag; might change + public final int bciProfileWidth = getVMOption("BciProfileWidth", 2); + public final int typeProfileWidth = getVMOptionInt("TypeProfileWidth"); public final int methodProfileWidth = getVMOptionInt("MethodProfileWidth"); - public long inlineCacheMissStub; - public long handleDeoptStub; - public long uncommonTrapStub; + public final long inlineCacheMissStub = getUninitializedLong(); + public final long handleDeoptStub = getUninitializedLong(); + public final long uncommonTrapStub = getUninitializedLong(); - public long aescryptEncryptBlockStub; - public long aescryptDecryptBlockStub; - public long cipherBlockChainingEncryptAESCryptStub; - public long cipherBlockChainingDecryptAESCryptStub; - public long updateBytesCRC32Stub; + public final long aescryptEncryptBlockStub = getUninitializedLong(); + public final long aescryptDecryptBlockStub = getUninitializedLong(); + public final long cipherBlockChainingEncryptAESCryptStub = getUninitializedLong(); + public final long cipherBlockChainingDecryptAESCryptStub = getUninitializedLong(); + public final long updateBytesCRC32Stub = getUninitializedLong(); - public long newInstanceAddress; - public long newArrayAddress; - public long newMultiArrayAddress; - public long dynamicNewArrayAddress; - public long registerFinalizerAddress; - public long threadIsInterruptedAddress; - public long vmMessageAddress; - public long identityHashCodeAddress; - public long exceptionHandlerForPcAddress; - public long exceptionHandlerForReturnAddressAddress; - public long osrMigrationEndAddress; - public long monitorenterAddress; - public long monitorexitAddress; - public long createNullPointerExceptionAddress; - public long createOutOfBoundsExceptionAddress; - public long logPrimitiveAddress; - public long logObjectAddress; - public long logPrintfAddress; - public long vmErrorAddress; - public long writeBarrierPreAddress; - public long writeBarrierPostAddress; - public long validateObject; - public long javaTimeMillisAddress; - public long javaTimeNanosAddress; - public long arithmeticSinAddress; - public long arithmeticCosAddress; - public long arithmeticTanAddress; - public long loadAndClearExceptionAddress; - public long crcTableAddress; + public final long newInstanceAddress = getUninitializedLong(); + public final long newArrayAddress = getUninitializedLong(); + public final long newMultiArrayAddress = getUninitializedLong(); + public final long dynamicNewArrayAddress = getUninitializedLong(); + public final long registerFinalizerAddress = getUninitializedLong(); + public final long threadIsInterruptedAddress = getUninitializedLong(); + public final long vmMessageAddress = getUninitializedLong(); + public final long identityHashCodeAddress = getUninitializedLong(); + public final long exceptionHandlerForPcAddress = getUninitializedLong(); + public final long exceptionHandlerForReturnAddressAddress = getUninitializedLong(); + public final long osrMigrationEndAddress = getUninitializedLong(); + public final long monitorenterAddress = getUninitializedLong(); + public final long monitorexitAddress = getUninitializedLong(); + public final long createNullPointerExceptionAddress = getUninitializedLong(); + public final long createOutOfBoundsExceptionAddress = getUninitializedLong(); + public final long logPrimitiveAddress = getUninitializedLong(); + public final long logObjectAddress = getUninitializedLong(); + public final long logPrintfAddress = getUninitializedLong(); + public final long vmErrorAddress = getUninitializedLong(); + public final long writeBarrierPreAddress = getUninitializedLong(); + public final long writeBarrierPostAddress = getUninitializedLong(); + public final long validateObject = getUninitializedLong(); + public final long javaTimeMillisAddress = getUninitializedLong(); + public final long javaTimeNanosAddress = getUninitializedLong(); + public final long arithmeticSinAddress = getUninitializedLong(); + public final long arithmeticCosAddress = getUninitializedLong(); + public final long arithmeticTanAddress = getUninitializedLong(); + public final long loadAndClearExceptionAddress = getUninitializedLong(); + public final long crcTableAddress = getUninitializedLong(); - public int deoptReasonNone; - public int deoptReasonNullCheck; - public int deoptReasonRangeCheck; - public int deoptReasonClassCheck; - public int deoptReasonArrayCheck; - public int deoptReasonUnreached0; - public int deoptReasonTypeCheckInlining; - public int deoptReasonOptimizedTypeCheck; - public int deoptReasonNotCompiledExceptionHandler; - public int deoptReasonUnresolved; - public int deoptReasonJsrMismatch; - public int deoptReasonDiv0Check; - public int deoptReasonConstraint; - public int deoptReasonLoopLimitCheck; + public final int deoptReasonNone = getUninitializedInt(); + public final int deoptReasonNullCheck = getUninitializedInt(); + public final int deoptReasonRangeCheck = getUninitializedInt(); + public final int deoptReasonClassCheck = getUninitializedInt(); + public final int deoptReasonArrayCheck = getUninitializedInt(); + public final int deoptReasonUnreached0 = getUninitializedInt(); + public final int deoptReasonTypeCheckInlining = getUninitializedInt(); + public final int deoptReasonOptimizedTypeCheck = getUninitializedInt(); + public final int deoptReasonNotCompiledExceptionHandler = getUninitializedInt(); + public final int deoptReasonUnresolved = getUninitializedInt(); + public final int deoptReasonJsrMismatch = getUninitializedInt(); + public final int deoptReasonDiv0Check = getUninitializedInt(); + public final int deoptReasonConstraint = getUninitializedInt(); + public final int deoptReasonLoopLimitCheck = getUninitializedInt(); - public int deoptActionNone; - public int deoptActionMaybeRecompile; - public int deoptActionReinterpret; - public int deoptActionMakeNotEntrant; - public int deoptActionMakeNotCompilable; + public final int deoptActionNone = getUninitializedInt(); + public final int deoptActionMaybeRecompile = getUninitializedInt(); + public final int deoptActionReinterpret = getUninitializedInt(); + public final int deoptActionMakeNotEntrant = getUninitializedInt(); + public final int deoptActionMakeNotCompilable = getUninitializedInt(); - public int vmIntrinsicInvokeBasic; - public int vmIntrinsicLinkToVirtual; - public int vmIntrinsicLinkToStatic; - public int vmIntrinsicLinkToSpecial; - public int vmIntrinsicLinkToInterface; + public final int vmIntrinsicInvokeBasic = getUninitializedInt(); + public final int vmIntrinsicLinkToVirtual = getUninitializedInt(); + public final int vmIntrinsicLinkToStatic = getUninitializedInt(); + public final int vmIntrinsicLinkToSpecial = getUninitializedInt(); + public final int vmIntrinsicLinkToInterface = getUninitializedInt(); - public void check() { - assert codeEntryAlignment > 0; + public boolean check() { + assert codeEntryAlignment > 0 : codeEntryAlignment; assert stackShadowPages > 0; + for (Field f : getClass().getDeclaredFields()) { + int modifiers = f.getModifiers(); + if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) { + assert Modifier.isFinal(modifiers) : "field should be final: " + f; + } + } + return true; } } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue Aug 27 22:08:52 2013 +0200 @@ -131,6 +131,8 @@ public void startCompiler(boolean bootstrapEnabled) throws Throwable { + FastNodeClassRegistry.initialize(); + bootstrapRunning = bootstrapEnabled; HotSpotVMConfig config = graalRuntime.getConfig(); @@ -260,6 +262,31 @@ compilerStartTime = System.nanoTime(); } + /** + * A fast-path for {@link NodeClass} retrieval using {@link HotSpotResolvedObjectType}. + */ + static class FastNodeClassRegistry extends NodeClass.Registry { + + @SuppressWarnings("unused") + static void initialize() { + new FastNodeClassRegistry(); + } + + private static HotSpotResolvedObjectType type(Class key) { + return (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(key); + } + + @Override + public NodeClass get(Class key) { + return type(key).getNodeClass(); + } + + @Override + protected void registered(Class key, NodeClass value) { + type(key).setNodeClass(value); + } + } + private final class BenchmarkCountersOutputStream extends CallbackOutputStream { private long startTime; diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Tue Aug 27 22:08:52 2013 +0200 @@ -33,6 +33,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; /** @@ -65,6 +66,11 @@ private final String simpleName; /** + * Used for implemented a lazy binding from a {@link Node} type to a {@link NodeClass} value. + */ + private NodeClass nodeClass; + + /** * The instance size (in bytes) for an instance type, * {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} denoting an interface type or * {@link HotSpotResolvedObjectType#ARRAY_SPECIES_VALUE} denoting an array type. @@ -554,4 +560,18 @@ public Constant newArray(int length) { return Constant.forObject(Array.newInstance(javaMirror, length)); } + + /** + * @return the {@link NodeClass} value (which may be {@code null}) associated with this type + */ + public NodeClass getNodeClass() { + return nodeClass; + } + + /** + * Sets the {@link NodeClass} value associated with this type. + */ + public void setNodeClass(NodeClass nodeClass) { + this.nodeClass = nodeClass; + } } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Tue Aug 27 22:08:52 2013 +0200 @@ -24,13 +24,12 @@ import static com.oracle.graal.phases.GraalOptions.*; -import java.util.*; - import com.oracle.graal.api.code.*; -import com.oracle.graal.graph.Graph.NodeChangedListener; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.util.*; import com.oracle.graal.phases.tiers.*; public class IterativeConditionalEliminationPhase extends BasePhase { @@ -39,36 +38,28 @@ @Override protected void run(StructuredGraph graph, PhaseContext context) { - Set canonicalizationRoots = new HashSet<>(); ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase(context.getRuntime()); - Listener listener = new Listener(canonicalizationRoots); + HashSetNodeChangeListener listener = new HashSetNodeChangeListener(); int count = 0; while (true) { graph.trackInputChange(listener); + graph.trackUsagesDroppedZero(listener); eliminate.apply(graph); graph.stopTrackingInputChange(); - if (canonicalizationRoots.isEmpty()) { + graph.stopTrackingUsagesDroppedZero(); + if (listener.getChangedNodes().isEmpty()) { break; } - new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), canonicalizationRoots, null).apply(graph); - canonicalizationRoots.clear(); + for (Node node : graph.getNodes()) { + if (node instanceof Simplifiable) { + listener.getChangedNodes().add(node); + } + } + new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), listener.getChangedNodes(), null).apply(graph); + listener.getChangedNodes().clear(); if (++count > MAX_ITERATIONS) { throw new BailoutException("Number of iterations in conditional elimination phase exceeds " + MAX_ITERATIONS); } } } - - private static class Listener implements NodeChangedListener { - - private final Set canonicalizationRoots; - - public Listener(Set canonicalizationRoots) { - this.canonicalizationRoots = canonicalizationRoots; - } - - @Override - public void nodeChanged(Node node) { - canonicalizationRoots.add(node); - } - } } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeChangeListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeChangeListener.java Tue Aug 27 22:08:52 2013 +0200 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.phases.common.util; + +import java.util.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Graph.*; + +/** + * A simple {@link NodeChangedListener} implementation that accumulates the changed nodes in a + * {@link HashSet}. + */ +public class HashSetNodeChangeListener implements NodeChangedListener { + + private final Set changedNodes; + + public HashSetNodeChangeListener() { + this.changedNodes = new HashSet<>(); + } + + @Override + public void nodeChanged(Node node) { + changedNodes.add(node); + } + + public Set getChangedNodes() { + return changedNodes; + } +} diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Tue Aug 27 22:08:52 2013 +0200 @@ -131,7 +131,7 @@ } new DeadCodeEliminationPhase().apply(resultGraph); - new PartialEscapePhase(true, canonicalizer).apply(resultGraph, context); + new PartialEscapePhase(true).apply(resultGraph, context); if (TruffleInlinePrinter.getValue()) { InlinePrinterProcessor.printTree(); diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Tue Aug 27 22:08:52 2013 +0200 @@ -100,6 +100,26 @@ } @Override + public byte getByte(FrameSlot slot) throws FrameSlotTypeException { + verifyGet(slot, FrameSlotKind.Byte); + return getByteUnsafe(slot); + } + + private byte getByteUnsafe(FrameSlot slot) { + return unsafe.getByte(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET); + } + + @Override + public void setByte(FrameSlot slot, byte value) throws FrameSlotTypeException { + verifySet(slot, FrameSlotKind.Byte); + setByteUnsafe(slot, value); + } + + private void setByteUnsafe(FrameSlot slot, byte value) { + unsafe.putByte(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value); + } + + @Override public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { verifyGet(slot, FrameSlotKind.Boolean); return getBooleanUnsafe(slot); diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Aug 27 22:08:52 2013 +0200 @@ -178,7 +178,7 @@ // EA frame and clean up. new VerifyFrameDoesNotEscapePhase().apply(graph, false); - new PartialEscapePhase(false, new CanonicalizerPhase(!AOTCompilation.getValue())).apply(graph, context); + new PartialEscapePhase(false).apply(graph, context); new VerifyNoIntrinsicsLeftPhase().apply(graph, false); for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) { materializeNode.replaceAtUsages(materializeNode.getFrame()); diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Tue Aug 27 22:08:52 2013 +0200 @@ -112,7 +112,7 @@ optimizeGraph(newGraph, tmpAssumptions); PhaseContext context = new PhaseContext(metaAccessProvider, tmpAssumptions, replacements); - PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, new CanonicalizerPhase(true)); + PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false); partialEscapePhase.apply(newGraph, context); cache.put(method, newGraph); @@ -153,7 +153,7 @@ ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(metaAccessProvider); ConvertDeoptimizeToGuardPhase convertDeoptimizeToGuardPhase = new ConvertDeoptimizeToGuardPhase(); CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase(!AOTCompilation.getValue()); - EarlyReadEliminationPhase readEliminationPhase = new EarlyReadEliminationPhase(canonicalizerPhase); + EarlyReadEliminationPhase readEliminationPhase = new EarlyReadEliminationPhase(); int maxNodes = TruffleCompilerOptions.TruffleOperationCacheMaxNodes.getValue(); diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java Tue Aug 27 22:08:52 2013 +0200 @@ -34,6 +34,7 @@ import com.oracle.graal.nodes.type.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.substitutions.*; import com.oracle.truffle.api.frame.*; /** @@ -70,7 +71,7 @@ return getConstantFrameSlot().getIndex(); } - protected boolean isConstantFrameSlot() { + public boolean isConstantFrameSlot() { return slot.isConstant() && !slot.isNullConstant(); } @@ -113,14 +114,17 @@ } protected final boolean isValidAccessKind() { - if (getSlotKind() == Kind.Byte) { - // tag access + if (isTagAccess()) { return true; } return getSlotKind() == getGraalKind(getConstantFrameSlot().getKind()); } + protected final boolean isTagAccess() { + return field == FrameWithoutBoxingSubstitutions.TAGS_FIELD; + } + private static Kind getGraalKind(FrameSlotKind kind) { switch (kind) { case Object: @@ -156,6 +160,9 @@ @Override public Map getDebugProperties(Map map) { Map properties = super.getDebugProperties(map); + if (isTagAccess()) { + properties.put("slotKind", "Tag"); + } if (isConstantFrameSlot()) { properties.put("frameSlot", getConstantFrameSlot().toString()); } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java Tue Aug 27 22:08:52 2013 +0200 @@ -78,12 +78,12 @@ LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field)); structuredGraph.addBeforeFixed(this, loadFieldNode); FixedWithNextNode loadNode; - if (!getSlotKind().isPrimitive()) { + if (isTagAccess()) { + ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); + loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, getSlotKind())); + } else if (!getSlotKind().isPrimitive()) { ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Object)); - } else if (getSlotKind() == Kind.Byte) { - ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); - loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Byte)); } else { ValueNode slotOffset = getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getRuntime()); loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, Unsafe.ARRAY_LONG_BASE_OFFSET, slotOffset, getSlotKind())); diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java Tue Aug 27 22:08:52 2013 +0200 @@ -79,10 +79,10 @@ structuredGraph.addBeforeFixed(this, loadFieldNode); FixedWithNextNode storeNode; ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); - if (!getSlotKind().isPrimitive()) { + if (isTagAccess()) { + storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, getSlotKind(), value)); + } else if (!getSlotKind().isPrimitive()) { storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Object, value)); - } else if (getSlotKind() == Kind.Byte) { - storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Byte, value)); } else { storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Long, value)); } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java Tue Aug 27 22:08:52 2013 +0200 @@ -37,9 +37,8 @@ @Override protected void run(StructuredGraph graph) { - NewFrameNode frame = graph.getNodes(NewFrameNode.class).first(); - if (frame != null) { - for (MethodCallTargetNode callTarget : frame.usages().filter(MethodCallTargetNode.class)) { + for (NewFrameNode virtualFrame : graph.getNodes(NewFrameNode.class)) { + for (MethodCallTargetNode callTarget : virtualFrame.usages().filter(MethodCallTargetNode.class)) { if (callTarget.invoke() != null) { String properties = callTarget.getDebugProperties().toString(); String arguments = callTarget.arguments().toString(); @@ -47,6 +46,12 @@ throw GraphUtil.approxSourceException(callTarget, exception); } } + for (FrameAccessNode frameAccess : virtualFrame.usages().filter(FrameAccessNode.class)) { + if (!frameAccess.isConstantFrameSlot()) { + Throwable exception = new VerificationError("Frame slot must be compile-time constant in virtual frame access at: %s frameSlot=%s", frameAccess, frameAccess.getSlot()); + throw GraphUtil.approxSourceException(frameAccess, exception); + } + } } } } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java Tue Aug 27 22:08:52 2013 +0200 @@ -36,7 +36,7 @@ private static final ResolvedJavaField LOCALS_FIELD; private static final ResolvedJavaField PRIMITIVELOCALS_FIELD; - private static final ResolvedJavaField TAGS_FIELD; + public static final ResolvedJavaField TAGS_FIELD; static { try { @@ -80,6 +80,18 @@ } @MethodSubstitution(isStatic = false, forced = true) + public static byte getByte(FrameWithoutBoxing frame, FrameSlot slot) { + verifyGet(frame, slot, FrameSlotKind.Byte); + return getByteUnsafe(frame, slot); + } + + @MethodSubstitution(isStatic = false, forced = true) + public static void setByte(FrameWithoutBoxing frame, FrameSlot slot, byte value) { + verifySet(frame, slot, FrameSlotKind.Byte); + setByteUnsafe(frame, slot, value); + } + + @MethodSubstitution(isStatic = false, forced = true) public static float getFloat(FrameWithoutBoxing frame, FrameSlot slot) { verifyGet(frame, slot, FrameSlotKind.Float); return getFloatUnsafe(frame, slot); @@ -148,6 +160,16 @@ } @MethodSubstitution(isStatic = false) + public static byte getByteUnsafe(FrameWithoutBoxing frame, FrameSlot slot) { + return FrameGetNode.get(Kind.Byte, frame, slot, PRIMITIVELOCALS_FIELD); + } + + @MethodSubstitution(isStatic = false) + public static void setByteUnsafe(FrameWithoutBoxing frame, FrameSlot slot, byte value) { + FrameSetNode.set(Kind.Byte, frame, slot, value, PRIMITIVELOCALS_FIELD); + } + + @MethodSubstitution(isStatic = false) public static int getIntUnsafe(FrameWithoutBoxing frame, FrameSlot slot) { return FrameGetNode.get(Kind.Int, frame, slot, PRIMITIVELOCALS_FIELD); } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EarlyReadEliminationPhase.java Tue Aug 27 22:08:52 2013 +0200 @@ -25,14 +25,13 @@ import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; public class EarlyReadEliminationPhase extends EffectsPhase { - public EarlyReadEliminationPhase(CanonicalizerPhase canonicalizer) { - super(1, canonicalizer); + public EarlyReadEliminationPhase() { + super(1); } @Override diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Tue Aug 27 22:08:52 2013 +0200 @@ -27,9 +27,12 @@ import java.util.concurrent.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.common.util.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; @@ -44,11 +47,9 @@ } private final int maxIterations; - private CanonicalizerPhase canonicalizer; - public EffectsPhase(int maxIterations, CanonicalizerPhase canonicalizer) { + public EffectsPhase(int maxIterations) { this.maxIterations = maxIterations; - this.canonicalizer = canonicalizer; } @Override @@ -73,15 +74,23 @@ } // apply the effects collected during this iteration + HashSetNodeChangeListener listener = new HashSetNodeChangeListener(); + graph.trackInputChange(listener); + graph.trackUsagesDroppedZero(listener); closure.applyEffects(); + graph.stopTrackingInputChange(); + graph.stopTrackingUsagesDroppedZero(); Debug.dump(graph, "after " + getName() + " iteration"); new DeadCodeEliminationPhase().apply(graph); - if (OptCanonicalizer.getValue()) { - canonicalizer.apply(graph, context); + for (Node node : graph.getNodes()) { + if (node instanceof Simplifiable) { + listener.getChangedNodes().add(node); + } } + new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), listener.getChangedNodes(), null).apply(graph); return true; } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Tue Aug 27 22:08:52 2013 +0200 @@ -60,7 +60,7 @@ @Override public Boolean call() { boolean progress = false; - PartialEscapePhase ea = new PartialEscapePhase(false, canonicalizer); + PartialEscapePhase ea = new PartialEscapePhase(false); boolean eaResult = ea.runAnalysis(graph, context); progress |= eaResult; diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Tue Aug 27 22:08:52 2013 +0200 @@ -33,7 +33,6 @@ import com.oracle.graal.nodes.util.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.options.*; -import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; @@ -47,12 +46,12 @@ private final boolean readElimination; - public PartialEscapePhase(boolean iterative, CanonicalizerPhase canonicalizer) { - this(iterative, OptEarlyReadElimination.getValue(), canonicalizer); + public PartialEscapePhase(boolean iterative) { + this(iterative, OptEarlyReadElimination.getValue()); } - public PartialEscapePhase(boolean iterative, boolean readElimination, CanonicalizerPhase canonicalizer) { - super(iterative ? EscapeAnalysisIterations.getValue() : 1, canonicalizer); + public PartialEscapePhase(boolean iterative, boolean readElimination) { + super(iterative ? EscapeAnalysisIterations.getValue() : 1); this.readElimination = readElimination; } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Tue Aug 27 22:08:52 2013 +0200 @@ -67,6 +67,23 @@ void setObject(FrameSlot slot, Object value) throws FrameSlotTypeException; /** + * Read access to a local variable of type byte. + * + * @param slot the slot of the local variable + * @return the current value of the local variable + */ + byte getByte(FrameSlot slot) throws FrameSlotTypeException; + + /** + * Write access to a local variable of type byte. + * + * @param slot the slot of the local variable + * @param value the new value of the local variable + */ + + void setByte(FrameSlot slot, byte value) throws FrameSlotTypeException; + + /** * Read access to a local variable of type boolean. * * @param slot the slot of the local variable diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java Tue Aug 27 22:08:52 2013 +0200 @@ -25,5 +25,5 @@ package com.oracle.truffle.api.frame; public enum FrameSlotKind { - Illegal, Object, Long, Int, Double, Float, Boolean; + Illegal, Object, Long, Int, Double, Float, Boolean, Byte; } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java Tue Aug 27 22:08:52 2013 +0200 @@ -46,6 +46,25 @@ } /** + * Write access to a local variable of type {@code byte}. + * + * Sets the frame slot type to {@code byte} if it isn't already. + * + * @param slot the slot of the local variable + * @param value the new value of the local variable + */ + public static void setByteSafe(Frame frame, FrameSlot slot, byte value) { + if (slot.getKind() != FrameSlotKind.Byte) { + slot.setKind(FrameSlotKind.Byte); + } + try { + frame.setByte(slot, value); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(); + } + } + + /** * Write access to a local variable of type {@code boolean}. * * Sets the frame slot type to {@code boolean} if it isn't already. diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java Tue Aug 27 22:08:52 2013 +0200 @@ -57,6 +57,16 @@ } @Override + public byte getByte(FrameSlot slot) { + throw new UnsupportedOperationException("native frame"); + } + + @Override + public void setByte(FrameSlot slot, byte value) { + throw new UnsupportedOperationException("native frame"); + } + + @Override public boolean getBoolean(FrameSlot slot) { throw new UnsupportedOperationException("native frame"); } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java Tue Aug 27 22:08:52 2013 +0200 @@ -51,6 +51,16 @@ } @Override + public byte getByte(FrameSlot slot) throws FrameSlotTypeException { + return wrapped.getByte(slot); + } + + @Override + public void setByte(FrameSlot slot, byte value) throws FrameSlotTypeException { + wrapped.setByte(slot, value); + } + + @Override public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getBoolean(slot); } diff -r efe58aa92f86 -r f406557f1a0d graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Tue Aug 27 22:08:26 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Tue Aug 27 22:08:52 2013 +0200 @@ -79,6 +79,18 @@ } @Override + public byte getByte(FrameSlot slot) throws FrameSlotTypeException { + verifyGet(slot, FrameSlotKind.Byte); + return (byte) locals[slot.getIndex()]; + } + + @Override + public void setByte(FrameSlot slot, byte value) throws FrameSlotTypeException { + verifySet(slot, FrameSlotKind.Byte); + locals[slot.getIndex()] = value; + } + + @Override public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { verifyGet(slot, FrameSlotKind.Boolean); return (boolean) locals[slot.getIndex()]; diff -r efe58aa92f86 -r f406557f1a0d mx/commands.py --- a/mx/commands.py Tue Aug 27 22:08:26 2013 +0200 +++ b/mx/commands.py Tue Aug 27 22:08:52 2013 +0200 @@ -680,7 +680,7 @@ if cwd is None: cwd = _vm_cwd - elif _vm_cwd != cwd: + elif _vm_cwd is not None and _vm_cwd != cwd: mx.abort("conflicting working directories: do not set --vmcwd for this command") build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product'