changeset 19766:29916dcee0b8

Verify dependencies when assertions are enabled
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 10 Mar 2015 22:18:53 -0700
parents ea8d6fa333ab
children e6a4ba0980dd 6b73ce815fc2
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalEnv.cpp src/share/vm/graal/graalEnv.hpp src/share/vm/graal/graalJavaAccess.cpp src/share/vm/graal/graalJavaAccess.hpp src/share/vm/graal/vmStructs_graal.hpp
diffstat 10 files changed, 77 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- 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;
 
--- 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;
--- 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);
     }
--- 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
 
--- 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"))                  \
--- 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,
--- 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; }
--- 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)
 
 
 
--- 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);
--- 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)                                                      \
                                                                                                   \