# HG changeset patch # User Lukas Stadler # Date 1307728216 -7200 # Node ID c7783b6773ea9048da1642d48f855dcd62e443a5 # Parent 3fa0e12d524af7adb054a4999259b15c86098519 fixed graph start frame state new option: DeoptALot lots of fixes to debug info handling in graalCodeInstaller fix to uncommon trap stub diff -r 3fa0e12d524a -r c7783b6773ea graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- 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)}. diff -r 3fa0e12d524a -r c7783b6773ea graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- 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()); diff -r 3fa0e12d524a -r c7783b6773ea graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java --- 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); diff -r 3fa0e12d524a -r c7783b6773ea graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java --- 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 getDebugProperties() { + Map 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; } diff -r 3fa0e12d524a -r c7783b6773ea graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java --- 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)) { diff -r 3fa0e12d524a -r c7783b6773ea graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java --- 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) { diff -r 3fa0e12d524a -r c7783b6773ea graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java --- 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); } diff -r 3fa0e12d524a -r c7783b6773ea graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java --- 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(); } diff -r 3fa0e12d524a -r c7783b6773ea src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- 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. diff -r 3fa0e12d524a -r c7783b6773ea src/share/vm/graal/graalCodeInstaller.cpp --- 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); diff -r 3fa0e12d524a -r c7783b6773ea src/share/vm/runtime/deoptimization.cpp --- 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, ®_map, thread); compiledVFrame* cvf = compiledVFrame::cast(vf);