# HG changeset patch # User Thomas Wuerthinger # Date 1424133853 -3600 # Node ID d786fa19dc471c424db254100dd2deb393363ace # Parent ac5b08ea9a6aa4a07ccc4628f9a988be5c6336c2# Parent 5779b6771043be057cb2b715753319af148e5a0c Merge. diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Feb 17 01:44:13 2015 +0100 @@ -82,7 +82,7 @@ } @SuppressWarnings("rawtypes") - private static NodeClass getNodeClassViaReflection(Class superclass) { + public static NodeClass getNodeClassViaReflection(Class superclass) { try { Field field = superclass.getDeclaredField("TYPE"); field.setAccessible(true); diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Feb 17 01:44:13 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,9 @@ } protected double branchProbability() { + if (profilingInfo == null) { + return 0.5; + } double probability = profilingInfo.getBranchTakenProbability(bci()); if (probability < 0) { assert probability == -1 : "invalid probability"; diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Tue Feb 17 01:44:13 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); } diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Feb 17 01:44:13 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), " ")); } @@ -297,7 +297,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()); } } } @@ -321,7 +322,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) { @@ -333,12 +334,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; } } @@ -473,7 +476,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 +857,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); } @@ -868,6 +871,7 @@ } if (tryAnnotatedInvocationPlugin(args, targetMethod)) { + System.out.println("plugin used for : " + targetMethod); if (GraalOptions.TraceInlineDuringParsing.getValue()) { TTY.println(format("%sUsed annotated invocation plugin for %s", nSpaces(currentDepth), targetMethod)); } @@ -882,7 +886,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 +937,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; } @@ -1687,8 +1688,6 @@ return; } - double probability = branchProbability(); - // the mirroring and negation operations get the condition into canonical form boolean mirror = cond.canonicalMirror(); boolean negate = cond.canonicalNegate(); @@ -1772,6 +1771,8 @@ } this.controlFlowSplit = true; + + double probability = branchProbability(); ValueNode trueSuccessor = createBlockTarget(probability, trueBlock, frameState); ValueNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState); diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java Tue Feb 17 01:44:13 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 { diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Feb 17 01:44:13 2015 +0100 @@ -98,7 +98,18 @@ } } }); - compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), 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(), factory); } diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/AlternateFrameWithoutBoxing.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/AlternateFrameWithoutBoxing.java Mon Feb 16 15:41:46 2015 -0800 +++ /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 unsafeCast(Object value, Class 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); - } - } -} diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithBoxing.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithBoxing.java Tue Feb 17 01:44:13 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 unsafeCast(Object value, Class 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); + } + } +} diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Tue Feb 17 01:44:13 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"}) diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Tue Feb 17 01:44:13 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 diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Feb 17 01:44:13 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 getCallNodes() { diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Feb 17 01:44:13 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); diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Tue Feb 17 01:44:13 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)); diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Tue Feb 17 01:44:13 2015 +0100 @@ -104,6 +104,9 @@ @Option(help = "Enable asynchronous truffle compilation in background thread", type = OptionType.Expert) public static final OptionValue TruffleBackgroundCompilation = new OptionValue<>(true); + @Option(help = "Manually set the number of compiler threads", type = OptionType.Expert) + public static final StableOptionValue TruffleCompilerThreads = new StableOptionValue<>(0); + @Option(help = "Enable inlining across Truffle boundary", type = OptionType.Expert) public static final OptionValue TruffleInlineAcrossTruffleBoundary = new OptionValue<>(false); @@ -119,6 +122,9 @@ @Option(help = "", type = OptionType.Debug) public static final OptionValue TruffleArgumentTypeSpeculation = new StableOptionValue<>(true); + @Option(help = "", type = OptionType.Debug) + public static final StableOptionValue TruffleUseFrameWithoutBoxing = new StableOptionValue<>(true); + // tracing @Option(help = "Print potential performance problems", type = OptionType.Debug) public static final OptionValue TraceTrufflePerformanceWarnings = new OptionValue<>(false); @@ -181,6 +187,6 @@ public static final OptionValue TruffleCompilationStatisticDetails = new OptionValue<>(false); @Option(help = "Experimental new version of the partial evaluator.", type = OptionType.Debug) - public static final OptionValue FastPE = new OptionValue<>(false); + public static final OptionValue FastPE = new OptionValue<>(true); // @formatter:on } diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java Tue Feb 17 01:44:13 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 materialize(FrameWithoutBoxing frame); + public static native T materialize(VirtualFrame frame); } diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Tue Feb 17 01:44:13 2015 +0100 @@ -244,5 +244,5 @@ } @NodeIntrinsic - public static native FrameWithoutBoxing allocate(@ConstantNodeParameter Class frameType, FrameDescriptor descriptor, Object[] args); + public static native VirtualFrame allocate(@ConstantNodeParameter Class frameType, FrameDescriptor descriptor, Object[] args); } diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Tue Feb 17 01:44:13 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); } diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Tue Feb 17 01:44:13 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) { @@ -211,7 +220,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) { diff -r 5779b6771043 -r d786fa19dc47 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java Mon Feb 16 15:41:46 2015 -0800 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java Tue Feb 17 01:44:13 2015 +0100 @@ -33,4 +33,10 @@ Float, Boolean, Byte; + + public final byte tag; + + private FrameSlotKind() { + this.tag = (byte) ordinal(); + } }