Mercurial > hg > truffle
changeset 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | 5b25562f8bd7 |
children | 5c63e4385115 |
files | graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCompiler.cpp src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalVMToCompiler.cpp src/share/vm/graal/graalVMToCompiler.hpp |
diffstat | 10 files changed, 24 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Fri Apr 12 11:06:19 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Apr 15 19:54:58 2013 +0200 @@ -169,6 +169,8 @@ HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass); + boolean hasFinalizableSubclass(HotSpotResolvedObjectType klass); + /** * Gets the compiled code size for a method. *
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Apr 12 11:06:19 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Apr 15 19:54:58 2013 +0200 @@ -106,6 +106,9 @@ public native boolean isTypeInitialized(HotSpotResolvedObjectType klass); @Override + public native boolean hasFinalizableSubclass(HotSpotResolvedObjectType klass); + + @Override public native void initializeType(HotSpotResolvedObjectType klass); @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Fri Apr 12 11:06:19 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Mon Apr 15 19:54:58 2013 +0200 @@ -76,7 +76,6 @@ * @param name the {@linkplain JavaType#getName() name} of the type * @param simpleName a simple, unqualified name for the type * @param javaMirror the {@link Class} mirror - * @param hasFinalizableSubclass specifies if the type has a finalizable subtype * @param sizeOrSpecies the size of an instance of the type, or * {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} or * {@link HotSpotResolvedObjectType#ARRAY_SPECIES_VALUE} @@ -84,7 +83,7 @@ * instantiated by this call in the case of another thread racing to create the same * type */ - ResolvedJavaType createResolvedJavaType(long metaspaceKlass, String name, String simpleName, Class javaMirror, boolean hasFinalizableSubclass, int sizeOrSpecies); + ResolvedJavaType createResolvedJavaType(long metaspaceKlass, String name, String simpleName, Class javaMirror, int sizeOrSpecies); Constant createConstant(Kind kind, long value);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri Apr 12 11:06:19 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Mon Apr 15 19:54:58 2013 +0200 @@ -683,8 +683,8 @@ } @Override - public HotSpotResolvedObjectType createResolvedJavaType(long metaspaceKlass, String name, String simpleName, Class javaMirror, boolean hasFinalizableSubclass, int sizeOrSpecies) { - HotSpotResolvedObjectType type = new HotSpotResolvedObjectType(metaspaceKlass, name, simpleName, javaMirror, hasFinalizableSubclass, sizeOrSpecies); + public HotSpotResolvedObjectType createResolvedJavaType(long metaspaceKlass, String name, String simpleName, Class javaMirror, int sizeOrSpecies) { + HotSpotResolvedObjectType type = new HotSpotResolvedObjectType(metaspaceKlass, name, simpleName, javaMirror, sizeOrSpecies); long offset = HotSpotGraalRuntime.getInstance().getConfig().graalMirrorInClassOffset; if (!unsafe.compareAndSwapObject(javaMirror, offset, null, type)) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Fri Apr 12 11:06:19 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Mon Apr 15 19:54:58 2013 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.hotspot.meta; import static com.oracle.graal.api.meta.MetaUtil.*; -import static com.oracle.graal.graph.FieldIntrospection.*; +import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static java.lang.reflect.Modifier.*; @@ -63,7 +63,6 @@ private final Class<?> javaMirror; // this could be read directly from 'metaspaceKlass'... private final String simpleName; - private final boolean hasFinalizableSubclass; /** * The instance size (in bytes) for an instance type, @@ -120,17 +119,15 @@ } /** - * @param hasFinalizableSubclass * @param sizeOrSpecies the size of an instance of the type, or * {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} or * {@link HotSpotResolvedObjectType#ARRAY_SPECIES_VALUE} */ - public HotSpotResolvedObjectType(long metaspaceKlass, String name, String simpleName, Class javaMirror, boolean hasFinalizableSubclass, int sizeOrSpecies) { + public HotSpotResolvedObjectType(long metaspaceKlass, String name, String simpleName, Class javaMirror, int sizeOrSpecies) { super(name); this.metaspaceKlass = metaspaceKlass; this.javaMirror = javaMirror; this.simpleName = simpleName; - this.hasFinalizableSubclass = hasFinalizableSubclass; this.sizeOrSpecies = sizeOrSpecies; assert name.charAt(0) != '[' || sizeOrSpecies == ARRAY_SPECIES_VALUE : name + " " + Long.toHexString(sizeOrSpecies); assert javaMirror.isArray() == isArray(); @@ -260,7 +257,8 @@ @Override public boolean hasFinalizableSubclass() { - return hasFinalizableSubclass; + assert !isArray(); + return HotSpotGraalRuntime.getInstance().getCompilerToVM().hasFinalizableSubclass(this); } @Override
--- a/src/share/vm/classfile/vmSymbols.hpp Fri Apr 12 11:06:19 2013 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Apr 15 19:54:58 2013 +0200 @@ -360,7 +360,7 @@ template(createUnresolvedJavaType_name, "createUnresolvedJavaType") \ template(createUnresolvedJavaType_signature, "(Ljava/lang/String;)Lcom/oracle/graal/api/meta/JavaType;") \ template(createResolvedJavaType_name, "createResolvedJavaType") \ - template(createResolvedJavaType_signature, "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/Class;ZI)Lcom/oracle/graal/api/meta/ResolvedJavaType;") \ + template(createResolvedJavaType_signature, "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/Class;I)Lcom/oracle/graal/api/meta/ResolvedJavaType;") \ template(createPrimitiveJavaType_name, "createPrimitiveJavaType") \ template(createPrimitiveJavaType_signature, "(I)Lcom/oracle/graal/api/meta/JavaType;") \ template(createLocalImpl_name, "createLocalImpl") \
--- a/src/share/vm/graal/graalCompiler.cpp Fri Apr 12 11:06:19 2013 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Mon Apr 15 19:54:58 2013 +0200 @@ -293,9 +293,6 @@ name = java_lang_String::create_from_str(ik->signature_name(), CHECK_NULL); } - // TODO replace this with the correct value - bool hasFinalizableSubclass = false; - int sizeOrSpecies; if (klass->is_interface()) { sizeOrSpecies = (int) 0x80000000; // see HotSpotResolvedObjectType.INTERFACE_SPECIES_VALUE @@ -308,7 +305,7 @@ } } - return VMToCompiler::createResolvedJavaType(klass(), name, simpleName, java_class, hasFinalizableSubclass, sizeOrSpecies, CHECK_NULL); + return VMToCompiler::createResolvedJavaType(klass(), name, simpleName, java_class, sizeOrSpecies, CHECK_NULL); } BasicType GraalCompiler::kindToBasicType(jchar ch) {
--- a/src/share/vm/graal/graalCompilerToVM.cpp Fri Apr 12 11:06:19 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Apr 15 19:54:58 2013 +0200 @@ -550,6 +550,12 @@ return InstanceKlass::cast(klass)->is_initialized(); C2V_END +C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject hotspot_klass)) + Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass)); + assert(klass != NULL, "method must not be called for primitive types"); + return Dependencies::find_finalizable_subclass(klass) != NULL; +C2V_END + C2V_VMENTRY(void, initializeType, (JNIEnv *, jobject, jobject hotspot_klass)) Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass)); assert(klass != NULL, "method must not be called for primitive types"); @@ -1131,6 +1137,7 @@ {CC"resolveMethod", CC"("HS_RESOLVED_TYPE STRING STRING")"METHOD, FN_PTR(resolveMethod)}, {CC"getInstanceFields", CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD, FN_PTR(getInstanceFields)}, {CC"isTypeInitialized", CC"("HS_RESOLVED_TYPE")Z", FN_PTR(isTypeInitialized)}, + {CC"hasFinalizableSubclass", CC"("HS_RESOLVED_TYPE")Z", FN_PTR(hasFinalizableSubclass)}, {CC"initializeType", CC"("HS_RESOLVED_TYPE")V", FN_PTR(initializeType)}, {CC"getMaxCallTargetOffset", CC"(J)J", FN_PTR(getMaxCallTargetOffset)}, {CC"getResolvedType", CC"("CLASS")"RESOLVED_TYPE, FN_PTR(getResolvedType)},
--- a/src/share/vm/graal/graalVMToCompiler.cpp Fri Apr 12 11:06:19 2013 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Mon Apr 15 19:54:58 2013 +0200 @@ -208,7 +208,7 @@ return (oop) result.get_jobject(); } -oop VMToCompiler::createResolvedJavaType(Klass* klass, Handle name, Handle simpleName, Handle java_mirror, jboolean hasFinalizableSubclass, jint sizeOrSpecies, TRAPS) { +oop VMToCompiler::createResolvedJavaType(Klass* klass, Handle name, Handle simpleName, Handle java_mirror, jint sizeOrSpecies, TRAPS) { assert(!name.is_null(), "just checking"); assert(!simpleName.is_null(), "just checking"); JavaValue result(T_OBJECT); @@ -218,7 +218,6 @@ args.push_oop(name); args.push_oop(simpleName); args.push_oop(java_mirror); - args.push_int(hasFinalizableSubclass); args.push_int(sizeOrSpecies); JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createResolvedJavaType_name(), vmSymbols::createResolvedJavaType_signature(), &args, THREAD); check_pending_exception("Error while calling createResolvedJavaType");
--- a/src/share/vm/graal/graalVMToCompiler.hpp Fri Apr 12 11:06:19 2013 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.hpp Mon Apr 15 19:54:58 2013 +0200 @@ -77,8 +77,8 @@ // public abstract JavaType createUnresolvedJavaType(String name); static oop createUnresolvedJavaType(Handle name, TRAPS); - // public abstract ResolvedJavaType createResolvedJavaType(long metaspaceKlass, String name, String simpleName, Class javaMirror, boolean hasFinalizableSubclass, int sizeOrSpecies); - static oop createResolvedJavaType(Klass* klass, Handle name, Handle simpleName, Handle java_mirror, jboolean hasFinalizableSubclass, jint sizeOrSpecies, TRAPS); + // public abstract ResolvedJavaType createResolvedJavaType(long metaspaceKlass, String name, String simpleName, Class javaMirror, int sizeOrSpecies); + static oop createResolvedJavaType(Klass* klass, Handle name, Handle simpleName, Handle java_mirror, jint sizeOrSpecies, TRAPS); // public abstract JavaType createPrimitiveJavaType(int basicType); static oop createPrimitiveJavaType(int basicType, TRAPS);