changeset 2938:c7783b6773ea

fixed graph start frame state new option: DeoptALot lots of fixes to debug info handling in graalCodeInstaller fix to uncommon trap stub
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 10 Jun 2011 19:50:16 +0200
parents 3fa0e12d524a
children 668603cb3263
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java src/cpu/x86/vm/sharedRuntime_x86_64.cpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/runtime/deoptimization.cpp
diffstat 11 files changed, 152 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Fri Jun 10 15:12:10 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Fri Jun 10 19:50:16 2011 +0200
@@ -55,6 +55,7 @@
     public static boolean ZapStackOnMethodEntry              = ____;
     public static boolean StressLinearScan                   = ____;
     public static boolean BailoutOnException                 = ____;
+    public static boolean DeoptALot                          = ____;
 
     /**
      * See {@link Filter#Filter(String, Object)}.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Fri Jun 10 15:12:10 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Fri Jun 10 19:50:16 2011 +0200
@@ -296,12 +296,22 @@
         if (Modifier.isSynchronized(compilation.method.accessFlags())) {
             bci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
         }
+
+        boolean withReceiver = !Modifier.isStatic(compilation.method.accessFlags());
+        CiKind[] arguments = Util.signatureToKinds(compilation.method.signature(), withReceiver ? CiKind.Object : null);
+        int[] argumentSlots = new int[arguments.length];
+        int slot = 0;
+        for (int arg = 0; arg < arguments.length; arg++) {
+            argumentSlots[arg] = slot;
+            slot += arguments[arg].sizeInSlots();
+        }
+
         FrameState fs = new FrameState(compilation.method, bci, compilation.method.maxLocals(), 0, 0, compilation.graph);
         for (Node node : compilation.graph.start().usages()) {
             if (node instanceof Local) {
                 Local local = (Local) node;
                 int i = local.index();
-                fs.storeLocal(i, local);
+                fs.storeLocal(argumentSlots[i], local);
 
                 CiValue src = args.locations[i];
                 assert src.isLegal() : "check";
@@ -313,9 +323,21 @@
                 setResult(local, dest);
             }
         }
+        assert checkOperands(fs);
         return fs;
     }
 
+    private boolean checkOperands(FrameState fs) {
+        boolean withReceiver = !Modifier.isStatic(compilation.method.accessFlags());
+        CiKind[] arguments = Util.signatureToKinds(compilation.method.signature(), withReceiver ? CiKind.Object : null);
+        int slot = 0;
+        for (CiKind kind : arguments) {
+            assert fs.localAt(slot) != null : "slot: " + slot;
+            slot += kind.sizeInSlots();
+        }
+        return true;
+    }
+
     @Override
     public void visitCheckCast(CheckCast x) {
         XirArgument obj = toXirArgument(x.object());
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Fri Jun 10 15:12:10 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Fri Jun 10 19:50:16 2011 +0200
@@ -87,8 +87,8 @@
 
         if (GraalOptions.OptCanonicalizer) {
             new CanonicalizerPhase().apply(graph);
+            new DeadCodeEliminationPhase().apply(compilation.graph);
             printGraph("After Canonicalization", graph);
-            new DeadCodeEliminationPhase().apply(compilation.graph);
         }
 
         new SplitCriticalEdgesPhase().apply(graph);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java	Fri Jun 10 15:12:10 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java	Fri Jun 10 19:50:16 2011 +0200
@@ -22,8 +22,11 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import java.util.*;
+
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.graph.*;
+import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ri.*;
 
@@ -34,15 +37,38 @@
 public final class Local extends FloatingNode {
 
     private static final int INPUT_COUNT = 1;
+    private static final int INPUT_START = 0;
 
     private static final int SUCCESSOR_COUNT = 0;
 
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    @Override
+    protected int successorCount() {
+        return super.successorCount() + SUCCESSOR_COUNT;
+    }
+
+    /**
+     * The start node of the graph that this local belongs to. This is used for correctly scheduling the locals.
+     */
+     private StartNode start() {
+        return (StartNode) inputs().get(super.inputCount() + INPUT_START);
+    }
+
+     private void setStart(StartNode n) {
+         inputs().set(super.inputCount() + INPUT_START, n);
+     }
+
     private final int index;
     private RiType declaredType;
 
-    public Local(CiKind kind, int javaIndex, Graph graph) {
+    public Local(CiKind kind, int javaIndex, StartNode start, Graph graph) {
         super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         this.index = javaIndex;
+        setStart(start);
     }
 
     /**
@@ -81,18 +107,15 @@
     }
 
     @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
-
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("index", index());
+        return properties;
     }
 
     @Override
     public Node copy(Graph into) {
-        Local x = new Local(kind, index, into);
+        Local x = new Local(kind, index, start(), into);
         x.setDeclaredType(declaredType());
         return x;
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Fri Jun 10 15:12:10 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Fri Jun 10 19:50:16 2011 +0200
@@ -38,6 +38,27 @@
         this.graph = graph;
         this.flood = graph.createNodeFlood();
 
+        // remove chained Merges
+//        for (Merge merge : graph.getNodes(Merge.class)) {
+//            if (merge.predecessors().size() == 1 && merge.usages().size() == 0) {
+//                if (merge.successors().get(0) instanceof Merge) {
+//                    Node pred = merge.predecessors().get(0);
+//                    int predIndex = merge.predecessorsIndex().get(0);
+//                    pred.successors().setAndClear(predIndex, merge, 0);
+//                    merge.delete();
+//                }
+//            }
+//        }
+//        Node startSuccessor = graph.start().successors().get(0);
+//        if (startSuccessor instanceof Merge) {
+//            Merge startMerge = (Merge) startSuccessor;
+//            if (startMerge.predecessors().size() == 1 && startMerge.usages().size() == 0) {
+//                int predIndex = startMerge.predecessorsIndex().get(0);
+//                graph.start().successors().setAndClear(predIndex, startMerge, 0);
+//                startMerge.delete();
+//            }
+//        }
+
         flood.add(graph.start());
 
         iterateSuccessors();
@@ -96,6 +117,9 @@
 
     private void iterateInputs() {
         for (Node node : graph.getNodes()) {
+            if (node instanceof Local) {
+                flood.add(node);
+            }
             if (node != Node.Null && flood.isMarked(node)) {
                 for (Node input : node.inputs()) {
                     if (!isCFG(input)) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Fri Jun 10 15:12:10 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Fri Jun 10 19:50:16 2011 +0200
@@ -920,10 +920,15 @@
 
     private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) {
         CiKind resultType = returnKind(target);
-        Invoke invoke = new Invoke(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(method.holder()), method.typeProfile(bci()), graph);
-        Value result = appendWithBCI(invoke);
-        invoke.setExceptionEdge(handleException(null, bci()));
-        frameState.pushReturn(resultType, result);
+        if (GraalOptions.DeoptALot) {
+            append(new Deoptimize(DeoptAction.None, graph));
+            frameState.pushReturn(resultType, Constant.defaultForKind(resultType, graph));
+        } else {
+            Invoke invoke = new Invoke(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(method.holder()), method.typeProfile(bci()), graph);
+            Value result = appendWithBCI(invoke);
+            invoke.setExceptionEdge(handleException(null, bci()));
+            frameState.pushReturn(resultType, result);
+        }
     }
 
     private RiType getExactType(RiType staticType, Value receiver) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java	Fri Jun 10 15:12:10 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java	Fri Jun 10 19:50:16 2011 +0200
@@ -58,8 +58,7 @@
         int index = 0;
         if (!isStatic(method.accessFlags())) {
             // add the receiver and assume it is non null
-            Local local = new Local(method.holder().kind(), javaIndex, graph);
-            local.inputs().set(0, graph.start());
+            Local local = new Local(method.holder().kind(), javaIndex, graph.start(), graph);
             local.setDeclaredType(method.holder());
             storeLocal(javaIndex, local);
             javaIndex = 1;
@@ -71,8 +70,7 @@
         for (int i = 0; i < max; i++) {
             RiType type = sig.argumentTypeAt(i, accessingClass);
             CiKind kind = type.kind().stackKind();
-            Local local = new Local(kind, index, graph);
-            local.inputs().set(0, graph.start());
+            Local local = new Local(kind, index, graph.start(), graph);
             if (type.isResolved()) {
                 local.setDeclaredType(type);
             }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java	Fri Jun 10 15:12:10 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java	Fri Jun 10 19:50:16 2011 +0200
@@ -998,8 +998,8 @@
                 asm.bindOutOfLine(slowStoreCheck);
                 checkSubtype(asm, temp, valueHub, compHub);
                 asm.jneq(store, temp, asm.w(0));
-                XirOperand scratch = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10);
-                asm.mov(scratch, valueHub);
+                XirOperand scratch = asm.createRegisterTemp("scratch", CiKind.Word, AMD64.r10);
+                asm.mov(scratch, asm.createConstant(CiConstant.forWord(0)));
                 asm.callRuntime(CiRuntimeCall.Deoptimize, null);
                 asm.shouldNotReachHere();
             }
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Jun 10 15:12:10 2011 +0200
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Jun 10 19:50:16 2011 +0200
@@ -2656,6 +2656,7 @@
 
   int jmp_uncommon_trap_offset = __ pc() - start;
   __ pushptr(Address(r15_thread, in_bytes(JavaThread::ScratchA_offset())));
+  __ movptr(rscratch1, 0);
 
   int uncommon_trap_offset = __ pc() - start;
 
@@ -2752,7 +2753,7 @@
   // or captured in the vframeArray.
   RegisterSaver::restore_result_registers(masm);
 
-  // All of the register save area has been popped of the stack. Only the
+  // All of the register save area has been poppeset_jmp_uncommon_trap_offsetd of the stack. Only the
   // return address remains.
 
   // Pop all the frames we must move/replace.
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Fri Jun 10 15:12:10 2011 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Fri Jun 10 19:50:16 2011 +0200
@@ -106,7 +106,8 @@
 }
 
 // TODO: finish this - graal doesn't provide any scope values at the moment
-static ScopeValue* get_hotspot_value(oop value, int frame_size) {
+static ScopeValue* get_hotspot_value(oop value, int frame_size, ScopeValue* &second) {
+  second = NULL;
   if (value == CiValue::IllegalValue()) {
     return new LocationValue(Location::new_stk_loc(Location::invalid, 0));
   }
@@ -114,27 +115,61 @@
   BasicType type = GraalCompiler::kindToBasicType(CiKind::typeChar(CiValue::kind(value)));
   Location::Type locationType = Location::normal;
   if (type == T_OBJECT || type == T_ARRAY) locationType = Location::oop;
+
   if (value->is_a(CiRegisterValue::klass())) {
     jint number = CiRegister::number(CiRegisterValue::reg(value));
     if (number < 16) {
-      return new LocationValue(Location::new_reg_loc(locationType, as_Register(number)->as_VMReg()));
+      if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) {
+        locationType = Location::int_in_long;
+      } else if (type == T_LONG) {
+        locationType = Location::lng;
+      } else {
+        assert(type == T_OBJECT || type == T_ARRAY, "unexpected type in cpu register");
+      }
+      ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_Register(number)->as_VMReg()));
+      if (type == T_LONG) {
+        second = value;
+      }
+      return value;
     } else {
-      return new LocationValue(Location::new_reg_loc(locationType, as_XMMRegister(number - 16)->as_VMReg()));
+      assert(type == T_FLOAT || type == T_DOUBLE, "only float and double expected in xmm register");
+      if (type == T_FLOAT) {
+        // this seems weird, but the same value is used in c1_LinearScan
+        locationType = Location::normal;
+      } else {
+        locationType = Location::dbl;
+      }
+      ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_XMMRegister(number - 16)->as_VMReg()));
+      if (type == T_DOUBLE) {
+        second = value;
+      }
+      return value;
     }
   } else if (value->is_a(CiStackSlot::klass())) {
+    if (type == T_DOUBLE) {
+      locationType = Location::dbl;
+    } else if (type == T_LONG) {
+      locationType = Location::lng;
+    }
     jint index = CiStackSlot::index(value);
+    ScopeValue* value;
     if (index >= 0) {
-      return new LocationValue(Location::new_stk_loc(locationType, index * HeapWordSize));
+      value = new LocationValue(Location::new_stk_loc(locationType, index * HeapWordSize));
     } else {
       int frame_size_bytes = frame_size + 2 * HeapWordSize;
-      return new LocationValue(Location::new_stk_loc(locationType, -(index * HeapWordSize) + frame_size_bytes));
+      value = new LocationValue(Location::new_stk_loc(locationType, -(index * HeapWordSize) + frame_size_bytes));
     }
+    if (type == T_DOUBLE || type == T_LONG) {
+      second = value;
+    }
+    return value;
   } else if (value->is_a(CiConstant::klass())){
     oop obj = CiConstant::object(value);
     jlong prim = CiConstant::primitive(value);
     if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) {
       return new ConstantIntValue(*(jint*)&prim);
     } else if (type == T_LONG || type == T_DOUBLE) {
+      second = new ConstantIntValue(0);
       return new ConstantLongValue(prim);
     } else if (type == T_OBJECT) {
       oop obj = CiConstant::object(value);
@@ -433,19 +468,32 @@
     }
 
     for (jint i = 0; i < values->length(); i++) {
-      ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], _frame_size);
+      ScopeValue* second = NULL;
+      ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], _frame_size, second);
 
       if (i < local_count) {
+        if (second != NULL) {
+          locals->append(second);
+        }
         locals->append(value);
       } else if (i < local_count + expression_count) {
+        if (second != NULL) {
+          expressions->append(value);
+        }
         expressions->append(value);
       } else {
+        assert(second == NULL, "monitor cannot occupy two stack slots");
         assert(value->is_location(), "invalid monitor location");
         LocationValue* loc = (LocationValue*)value;
         int monitor_offset = loc->location().stack_offset();
         LocationValue* obj = new LocationValue(Location::new_stk_loc(Location::oop, monitor_offset + BasicObjectLock::obj_offset_in_bytes()));
         monitors->append(new MonitorValue(obj, Location::new_stk_loc(Location::normal, monitor_offset  + BasicObjectLock::lock_offset_in_bytes())));
       }
+      if (second != NULL) {
+        i++;
+        assert(i < values->length(), "double-slot value not followed by CiValue.IllegalValue");
+        assert(((oop*) values->base(T_OBJECT))[i] == CiValue::IllegalValue(), "double-slot value not followed by CiValue.IllegalValue");
+      }
     }
     DebugToken* locals_token = _debug_recorder->create_scope_values(locals);
     DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions);
--- a/src/share/vm/runtime/deoptimization.cpp	Fri Jun 10 15:12:10 2011 +0200
+++ b/src/share/vm/runtime/deoptimization.cpp	Fri Jun 10 19:50:16 2011 +0200
@@ -1221,6 +1221,8 @@
     DeoptAction action = trap_request_action(trap_request);
     jint unloaded_class_index = trap_request_index(trap_request); // CP idx or -1
 
+//    tty->print_cr("trap_request: %08x, cpi: %i, pc: %016x", trap_request, unloaded_class_index, fr.pc());
+
     Events::log("Uncommon trap occurred @" INTPTR_FORMAT " unloaded_class_index = %d", fr.pc(), (int) trap_request);
     vframe*  vf  = vframe::new_vframe(&fr, &reg_map, thread);
     compiledVFrame* cvf = compiledVFrame::cast(vf);