changeset 22960:20e85d1dd9a5

Merge.
author Chris Seaton <chris.seaton@oracle.com>
date Sun, 08 Nov 2015 20:41:58 +0000
parents 267fb5779338 (current diff) 91a0b42ea9ed (diff)
children 09d0f549f05e
files
diffstat 13 files changed, 145 insertions(+), 182 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Sun Nov 08 20:41:58 2015 +0000
@@ -411,12 +411,13 @@
         return result;
     }
 
-    public Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) {
+    @Override
+    public Value emitUncommonTrapCall(Value trapRequest, Value mode, SaveRegistersOp saveRegisterOp) {
         ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(UNCOMMON_TRAP);
 
         Register thread = getProviders().getRegisters().getThreadRegister();
         append(new AMD64HotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread));
-        Variable result = super.emitForeignCall(linkage, null, thread.asValue(LIRKind.value(AMD64Kind.QWORD)), trapRequest);
+        Variable result = super.emitForeignCall(linkage, null, thread.asValue(LIRKind.value(AMD64Kind.QWORD)), trapRequest, mode);
         append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), thread));
 
         Map<LIRFrameState, SaveRegistersOp> calleeSaveInfo = ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo();
@@ -426,12 +427,13 @@
         return result;
     }
 
-    public Value emitDeoptimizationFetchUnrollInfoCall(SaveRegistersOp saveRegisterOp) {
+    @Override
+    public Value emitDeoptimizationFetchUnrollInfoCall(Value mode, SaveRegistersOp saveRegisterOp) {
         ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(FETCH_UNROLL_INFO);
 
         Register thread = getProviders().getRegisters().getThreadRegister();
         append(new AMD64HotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread));
-        Variable result = super.emitForeignCall(linkage, null, thread.asValue(LIRKind.value(AMD64Kind.QWORD)));
+        Variable result = super.emitForeignCall(linkage, null, thread.asValue(LIRKind.value(AMD64Kind.QWORD)), mode);
         append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaFpOffset(), thread));
 
         Map<LIRFrameState, SaveRegistersOp> calleeSaveInfo = ((AMD64HotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo();
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Sun Nov 08 20:41:58 2015 +0000
@@ -438,7 +438,8 @@
         append(new SPARCHotSpotPushInterpreterFrameOp(frameSizeVariable, framePcVariable, senderSpVariable, initialInfoVariable));
     }
 
-    public Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) {
+    @Override
+    public Value emitUncommonTrapCall(Value trapRequest, Value mode, SaveRegistersOp saveRegisterOp) {
         ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(UNCOMMON_TRAP);
 
         Register threadRegister = getProviders().getRegisters().getThreadRegister();
@@ -446,7 +447,7 @@
         Register stackPointerRegister = getProviders().getRegisters().getStackPointerRegister();
         Variable spScratch = newVariable(LIRKind.value(target().arch.getWordKind()));
         append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), threadRegister, stackPointerRegister, threadTemp, spScratch));
-        Variable result = super.emitForeignCall(linkage, null, threadRegister.asValue(LIRKind.value(target().arch.getWordKind())), trapRequest);
+        Variable result = super.emitForeignCall(linkage, null, threadRegister.asValue(LIRKind.value(target().arch.getWordKind())), trapRequest, mode);
         append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), threadRegister, threadTemp));
 
         Map<LIRFrameState, SaveRegistersOp> calleeSaveInfo = ((SPARCHotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo();
@@ -458,7 +459,7 @@
     }
 
     @Override
-    public Value emitDeoptimizationFetchUnrollInfoCall(SaveRegistersOp saveRegisterOp) {
+    public Value emitDeoptimizationFetchUnrollInfoCall(Value mode, SaveRegistersOp saveRegisterOp) {
         ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(FETCH_UNROLL_INFO);
 
         Register threadRegister = getProviders().getRegisters().getThreadRegister();
@@ -466,7 +467,7 @@
         Register stackPointerRegister = getProviders().getRegisters().getStackPointerRegister();
         Variable spScratch = newVariable(LIRKind.value(target().arch.getWordKind()));
         append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), threadRegister, stackPointerRegister, threadTemp, spScratch));
-        Variable result = super.emitForeignCall(linkage, null, threadRegister.asValue(LIRKind.value(target().arch.getWordKind())));
+        Variable result = super.emitForeignCall(linkage, null, threadRegister.asValue(LIRKind.value(target().arch.getWordKind())), mode);
         append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), threadRegister, threadTemp));
 
         Map<LIRFrameState, SaveRegistersOp> calleeSaveInfo = ((SPARCHotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Sun Nov 08 20:41:58 2015 +0000
@@ -114,7 +114,7 @@
     /**
      * @see DeoptimizationFetchUnrollInfoCallNode
      */
-    public static final ForeignCallDescriptor FETCH_UNROLL_INFO = new ForeignCallDescriptor("fetchUnrollInfo", Word.class, long.class);
+    public static final ForeignCallDescriptor FETCH_UNROLL_INFO = new ForeignCallDescriptor("fetchUnrollInfo", Word.class, long.class, int.class);
 
     /**
      * @see DeoptimizationStub#unpackFrames(ForeignCallDescriptor, Word, int)
@@ -154,7 +154,7 @@
     /**
      * New array stub.
      */
-    public static final ForeignCallDescriptor NEW_ARRAY = new ForeignCallDescriptor("new_array", Object.class, Word.class, int.class);
+    public static final ForeignCallDescriptor NEW_ARRAY = new ForeignCallDescriptor("new_array", Object.class, Word.class, int.class, boolean.class);
 
     /**
      * New insstance stub.
@@ -164,7 +164,7 @@
     /**
      * @see UncommonTrapCallNode
      */
-    public static final ForeignCallDescriptor UNCOMMON_TRAP = new ForeignCallDescriptor("uncommonTrap", Word.class, Word.class, int.class);
+    public static final ForeignCallDescriptor UNCOMMON_TRAP = new ForeignCallDescriptor("uncommonTrap", Word.class, Word.class, int.class, int.class);
 
     public HotSpotBackend(HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {
         super(providers);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java	Sun Nov 08 20:41:58 2015 +0000
@@ -121,20 +121,22 @@
      * Emits code for a {@link UncommonTrapCallNode}.
      *
      * @param trapRequest
+     * @param mode
      * @param saveRegisterOp
      * @return a {@code Deoptimization::UnrollBlock} pointer
      */
-    default Value emitUncommonTrapCall(Value trapRequest, SaveRegistersOp saveRegisterOp) {
+    default Value emitUncommonTrapCall(Value trapRequest, Value mode, SaveRegistersOp saveRegisterOp) {
         throw JVMCIError.unimplemented();
     }
 
     /**
      * Emits code for a {@link DeoptimizationFetchUnrollInfoCallNode}.
      *
+     * @param mode
      * @param saveRegisterOp
      * @return a {@code Deoptimization::UnrollBlock} pointer
      */
-    default Value emitDeoptimizationFetchUnrollInfoCall(SaveRegistersOp saveRegisterOp) {
+    default Value emitDeoptimizationFetchUnrollInfoCall(Value mode, SaveRegistersOp saveRegisterOp) {
         throw JVMCIError.unimplemented();
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java	Sun Nov 08 20:41:58 2015 +0000
@@ -49,11 +49,13 @@
 
     public static final NodeClass<DeoptimizationFetchUnrollInfoCallNode> TYPE = NodeClass.create(DeoptimizationFetchUnrollInfoCallNode.class);
     @Input SaveAllRegistersNode registerSaver;
+    @Input ValueNode mode;
     protected final ForeignCallsProvider foreignCalls;
 
-    public DeoptimizationFetchUnrollInfoCallNode(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ValueNode registerSaver) {
+    public DeoptimizationFetchUnrollInfoCallNode(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ValueNode registerSaver, ValueNode mode) {
         super(TYPE, StampFactory.forKind(JavaKind.fromJavaClass(FETCH_UNROLL_INFO.getResultType())));
         this.registerSaver = (SaveAllRegistersNode) registerSaver;
+        this.mode = mode;
         this.foreignCalls = foreignCalls;
     }
 
@@ -66,12 +68,20 @@
         return registerSaver.getSaveRegistersOp();
     }
 
+    /**
+     * Returns the node representing the exec_mode/unpack_kind used during this fetch_unroll_info
+     * call.
+     */
+    public ValueNode getMode() {
+        return mode;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        Value result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitDeoptimizationFetchUnrollInfoCall(getSaveRegistersOp());
+        Value result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitDeoptimizationFetchUnrollInfoCall(gen.operand(getMode()), getSaveRegistersOp());
         gen.setResult(this, result);
     }
 
     @NodeIntrinsic
-    public static native Word fetchUnrollInfo(long registerSaver);
+    public static native Word fetchUnrollInfo(long registerSaver, int mode);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java	Sun Nov 08 20:41:58 2015 +0000
@@ -23,9 +23,6 @@
 package com.oracle.graal.hotspot.nodes;
 
 import static com.oracle.graal.hotspot.HotSpotBackend.UNCOMMON_TRAP;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.LocationIdentity;
-import jdk.vm.ci.meta.Value;
 
 import com.oracle.graal.compiler.common.spi.ForeignCallsProvider;
 import com.oracle.graal.compiler.common.type.StampFactory;
@@ -41,6 +38,10 @@
 import com.oracle.graal.nodes.spi.NodeLIRBuilderTool;
 import com.oracle.graal.word.Word;
 
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LocationIdentity;
+import jdk.vm.ci.meta.Value;
+
 /**
  * A call to the runtime code implementing the uncommon trap logic.
  */
@@ -49,12 +50,14 @@
 
     public static final NodeClass<UncommonTrapCallNode> TYPE = NodeClass.create(UncommonTrapCallNode.class);
     @Input ValueNode trapRequest;
+    @Input ValueNode mode;
     @Input SaveAllRegistersNode registerSaver;
     protected final ForeignCallsProvider foreignCalls;
 
-    public UncommonTrapCallNode(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ValueNode registerSaver, ValueNode trapRequest) {
+    public UncommonTrapCallNode(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ValueNode registerSaver, ValueNode trapRequest, ValueNode mode) {
         super(TYPE, StampFactory.forKind(JavaKind.fromJavaClass(UNCOMMON_TRAP.getResultType())));
         this.trapRequest = trapRequest;
+        this.mode = mode;
         this.registerSaver = (SaveAllRegistersNode) registerSaver;
         this.foreignCalls = foreignCalls;
     }
@@ -68,13 +71,22 @@
         return registerSaver.getSaveRegistersOp();
     }
 
+    /**
+     * Returns the node representing the exec_mode/unpack_kind used during this fetch_unroll_info
+     * call.
+     */
+    public ValueNode getMode() {
+        return mode;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         Value trapRequestValue = gen.operand(trapRequest);
-        Value result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitUncommonTrapCall(trapRequestValue, getSaveRegistersOp());
+        Value modeValue = gen.operand(getMode());
+        Value result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitUncommonTrapCall(trapRequestValue, modeValue, getSaveRegistersOp());
         gen.setResult(this, result);
     }
 
     @NodeIntrinsic
-    public static native Word uncommonTrap(long registerSaver, int trapRequest);
+    public static native Word uncommonTrap(long registerSaver, int trapRequest, int mode);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Sun Nov 08 20:41:58 2015 +0000
@@ -264,14 +264,14 @@
             newarray_loopInit.inc();
             result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, maybeUnroll, true);
         } else {
-            result = newArray(HotSpotBackend.NEW_ARRAY, hub, length);
+            result = newArray(HotSpotBackend.NEW_ARRAY, hub, length, fillContents);
         }
         profileAllocation("array", allocationSize, typeContext);
         return result;
     }
 
     @NodeIntrinsic(ForeignCallNode.class)
-    public static native Object newArray(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub, int length);
+    public static native Object newArray(@ConstantNodeParameter ForeignCallDescriptor descriptor, KlassPointer hub, int length, boolean fillContents);
 
     public static final ForeignCallDescriptor DYNAMIC_NEW_ARRAY = new ForeignCallDescriptor("dynamic_new_array", Object.class, Class.class, int.class);
     public static final ForeignCallDescriptor DYNAMIC_NEW_INSTANCE = new ForeignCallDescriptor("dynamic_new_instance", Object.class, Class.class);
@@ -537,7 +537,6 @@
             args.addConst("threadRegister", registers.getThreadRegister());
             args.addConst("maybeUnroll", length.isConstant());
             args.addConst("typeContext", ProfileAllocations.getValue() ? arrayType.toJavaName(false) : "");
-
             SnippetTemplate template = template(args);
             Debug.log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args);
             template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java	Sun Nov 08 20:41:58 2015 +0000
@@ -127,8 +127,12 @@
         final Word thread = registerAsWord(threadRegister);
         final long registerSaver = SaveAllRegistersNode.saveAllRegisters();
 
-        final Word unrollBlock = fetchUnrollInfo(registerSaver);
+        final Word unrollBlock = fetchUnrollInfo(registerSaver, deoptimizationUnpackDeopt());
 
+        deoptimizationCommon(stackPointerRegister, thread, registerSaver, unrollBlock);
+    }
+
+    static void deoptimizationCommon(Register stackPointerRegister, final Word thread, final long registerSaver, final Word unrollBlock) {
         // Pop all the frames we must move/replace.
         //
         // Frame picture (youngest to oldest)
@@ -201,8 +205,7 @@
         final Word senderFp = initialInfo;
         EnterUnpackFramesStackFrameNode.enterUnpackFramesStackFrame(framePc, senderSp, senderFp, registerSaver);
 
-        // Pass unpack deopt mode to unpack frames.
-        final int mode = deoptimizationUnpackDeopt();
+        final int mode = unrollBlock.readInt(deoptimizationUnrollBlockUnpackKindOffset());
         unpackFrames(UNPACK_FRAMES, thread, mode);
 
         LeaveUnpackFramesStackFrameNode.leaveUnpackFramesStackFrame(registerSaver);
@@ -263,6 +266,11 @@
     }
 
     @Fold
+    private static int deoptimizationUnrollBlockUnpackKindOffset() {
+        return config().deoptimizationUnrollBlockUnpackKindOffset;
+    }
+
+    @Fold
     private static int deoptimizationUnrollBlockFrameSizesOffset() {
         return config().deoptimizationUnrollBlockFrameSizesOffset;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Sun Nov 08 20:41:58 2015 +0000
@@ -76,10 +76,10 @@
         HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) providers.getMetaAccess().lookupJavaType(int[].class);
         int count = method.getSignature().getParameterCount(false);
         Object[] args = new Object[count];
-        assert checkConstArg(2, "intArrayHub");
-        assert checkConstArg(3, "threadRegister");
-        args[2] = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), intArrayType.klass(), null);
-        args[3] = providers.getRegisters().getThreadRegister();
+        assert checkConstArg(3, "intArrayHub");
+        assert checkConstArg(4, "threadRegister");
+        args[3] = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), intArrayType.klass(), null);
+        args[4] = providers.getRegisters().getThreadRegister();
         return args;
     }
 
@@ -94,10 +94,11 @@
      *
      * @param hub the hub of the object to be allocated
      * @param length the length of the array
+     * @param fillContents Should the array be filled with zeroes?
      * @param intArrayHub the hub for {@code int[].class}
      */
     @Snippet
-    private static Object newArray(KlassPointer hub, int length, @ConstantParameter KlassPointer intArrayHub, @ConstantParameter Register threadRegister) {
+    private static Object newArray(KlassPointer hub, int length, boolean fillContents, @ConstantParameter KlassPointer intArrayHub, @ConstantParameter Register threadRegister) {
         int layoutHelper = loadKlassLayoutHelperIntrinsic(hub);
         int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
         int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
@@ -118,7 +119,7 @@
                 if (logging()) {
                     printf("newArray: allocated new array at %p\n", memory.rawValue());
                 }
-                return verifyObject(formatArray(hub, sizeInBytes, length, headerSize, memory, Word.unsigned(arrayPrototypeMarkWord()), true, false, false));
+                return verifyObject(formatArray(hub, sizeInBytes, length, headerSize, memory, Word.unsigned(arrayPrototypeMarkWord()), fillContents, false, false));
             }
         }
         if (logging()) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java	Sun Nov 08 20:41:58 2015 +0000
@@ -22,32 +22,19 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
-import static com.oracle.graal.hotspot.HotSpotBackend.UNPACK_FRAMES;
 import static com.oracle.graal.hotspot.HotSpotBackend.Options.PreferGraalStubs;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.config;
-import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.pageSize;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.readPendingDeoptimization;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
-import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.writePendingDeoptimization;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.writeRegisterAsWord;
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.common.JVMCIError;
-import jdk.vm.ci.meta.LocationIdentity;
 
 import com.oracle.graal.api.replacements.Fold;
-import com.oracle.graal.asm.NumUtil;
 import com.oracle.graal.compiler.common.spi.ForeignCallDescriptor;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.HotSpotForeignCallLinkage;
 import com.oracle.graal.hotspot.meta.HotSpotProviders;
-import com.oracle.graal.hotspot.nodes.EnterUnpackFramesStackFrameNode;
-import com.oracle.graal.hotspot.nodes.LeaveCurrentStackFrameNode;
-import com.oracle.graal.hotspot.nodes.LeaveDeoptimizedStackFrameNode;
-import com.oracle.graal.hotspot.nodes.LeaveUnpackFramesStackFrameNode;
-import com.oracle.graal.hotspot.nodes.PushInterpreterFrameNode;
 import com.oracle.graal.hotspot.nodes.SaveAllRegistersNode;
 import com.oracle.graal.hotspot.nodes.StubForeignCallNode;
 import com.oracle.graal.hotspot.nodes.UncommonTrapCallNode;
@@ -56,6 +43,11 @@
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.word.Word;
 
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.LocationIdentity;
+
 /**
  * Uncommon trap stub.
  *
@@ -142,85 +134,9 @@
         final int actionAndReason = readPendingDeoptimization(thread);
         writePendingDeoptimization(thread, -1);
 
-        final Word unrollBlock = UncommonTrapCallNode.uncommonTrap(registerSaver, actionAndReason);
-
-        // Pop all the frames we must move/replace.
-        //
-        // Frame picture (youngest to oldest)
-        // 1: self-frame
-        // 2: deoptimizing frame
-        // 3: caller of deoptimizing frame (could be compiled/interpreted).
-
-        // Pop self-frame.
-        LeaveCurrentStackFrameNode.leaveCurrentStackFrame(registerSaver);
-
-        // Load the initial info we should save (e.g. frame pointer).
-        final Word initialInfo = unrollBlock.readWord(deoptimizationUnrollBlockInitialInfoOffset());
-
-        // Pop deoptimized frame.
-        final int sizeOfDeoptimizedFrame = unrollBlock.readInt(deoptimizationUnrollBlockSizeOfDeoptimizedFrameOffset());
-        LeaveDeoptimizedStackFrameNode.leaveDeoptimizedStackFrame(sizeOfDeoptimizedFrame, initialInfo);
-
-        /*
-         * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for
-         * total size of the interpreter frames plus shadow page size. Bang one page at a time
-         * because large sizes can bang beyond yellow and red zones.
-         * 
-         * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository.
-         */
-        final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset());
-        final int bangPages = NumUtil.roundUp(totalFrameSizes, pageSize()) / pageSize() + stackShadowPages();
-        Word stackPointer = readRegister(stackPointerRegister);
-
-        for (int i = 1; i < bangPages; i++) {
-            stackPointer.writeInt((-i * pageSize()) + stackBias(), 0, STACK_BANG_LOCATION);
-        }
-
-        // Load number of interpreter frames.
-        final int numberOfFrames = unrollBlock.readInt(deoptimizationUnrollBlockNumberOfFramesOffset());
-
-        // Load address of array of frame sizes.
-        final Word frameSizes = unrollBlock.readWord(deoptimizationUnrollBlockFrameSizesOffset());
+        final Word unrollBlock = UncommonTrapCallNode.uncommonTrap(registerSaver, actionAndReason, deoptimizationUnpackUncommonTrap());
 
-        // Load address of array of frame PCs.
-        final Word framePcs = unrollBlock.readWord(deoptimizationUnrollBlockFramePcsOffset());
-
-        /*
-         * Get the current stack pointer (sender's original SP) before adjustment so that we can
-         * save it in the skeletal interpreter frame.
-         */
-        Word senderSp = readRegister(stackPointerRegister);
-
-        // Adjust old interpreter frame to make space for new frame's extra Java locals.
-        final int callerAdjustment = unrollBlock.readInt(deoptimizationUnrollBlockCallerAdjustmentOffset());
-        writeRegister(stackPointerRegister, readRegister(stackPointerRegister).subtract(callerAdjustment));
-
-        for (int i = 0; i < numberOfFrames; i++) {
-            final Word frameSize = frameSizes.readWord(i * wordSize());
-            final Word framePc = framePcs.readWord(i * wordSize());
-
-            // Push an interpreter frame onto the stack.
-            PushInterpreterFrameNode.pushInterpreterFrame(frameSize, framePc, senderSp, initialInfo);
-
-            // Get the current stack pointer (sender SP) and pass it to next frame.
-            senderSp = readRegister(stackPointerRegister);
-        }
-
-        // Get final return address.
-        final Word framePc = framePcs.readWord(numberOfFrames * wordSize());
-
-        /*
-         * Enter a frame to call out to unpack frames. Since we changed the stack pointer to an
-         * unknown alignment we need to align it here before calling C++ code.
-         */
-        final Word senderFp = initialInfo;
-        EnterUnpackFramesStackFrameNode.enterUnpackFramesStackFrame(framePc, senderSp, senderFp, registerSaver);
-
-        // Pass uncommon trap mode to unpack frames.
-        final int mode = deoptimizationUnpackUncommonTrap();
-        unpackFrames(UNPACK_FRAMES, thread, mode);
-
-        LeaveUnpackFramesStackFrameNode.leaveUnpackFramesStackFrame(registerSaver);
+        DeoptimizationStub.deoptimizationCommon(stackPointerRegister, thread, registerSaver, unrollBlock);
     }
 
     /**
--- a/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/dumper/AbstractMethodScopeDumper.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/dumper/AbstractMethodScopeDumper.java	Sun Nov 08 20:41:58 2015 +0000
@@ -77,12 +77,14 @@
 
     protected void openScope(MethodContext.Item item) throws IOException {
         int debugId = item.getDebugId();
-        pathStack.push(debugId != -1 ? debugId : pathCounter);
+        int id = debugId != -1 ? debugId : pathCounter;
+
+        pathStack.push(id);
         itemIdStack.push(itemIdCounter);
         pathCounter = 0;
         itemIdCounter = 0;
 
-        processMethod(item.getMethod(), item.getName());
+        processMethod(item.getMethod(), id, item.getName());
     }
 
     @SuppressWarnings("unused")
@@ -96,8 +98,9 @@
         }
     }
 
-    protected void processMethod(JavaMethod method, String name) throws IOException {
+    protected void processMethod(JavaMethod method, int id, String name) throws IOException {
         DataDict dataDict = new DataDict();
+        dataDict.put("id", id);
         dataDict.put("name", name);
 
         if (method instanceof ResolvedJavaMethod) {
--- a/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/dumper/GraphDumper.java	Sun Nov 08 20:41:31 2015 +0000
+++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/dumper/GraphDumper.java	Sun Nov 08 20:41:58 2015 +0000
@@ -77,7 +77,7 @@
         nodeClassCategoryMap.put(VirtualState.class, "State");
         nodeClassCategoryMap.put(PhiNode.class, "Phi");
         nodeClassCategoryMap.put(ProxyNode.class, "Proxy");
-        // nodeClassCategoryMap.put(Object.class, "Floating");
+        // nodeClassCategoryMap.put(Node.class, "Floating");
     }
 
     @Override
@@ -116,20 +116,6 @@
             }
         }
 
-        ControlFlowGraph cfg = null;
-        List<Block> blocks = null;
-        NodeMap<Block> nodeToBlock = null;
-        BlockMap<List<Node>> blockToNodes = null;
-
-        if (schedule != null) {
-            cfg = schedule.getCFG();
-            if (cfg != null) {
-                blocks = cfg.getBlocks();
-                nodeToBlock = schedule.getNodeToBlockMap();
-                blockToNodes = schedule.getBlockToNodesMap();
-            }
-        }
-
         DataDict dataDict = new DataDict();
         dataDict.put("id", nextItemId());
         dataDict.put("name", name);
@@ -137,15 +123,19 @@
         DataDict graphDict = new DataDict();
         dataDict.put("graph", graphDict);
 
-        processNodes(graphDict, graph.getNodes(), nodeToBlock, cfg);
+        processNodes(graphDict, graph.getNodes(), schedule);
 
-        if (blocks != null && blockToNodes != null) {
-            processBlocks(graphDict, blocks, blockToNodes);
+        if (schedule != null) {
+            ControlFlowGraph cfg = schedule.getCFG();
+            if (cfg != null) {
+                List<Block> blocks = cfg.getBlocks();
+                processBlocks(graphDict, blocks, schedule);
+            }
         }
         serializeAndFlush(createEventDictWithId("graph", dataDict));
     }
 
-    private static void processNodes(DataDict graphDict, NodeIterable<Node> nodes, NodeMap<Block> nodeToBlock, ControlFlowGraph cfg) {
+    private static void processNodes(DataDict graphDict, NodeIterable<Node> nodes, SchedulePhase schedule) {
         Map<NodeClass<?>, Integer> classMap = new HashMap<>();
 
         DataList classList = new DataList();
@@ -161,44 +151,52 @@
             NodeClass<?> nodeClass = node.getNodeClass();
 
             DataDict nodeDict = new DataDict();
+            nodeList.add(nodeDict);
+
             nodeDict.put("id", getNodeId(node));
             nodeDict.put("class", getNodeClassId(classMap, classList, nodeClass));
 
-            if (nodeToBlock != null) {
-                if (nodeToBlock.isNew(node)) {
-                    nodeDict.put("block", -1);
-                } else {
-                    Block block = nodeToBlock.get(node);
-                    if (block != null) {
-                        nodeDict.put("block", block.getId());
-                    }
-                }
+            if (schedule != null) {
+                processNodeSchedule(nodeDict, node, schedule);
             }
 
-            if (cfg != null && PrintGraphProbabilities.getValue() && node instanceof FixedNode) {
-                try {
-                    nodeDict.put("probability", cfg.blockFor(node).probability());
-                } catch (Throwable t) {
-                    nodeDict.put("probability", t);
-                }
+            DataDict propertyDict = new DataDict();
+            node.getDebugProperties(propertyDict);
+
+            if (!propertyDict.isEmpty()) {
+                nodeDict.put("properties", propertyDict);
             }
 
-            Map<Object, Object> debugProperties = node.getDebugProperties();
-            if (!debugProperties.isEmpty()) {
-                DataDict propertyDict = new DataDict();
-                nodeDict.put("properties", propertyDict);
-                for (Map.Entry<Object, Object> entry : debugProperties.entrySet()) {
-                    propertyDict.put(entry.getKey().toString(), entry.getValue());
-                }
-            }
-
-            nodeList.add(nodeDict);
             appendEdges(edgeList, node, Type.Inputs);
             appendEdges(edgeList, node, Type.Successors);
         }
     }
 
-    private static void processBlocks(DataDict graphDict, List<Block> blocks, BlockMap<List<Node>> blockToNodes) {
+    private static void processNodeSchedule(DataDict nodeDict, Node node, SchedulePhase schedule) {
+        NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap();
+        if (nodeToBlock != null) {
+            if (nodeToBlock.isNew(node)) {
+                nodeDict.put("block", -1);
+            } else {
+                Block block = nodeToBlock.get(node);
+                if (block != null) {
+                    nodeDict.put("block", block.getId());
+                }
+            }
+        }
+
+        ControlFlowGraph cfg = schedule.getCFG();
+        if (cfg != null && PrintGraphProbabilities.getValue() && node instanceof FixedNode) {
+            try {
+                nodeDict.put("probability", cfg.blockFor(node).probability());
+            } catch (Throwable t) {
+                nodeDict.put("probability", t);
+            }
+        }
+    }
+
+    private static void processBlocks(DataDict graphDict, List<Block> blocks, SchedulePhase schedule) {
+        BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap();
         DataList blockList = new DataList();
         graphDict.put("blocks", blockList);
 
@@ -206,6 +204,8 @@
             List<Node> nodes = blockToNodes.get(block);
             if (nodes != null) {
                 DataDict blockDict = new DataDict();
+                blockList.add(blockDict);
+
                 blockDict.put("id", block.getId());
 
                 DataList nodeList = new DataList();
@@ -215,13 +215,14 @@
                     nodeList.add(getNodeId(node));
                 }
 
-                DataList successorList = new DataList();
-                blockDict.put("successors", successorList);
-                for (Block successor : block.getSuccessors()) {
-                    successorList.add(successor.getId());
+                List<Block> successors = block.getSuccessors();
+                if (successors != null && !successors.isEmpty()) {
+                    DataList successorList = new DataList();
+                    blockDict.put("successors", successorList);
+                    for (Block successor : successors) {
+                        successorList.add(successor.getId());
+                    }
                 }
-
-                blockList.add(blockDict);
             }
         }
     }
@@ -332,10 +333,18 @@
         for (int i = 0; i < edges.getCount(); i++) {
             DataDict edgeDict = new DataDict();
             String name = edges.getName(i);
+            Class<?> fieldClass = edges.getType(i);
             edgeDict.put("name", name);
-            edgeDict.put("jtype", edges.getType(i).getName());
+            edgeDict.put("jtype", fieldClass.getName());
+            if (NodeList.class.isAssignableFrom(fieldClass)) {
+                edgeDict.put("isList", true);
+            }
             if (type == Type.Inputs) {
-                edgeDict.put("type", ((InputEdges) edges).getInputType(i));
+                InputEdges inputEdges = ((InputEdges) edges);
+                edgeDict.put("type", inputEdges.getInputType(i));
+                if (inputEdges.isOptional(i)) {
+                    edgeDict.put("isOptional", true);
+                }
             }
             edgeInfoDict.put(name, edgeDict);
         }
--- a/mx.graal/suite.py	Sun Nov 08 20:41:31 2015 +0000
+++ b/mx.graal/suite.py	Sun Nov 08 20:41:58 2015 +0000
@@ -39,7 +39,7 @@
             {
                "name" : "jvmci",
                "optional" : "true",
-               "version" : "eada427470a3aa671dd7f4fdce5197b60d1e4351",
+               "version" : "9860aa60385f94d935ea1cc7802a99b0f2f68171",
                "urls" : [
                     {"url" : "http://lafo.ssw.uni-linz.ac.at/hg/graal-jvmci-8", "kind" : "hg"},
                     {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},