# HG changeset patch # User Doug Simon # Date 1368040178 -7200 # Node ID 5e3c8dd8063252f7ba9bee27ad0a508e6d48867e # Parent bd4a7d657dcc4f55f834cbbc3c1cc6b30ce70b05# Parent ae17e540c5d2efc88dfdcb39a62a1f0ac2996ef0 Merge. diff -r bd4a7d657dcc -r 5e3c8dd80632 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Wed May 08 21:05:39 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Wed May 08 21:09:38 2013 +0200 @@ -208,4 +208,11 @@ * @return a constant representing a reference to this method */ Constant getEncoding(); + + /** + * Checks if this method is present in the virtual table. + * + * @return true is this method is present in the virtual table + */ + boolean isInVirtualMethodTable(); } diff -r bd4a7d657dcc -r 5e3c8dd80632 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed May 08 21:05:39 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed May 08 21:09:38 2013 +0200 @@ -210,6 +210,8 @@ int getVtableEntryOffset(long metaspaceMethod); + boolean hasVtableEntry(long metaspaceMethod); + long[] getDeoptedLeafGraphIds(); long[] getLineNumberTable(HotSpotResolvedJavaMethod method); diff -r bd4a7d657dcc -r 5e3c8dd80632 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed May 08 21:05:39 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed May 08 21:09:38 2013 +0200 @@ -145,6 +145,9 @@ public native int getVtableEntryOffset(long metaspaceMethod); @Override + public native boolean hasVtableEntry(long metaspaceMethod); + + @Override public native long[] getDeoptedLeafGraphIds(); @Override diff -r bd4a7d657dcc -r 5e3c8dd80632 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed May 08 21:05:39 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed May 08 21:09:38 2013 +0200 @@ -383,7 +383,8 @@ /** * Returns the offset of this method into the v-table. If the holder is not initialized, returns - * -1 + * -1. If it is initialized the method must have a v-table entry has indicated by + * {@link #hasVtableEntry()}. * * @return the offset of this method into the v-table */ @@ -394,6 +395,10 @@ return graalRuntime().getCompilerToVM().getVtableEntryOffset(metaspaceMethod); } + public boolean hasVtableEntry() { + return graalRuntime().getCompilerToVM().hasVtableEntry(metaspaceMethod); + } + public void setCurrentTask(CompilationTask task) { currentTask = task; } @@ -455,4 +460,9 @@ throw new IllegalArgumentException(ex); } } + + @Override + public boolean isInVirtualMethodTable() { + return hasVtableEntry(); + } } diff -r bd4a7d657dcc -r 5e3c8dd80632 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed May 08 21:05:39 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed May 08 21:09:38 2013 +0200 @@ -772,8 +772,8 @@ HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); if (!hsMethod.getDeclaringClass().isInterface()) { - int vtableEntryOffset = hsMethod.vtableEntryOffset(); - if (vtableEntryOffset > 0) { + if (hsMethod.hasVtableEntry()) { + int vtableEntryOffset = hsMethod.vtableEntryOffset(); assert vtableEntryOffset > 0; ReadNode hub = this.createReadHub(tool, graph, wordKind, receiver); ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod); @@ -1048,6 +1048,7 @@ private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, ResolvedJavaMethod method) { HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; assert !hsMethod.getDeclaringClass().isInterface(); + assert hsMethod.hasVtableEntry(); int vtableEntryOffset = hsMethod.vtableEntryOffset(); assert vtableEntryOffset > 0; @@ -1107,11 +1108,11 @@ return barrierType; } - private static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field) { + protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field) { return ConstantLocationNode.create(field, field.getKind(), field.offset(), graph); } - private IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) { + protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) { int scale = this.graalRuntime.getTarget().arch.getSizeInBytes(elementKind); return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale); } diff -r bd4a7d657dcc -r 5e3c8dd80632 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed May 08 21:05:39 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed May 08 21:09:38 2013 +0200 @@ -70,6 +70,26 @@ return super.canonical(tool); } + private void virtualizeNonVirtualComparison(State state, ValueNode other, VirtualizerTool tool) { + if (!state.getVirtualObject().hasIdentity() && state.getVirtualObject().entryKind(0) == Kind.Boolean) { + if (other.isConstant()) { + int expectedValue = ((Boolean) other.asConstant().asObject()) ? 1 : 0; + final IntegerEqualsNode equals = new IntegerEqualsNode(state.getEntry(0), ConstantNode.forInt(expectedValue, graph())); + tool.customAction(new Runnable() { + + @Override + public void run() { + graph().add(equals); + } + }); + tool.replaceWithValue(equals); + } + } else { + // one of them is virtual: they can never be the same objects + tool.replaceWithValue(LogicConstantNode.contradiction(graph())); + } + } + @Override public void virtualize(VirtualizerTool tool) { State stateX = tool.getObjectState(x()); @@ -78,15 +98,9 @@ boolean yVirtual = stateY != null && stateY.getState() == EscapeState.Virtual; if (xVirtual && !yVirtual) { - if (stateX.getVirtualObject().hasIdentity()) { - // one of them is virtual: they can never be the same objects - tool.replaceWithValue(LogicConstantNode.contradiction(graph())); - } + virtualizeNonVirtualComparison(stateX, stateY != null ? stateY.getMaterializedValue() : y(), tool); } else if (!xVirtual && yVirtual) { - if (stateY.getVirtualObject().hasIdentity()) { - // one of them is virtual: they can never be the same objects - tool.replaceWithValue(LogicConstantNode.contradiction(graph())); - } + virtualizeNonVirtualComparison(stateY, stateX != null ? stateX.getMaterializedValue() : x(), tool); } else if (xVirtual && yVirtual) { boolean xIdentity = stateX.getVirtualObject().hasIdentity(); boolean yIdentity = stateY.getVirtualObject().hasIdentity(); diff -r bd4a7d657dcc -r 5e3c8dd80632 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Wed May 08 21:05:39 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Wed May 08 21:09:38 2013 +0200 @@ -53,7 +53,7 @@ cfg.computePostdominators(); } // there's not much to verify when connectBlocks == false - assert !connectBlocks || CFGVerifier.verify(cfg); + assert !(connectBlocks || computeLoops || computeDominators || computePostdominators) || CFGVerifier.verify(cfg); return cfg; } diff -r bd4a7d657dcc -r 5e3c8dd80632 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Wed May 08 21:05:39 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Wed May 08 21:09:38 2013 +0200 @@ -47,6 +47,7 @@ this.method = method; assert !Modifier.isAbstract(method.getModifiers()) : "Cannot load abstract method from a hub"; assert !Modifier.isStatic(method.getModifiers()) : "Cannot load a static method from a hub"; + assert method.isInVirtualMethodTable(); } @Override diff -r bd4a7d657dcc -r 5e3c8dd80632 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeArrayCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeArrayCastNode.java Wed May 08 21:05:39 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeArrayCastNode.java Wed May 08 21:09:38 2013 +0200 @@ -37,6 +37,11 @@ return length; } + public UnsafeArrayCastNode(ValueNode object, ValueNode length, Stamp stamp) { + super(object, stamp); + this.length = length; + } + public UnsafeArrayCastNode(ValueNode object, ValueNode length, Stamp stamp, ValueNode anchor) { super(object, stamp, anchor); this.length = length; @@ -51,5 +56,8 @@ } @NodeIntrinsic + public static native T unsafeArrayCast(Object object, int length, @ConstantNodeParameter Stamp stamp); + + @NodeIntrinsic public static native T unsafeArrayCast(Object object, int length, @ConstantNodeParameter Stamp stamp, Object anchor); } diff -r bd4a7d657dcc -r 5e3c8dd80632 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed May 08 21:05:39 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed May 08 21:09:38 2013 +0200 @@ -640,7 +640,6 @@ assert concretes.size() > 0; Debug.log("Method check cascade with %d methods", concretes.size()); - LoadMethodNode[] methods = new LoadMethodNode[concretes.size()]; ValueNode[] constantMethods = new ValueNode[concretes.size()]; double[] probability = new double[concretes.size()]; for (int i = 0; i < concretes.size(); ++i) { @@ -665,8 +664,7 @@ FixedNode lastSucc = successors[concretes.size()]; for (int i = concretes.size() - 1; i >= 0; --i) { LoadMethodNode method = graph.add(new LoadMethodNode(concretes.get(i), hub, constantMethods[i].kind())); - methods[i] = method; - CompareNode methodCheck = CompareNode.createCompareNode(Condition.EQ, methods[i], constantMethods[i]); + CompareNode methodCheck = CompareNode.createCompareNode(Condition.EQ, method, constantMethods[i]); IfNode ifNode = graph.add(new IfNode(methodCheck, successors[i], lastSucc, probability[i])); method.setNext(ifNode); lastSucc = method; @@ -698,6 +696,12 @@ } private boolean chooseMethodDispatch() { + for (ResolvedJavaMethod concrete : concretes) { + if (!concrete.isInVirtualMethodTable()) { + return false; + } + } + if (concretes.size() == 1 && this.notRecordedTypeProbability > 0) { // Always chose method dispatch if there is a single concrete method and the call // site is megamorphic. diff -r bd4a7d657dcc -r 5e3c8dd80632 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed May 08 21:05:39 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed May 08 21:09:38 2013 +0200 @@ -1001,6 +1001,7 @@ Method* method = asMethod(metaspace_method); assert(!InstanceKlass::cast(method->method_holder())->is_interface(), "vtableEntryOffset cannot be called for interface methods"); assert(InstanceKlass::cast(method->method_holder())->is_linked(), "vtableEntryOffset cannot be called is holder is not linked"); + assert(method->vtable_index() >= 0, "vtable entry offset should not be used"); // get entry offset in words int vtable_entry_offset = InstanceKlass::vtable_start_offset() + method->vtable_index() * vtableEntry::size(); @@ -1010,6 +1011,11 @@ return vtable_entry_offset; C2V_END +C2V_VMENTRY(jboolean, hasVtableEntry, (JNIEnv *, jobject, jlong metaspace_method)) + Method* method = asMethod(metaspace_method); + return method->vtable_index() >= 0; +C2V_END + C2V_VMENTRY(jobject, getDeoptedLeafGraphIds, (JNIEnv *, jobject)) // the contract for this method is as follows: @@ -1177,6 +1183,7 @@ {CC"getInvocationCount", CC"("METASPACE_METHOD")I", FN_PTR(getInvocationCount)}, {CC"getCompiledCodeSize", CC"("METASPACE_METHOD")I", FN_PTR(getCompiledCodeSize)}, {CC"getVtableEntryOffset", CC"("METASPACE_METHOD")I", FN_PTR(getVtableEntryOffset)}, + {CC"hasVtableEntry", CC"("METASPACE_METHOD")Z", FN_PTR(hasVtableEntry)}, {CC"constantPoolLength", CC"("HS_RESOLVED_TYPE")I", FN_PTR(constantPoolLength)}, {CC"lookupType", CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE, FN_PTR(lookupType)}, {CC"lookupConstantInPool", CC"("HS_RESOLVED_TYPE"I)"OBJECT, FN_PTR(lookupConstantInPool)},