changeset 19437:2e91c189b0d8

Introduce option TruffleUseFrameWithoutBoxing, default to true.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Mon, 16 Feb 2015 23:21:37 +0100
parents fa20f31fead0
children 936f9d0b58e2
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 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithBoxing.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java
diffstat 11 files changed, 531 insertions(+), 512 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Feb 16 22:23:17 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Feb 16 23:21:37 2015 +0100
@@ -291,7 +291,8 @@
                     processBlock(this, unwindBlock);
 
                     if (Debug.isDumpEnabled() && this.beforeReturnNode != startInstruction) {
-                        Debug.dump(currentGraph, "Bytecodes parsed: " + method.getDeclaringClass().getUnqualifiedName() + "." + method.getName());
+                        // Debug.dump(currentGraph, "Bytecodes parsed: " +
+// method.getDeclaringClass().getUnqualifiedName() + "." + method.getName());
                     }
                 }
             }
@@ -315,7 +316,7 @@
                 context.peelIteration = this.getCurrentDimension();
                 context.targetPeelIteration = -1;
                 explodeLoopsContext.push(context);
-                Debug.dump(currentGraph, "before loop explosion " + context.peelIteration);
+                // Debug.dump(currentGraph, "before loop explosion " + context.peelIteration);
 
                 while (true) {
 
@@ -327,12 +328,14 @@
 
                     if (context.targetPeelIteration != -1) {
                         // We were reaching the backedge during explosion. Explode further.
-                        Debug.dump(currentGraph, "Before loop explosion " + context.targetPeelIteration);
+                        // 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);
+                        // Debug.dump(currentGraph, "after loop explosion " +
+// context.peelIteration);
                         break;
                     }
                 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/AlternateFrameWithoutBoxing.java	Mon Feb 16 22:23:17 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	Mon Feb 16 23:21:37 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	Mon Feb 16 22:23:17 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Mon Feb 16 23:21:37 2015 +0100
@@ -39,6 +39,8 @@
     private final FrameDescriptor descriptor;
     private final Object[] arguments;
     private Object[] locals;
+    private long[] primitiveLocals;
+    private byte[] tags;
 
     public FrameWithoutBoxing(FrameDescriptor descriptor, Object[] arguments) {
         this.descriptor = descriptor;
@@ -49,6 +51,8 @@
         if (defaultValue != null) {
             Arrays.fill(locals, defaultValue);
         }
+        this.primitiveLocals = new long[size];
+        this.tags = new byte[size];
     }
 
     @Override
@@ -62,111 +66,174 @@
     }
 
     @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 {
+        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) {
-        int index = slot.getIndex();
-        Object[] curLocals = this.getLocals();
-        if (CompilerDirectives.inInterpreter() && index >= curLocals.length) {
-            curLocals = resizeAndCheck(slot);
-        }
-        curLocals[index] = 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 {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Byte)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Byte) result;
+        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) {
-        setObject(slot, 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 {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Boolean)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Boolean) result;
+        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) {
-        setObject(slot, 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 {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Float)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Float) result;
+        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) {
-        setObject(slot, 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 {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Long)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Long) result;
+        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) {
-        setObject(slot, 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 {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Integer)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Integer) result;
+        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) {
-        setObject(slot, 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 {
-        Object result = getObject(slot);
-        if (CompilerDirectives.inInterpreter() && !(result instanceof Double)) {
-            throw new FrameSlotTypeException();
-        }
-        return (Double) result;
+        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) {
-        setObject(slot, 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
@@ -174,62 +241,117 @@
         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(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));
+            }
         }
-        return locals;
+        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) {
-        return getObject(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 = 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.ordinal();
     }
 
     @Override
     public boolean isByte(FrameSlot slot) {
-        return getObject(slot) instanceof Byte;
+        return getTag(slot) == FrameSlotKind.Byte.ordinal();
     }
 
     @Override
     public boolean isBoolean(FrameSlot slot) {
-        return getObject(slot) instanceof Boolean;
+        return getTag(slot) == FrameSlotKind.Boolean.ordinal();
     }
 
     @Override
     public boolean isInt(FrameSlot slot) {
-        return getObject(slot) instanceof Integer;
+        return getTag(slot) == FrameSlotKind.Int.ordinal();
     }
 
     @Override
     public boolean isLong(FrameSlot slot) {
-        return getObject(slot) instanceof Long;
+        return getTag(slot) == FrameSlotKind.Long.ordinal();
     }
 
     @Override
     public boolean isFloat(FrameSlot slot) {
-        return getObject(slot) instanceof Float;
+        return getTag(slot) == FrameSlotKind.Float.ordinal();
     }
 
     @Override
     public boolean isDouble(FrameSlot slot) {
-        return getObject(slot) instanceof Double;
+        return getTag(slot) == FrameSlotKind.Double.ordinal();
     }
 
     @SuppressWarnings({"unchecked", "unused"})
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Mon Feb 16 22:23:17 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Mon Feb 16 23:21:37 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	Mon Feb 16 22:23:17 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Feb 16 23:21:37 2015 +0100
@@ -161,7 +161,7 @@
         Object result = doInvoke(args);
         Class<?> klass = profiledReturnType;
         if (klass != null && CompilerDirectives.inCompiledCode() && profiledReturnTypeAssumption.isValid()) {
-            result = FrameWithoutBoxing.unsafeCast(result, klass, true, true);
+            result = FrameWithBoxing.unsafeCast(result, klass, true, true);
         }
         return result;
     }
@@ -251,7 +251,7 @@
     public final Object callRoot(Object[] originalArguments) {
         Object[] args = originalArguments;
         if (this.profiledArgumentTypesAssumption != null && CompilerDirectives.inCompiledCode() && profiledArgumentTypesAssumption.isValid()) {
-            args = FrameWithoutBoxing.unsafeCast(castArrayFixedLength(args, profiledArgumentTypes.length), Object[].class, true, true);
+            args = FrameWithBoxing.unsafeCast(castArrayFixedLength(args, profiledArgumentTypes.length), Object[].class, true, true);
             if (TruffleArgumentTypeSpeculation.getValue()) {
                 args = castArguments(args);
             }
@@ -408,7 +408,7 @@
     private Object[] castArguments(Object[] originalArguments) {
         Object[] castArguments = new Object[profiledArgumentTypes.length];
         for (int i = 0; i < profiledArgumentTypes.length; i++) {
-            castArguments[i] = profiledArgumentTypes[i] != null ? FrameWithoutBoxing.unsafeCast(originalArguments[i], profiledArgumentTypes[i], true, true) : originalArguments[i];
+            castArguments[i] = profiledArgumentTypes[i] != null ? FrameWithBoxing.unsafeCast(originalArguments[i], profiledArgumentTypes[i], true, true) : originalArguments[i];
         }
         return castArguments;
     }
@@ -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/TruffleCompilerOptions.java	Mon Feb 16 22:23:17 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Mon Feb 16 23:21:37 2015 +0100
@@ -119,6 +119,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);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java	Mon Feb 16 22:23:17 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java	Mon Feb 16 23:21:37 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	Mon Feb 16 22:23:17 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Mon Feb 16 23:21:37 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/OptimizedCallTargetSubstitutions.java	Mon Feb 16 22:23:17 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java	Mon Feb 16 23:21:37 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	Mon Feb 16 22:23:17 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Mon Feb 16 23:21:37 2015 +0100
@@ -179,27 +179,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) {