# HG changeset patch # User Tom Rodriguez # Date 1426051133 25200 # Node ID 29916dcee0b84eac8bf1195532c0e443240396ce # Parent ea8d6fa333ab2119e586947b7dcf7d45a8d57ca0 Verify dependencies when assertions are enabled diff -r ea8d6fa333ab -r 29916dcee0b8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Mar 10 22:15:39 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Mar 10 22:18:53 2015 -0700 @@ -1503,6 +1503,7 @@ @HotSpotVMConstant(name = "GraalEnv::ok") @Stable public int codeInstallResultOk; @HotSpotVMConstant(name = "GraalEnv::dependencies_failed") @Stable public int codeInstallResultDependenciesFailed; + @HotSpotVMConstant(name = "GraalEnv::dependencies_invalid") @Stable public int codeInstallResultDependenciesInvalid; @HotSpotVMConstant(name = "GraalEnv::cache_full") @Stable public int codeInstallResultCacheFull; @HotSpotVMConstant(name = "GraalEnv::code_too_large") @Stable public int codeInstallResultCodeTooLarge; diff -r ea8d6fa333ab -r 29916dcee0b8 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 Tue Mar 10 22:15:39 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Tue Mar 10 22:18:53 2015 -0700 @@ -176,6 +176,7 @@ public enum CodeInstallResult { OK("ok"), DEPENDENCIES_FAILED("dependencies failed"), + DEPENDENCIES_INVALID("dependencies invalid"), CACHE_FULL("code cache is full"), CODE_TOO_LARGE("code is too large"); @@ -191,6 +192,9 @@ case "dependencies failed": this.value = config.codeInstallResultDependenciesFailed; break; + case "dependencies invalid": + this.value = config.codeInstallResultDependenciesInvalid; + break; case "code cache is full": this.value = config.codeInstallResultCacheFull; break; diff -r ea8d6fa333ab -r 29916dcee0b8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Tue Mar 10 22:15:39 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Tue Mar 10 22:18:53 2015 -0700 @@ -264,9 +264,14 @@ if (result != CodeInstallResult.OK) { String msg = compiledCode.getInstallationFailureMessage(); if (msg != null) { - throw new BailoutException(result != CodeInstallResult.DEPENDENCIES_FAILED, "Code installation failed: %s%n%s", result, msg); + msg = String.format("Code installation failed: %s%n%s", result, msg); + } else { + msg = String.format("Code installation failed: %s", result); } - throw new BailoutException(result != CodeInstallResult.DEPENDENCIES_FAILED, "Code installation failed: %s", result); + if (result == CodeInstallResult.DEPENDENCIES_INVALID) { + throw new AssertionError(result + " " + msg); + } + throw new BailoutException(result != CodeInstallResult.DEPENDENCIES_FAILED, msg); } return logOrDump(installedCode, compResult); } diff -r ea8d6fa333ab -r 29916dcee0b8 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Tue Mar 10 22:15:39 2015 -0700 +++ b/src/share/vm/classfile/systemDictionary.hpp Tue Mar 10 22:18:53 2015 -0700 @@ -186,6 +186,7 @@ /* Support for Graal */ \ do_klass(BitSet_klass, java_util_BitSet, Opt ) \ /* Graal classes. These are loaded on-demand. */ \ + GRAAL_ONLY(do_klass(Debug_klass, com_oracle_graal_debug_Debug, Graal)) \ GRAAL_ONLY(do_klass(Node_klass, com_oracle_graal_graph_Node, Graal)) \ GRAAL_ONLY(do_klass(NodeClass_klass, com_oracle_graal_graph_NodeClass, Graal)) \ GRAAL_ONLY(do_klass(HotSpotCompiledCode_klass, com_oracle_graal_hotspot_HotSpotCompiledCode, Graal)) \ @@ -258,7 +259,7 @@ WKID_LIMIT, #ifdef GRAAL - FIRST_GRAAL_WKID = WK_KLASS_ENUM_NAME(Node_klass), + FIRST_GRAAL_WKID = WK_KLASS_ENUM_NAME(Debug_klass), LAST_GRAAL_WKID = WK_KLASS_ENUM_NAME(AbstractValue_klass), #endif diff -r ea8d6fa333ab -r 29916dcee0b8 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue Mar 10 22:15:39 2015 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Mar 10 22:18:53 2015 -0700 @@ -291,6 +291,7 @@ \ /* Support for Graal */ \ template(java_util_BitSet, "java/util/BitSet") \ + GRAAL_ONLY(template(com_oracle_graal_debug_Debug, "com/oracle/graal/debug/Debug")) \ GRAAL_ONLY(template(com_oracle_graal_graph_Node, "com/oracle/graal/graph/Node")) \ GRAAL_ONLY(template(com_oracle_graal_graph_NodeClass, "com/oracle/graal/graph/NodeClass")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_HotSpotGraalRuntime, "com/oracle/graal/hotspot/HotSpotGraalRuntime")) \ diff -r ea8d6fa333ab -r 29916dcee0b8 src/share/vm/graal/graalEnv.cpp --- a/src/share/vm/graal/graalEnv.cpp Tue Mar 10 22:15:39 2015 -0700 +++ b/src/share/vm/graal/graalEnv.cpp Tue Mar 10 22:18:53 2015 -0700 @@ -421,12 +421,13 @@ // ------------------------------------------------------------------ // Check for changes to the system dictionary during compilation // class loads, evolution, breakpoints -bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies, Handle compiled_code, GraalEnv* env, char** failure_detail) { +GraalEnv::CodeInstallResult GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies, Handle compiled_code, + GraalEnv* env, char** failure_detail) { // If JVMTI capabilities were enabled during compile, the compilation is invalidated. if (env != NULL) { if (!env->_jvmti_can_hotswap_or_post_breakpoint && JvmtiExport::can_hotswap_or_post_breakpoint()) { *failure_detail = (char*) "Hotswapping or breakpointing was enabled during compilation"; - return false; + return GraalEnv::dependencies_failed; } } @@ -434,9 +435,9 @@ // or if we don't know whether it has changed (i.e., env == NULL). // In debug mode, always check dependencies. bool counter_changed = env != NULL && env->_system_dictionary_modification_counter != SystemDictionary::number_of_modifications(); - bool verify_deps = env == NULL || trueInDebug; + bool verify_deps = env == NULL || trueInDebug || Debug::ENABLED(); if (!counter_changed && !verify_deps) { - return true; + return GraalEnv::ok; } for (Dependencies::DepStream deps(dependencies); deps.next(); ) { @@ -448,14 +449,21 @@ stringStream st(buffer, O_BUFLEN); deps.print_dependency(witness, true, &st); *failure_detail = st.as_string(); - return false; + if (env == NULL || counter_changed) { + return GraalEnv::dependencies_failed; + } else { + // The dependencies were invalid at the time of installation + // without any intervening modification of the system + // dictionary. That means they were invalidly constructed. + return GraalEnv::dependencies_invalid; + } } if (LogCompilation) { deps.log_dependency(); } } - return true; + return GraalEnv::ok; } // ------------------------------------------------------------------ @@ -496,7 +504,8 @@ dependencies->encode_content_bytes(); // Check for {class loads, evolution, breakpoints} during compilation - if (!check_for_system_dictionary_modification(dependencies, compiled_code, env, &failure_detail)) { + result = check_for_system_dictionary_modification(dependencies, compiled_code, env, &failure_detail); + if (result != GraalEnv::ok) { // While not a true deoptimization, it is a preemptive decompile. MethodData* mdp = method()->method_data(); if (mdp != NULL) { @@ -513,7 +522,6 @@ // If the code buffer is created on each compile attempt // as in C2, then it must be freed. //code_buffer->free_blob(); - result = GraalEnv::dependencies_failed; } else { ImplicitExceptionTable implicit_tbl; nm = nmethod::new_nmethod(method, diff -r ea8d6fa333ab -r 29916dcee0b8 src/share/vm/graal/graalEnv.hpp --- a/src/share/vm/graal/graalEnv.hpp Tue Mar 10 22:15:39 2015 -0700 +++ b/src/share/vm/graal/graalEnv.hpp Tue Mar 10 22:18:53 2015 -0700 @@ -61,6 +61,7 @@ enum CodeInstallResult { ok, dependencies_failed, + dependencies_invalid, cache_full, code_too_large }; @@ -133,7 +134,8 @@ // Helper routine for determining the validity of a compilation // with respect to concurrent class loading. - static bool check_for_system_dictionary_modification(Dependencies* target, Handle compiled_code, GraalEnv* env, char** failure_detail); + static GraalEnv::CodeInstallResult check_for_system_dictionary_modification(Dependencies* target, Handle compiled_code, + GraalEnv* env, char** failure_detail); public: CompileTask* task() { return _task; } diff -r ea8d6fa333ab -r 29916dcee0b8 src/share/vm/graal/graalJavaAccess.cpp --- a/src/share/vm/graal/graalJavaAccess.cpp Tue Mar 10 22:15:39 2015 -0700 +++ b/src/share/vm/graal/graalJavaAccess.cpp Tue Mar 10 22:18:53 2015 -0700 @@ -63,10 +63,11 @@ #define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false) #define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true) #define STATIC_INT_FIELD(klass, name) FIELD(klass, name, "I", true) +#define STATIC_BOOLEAN_FIELD(klass, name) FIELD(klass, name, "Z", true) void graal_compute_offsets() { - COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, OOP_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD) + COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, OOP_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD) guarantee(InstalledCode::_address_offset == sizeof(oopDesc), "codeBlob must be first field!"); } @@ -76,7 +77,7 @@ #define FIELD2(klass, name) int klass::_##name##_offset = 0; #define FIELD3(klass, name, sig) FIELD2(klass, name) -COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2) +COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2, FIELD2) diff -r ea8d6fa333ab -r 29916dcee0b8 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Tue Mar 10 22:15:39 2015 -0700 +++ b/src/share/vm/graal/graalJavaAccess.hpp Tue Mar 10 22:18:53 2015 -0700 @@ -47,7 +47,7 @@ * */ -#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, typeArrayOop_field, objArrayOop_field, static_oop_field, static_int_field) \ +#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, typeArrayOop_field, objArrayOop_field, static_oop_field, static_int_field, static_boolean_field) \ start_class(HotSpotResolvedObjectTypeImpl) \ oop_field(HotSpotResolvedObjectTypeImpl, javaClass, "Ljava/lang/Class;") \ end_class \ @@ -260,6 +260,9 @@ objArrayOop_field(HotSpotStackFrameReference, locals, "[Ljava/lang/Object;") \ typeArrayOop_field(HotSpotStackFrameReference, localIsVirtual, "[Z") \ end_class \ + start_class(Debug) \ + static_boolean_field(Debug, ENABLED) \ + end_class \ /* end*/ #define START_CLASS(name) \ @@ -294,39 +297,42 @@ #define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field, EMPTY_CAST) #define OBJARRAYOOP_FIELD(klass, name, signature) FIELD(name, objArrayOop, obj_field, (objArrayOop)) #define TYPEARRAYOOP_FIELD(klass, name, signature) FIELD(name, typeArrayOop, obj_field, (typeArrayOop)) -#define STATIC_OOP_FIELD(klassName, name, signature) \ - static int _##name##_offset; \ - static oop name() { \ - InstanceKlass* ik = InstanceKlass::cast(klassName::klass()); \ - address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \ - if (UseCompressedOops) { \ - return oopDesc::load_decode_heap_oop((narrowOop *)addr); \ - } else { \ - return oopDesc::load_decode_heap_oop((oop*)addr); \ - } \ - } \ - static void set_##name(oop x) { \ - InstanceKlass* ik = InstanceKlass::cast(klassName::klass()); \ - address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \ - if (UseCompressedOops) { \ - oop_store((narrowOop *)addr, x); \ - } else { \ - oop_store((oop*)addr, x); \ - } \ +#define STATIC_OOP_FIELD(klassName, name, signature) \ + static int _##name##_offset; \ + static oop name() { \ + InstanceKlass* ik = InstanceKlass::cast(klassName::klass()); \ + address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \ + if (UseCompressedOops) { \ + return oopDesc::load_decode_heap_oop((narrowOop *)addr); \ + } else { \ + return oopDesc::load_decode_heap_oop((oop*)addr); \ + } \ + } \ + static void set_##name(oop x) { \ + InstanceKlass* ik = InstanceKlass::cast(klassName::klass()); \ + address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \ + if (UseCompressedOops) { \ + oop_store((narrowOop *)addr, x); \ + } else { \ + oop_store((oop*)addr, x); \ + } \ } -#define STATIC_INT_FIELD(klassName, name) \ - static int _##name##_offset; \ - static int name() { \ - InstanceKlass* ik = InstanceKlass::cast(klassName::klass()); \ - address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \ - return *((jint *)addr); \ - } \ - static void set_##name(int x) { \ - InstanceKlass* ik = InstanceKlass::cast(klassName::klass()); \ - address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \ - *((jint *)addr) = x; \ +#define STATIC_PRIMITIVE_FIELD(klassName, name, typename, jtypename) \ + static int _##name##_offset; \ + static typename name() { \ + InstanceKlass* ik = InstanceKlass::cast(klassName::klass()); \ + address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \ + return *((jtypename *)addr); \ + } \ + static void set_##name(typename x) { \ + InstanceKlass* ik = InstanceKlass::cast(klassName::klass()); \ + address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \ + *((jtypename *)addr) = x; \ } -COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, TYPEARRAYOOP_FIELD, OBJARRAYOOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD) +#define STATIC_INT_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, int, jint) +#define STATIC_BOOLEAN_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, bool, jboolean) + +COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, TYPEARRAYOOP_FIELD, OBJARRAYOOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD) #undef START_CLASS #undef END_CLASS #undef FIELD @@ -340,6 +346,7 @@ #undef OBJARRAYOOP_FIELD #undef STATIC_OOP_FIELD #undef STATIC_INT_FIELD +#undef STATIC_BOOLEAN_FIELD #undef EMPTY_CAST void compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field); diff -r ea8d6fa333ab -r 29916dcee0b8 src/share/vm/graal/vmStructs_graal.hpp --- a/src/share/vm/graal/vmStructs_graal.hpp Tue Mar 10 22:15:39 2015 -0700 +++ b/src/share/vm/graal/vmStructs_graal.hpp Tue Mar 10 22:18:53 2015 -0700 @@ -52,6 +52,7 @@ declare_constant(Deoptimization::Reason_jsr_mismatch) \ declare_constant(GraalEnv::ok) \ declare_constant(GraalEnv::dependencies_failed) \ + declare_constant(GraalEnv::dependencies_invalid) \ declare_constant(GraalEnv::cache_full) \ declare_constant(GraalEnv::code_too_large) \ \