changeset 19461:501d2d0778c3

Merge.
author Doug Simon <doug.simon@oracle.com>
date Wed, 18 Feb 2015 00:09:24 +0100
parents cdf80eaa38ca (current diff) f04d2a9f2020 (diff)
children 33a783b15758 fd2baaf2b6d3
files graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/AlternateFrameWithoutBoxing.java
diffstat 25 files changed, 736 insertions(+), 569 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Wed Feb 18 00:09:24 2015 +0100
@@ -30,6 +30,7 @@
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
+import java.util.concurrent.atomic.*;
 
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
@@ -82,7 +83,7 @@
     }
 
     @SuppressWarnings("rawtypes")
-    private static NodeClass<?> getNodeClassViaReflection(Class<?> superclass) {
+    public static NodeClass<?> getNodeClassViaReflection(Class<?> superclass) {
         try {
             Field field = superclass.getDeclaredField("TYPE");
             field.setAccessible(true);
@@ -96,7 +97,7 @@
     private static final Class<?> INPUT_LIST_CLASS = NodeInputList.class;
     private static final Class<?> SUCCESSOR_LIST_CLASS = NodeSuccessorList.class;
 
-    private static int nextIterableId = 0;
+    private static AtomicInteger nextIterableId = new AtomicInteger();
 
     private final InputEdges inputs;
     private final SuccessorEdges successors;
@@ -172,7 +173,7 @@
         } else if (IterableNodeType.class.isAssignableFrom(clazz)) {
             ITERABLE_NODE_TYPES.increment();
             try (TimerCloseable t1 = Init_IterableIds.start()) {
-                this.iterableId = nextIterableId++;
+                this.iterableId = nextIterableId.getAndIncrement();
 
                 NodeClass<?> snc = superNodeClass;
                 while (snc != null && IterableNodeType.class.isAssignableFrom(snc.getClazz())) {
@@ -245,7 +246,7 @@
     }
 
     static int allocatedNodeIterabledIds() {
-        return nextIterableId;
+        return nextIterableId.get();
     }
 
     public EnumSet<InputType> getAllowedUsageTypes() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java	Wed Feb 18 00:09:24 2015 +0100
@@ -511,7 +511,9 @@
         int count = sig.getParameterCount(false);
         Class<?>[] result = new Class<?>[count];
         for (int i = 0; i < result.length; ++i) {
-            result[i] = ((HotSpotResolvedJavaType) sig.getParameterType(i, holder).resolve(holder)).mirror();
+            JavaType parameterType = sig.getParameterType(i, holder);
+            HotSpotResolvedJavaType resolvedParameterType = (HotSpotResolvedJavaType) parameterType.resolve(holder);
+            result[i] = resolvedParameterType.mirror();
         }
         return result;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Wed Feb 18 00:09:24 2015 +0100
@@ -118,13 +118,11 @@
         return Kind.fromTypeString(parameters.get(index));
     }
 
-    private static boolean checkValidCache(JavaType type, ResolvedJavaType accessingClass) {
+    private static boolean checkValidCache(ResolvedJavaType type, ResolvedJavaType accessingClass) {
         assert accessingClass != null;
-        if (!(type instanceof ResolvedJavaType)) {
+        if (type == null) {
             return false;
-        }
-
-        if (type instanceof HotSpotResolvedObjectTypeImpl) {
+        } else if (type instanceof HotSpotResolvedObjectTypeImpl) {
             return ((HotSpotResolvedObjectTypeImpl) type).isDefinitelyResolvedWithRespectTo(accessingClass);
         }
         return true;
@@ -151,8 +149,13 @@
 
         ResolvedJavaType type = parameterTypes[index];
         if (!checkValidCache(type, accessingClass)) {
-            type = (ResolvedJavaType) runtime.lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, false);
-            parameterTypes[index] = type;
+            JavaType result = runtime.lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, false);
+            if (result instanceof ResolvedJavaType) {
+                type = (ResolvedJavaType) result;
+                parameterTypes[index] = type;
+            } else {
+                return result;
+            }
         }
         return type;
     }
@@ -176,7 +179,12 @@
             return getUnresolvedOrPrimitiveType(runtime, returnType);
         }
         if (!checkValidCache(returnTypeCache, accessingClass)) {
-            returnTypeCache = (ResolvedJavaType) runtime.lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, false);
+            JavaType result = runtime.lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, false);
+            if (result instanceof ResolvedJavaType) {
+                returnTypeCache = (ResolvedJavaType) result;
+            } else {
+                return result;
+            }
         }
         return returnTypeCache;
     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Wed Feb 18 00:09:24 2015 +0100
@@ -91,7 +91,7 @@
         this.optimisticOpts = optimisticOpts;
         this.metaAccess = metaAccess;
         this.stream = new BytecodeStream(method.getCode());
-        this.profilingInfo = method.getProfilingInfo();
+        this.profilingInfo = (graphBuilderConfig.getUseProfiling() ? method.getProfilingInfo() : null);
         this.constantPool = method.getConstantPool();
         this.method = method;
         this.parsingReplacement = isReplacement;
@@ -573,7 +573,7 @@
     }
 
     private JavaTypeProfile getProfileForTypeCheck(ResolvedJavaType type) {
-        if (!optimisticOpts.useTypeCheckHints() || !canHaveSubtype(type)) {
+        if (profilingInfo == null || !optimisticOpts.useTypeCheckHints() || !canHaveSubtype(type)) {
             return null;
         } else {
             return profilingInfo.getTypeProfile(bci());
@@ -727,7 +727,7 @@
 
     protected void emitExplicitExceptions(T receiver, T outOfBoundsIndex) {
         assert receiver != null;
-        if (graphBuilderConfig.omitAllExceptionEdges() ||
+        if (graphBuilderConfig.omitAllExceptionEdges() || profilingInfo == null ||
                         (optimisticOpts.useExceptionProbabilityForOperations() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE && !GraalOptions.StressExplicitExceptionCode.getValue())) {
             return;
         }
@@ -806,7 +806,7 @@
     protected abstract void genRet(int localIndex);
 
     private double[] switchProbability(int numberOfCases, int bci) {
-        double[] prob = profilingInfo.getSwitchProbabilities(bci);
+        double[] prob = (profilingInfo == null ? null : profilingInfo.getSwitchProbabilities(bci));
         if (prob != null) {
             assert prob.length == numberOfCases;
         } else {
@@ -910,6 +910,10 @@
     }
 
     protected double branchProbability() {
+        if (profilingInfo == null) {
+            return 0.5;
+        }
+        assert assertAtIfBytecode();
         double probability = profilingInfo.getBranchTakenProbability(bci());
         if (probability < 0) {
             assert probability == -1 : "invalid probability";
@@ -927,6 +931,31 @@
         return probability;
     }
 
+    private boolean assertAtIfBytecode() {
+        int bytecode = stream.currentBC();
+        switch (bytecode) {
+            case IFEQ:
+            case IFNE:
+            case IFLT:
+            case IFGE:
+            case IFGT:
+            case IFLE:
+            case IF_ICMPEQ:
+            case IF_ICMPNE:
+            case IF_ICMPLT:
+            case IF_ICMPGE:
+            case IF_ICMPGT:
+            case IF_ICMPLE:
+            case IF_ACMPEQ:
+            case IF_ACMPNE:
+            case IFNULL:
+            case IFNONNULL:
+                return true;
+        }
+        assert false : String.format("%x is not an if bytecode", bytecode);
+        return true;
+    }
+
     protected abstract void iterateBytecodesForBlock(BciBlock block);
 
     public final void processBytecode(int bci, int opcode) {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/ComputeLoopFrequenciesClosure.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/ComputeLoopFrequenciesClosure.java	Wed Feb 18 00:09:24 2015 +0100
@@ -62,10 +62,11 @@
         Map<LoopExitNode, Double> exitStates = ReentrantNodeIterator.processLoop(this, loop, 1D).exitStates;
 
         double exitProbability = exitStates.values().stream().mapToDouble(d -> d).sum();
-        assert exitProbability <= 1D && exitProbability >= 0D;
+        exitProbability = Math.min(1D, exitProbability);
         if (exitProbability < MIN_PROBABILITY) {
             exitProbability = MIN_PROBABILITY;
         }
+        assert exitProbability <= 1D && exitProbability >= 0D;
         double loopFrequency = 1D / exitProbability;
         loop.setLoopFrequency(loopFrequency);
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java	Wed Feb 18 00:09:24 2015 +0100
@@ -41,12 +41,13 @@
     private final ResolvedJavaType[] skippedExceptionTypes;
     private final DebugInfoMode debugInfoMode;
     private final boolean doLivenessAnalysis;
-    private final InvocationPlugins invocationPlugins = new InvocationPlugins();
+    private InvocationPlugins invocationPlugins = new InvocationPlugins();
     private LoadFieldPlugin loadFieldPlugin;
     private ParameterPlugin parameterPlugin;
     private InlineInvokePlugin inlineInvokePlugin;
     private AnnotatedInvocationPlugin annotatedInvocationPlugin;
     private LoopExplosionPlugin loopExplosionPlugin;
+    private boolean useProfiling;
 
     public static enum DebugInfoMode {
         SafePointsOnly,
@@ -78,14 +79,24 @@
         this.debugInfoMode = debugInfoMode;
         this.skippedExceptionTypes = skippedExceptionTypes;
         this.doLivenessAnalysis = doLivenessAnalysis;
+        this.useProfiling = true;
     }
 
     public GraphBuilderConfiguration copy() {
         GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis);
+        result.useProfiling = useProfiling;
         result.copyPluginsFrom(this);
         return result;
     }
 
+    public boolean getUseProfiling() {
+        return useProfiling;
+    }
+
+    public void setUseProfiling(boolean b) {
+        this.useProfiling = b;
+    }
+
     public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) {
         return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis);
     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Feb 18 00:09:24 2015 +0100
@@ -239,7 +239,7 @@
 
             protected void build(int depth, FixedWithNextNode startInstruction, HIRFrameStateBuilder startFrameState) {
                 this.currentDepth = depth;
-                if (PrintProfilingInformation.getValue()) {
+                if (PrintProfilingInformation.getValue() && profilingInfo != null) {
                     TTY.println("Profiling info for " + method.format("%H.%n(%p)"));
                     TTY.println(MetaUtil.indent(profilingInfo.toString(method, CodeUtil.NEW_LINE), "  "));
                 }
@@ -333,12 +333,10 @@
 
                     if (context.targetPeelIteration != -1) {
                         // We were reaching the backedge during explosion. Explode further.
-                        Debug.dump(currentGraph, "Before loop explosion " + context.targetPeelIteration);
                         context.peelIteration = context.targetPeelIteration;
                         context.targetPeelIteration = -1;
                     } else {
                         // We did not reach the backedge. Exit.
-                        Debug.dump(currentGraph, "after loop explosion " + context.peelIteration);
                         break;
                     }
                 }
@@ -473,7 +471,7 @@
 
             private DispatchBeginNode handleException(ValueNode exceptionObject, int bci) {
                 assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci";
-                Debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, profilingInfo.getExceptionSeen(bci));
+                Debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));
 
                 BciBlock dispatchBlock = currentBlock.exceptionDispatchBlock();
                 /*
@@ -854,7 +852,7 @@
                 }
                 if (invokeKind.hasReceiver()) {
                     emitExplicitExceptions(args[0], null);
-                    if (invokeKind.isIndirect() && this.optimisticOpts.useTypeCheckHints()) {
+                    if (invokeKind.isIndirect() && profilingInfo != null && this.optimisticOpts.useTypeCheckHints()) {
                         JavaTypeProfile profile = profilingInfo.getTypeProfile(bci());
                         args[0] = TypeProfileProxyNode.proxify(args[0], profile);
                     }
@@ -882,7 +880,7 @@
 
                 // be conservative if information was not recorded (could result in endless
                 // recompiles otherwise)
-                if (graphBuilderConfig.omitAllExceptionEdges() || (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE)) {
+                if (graphBuilderConfig.omitAllExceptionEdges() || (optimisticOpts.useExceptionProbability() && profilingInfo != null && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE)) {
                     createInvoke(callTarget, resultType);
                 } else {
                     InvokeWithExceptionNode invoke = createInvokeWithException(callTarget, resultType);
@@ -933,17 +931,14 @@
                     return false;
                 }
                 ResolvedJavaMethod inlinedMethod = plugin.getInlinedMethod(this, targetMethod, args, returnType, currentDepth);
-                if (inlinedMethod != null) {
-                    if (inlinedMethod != null) {
-                        assert inlinedMethod.hasBytecodes();
-                        if (TraceInlineDuringParsing.getValue()) {
-                            int bci = this.bci();
-                            StackTraceElement ste = this.method.asStackTraceElement(bci);
-                            TTY.println(format("%s%s (%s:%d) inlining call to %s", nSpaces(currentDepth), method.getName(), ste.getFileName(), ste.getLineNumber(), inlinedMethod.format("%h.%n(%p)")));
-                        }
-                        parseAndInlineCallee(inlinedMethod, args, parsingReplacement || !inlinedMethod.equals(targetMethod));
-                        plugin.postInline(inlinedMethod);
+                if (inlinedMethod != null && inlinedMethod.hasBytecodes()) {
+                    if (TraceInlineDuringParsing.getValue()) {
+                        int bci = this.bci();
+                        StackTraceElement ste = this.method.asStackTraceElement(bci);
+                        TTY.println(format("%s%s (%s:%d) inlining call to %s", nSpaces(currentDepth), method.getName(), ste.getFileName(), ste.getLineNumber(), inlinedMethod.format("%h.%n(%p)")));
                     }
+                    parseAndInlineCallee(inlinedMethod, args, parsingReplacement || !inlinedMethod.equals(targetMethod));
+                    plugin.postInline(inlinedMethod);
                     return true;
                 }
 
@@ -1677,8 +1672,6 @@
 
             @Override
             protected void genIf(ValueNode x, Condition cond, ValueNode y) {
-                // assert !x.isDeleted() && !y.isDeleted();
-                // assert currentBlock.numNormalSuccessors() == 2;
                 assert currentBlock.getSuccessorCount() == 2;
                 BciBlock trueBlock = currentBlock.getSuccessor(0);
                 BciBlock falseBlock = currentBlock.getSuccessor(1);
@@ -1687,8 +1680,6 @@
                     return;
                 }
 
-                double probability = branchProbability();
-
                 // the mirroring and negation operations get the condition into canonical form
                 boolean mirror = cond.canonicalMirror();
                 boolean negate = cond.canonicalNegate();
@@ -1732,6 +1723,9 @@
                         condition = currentGraph.unique(condition);
                     }
 
+                    // Need to get probability based on current bci.
+                    double probability = branchProbability();
+
                     int oldBci = stream.currentBCI();
                     int trueBlockInt = checkPositiveIntConstantPushed(trueBlock);
                     if (trueBlockInt != -1) {
@@ -1772,6 +1766,7 @@
                     }
 
                     this.controlFlowSplit = true;
+
                     ValueNode trueSuccessor = createBlockTarget(probability, trueBlock, frameState);
                     ValueNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState);
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java	Wed Feb 18 00:09:24 2015 +0100
@@ -186,11 +186,14 @@
      */
     public void updateFrom(InvocationPlugins other) {
         this.plugins.putAll(other.plugins);
+        if (other.defaults != null) {
+            updateFrom(other.defaults);
+        }
     }
 
     @Override
     public String toString() {
-        return plugins.keySet().stream().map(m -> m.format("%H.%n(%p)")).collect(Collectors.joining(", "));
+        return plugins.keySet().stream().map(m -> m.format("%H.%n(%p)")).collect(Collectors.joining(", ")) + " / defaults: " + this.defaults;
     }
 
     private static class Checker {
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Wed Feb 18 00:09:24 2015 +0100
@@ -98,7 +98,18 @@
                 }
             }
         });
-        compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
+        int selectedProcessors = TruffleCompilerOptions.TruffleCompilerThreads.getValue();
+        if (selectedProcessors == 0) {
+            // No manual selection made, check how many processors are available.
+            int availableProcessors = Runtime.getRuntime().availableProcessors();
+            if (availableProcessors >= 4) {
+                selectedProcessors = 2;
+            } else if (availableProcessors >= 12) {
+                selectedProcessors = 4;
+            }
+        }
+        selectedProcessors = Math.max(1, selectedProcessors);
+        compileQueue = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
 
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/AlternateFrameWithoutBoxing.java	Tue Feb 17 22:21:53 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,427 +0,0 @@
-/*
- * 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.truffle;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import sun.misc.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * More efficient implementation of the Truffle frame that has no safety checks for frame accesses
- * and therefore is much faster. Should not be used during debugging as potential misuses of the
- * frame object would show up very late and would be hard to identify.
- */
-public final class AlternateFrameWithoutBoxing implements VirtualFrame, MaterializedFrame {
-    private final FrameDescriptor descriptor;
-    private final Object[] arguments;
-    private Object[] locals;
-    private long[] primitiveLocals;
-    private byte[] tags;
-
-    public AlternateFrameWithoutBoxing(FrameDescriptor descriptor, Object[] arguments) {
-        this.descriptor = descriptor;
-        this.arguments = arguments;
-        int size = descriptor.getSize();
-        this.locals = new Object[size];
-        Object defaultValue = descriptor.getDefaultValue();
-        if (defaultValue != null) {
-            Arrays.fill(locals, defaultValue);
-        }
-        this.primitiveLocals = new long[size];
-        this.tags = new byte[size];
-    }
-
-    @Override
-    public Object[] getArguments() {
-        return unsafeCast(arguments, Object[].class, true, true);
-    }
-
-    @Override
-    public MaterializedFrame materialize() {
-        return this;
-    }
-
-    @Override
-    public Object getObject(FrameSlot slot) throws FrameSlotTypeException {
-        verifyGet(slot, FrameSlotKind.Object);
-        return getObjectUnsafe(slot);
-    }
-
-    private Object[] getLocals() {
-        return unsafeCast(locals, Object[].class, true, true);
-    }
-
-    private long[] getPrimitiveLocals() {
-        return unsafeCast(this.primitiveLocals, long[].class, true, true);
-    }
-
-    private byte[] getTags() {
-        return unsafeCast(tags, byte[].class, true, true);
-    }
-
-    private Object getObjectUnsafe(FrameSlot slot) {
-        int slotIndex = slot.getIndex();
-        return unsafeGetObject(getLocals(), Unsafe.ARRAY_OBJECT_BASE_OFFSET + slotIndex * (long) Unsafe.ARRAY_OBJECT_INDEX_SCALE, this.getTags()[slotIndex] == FrameSlotKind.Object.ordinal(), slot);
-    }
-
-    @Override
-    public void setObject(FrameSlot slot, Object value) {
-        verifySet(slot, FrameSlotKind.Object);
-        setObjectUnsafe(slot, value);
-    }
-
-    private void setObjectUnsafe(FrameSlot slot, Object value) {
-        unsafePutObject(getLocals(), Unsafe.ARRAY_OBJECT_BASE_OFFSET + slot.getIndex() * (long) Unsafe.ARRAY_OBJECT_INDEX_SCALE, value, slot);
-    }
-
-    @Override
-    public byte getByte(FrameSlot slot) throws FrameSlotTypeException {
-        verifyGet(slot, FrameSlotKind.Byte);
-        return getByteUnsafe(slot);
-    }
-
-    private byte getByteUnsafe(FrameSlot slot) {
-        long offset = getPrimitiveOffset(slot);
-        boolean condition = this.getTags()[slot.getIndex()] == FrameSlotKind.Byte.ordinal();
-        return (byte) unsafeGetInt(getPrimitiveLocals(), offset, condition, slot);
-    }
-
-    @Override
-    public void setByte(FrameSlot slot, byte value) {
-        verifySet(slot, FrameSlotKind.Byte);
-        setByteUnsafe(slot, value);
-    }
-
-    private void setByteUnsafe(FrameSlot slot, byte value) {
-        long offset = getPrimitiveOffset(slot);
-        unsafePutInt(getPrimitiveLocals(), offset, value, slot);
-    }
-
-    @Override
-    public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException {
-        verifyGet(slot, FrameSlotKind.Boolean);
-        return getBooleanUnsafe(slot);
-    }
-
-    private boolean getBooleanUnsafe(FrameSlot slot) {
-        long offset = getPrimitiveOffset(slot);
-        boolean condition = this.getTags()[slot.getIndex()] == FrameSlotKind.Boolean.ordinal();
-        return unsafeGetInt(getPrimitiveLocals(), offset, condition, slot) != 0;
-    }
-
-    @Override
-    public void setBoolean(FrameSlot slot, boolean value) {
-        verifySet(slot, FrameSlotKind.Boolean);
-        setBooleanUnsafe(slot, value);
-    }
-
-    private void setBooleanUnsafe(FrameSlot slot, boolean value) {
-        long offset = getPrimitiveOffset(slot);
-        unsafePutInt(getPrimitiveLocals(), offset, value ? 1 : 0, slot);
-    }
-
-    @Override
-    public float getFloat(FrameSlot slot) throws FrameSlotTypeException {
-        verifyGet(slot, FrameSlotKind.Float);
-        return getFloatUnsafe(slot);
-    }
-
-    private float getFloatUnsafe(FrameSlot slot) {
-        long offset = getPrimitiveOffset(slot);
-        boolean condition = this.getTags()[slot.getIndex()] == FrameSlotKind.Float.ordinal();
-        return unsafeGetFloat(getPrimitiveLocals(), offset, condition, slot);
-    }
-
-    @Override
-    public void setFloat(FrameSlot slot, float value) {
-        verifySet(slot, FrameSlotKind.Float);
-        setFloatUnsafe(slot, value);
-    }
-
-    private void setFloatUnsafe(FrameSlot slot, float value) {
-        long offset = getPrimitiveOffset(slot);
-        unsafePutFloat(getPrimitiveLocals(), offset, value, slot);
-    }
-
-    @Override
-    public long getLong(FrameSlot slot) throws FrameSlotTypeException {
-        verifyGet(slot, FrameSlotKind.Long);
-        return getLongUnsafe(slot);
-    }
-
-    private long getLongUnsafe(FrameSlot slot) {
-        long offset = getPrimitiveOffset(slot);
-        boolean condition = this.getTags()[slot.getIndex()] == FrameSlotKind.Long.ordinal();
-        return unsafeGetLong(getPrimitiveLocals(), offset, condition, slot);
-    }
-
-    @Override
-    public void setLong(FrameSlot slot, long value) {
-        verifySet(slot, FrameSlotKind.Long);
-        setLongUnsafe(slot, value);
-    }
-
-    private void setLongUnsafe(FrameSlot slot, long value) {
-        long offset = getPrimitiveOffset(slot);
-        unsafePutLong(getPrimitiveLocals(), offset, value, slot);
-    }
-
-    @Override
-    public int getInt(FrameSlot slot) throws FrameSlotTypeException {
-        verifyGet(slot, FrameSlotKind.Int);
-        return getIntUnsafe(slot);
-    }
-
-    private int getIntUnsafe(FrameSlot slot) {
-        long offset = getPrimitiveOffset(slot);
-        boolean condition = this.getTags()[slot.getIndex()] == FrameSlotKind.Int.ordinal();
-        return unsafeGetInt(getPrimitiveLocals(), offset, condition, slot);
-    }
-
-    @Override
-    public void setInt(FrameSlot slot, int value) {
-        verifySet(slot, FrameSlotKind.Int);
-        setIntUnsafe(slot, value);
-    }
-
-    private void setIntUnsafe(FrameSlot slot, int value) {
-        long offset = getPrimitiveOffset(slot);
-        unsafePutInt(getPrimitiveLocals(), offset, value, slot);
-    }
-
-    @Override
-    public double getDouble(FrameSlot slot) throws FrameSlotTypeException {
-        verifyGet(slot, FrameSlotKind.Double);
-        return getDoubleUnsafe(slot);
-    }
-
-    private double getDoubleUnsafe(FrameSlot slot) {
-        long offset = getPrimitiveOffset(slot);
-        boolean condition = this.getTags()[slot.getIndex()] == FrameSlotKind.Double.ordinal();
-        return unsafeGetDouble(getPrimitiveLocals(), offset, condition, slot);
-    }
-
-    @Override
-    public void setDouble(FrameSlot slot, double value) {
-        verifySet(slot, FrameSlotKind.Double);
-        setDoubleUnsafe(slot, value);
-    }
-
-    private void setDoubleUnsafe(FrameSlot slot, double value) {
-        long offset = getPrimitiveOffset(slot);
-        unsafePutDouble(getPrimitiveLocals(), offset, value, slot);
-    }
-
-    @Override
-    public FrameDescriptor getFrameDescriptor() {
-        return this.descriptor;
-    }
-
-    private void verifySet(FrameSlot slot, FrameSlotKind accessKind) {
-        int slotIndex = slot.getIndex();
-        if (slotIndex >= getTags().length) {
-            CompilerDirectives.transferToInterpreter();
-            if (!resize()) {
-                throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot));
-            }
-        }
-        getTags()[slotIndex] = (byte) accessKind.ordinal();
-    }
-
-    private void verifyGet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException {
-        int slotIndex = slot.getIndex();
-        if (slotIndex >= getTags().length) {
-            CompilerDirectives.transferToInterpreter();
-            if (!resize()) {
-                throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot));
-            }
-        }
-        byte tag = this.getTags()[slotIndex];
-        if (tag != accessKind.ordinal()) {
-            CompilerDirectives.transferToInterpreter();
-            throw new FrameSlotTypeException();
-        }
-    }
-
-    private static long getPrimitiveOffset(FrameSlot slot) {
-        return Unsafe.ARRAY_LONG_BASE_OFFSET + slot.getIndex() * (long) Unsafe.ARRAY_LONG_INDEX_SCALE;
-    }
-
-    @Override
-    public Object getValue(FrameSlot slot) {
-        int slotIndex = slot.getIndex();
-        if (slotIndex >= getTags().length) {
-            CompilerDirectives.transferToInterpreter();
-            resize();
-        }
-        byte tag = getTags()[slotIndex];
-        if (tag == FrameSlotKind.Boolean.ordinal()) {
-            return getBooleanUnsafe(slot);
-        } else if (tag == FrameSlotKind.Byte.ordinal()) {
-            return getByteUnsafe(slot);
-        } else if (tag == FrameSlotKind.Int.ordinal()) {
-            return getIntUnsafe(slot);
-        } else if (tag == FrameSlotKind.Double.ordinal()) {
-            return getDoubleUnsafe(slot);
-        } else if (tag == FrameSlotKind.Long.ordinal()) {
-            return getLongUnsafe(slot);
-        } else if (tag == FrameSlotKind.Float.ordinal()) {
-            return getFloatUnsafe(slot);
-        } else {
-            assert tag == FrameSlotKind.Object.ordinal();
-            return getObjectUnsafe(slot);
-        }
-    }
-
-    private boolean resize() {
-        int oldSize = tags.length;
-        int newSize = descriptor.getSize();
-        if (newSize > oldSize) {
-            locals = Arrays.copyOf(locals, newSize);
-            Arrays.fill(locals, oldSize, newSize, descriptor.getDefaultValue());
-            primitiveLocals = Arrays.copyOf(primitiveLocals, newSize);
-            tags = Arrays.copyOf(tags, newSize);
-            return true;
-        }
-        return false;
-    }
-
-    private byte getTag(FrameSlot slot) {
-        int slotIndex = slot.getIndex();
-        if (slotIndex >= getTags().length) {
-            CompilerDirectives.transferToInterpreter();
-            resize();
-        }
-        return getTags()[slotIndex];
-    }
-
-    @Override
-    public boolean isObject(FrameSlot slot) {
-        return getTag(slot) == FrameSlotKind.Object.ordinal();
-    }
-
-    @Override
-    public boolean isByte(FrameSlot slot) {
-        return getTag(slot) == FrameSlotKind.Byte.ordinal();
-    }
-
-    @Override
-    public boolean isBoolean(FrameSlot slot) {
-        return getTag(slot) == FrameSlotKind.Boolean.ordinal();
-    }
-
-    @Override
-    public boolean isInt(FrameSlot slot) {
-        return getTag(slot) == FrameSlotKind.Int.ordinal();
-    }
-
-    @Override
-    public boolean isLong(FrameSlot slot) {
-        return getTag(slot) == FrameSlotKind.Long.ordinal();
-    }
-
-    @Override
-    public boolean isFloat(FrameSlot slot) {
-        return getTag(slot) == FrameSlotKind.Float.ordinal();
-    }
-
-    @Override
-    public boolean isDouble(FrameSlot slot) {
-        return getTag(slot) == FrameSlotKind.Double.ordinal();
-    }
-
-    @SuppressWarnings({"unchecked", "unused"})
-    static <T> T unsafeCast(Object value, Class<T> type, boolean condition, boolean nonNull) {
-        return (T) value;
-    }
-
-    @SuppressWarnings("unused")
-    static int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity) {
-        return UNSAFE.getInt(receiver, offset);
-    }
-
-    @SuppressWarnings("unused")
-    static long unsafeGetLong(Object receiver, long offset, boolean condition, Object locationIdentity) {
-        return UNSAFE.getLong(receiver, offset);
-    }
-
-    @SuppressWarnings("unused")
-    static float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity) {
-        return UNSAFE.getFloat(receiver, offset);
-    }
-
-    @SuppressWarnings("unused")
-    static double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity) {
-        return UNSAFE.getDouble(receiver, offset);
-    }
-
-    @SuppressWarnings("unused")
-    static Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity) {
-        return UNSAFE.getObject(receiver, offset);
-    }
-
-    @SuppressWarnings("unused")
-    static void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity) {
-        UNSAFE.putInt(receiver, offset, value);
-    }
-
-    @SuppressWarnings("unused")
-    static void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity) {
-        UNSAFE.putLong(receiver, offset, value);
-    }
-
-    @SuppressWarnings("unused")
-    static void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity) {
-        UNSAFE.putFloat(receiver, offset, value);
-    }
-
-    @SuppressWarnings("unused")
-    static void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity) {
-        UNSAFE.putDouble(receiver, offset, value);
-    }
-
-    @SuppressWarnings("unused")
-    static void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity) {
-        UNSAFE.putObject(receiver, offset, value);
-    }
-
-    private static final Unsafe UNSAFE = getUnsafe();
-
-    private static Unsafe getUnsafe() {
-        try {
-            return Unsafe.getUnsafe();
-        } catch (SecurityException e) {
-        }
-        try {
-            Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
-            theUnsafeInstance.setAccessible(true);
-            return (Unsafe) theUnsafeInstance.get(Unsafe.class);
-        } catch (Exception e) {
-            throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e);
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithBoxing.java	Wed Feb 18 00:09:24 2015 +0100
@@ -0,0 +1,305 @@
+/*
+ * 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.truffle;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import sun.misc.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+
+/**
+ * More efficient implementation of the Truffle frame that has no safety checks for frame accesses
+ * and therefore is much faster. Should not be used during debugging as potential misuses of the
+ * frame object would show up very late and would be hard to identify.
+ */
+public final class FrameWithBoxing implements VirtualFrame, MaterializedFrame {
+    private final FrameDescriptor descriptor;
+    private final Object[] arguments;
+    private Object[] locals;
+
+    public FrameWithBoxing(FrameDescriptor descriptor, Object[] arguments) {
+        this.descriptor = descriptor;
+        this.arguments = arguments;
+        int size = descriptor.getSize();
+        this.locals = new Object[size];
+        Object defaultValue = descriptor.getDefaultValue();
+        if (defaultValue != null) {
+            Arrays.fill(locals, defaultValue);
+        }
+    }
+
+    @Override
+    public Object[] getArguments() {
+        return unsafeCast(arguments, Object[].class, true, true);
+    }
+
+    @Override
+    public MaterializedFrame materialize() {
+        return this;
+    }
+
+    @Override
+    public Object getObject(FrameSlot slot) {
+        int index = slot.getIndex();
+        Object[] curLocals = this.getLocals();
+        if (CompilerDirectives.inInterpreter() && index >= curLocals.length) {
+            curLocals = resizeAndCheck(slot);
+        }
+        return curLocals[index];
+    }
+
+    private Object[] getLocals() {
+        return unsafeCast(locals, Object[].class, true, true);
+    }
+
+    @Override
+    public void setObject(FrameSlot slot, Object value) {
+        int index = slot.getIndex();
+        Object[] curLocals = this.getLocals();
+        if (CompilerDirectives.inInterpreter() && index >= curLocals.length) {
+            curLocals = resizeAndCheck(slot);
+        }
+        curLocals[index] = value;
+    }
+
+    @Override
+    public byte getByte(FrameSlot slot) throws FrameSlotTypeException {
+        Object result = getObject(slot);
+        if (CompilerDirectives.inInterpreter() && !(result instanceof Byte)) {
+            throw new FrameSlotTypeException();
+        }
+        return (Byte) result;
+    }
+
+    @Override
+    public void setByte(FrameSlot slot, byte value) {
+        setObject(slot, value);
+    }
+
+    @Override
+    public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException {
+        Object result = getObject(slot);
+        if (CompilerDirectives.inInterpreter() && !(result instanceof Boolean)) {
+            throw new FrameSlotTypeException();
+        }
+        return (Boolean) result;
+    }
+
+    @Override
+    public void setBoolean(FrameSlot slot, boolean value) {
+        setObject(slot, value);
+    }
+
+    @Override
+    public float getFloat(FrameSlot slot) throws FrameSlotTypeException {
+        Object result = getObject(slot);
+        if (CompilerDirectives.inInterpreter() && !(result instanceof Float)) {
+            throw new FrameSlotTypeException();
+        }
+        return (Float) result;
+    }
+
+    @Override
+    public void setFloat(FrameSlot slot, float value) {
+        setObject(slot, value);
+    }
+
+    @Override
+    public long getLong(FrameSlot slot) throws FrameSlotTypeException {
+        Object result = getObject(slot);
+        if (CompilerDirectives.inInterpreter() && !(result instanceof Long)) {
+            throw new FrameSlotTypeException();
+        }
+        return (Long) result;
+    }
+
+    @Override
+    public void setLong(FrameSlot slot, long value) {
+        setObject(slot, value);
+    }
+
+    @Override
+    public int getInt(FrameSlot slot) throws FrameSlotTypeException {
+        Object result = getObject(slot);
+        if (CompilerDirectives.inInterpreter() && !(result instanceof Integer)) {
+            throw new FrameSlotTypeException();
+        }
+        return (Integer) result;
+    }
+
+    @Override
+    public void setInt(FrameSlot slot, int value) {
+        setObject(slot, value);
+    }
+
+    @Override
+    public double getDouble(FrameSlot slot) throws FrameSlotTypeException {
+        Object result = getObject(slot);
+        if (CompilerDirectives.inInterpreter() && !(result instanceof Double)) {
+            throw new FrameSlotTypeException();
+        }
+        return (Double) result;
+    }
+
+    @Override
+    public void setDouble(FrameSlot slot, double value) {
+        setObject(slot, value);
+    }
+
+    @Override
+    public FrameDescriptor getFrameDescriptor() {
+        return this.descriptor;
+    }
+
+    private Object[] resizeAndCheck(FrameSlot slot) {
+        if (!resize()) {
+            throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot));
+        }
+        return locals;
+    }
+
+    @Override
+    public Object getValue(FrameSlot slot) {
+        return getObject(slot);
+    }
+
+    private boolean resize() {
+        int oldSize = locals.length;
+        int newSize = descriptor.getSize();
+        if (newSize > oldSize) {
+            locals = Arrays.copyOf(locals, newSize);
+            Arrays.fill(locals, oldSize, newSize, descriptor.getDefaultValue());
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isObject(FrameSlot slot) {
+        return getObject(slot) != null;
+    }
+
+    @Override
+    public boolean isByte(FrameSlot slot) {
+        return getObject(slot) instanceof Byte;
+    }
+
+    @Override
+    public boolean isBoolean(FrameSlot slot) {
+        return getObject(slot) instanceof Boolean;
+    }
+
+    @Override
+    public boolean isInt(FrameSlot slot) {
+        return getObject(slot) instanceof Integer;
+    }
+
+    @Override
+    public boolean isLong(FrameSlot slot) {
+        return getObject(slot) instanceof Long;
+    }
+
+    @Override
+    public boolean isFloat(FrameSlot slot) {
+        return getObject(slot) instanceof Float;
+    }
+
+    @Override
+    public boolean isDouble(FrameSlot slot) {
+        return getObject(slot) instanceof Double;
+    }
+
+    @SuppressWarnings({"unchecked", "unused"})
+    static <T> T unsafeCast(Object value, Class<T> type, boolean condition, boolean nonNull) {
+        return (T) value;
+    }
+
+    @SuppressWarnings("unused")
+    static int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getInt(receiver, offset);
+    }
+
+    @SuppressWarnings("unused")
+    static long unsafeGetLong(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getLong(receiver, offset);
+    }
+
+    @SuppressWarnings("unused")
+    static float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getFloat(receiver, offset);
+    }
+
+    @SuppressWarnings("unused")
+    static double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getDouble(receiver, offset);
+    }
+
+    @SuppressWarnings("unused")
+    static Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getObject(receiver, offset);
+    }
+
+    @SuppressWarnings("unused")
+    static void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity) {
+        UNSAFE.putInt(receiver, offset, value);
+    }
+
+    @SuppressWarnings("unused")
+    static void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity) {
+        UNSAFE.putLong(receiver, offset, value);
+    }
+
+    @SuppressWarnings("unused")
+    static void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity) {
+        UNSAFE.putFloat(receiver, offset, value);
+    }
+
+    @SuppressWarnings("unused")
+    static void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity) {
+        UNSAFE.putDouble(receiver, offset, value);
+    }
+
+    @SuppressWarnings("unused")
+    static void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity) {
+        UNSAFE.putObject(receiver, offset, value);
+    }
+
+    private static final Unsafe UNSAFE = getUnsafe();
+
+    private static Unsafe getUnsafe() {
+        try {
+            return Unsafe.getUnsafe();
+        } catch (SecurityException e) {
+        }
+        try {
+            Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafeInstance.setAccessible(true);
+            return (Unsafe) theUnsafeInstance.get(Unsafe.class);
+        } catch (Exception e) {
+            throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e);
+        }
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Wed Feb 18 00:09:24 2015 +0100
@@ -39,6 +39,27 @@
     private final FrameDescriptor descriptor;
     private final Object[] arguments;
     private Object[] locals;
+    private long[] primitiveLocals;
+    private byte[] tags;
+    public static final byte OBJECT_TAG = 0;
+    public static final byte ILLEGAL_TAG = 1;
+    public static final byte LONG_TAG = 2;
+    public static final byte INT_TAG = 3;
+    public static final byte DOUBLE_TAG = 4;
+    public static final byte FLOAT_TAG = 5;
+    public static final byte BOOLEAN_TAG = 6;
+    public static final byte BYTE_TAG = 7;
+
+    static {
+        assert OBJECT_TAG == FrameSlotKind.Object.tag;
+        assert ILLEGAL_TAG == FrameSlotKind.Illegal.tag;
+        assert LONG_TAG == FrameSlotKind.Long.tag;
+        assert INT_TAG == FrameSlotKind.Int.tag;
+        assert DOUBLE_TAG == FrameSlotKind.Double.tag;
+        assert FLOAT_TAG == FrameSlotKind.Float.tag;
+        assert BOOLEAN_TAG == FrameSlotKind.Boolean.tag;
+        assert BYTE_TAG == FrameSlotKind.Byte.tag;
+    }
 
     public FrameWithoutBoxing(FrameDescriptor descriptor, Object[] arguments) {
         this.descriptor = descriptor;
@@ -49,6 +70,8 @@
         if (defaultValue != null) {
             Arrays.fill(locals, defaultValue);
         }
+        this.primitiveLocals = new long[size];
+        this.tags = new byte[size];
     }
 
     @Override
@@ -62,111 +85,187 @@
     }
 
     @Override
-    public Object getObject(FrameSlot slot) {
-        int index = slot.getIndex();
-        Object[] curLocals = this.getLocals();
-        if (CompilerDirectives.inInterpreter() && index >= curLocals.length) {
-            curLocals = resizeAndCheck(slot);
-        }
-        return curLocals[index];
+    public Object getObject(FrameSlot slot) throws FrameSlotTypeException {
+        int slotIndex = slot.getIndex();
+        verifyGet(slotIndex, OBJECT_TAG);
+        return getObjectUnsafe(slotIndex, slot);
     }
 
     private Object[] getLocals() {
         return unsafeCast(locals, Object[].class, true, true);
     }
 
+    private long[] getPrimitiveLocals() {
+        return unsafeCast(this.primitiveLocals, long[].class, true, true);
+    }
+
+    private byte[] getTags() {
+        return unsafeCast(tags, byte[].class, true, true);
+    }
+
+    private Object getObjectUnsafe(int slotIndex, FrameSlot slot) {
+        return unsafeGetObject(getLocals(), Unsafe.ARRAY_OBJECT_BASE_OFFSET + slotIndex * (long) Unsafe.ARRAY_OBJECT_INDEX_SCALE, this.getTags()[slotIndex] == FrameSlotKind.Object.tag, slot);
+    }
+
     @Override
     public void setObject(FrameSlot slot, Object value) {
-        int index = slot.getIndex();
-        Object[] curLocals = this.getLocals();
-        if (CompilerDirectives.inInterpreter() && index >= curLocals.length) {
-            curLocals = resizeAndCheck(slot);
-        }
-        curLocals[index] = value;
+        int slotIndex = slot.getIndex();
+        verifySet(slotIndex, OBJECT_TAG);
+        setObjectUnsafe(slotIndex, slot, value);
+    }
+
+    private void setObjectUnsafe(int slotIndex, FrameSlot slot, Object value) {
+        unsafePutObject(getLocals(), Unsafe.ARRAY_OBJECT_BASE_OFFSET + slotIndex * (long) Unsafe.ARRAY_OBJECT_INDEX_SCALE, value, slot);
     }
 
     @Override
     public byte getByte(FrameSlot slot) throws FrameSlotTypeException {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Byte)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Byte) result;
+        int slotIndex = slot.getIndex();
+        verifyGet(slotIndex, BYTE_TAG);
+        return getByteUnsafe(slotIndex, slot);
+    }
+
+    private byte getByteUnsafe(int slotIndex, FrameSlot slot) {
+        long offset = getPrimitiveOffset(slotIndex);
+        boolean condition = this.getTags()[slotIndex] == FrameSlotKind.Byte.tag;
+        return (byte) unsafeGetInt(getPrimitiveLocals(), offset, condition, slot);
     }
 
     @Override
     public void setByte(FrameSlot slot, byte value) {
-        setObject(slot, value);
+        int slotIndex = slot.getIndex();
+        verifySet(slotIndex, BYTE_TAG);
+        setByteUnsafe(slotIndex, slot, value);
+    }
+
+    private void setByteUnsafe(int slotIndex, FrameSlot slot, byte value) {
+        long offset = getPrimitiveOffset(slotIndex);
+        unsafePutInt(getPrimitiveLocals(), offset, value, slot);
     }
 
     @Override
     public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Boolean)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Boolean) result;
+        int slotIndex = slot.getIndex();
+        verifyGet(slotIndex, BOOLEAN_TAG);
+        return getBooleanUnsafe(slotIndex, slot);
+    }
+
+    private boolean getBooleanUnsafe(int slotIndex, FrameSlot slot) {
+        long offset = getPrimitiveOffset(slotIndex);
+        boolean condition = this.getTags()[slotIndex] == FrameSlotKind.Boolean.tag;
+        return unsafeGetInt(getPrimitiveLocals(), offset, condition, slot) != 0;
     }
 
     @Override
     public void setBoolean(FrameSlot slot, boolean value) {
-        setObject(slot, value);
+        int slotIndex = slot.getIndex();
+        verifySet(slotIndex, BOOLEAN_TAG);
+        setBooleanUnsafe(slotIndex, slot, value);
+    }
+
+    private void setBooleanUnsafe(int slotIndex, FrameSlot slot, boolean value) {
+        long offset = getPrimitiveOffset(slotIndex);
+        unsafePutInt(getPrimitiveLocals(), offset, value ? 1 : 0, slot);
     }
 
     @Override
     public float getFloat(FrameSlot slot) throws FrameSlotTypeException {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Float)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Float) result;
+        int slotIndex = slot.getIndex();
+        verifyGet(slotIndex, FLOAT_TAG);
+        return getFloatUnsafe(slotIndex, slot);
+    }
+
+    private float getFloatUnsafe(int slotIndex, FrameSlot slot) {
+        long offset = getPrimitiveOffset(slotIndex);
+        boolean condition = this.getTags()[slotIndex] == FrameSlotKind.Float.tag;
+        return unsafeGetFloat(getPrimitiveLocals(), offset, condition, slot);
     }
 
     @Override
     public void setFloat(FrameSlot slot, float value) {
-        setObject(slot, value);
+        int slotIndex = slot.getIndex();
+        verifySet(slotIndex, FLOAT_TAG);
+        setFloatUnsafe(slotIndex, slot, value);
+    }
+
+    private void setFloatUnsafe(int slotIndex, FrameSlot slot, float value) {
+        long offset = getPrimitiveOffset(slotIndex);
+        unsafePutFloat(getPrimitiveLocals(), offset, value, slot);
     }
 
     @Override
     public long getLong(FrameSlot slot) throws FrameSlotTypeException {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Long)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Long) result;
+        int slotIndex = slot.getIndex();
+        verifyGet(slotIndex, LONG_TAG);
+        return getLongUnsafe(slotIndex, slot);
+    }
+
+    private long getLongUnsafe(int slotIndex, FrameSlot slot) {
+        long offset = getPrimitiveOffset(slotIndex);
+        boolean condition = this.getTags()[slotIndex] == FrameSlotKind.Long.tag;
+        return unsafeGetLong(getPrimitiveLocals(), offset, condition, slot);
     }
 
     @Override
     public void setLong(FrameSlot slot, long value) {
-        setObject(slot, value);
+        int slotIndex = slot.getIndex();
+        verifySet(slotIndex, LONG_TAG);
+        setLongUnsafe(slotIndex, slot, value);
+    }
+
+    private void setLongUnsafe(int slotIndex, FrameSlot slot, long value) {
+        long offset = getPrimitiveOffset(slotIndex);
+        unsafePutLong(getPrimitiveLocals(), offset, value, slot);
     }
 
     @Override
     public int getInt(FrameSlot slot) throws FrameSlotTypeException {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Integer)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Integer) result;
+        int slotIndex = slot.getIndex();
+        verifyGet(slotIndex, INT_TAG);
+        return getIntUnsafe(slotIndex, slot);
+    }
+
+    private int getIntUnsafe(int slotIndex, FrameSlot slot) {
+        long offset = getPrimitiveOffset(slotIndex);
+        boolean condition = this.getTags()[slot.getIndex()] == FrameSlotKind.Int.tag;
+        return unsafeGetInt(getPrimitiveLocals(), offset, condition, slot);
     }
 
     @Override
     public void setInt(FrameSlot slot, int value) {
-        setObject(slot, value);
+        int slotIndex = slot.getIndex();
+        verifySet(slotIndex, INT_TAG);
+        setIntUnsafe(slotIndex, slot, value);
+    }
+
+    private void setIntUnsafe(int slotIndex, FrameSlot slot, int value) {
+        long offset = getPrimitiveOffset(slotIndex);
+        unsafePutInt(getPrimitiveLocals(), offset, value, slot);
     }
 
     @Override
     public double getDouble(FrameSlot slot) throws FrameSlotTypeException {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Double)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Double) result;
+        int slotIndex = slot.getIndex();
+        verifyGet(slotIndex, DOUBLE_TAG);
+        return getDoubleUnsafe(slotIndex, slot);
+    }
+
+    private double getDoubleUnsafe(int slotIndex, FrameSlot slot) {
+        long offset = getPrimitiveOffset(slotIndex);
+        boolean condition = this.getTags()[slotIndex] == FrameSlotKind.Double.tag;
+        return unsafeGetDouble(getPrimitiveLocals(), offset, condition, slot);
     }
 
     @Override
     public void setDouble(FrameSlot slot, double value) {
-        setObject(slot, value);
+        int slotIndex = slot.getIndex();
+        verifySet(slotIndex, DOUBLE_TAG);
+        setDoubleUnsafe(slotIndex, slot, value);
+    }
+
+    private void setDoubleUnsafe(int slotIndex, FrameSlot slot, double value) {
+        long offset = getPrimitiveOffset(slotIndex);
+        unsafePutDouble(getPrimitiveLocals(), offset, value, slot);
     }
 
     @Override
@@ -174,62 +273,112 @@
         return this.descriptor;
     }
 
-    private Object[] resizeAndCheck(FrameSlot slot) {
-        if (!resize()) {
-            throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slot));
+    private void verifySet(int slotIndex, byte tag) {
+        if (CompilerDirectives.inInterpreter() && slotIndex >= getTags().length) {
+            if (!resize()) {
+                throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slotIndex));
+            }
         }
-        return locals;
+        getTags()[slotIndex] = tag;
+    }
+
+    private void verifyGet(int slotIndex, byte tag) throws FrameSlotTypeException {
+        if (CompilerDirectives.inInterpreter() && slotIndex >= getTags().length) {
+            if (!resize()) {
+                throw new IllegalArgumentException(String.format("The frame slot '%s' is not known by the frame descriptor.", slotIndex));
+            }
+        }
+        if (getTags()[slotIndex] != tag) {
+            CompilerDirectives.transferToInterpreter();
+            throw new FrameSlotTypeException();
+        }
+    }
+
+    private static long getPrimitiveOffset(int slotIndex) {
+        return Unsafe.ARRAY_LONG_BASE_OFFSET + slotIndex * (long) Unsafe.ARRAY_LONG_INDEX_SCALE;
     }
 
     @Override
     public Object getValue(FrameSlot slot) {
-        return getObject(slot);
+        int slotIndex = slot.getIndex();
+        if (CompilerDirectives.inInterpreter() && slotIndex >= getTags().length) {
+            CompilerDirectives.transferToInterpreter();
+            resize();
+        }
+        byte tag = getTags()[slotIndex];
+        if (tag == FrameSlotKind.Boolean.tag) {
+            return getBooleanUnsafe(slotIndex, slot);
+        } else if (tag == FrameSlotKind.Byte.tag) {
+            return getByteUnsafe(slotIndex, slot);
+        } else if (tag == FrameSlotKind.Int.tag) {
+            return getIntUnsafe(slotIndex, slot);
+        } else if (tag == FrameSlotKind.Double.tag) {
+            return getDoubleUnsafe(slotIndex, slot);
+        } else if (tag == FrameSlotKind.Long.tag) {
+            return getLongUnsafe(slotIndex, slot);
+        } else if (tag == FrameSlotKind.Float.tag) {
+            return getFloatUnsafe(slotIndex, slot);
+        } else {
+            assert tag == FrameSlotKind.Object.tag;
+            return getObjectUnsafe(slotIndex, slot);
+        }
     }
 
     private boolean resize() {
-        int oldSize = locals.length;
+        int oldSize = tags.length;
         int newSize = descriptor.getSize();
         if (newSize > oldSize) {
             locals = Arrays.copyOf(locals, newSize);
             Arrays.fill(locals, oldSize, newSize, descriptor.getDefaultValue());
+            primitiveLocals = Arrays.copyOf(primitiveLocals, newSize);
+            tags = Arrays.copyOf(tags, newSize);
             return true;
         }
         return false;
     }
 
+    private byte getTag(FrameSlot slot) {
+        int slotIndex = slot.getIndex();
+        if (slotIndex >= getTags().length) {
+            CompilerDirectives.transferToInterpreter();
+            resize();
+        }
+        return getTags()[slotIndex];
+    }
+
     @Override
     public boolean isObject(FrameSlot slot) {
-        return getObject(slot) != null;
+        return getTag(slot) == FrameSlotKind.Object.tag;
     }
 
     @Override
     public boolean isByte(FrameSlot slot) {
-        return getObject(slot) instanceof Byte;
+        return getTag(slot) == FrameSlotKind.Byte.tag;
     }
 
     @Override
     public boolean isBoolean(FrameSlot slot) {
-        return getObject(slot) instanceof Boolean;
+        return getTag(slot) == FrameSlotKind.Boolean.tag;
     }
 
     @Override
     public boolean isInt(FrameSlot slot) {
-        return getObject(slot) instanceof Integer;
+        return getTag(slot) == FrameSlotKind.Int.tag;
     }
 
     @Override
     public boolean isLong(FrameSlot slot) {
-        return getObject(slot) instanceof Long;
+        return getTag(slot) == FrameSlotKind.Long.tag;
     }
 
     @Override
     public boolean isFloat(FrameSlot slot) {
-        return getObject(slot) instanceof Float;
+        return getTag(slot) == FrameSlotKind.Float.tag;
     }
 
     @Override
     public boolean isDouble(FrameSlot slot) {
-        return getObject(slot) instanceof Double;
+        return getTag(slot) == FrameSlotKind.Double.tag;
     }
 
     @SuppressWarnings({"unchecked", "unused"})
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Wed Feb 18 00:09:24 2015 +0100
@@ -113,7 +113,7 @@
 
     @Override
     public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
-        return new FrameWithoutBoxing(frameDescriptor, arguments);
+        return new FrameWithBoxing(frameDescriptor, arguments);
     }
 
     @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Wed Feb 18 00:09:24 2015 +0100
@@ -417,8 +417,12 @@
         return args;
     }
 
-    public static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, Object[] args) {
-        return new FrameWithoutBoxing(descriptor, args);
+    public static VirtualFrame createFrame(FrameDescriptor descriptor, Object[] args) {
+        if (TruffleCompilerOptions.TruffleUseFrameWithoutBoxing.getValue()) {
+            return new FrameWithoutBoxing(descriptor, args);
+        } else {
+            return new FrameWithBoxing(descriptor, args);
+        }
     }
 
     public List<OptimizedDirectCallNode> getCallNodes() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Feb 18 00:09:24 2015 +0100
@@ -243,16 +243,14 @@
     @SuppressWarnings("unused")
     private void fastPartialEvaluation(OptimizedCallTarget callTarget, StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) {
         GraphBuilderConfiguration newConfig = configForRoot.copy();
-        newConfig.getInvocationPlugins().setDefaults(configForRoot.getInvocationPlugins());
+        newConfig.setUseProfiling(false);
         newConfig.setLoadFieldPlugin(new InterceptLoadFieldPlugin());
         newConfig.setParameterPlugin(new InterceptReceiverPlugin(callTarget));
         callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy()));
         newConfig.setInlineInvokePlugin(new InlineInvokePlugin(callTarget.getInlining(), providers.getReplacements()));
         newConfig.setLoopExplosionPlugin(new LoopExplosionPlugin());
         TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), newConfig.getInvocationPlugins());
-        long ms = System.currentTimeMillis();
         new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), this.snippetReflection, providers.getConstantReflection(), newConfig, TruffleCompilerImpl.Optimizations).apply(graph);
-        System.out.println("# ms: " + (System.currentTimeMillis() - ms));
         Debug.dump(graph, "After FastPE");
 
         for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE)) {
@@ -270,6 +268,7 @@
         // Do single partial escape and canonicalization pass.
         try (Scope pe = Debug.scope("TrufflePartialEscape", graph)) {
             new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext);
+            new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext);
             new IncrementalCanonicalizerPhase<>(canonicalizer, new ConditionalEliminationPhase()).apply(graph, tierContext);
         } catch (Throwable t) {
             Debug.handle(t);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Feb 18 00:09:24 2015 +0100
@@ -81,14 +81,24 @@
         this.compilationNotify = graalTruffleRuntime.getCompilationNotify();
         this.backend = runtime.getHostBackend();
         Replacements truffleReplacements = graalTruffleRuntime.getReplacements();
-        ConstantReflectionProvider constantReflection = new TruffleConstantReflectionProvider(backend.getProviders().getConstantReflection(), backend.getProviders().getMetaAccess());
-        this.providers = backend.getProviders().copyWith(truffleReplacements).copyWith(constantReflection);
+        Providers backendProviders = backend.getProviders();
+        ConstantReflectionProvider constantReflection = new TruffleConstantReflectionProvider(backendProviders.getConstantReflection(), backendProviders.getMetaAccess());
+        if (!TruffleCompilerOptions.FastPE.getValue()) {
+            backendProviders = backendProviders.copyWith(truffleReplacements);
+        }
+        this.providers = backendProviders.copyWith(constantReflection);
         this.suites = backend.getSuites().getDefaultSuites();
         this.lirSuites = backend.getSuites().getDefaultLIRSuites();
 
         ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
         GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault().withSkippedExceptionTypes(skippedExceptionTypes);
+
         this.config = GraphBuilderConfiguration.getDefault().withSkippedExceptionTypes(skippedExceptionTypes);
+        if (TruffleCompilerOptions.FastPE.getValue()) {
+            GraphBuilderPhase phase = (GraphBuilderPhase) backend.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous();
+            this.config.getInvocationPlugins().setDefaults(phase.getGraphBuilderConfig().getInvocationPlugins());
+        }
+
         this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, TruffleCompilerImpl.Optimizations);
 
         this.partialEvaluator = new PartialEvaluator(providers, config, truffleCache, Graal.getRequiredCapability(SnippetReflectionProvider.class));
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Feb 18 00:09:24 2015 +0100
@@ -104,6 +104,9 @@
     @Option(help = "Enable asynchronous truffle compilation in background thread", type = OptionType.Expert)
     public static final OptionValue<Boolean> TruffleBackgroundCompilation = new OptionValue<>(true);
 
+    @Option(help = "Manually set the number of compiler threads", type = OptionType.Expert)
+    public static final StableOptionValue<Integer> TruffleCompilerThreads = new StableOptionValue<>(0);
+
     @Option(help = "Enable inlining across Truffle boundary", type = OptionType.Expert)
     public static final OptionValue<Boolean> TruffleInlineAcrossTruffleBoundary = new OptionValue<>(false);
 
@@ -119,6 +122,9 @@
     @Option(help = "", type = OptionType.Debug)
     public static final OptionValue<Boolean> TruffleArgumentTypeSpeculation = new StableOptionValue<>(true);
 
+    @Option(help = "", type = OptionType.Debug)
+    public static final StableOptionValue<Boolean> TruffleUseFrameWithoutBoxing = new StableOptionValue<>(true);
+
     // tracing
     @Option(help = "Print potential performance problems", type = OptionType.Debug)
     public static final OptionValue<Boolean> TraceTrufflePerformanceWarnings = new OptionValue<>(false);
@@ -181,6 +187,6 @@
     public static final OptionValue<Boolean> TruffleCompilationStatisticDetails = new OptionValue<>(false);
 
     @Option(help = "Experimental new version of the partial evaluator.", type = OptionType.Debug)
-    public static final OptionValue<Boolean> FastPE = new OptionValue<>(false);
+    public static final OptionValue<Boolean> FastPE = new OptionValue<>(true);
     // @formatter:on
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IsCompilationConstantNode.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IsCompilationConstantNode.java	Wed Feb 18 00:09:24 2015 +0100
@@ -22,33 +22,36 @@
  */
 package com.oracle.graal.truffle.nodes;
 
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.replacements.nodes.*;
 
 @NodeInfo
-public final class IsCompilationConstantNode extends MacroStateSplitNode implements Canonicalizable {
+public final class IsCompilationConstantNode extends FloatingNode implements Lowerable, Canonicalizable {
 
     public static final NodeClass<IsCompilationConstantNode> TYPE = NodeClass.get(IsCompilationConstantNode.class);
 
-    public IsCompilationConstantNode(Invoke invoke) {
-        super(TYPE, invoke);
-        assert arguments.size() == 1;
+    @Input ValueNode value;
+
+    public IsCompilationConstantNode(ValueNode value) {
+        super(TYPE, StampFactory.forKind(Kind.Boolean));
+        this.value = value;
     }
 
     @Override
     public void lower(LoweringTool tool) {
-        /* Invoke will return false. */
-        replaceWithInvoke().lower(tool);
+        graph().replaceFloating(this, ConstantNode.forBoolean(false, graph()));
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        ValueNode arg0 = arguments.get(0);
+        ValueNode arg0 = value;
         if (arg0 instanceof BoxNode) {
             arg0 = ((BoxNode) arg0).getValue();
         }
@@ -57,4 +60,7 @@
         }
         return this;
     }
+
+    @NodeIntrinsic
+    public static native boolean check(Object value);
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java	Wed Feb 18 00:09:24 2015 +0100
@@ -25,7 +25,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.truffle.*;
+import com.oracle.truffle.api.frame.*;
 
 /**
  * Intrinsic node for materializing a Truffle frame.
@@ -46,5 +46,5 @@
     }
 
     @NodeIntrinsic
-    public static native <T> T materialize(FrameWithoutBoxing frame);
+    public static native <T> T materialize(VirtualFrame frame);
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Wed Feb 18 00:09:24 2015 +0100
@@ -244,5 +244,5 @@
     }
 
     @NodeIntrinsic
-    public static native FrameWithoutBoxing allocate(@ConstantNodeParameter Class<? extends VirtualFrame> frameType, FrameDescriptor descriptor, Object[] args);
+    public static native VirtualFrame allocate(@ConstantNodeParameter Class<? extends VirtualFrame> frameType, FrameDescriptor descriptor, Object[] args);
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Wed Feb 18 00:09:24 2015 +0100
@@ -73,8 +73,10 @@
     @MacroSubstitution(macro = BailoutNode.class, isStatic = true)
     public static native void bailout(String reason);
 
-    @MacroSubstitution(macro = IsCompilationConstantNode.class, isStatic = true)
-    public static native boolean isCompilationConstant(Object value);
+    @MethodSubstitution
+    public static boolean isCompilationConstant(Object value) {
+        return IsCompilationConstantNode.check(value);
+    }
 
     @MethodSubstitution
     public static void materialize(Object obj) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Wed Feb 18 00:09:24 2015 +0100
@@ -33,7 +33,7 @@
 public class OptimizedCallTargetSubstitutions {
 
     @MethodSubstitution
-    private static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, Object[] args) {
+    private static VirtualFrame createFrame(FrameDescriptor descriptor, Object[] args) {
         return NewFrameNode.allocate(FrameWithoutBoxing.class, descriptor, args);
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Wed Feb 18 00:09:24 2015 +0100
@@ -163,9 +163,10 @@
             public boolean apply(GraphBuilderContext builder, ValueNode value) {
                 if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
                     builder.push(Kind.Boolean.getStackKind(), builder.append(ConstantNode.forBoolean(true)));
-                    return true;
+                } else {
+                    builder.push(Kind.Boolean.getStackKind(), builder.append(new IsCompilationConstantNode(value)));
                 }
-                return false;
+                return true;
             }
         });
         r.register1("materialize", Object.class, new InvocationPlugin() {
@@ -179,27 +180,36 @@
         r = new Registration(plugins, metaAccess, OptimizedCallTarget.class);
         r.register2("createFrame", FrameDescriptor.class, Object[].class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext builder, ValueNode arg1, ValueNode arg2) {
-                builder.push(Kind.Object, builder.append(new NewFrameNode(StampFactory.exactNonNull(metaAccess.lookupJavaType(FrameWithoutBoxing.class)), arg1, arg2)));
+                Class<?> frameClass = TruffleCompilerOptions.TruffleUseFrameWithoutBoxing.getValue() ? FrameWithoutBoxing.class : FrameWithBoxing.class;
+                builder.push(Kind.Object, builder.append(new NewFrameNode(StampFactory.exactNonNull(metaAccess.lookupJavaType(frameClass)), arg1, arg2)));
                 return true;
             }
         });
 
         // FrameWithoutBoxing.class
         r = new Registration(plugins, metaAccess, FrameWithoutBoxing.class);
+        registerMaterialize(r);
+        registerUnsafeCast(r);
+        registerUnsafeLoadStorePlugins(r, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object);
+
+        // FrameWithBoxing.class
+        r = new Registration(plugins, metaAccess, FrameWithBoxing.class);
+        registerMaterialize(r);
+        registerUnsafeCast(r);
+
+        // CompilerDirectives.class
+        r = new Registration(plugins, metaAccess, UnsafeAccessImpl.class);
+        registerUnsafeCast(r);
+        registerUnsafeLoadStorePlugins(r, Kind.Boolean, Kind.Byte, Kind.Int, Kind.Short, Kind.Long, Kind.Float, Kind.Double, Kind.Object);
+    }
+
+    private static void registerMaterialize(Registration r) {
         r.register1("materialize", Receiver.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext builder, ValueNode frame) {
                 builder.push(Kind.Object, builder.append(new MaterializeFrameNode(frame)));
                 return true;
             }
         });
-        registerUnsafeCast(r);
-
-        registerUnsafeLoadStorePlugins(r, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object);
-
-        // CompilerDirectives.class
-        r = new Registration(plugins, metaAccess, UnsafeAccessImpl.class);
-        registerUnsafeCast(r);
-        registerUnsafeLoadStorePlugins(r, Kind.Boolean, Kind.Byte, Kind.Int, Kind.Short, Kind.Long, Kind.Float, Kind.Double, Kind.Object);
     }
 
     private static void registerUnsafeCast(Registration r) {
@@ -211,7 +221,16 @@
                     if (javaType == null) {
                         builder.push(Kind.Object, object);
                     } else {
-                        Stamp piStamp = StampFactory.declaredTrusted(javaType, nonNull.asJavaConstant().asInt() != 0);
+                        Stamp piStamp = null;
+                        if (javaType.isArray()) {
+                            if (nonNull.asJavaConstant().asInt() != 0) {
+                                piStamp = StampFactory.exactNonNull(javaType);
+                            } else {
+                                piStamp = StampFactory.exact(javaType);
+                            }
+                        } else {
+                            piStamp = StampFactory.declaredTrusted(javaType, nonNull.asJavaConstant().asInt() != 0);
+                        }
                         LogicNode compareNode = CompareNode.createCompareNode(object.graph(), Condition.EQ, condition, ConstantNode.forBoolean(true, object.graph()), constantReflection);
                         boolean skipAnchor = false;
                         if (compareNode instanceof LogicConstantNode) {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java	Tue Feb 17 22:21:53 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java	Wed Feb 18 00:09:24 2015 +0100
@@ -33,4 +33,10 @@
     Float,
     Boolean,
     Byte;
+
+    public final byte tag;
+
+    private FrameSlotKind() {
+        this.tag = (byte) ordinal();
+    }
 }
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Tue Feb 17 22:21:53 2015 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Feb 18 00:09:24 2015 +0100
@@ -240,13 +240,40 @@
   class_loader = accessing_klass->class_loader();
   protection_domain = accessing_klass->protection_domain();
 
-
   if (resolve) {
-    resolved_klass = SystemDictionary::resolve_or_fail(class_name, class_loader, protection_domain, true, THREAD);
+    resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK_0);
   } else {
-    resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, THREAD);
+    if (class_name->byte_at(0) == 'L' &&
+      class_name->byte_at(class_name->utf8_length()-1) == ';') {
+      // This is a name from a signature.  Strip off the trimmings.
+      // Call recursive to keep scope of strippedsym.
+      TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1,
+                                                          class_name->utf8_length()-2,
+                                                          CHECK_0);
+      resolved_klass = SystemDictionary::find(strippedsym, class_loader, protection_domain, CHECK_0);
+    } else if (FieldType::is_array(class_name)) {
+      FieldArrayInfo fd;
+      // dimension and object_key in FieldArrayInfo are assigned as a side-effect
+      // of this call
+      BasicType t = FieldType::get_array_info(class_name, fd, CHECK_0);
+      if (t == T_OBJECT) {
+        TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1+fd.dimension(),
+                                                            class_name->utf8_length()-2-fd.dimension(),
+                                                            CHECK_0);
+        // naked oop "k" is OK here -- we assign back into it
+        resolved_klass = SystemDictionary::find(strippedsym,
+                                                             class_loader,
+                                                             protection_domain,
+                                                             CHECK_0);
+        if (resolved_klass != NULL) {
+          resolved_klass = resolved_klass->array_klass(fd.dimension(), CHECK_0);
+        }
+      } else {
+        resolved_klass = Universe::typeArrayKlassObj(t);
+        resolved_klass = TypeArrayKlass::cast(resolved_klass)->array_klass(fd.dimension(), CHECK_0);
+      }
+    }
   }
-
   return (jlong) (address) resolved_klass;
 C2V_END