# HG changeset patch # User Gilles Duboscq # Date 1368023670 -7200 # Node ID ae17e540c5d2efc88dfdcb39a62a1f0ac2996ef0 # Parent c0d76a2ef720a5cc4acd9bd0bdce9d9e3bcf43a7 More asserts while getting vtable offsets Added check that methods have vtable entrys before using method dispatch instead of type dispatch diff -r c0d76a2ef720 -r ae17e540c5d2 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 13:42:14 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Wed May 08 16:34:30 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 c0d76a2ef720 -r ae17e540c5d2 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 13:42:14 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed May 08 16:34:30 2013 +0200 @@ -210,6 +210,8 @@ int getVtableEntryOffset(long metaspaceMethod); + boolean hasVtableEntry(long metaspaceMethod); + long[] getDeoptedLeafGraphIds(); long[] getLineNumberTable(HotSpotResolvedJavaMethod method); diff -r c0d76a2ef720 -r ae17e540c5d2 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 13:42:14 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed May 08 16:34:30 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 c0d76a2ef720 -r ae17e540c5d2 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 13:42:14 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed May 08 16:34:30 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 c0d76a2ef720 -r ae17e540c5d2 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 13:42:14 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed May 08 16:34:30 2013 +0200 @@ -773,8 +773,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); @@ -1049,6 +1049,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; diff -r c0d76a2ef720 -r ae17e540c5d2 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 13:42:14 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Wed May 08 16:34:30 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 c0d76a2ef720 -r ae17e540c5d2 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 13:42:14 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed May 08 16:34:30 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 c0d76a2ef720 -r ae17e540c5d2 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed May 08 13:42:14 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed May 08 16:34:30 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)},