< prev index next >

src/hotspot/share/memory/universe.cpp

Print this page

        

@@ -86,29 +86,14 @@
 #include "utilities/hashtable.inline.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
 #include "utilities/preserveException.hpp"
 
-#define PRIMITIVE_MIRRORS_DO(func) \
-  func(_int_mirror)    \
-  func(_float_mirror)  \
-  func(_double_mirror) \
-  func(_byte_mirror)   \
-  func(_bool_mirror)   \
-  func(_char_mirror)   \
-  func(_long_mirror)   \
-  func(_short_mirror)  \
-  func(_void_mirror)
-
-#define DEFINE_PRIMITIVE_MIRROR(m) \
-    oop Universe::m  = NULL;
-
 // Known objects
-PRIMITIVE_MIRRORS_DO(DEFINE_PRIMITIVE_MIRROR)
 Klass* Universe::_typeArrayKlassObjs[T_LONG+1]        = { NULL /*, NULL...*/ };
 Klass* Universe::_objectArrayKlassObj                 = NULL;
-oop Universe::_mirrors[T_VOID+1]                      = { NULL /*, NULL...*/ };
+OopHandle Universe::_mirrors[T_VOID+1];
 
 OopHandle Universe::_main_thread_group;
 OopHandle Universe::_system_thread_group;
 OopHandle Universe::_the_empty_class_array;
 OopHandle Universe::_the_null_string;

@@ -194,10 +179,39 @@
 oop Universe::arithmetic_exception_instance()     { return _arithmetic_exception_instance.resolve(); }
 oop Universe::virtual_machine_error_instance()    { return _virtual_machine_error_instance.resolve(); }
 
 oop Universe::the_null_sentinel()                 { return _the_null_sentinel.resolve(); }
 
+oop Universe::int_mirror()                        { return check_mirror(_mirrors[T_INT].resolve()); }
+oop Universe::float_mirror()                      { return check_mirror(_mirrors[T_FLOAT].resolve()); }
+oop Universe::double_mirror()                     { return check_mirror(_mirrors[T_DOUBLE].resolve()); }
+oop Universe::byte_mirror()                       { return check_mirror(_mirrors[T_BYTE].resolve()); }
+oop Universe::bool_mirror()                       { return check_mirror(_mirrors[T_BOOLEAN].resolve()); }
+oop Universe::char_mirror()                       { return check_mirror(_mirrors[T_CHAR].resolve()); }
+oop Universe::long_mirror()                       { return check_mirror(_mirrors[T_LONG].resolve()); }
+oop Universe::short_mirror()                      { return check_mirror(_mirrors[T_SHORT].resolve()); }
+oop Universe::void_mirror()                       { return check_mirror(_mirrors[T_VOID].resolve()); }
+
+oop Universe::java_mirror(BasicType t) {
+  assert((uint)t < T_VOID+1, "range check");
+  return check_mirror(_mirrors[t].resolve());
+}
+
+// Used by CDS dumping
+void Universe::replace_mirror(BasicType t, oop new_mirror) {
+  Universe::_mirrors[t].replace(new_mirror);
+}
+
+// Not sure why CDS has to do this
+void Universe::clear_basic_type_mirrors() {
+  for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
+    if (!is_reference_type((BasicType)i)) {
+      Universe::_mirrors[i].replace(NULL);
+    }
+  }
+}
+
 void Universe::basic_type_classes_do(void f(Klass*)) {
   for (int i = T_BOOLEAN; i < T_LONG+1; i++) {
     f(_typeArrayKlassObjs[i]);
   }
 }

@@ -206,20 +220,11 @@
   for (int i = T_BOOLEAN; i < T_LONG+1; i++) {
     closure->do_klass(_typeArrayKlassObjs[i]);
   }
 }
 
-#define DO_PRIMITIVE_MIRROR(m) \
-  f->do_oop((oop*) &m);
-
 void Universe::oops_do(OopClosure* f) {
-  PRIMITIVE_MIRRORS_DO(DO_PRIMITIVE_MIRROR);
-
-  for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
-    f->do_oop(&_mirrors[i]);
-  }
-  assert(_mirrors[0] == NULL && _mirrors[T_BOOLEAN - 1] == NULL, "checking");
 
   f->do_oop(&_reference_pending_list);
   ThreadsSMRSupport::exiting_threads_oops_do(f);
 }
 

@@ -245,33 +250,53 @@
   _throw_illegal_access_error_cache->metaspace_pointers_do(it);
   _throw_no_such_method_error_cache->metaspace_pointers_do(it);
   _do_stack_walk_cache->metaspace_pointers_do(it);
 }
 
-#define ASSERT_MIRROR_NULL(m) \
-  assert(m == NULL, "archived mirrors should be NULL");
+// Temporary location for mirrors during CDS save/restore until OopHandlized
+// GC doesn't need to know about this location.
+oop oop_mirrors[T_VOID+1] = { NULL /* , NULL */};
+
+// Reset oop mirrors to match gc-safe OopHandle mirrors, just before serialization
+void Universe::write_primitive_type_mirrors(SerializeClosure* f) {
+  for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
+    assert(DumpSharedSpaces, "should be dumping, what else?");
+    oop_mirrors[i] = _mirrors[i].resolve();
+    f->do_oop(&oop_mirrors[i]);
+    oop m = oop_mirrors[i];
+    if (m != NULL) { java_lang_Class::update_archived_primitive_mirror_native_pointers(m); }
+  }
+}
 
-#define SERIALIZE_MIRROR(m) \
-  f->do_oop(&m); \
+void Universe::read_primitive_type_mirrors(SerializeClosure* f) {
+  for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
+    f->do_oop(&oop_mirrors[i]);
+    oop m = oop_mirrors[i];
   if (m != NULL) { java_lang_Class::update_archived_primitive_mirror_native_pointers(m); }
+    _mirrors[i] = OopHandle(vm_global(), oop_mirrors[i]);
+    oop_mirrors[i] = NULL; // not needed anymore
+  }
+}
 
 // Serialize metadata and pointers to primitive type mirrors in and out of CDS archive
 void Universe::serialize(SerializeClosure* f) {
 
+#if INCLUDE_CDS_JAVA_HEAP
+  if (f->reading()) {
+    // read oop mirrors locally and create OopHandles for mirror array
+    read_primitive_type_mirrors(f);
+  } else {
+    // copy oop mirrors to local array for writing
+    write_primitive_type_mirrors(f);
+  }
+#endif
+
   for (int i = 0; i < T_LONG+1; i++) {
     f->do_ptr((void**)&_typeArrayKlassObjs[i]);
   }
 
   f->do_ptr((void**)&_objectArrayKlassObj);
-
-#if INCLUDE_CDS_JAVA_HEAP
-  DEBUG_ONLY(if (DumpSharedSpaces && !HeapShared::is_heap_object_archiving_allowed()) {
-      PRIMITIVE_MIRRORS_DO(ASSERT_MIRROR_NULL);
-    });
-  PRIMITIVE_MIRRORS_DO(SERIALIZE_MIRROR);
-#endif
-
   f->do_ptr((void**)&_the_array_interfaces_array);
   f->do_ptr((void**)&_the_empty_int_array);
   f->do_ptr((void**)&_the_empty_short_array);
   f->do_ptr((void**)&_the_empty_method_array);
   f->do_ptr((void**)&_the_empty_klass_array);

@@ -281,10 +306,11 @@
   _throw_illegal_access_error_cache->serialize(f);
   _throw_no_such_method_error_cache->serialize(f);
   _do_stack_walk_cache->serialize(f);
 }
 
+
 void Universe::check_alignment(uintx size, uintx alignment, const char* name) {
   if (size < alignment || size % alignment != 0) {
     vm_exit_during_initialization(
       err_msg("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment));
   }

@@ -439,48 +465,32 @@
 
 void Universe::initialize_basic_type_mirrors(TRAPS) {
 #if INCLUDE_CDS_JAVA_HEAP
     if (UseSharedSpaces &&
         HeapShared::open_archive_heap_region_mapped() &&
-        _int_mirror != NULL) {
+        _mirrors[T_INT].resolve() != NULL) {
       assert(HeapShared::is_heap_object_archiving_allowed(), "Sanity");
-      PRIMITIVE_MIRRORS_DO(ASSERT_MIRROR_NOT_NULL);
+
+      // check that all mirrors are mapped also
+      for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
+        if (!is_reference_type((BasicType)i)) {
+          oop m = _mirrors[i].resolve();
+          assert(m != NULL, "archived mirrors should not be NULL");
+        }
+      }
     } else
-      // _int_mirror could be NULL if archived heap is not mapped.
+      // _mirror[T_INT} could be NULL if archived heap is not mapped.
 #endif
     {
-      _int_mirror     =
-        java_lang_Class::create_basic_type_mirror("int",    T_INT, CHECK);
-      _float_mirror   =
-        java_lang_Class::create_basic_type_mirror("float",  T_FLOAT,   CHECK);
-      _double_mirror  =
-        java_lang_Class::create_basic_type_mirror("double", T_DOUBLE,  CHECK);
-      _byte_mirror    =
-        java_lang_Class::create_basic_type_mirror("byte",   T_BYTE, CHECK);
-      _bool_mirror    =
-        java_lang_Class::create_basic_type_mirror("boolean",T_BOOLEAN, CHECK);
-      _char_mirror    =
-        java_lang_Class::create_basic_type_mirror("char",   T_CHAR, CHECK);
-      _long_mirror    =
-        java_lang_Class::create_basic_type_mirror("long",   T_LONG, CHECK);
-      _short_mirror   =
-        java_lang_Class::create_basic_type_mirror("short",  T_SHORT,   CHECK);
-      _void_mirror    =
-        java_lang_Class::create_basic_type_mirror("void",   T_VOID, CHECK);
-    }
-
-    _mirrors[T_INT]     = _int_mirror;
-    _mirrors[T_FLOAT]   = _float_mirror;
-    _mirrors[T_DOUBLE]  = _double_mirror;
-    _mirrors[T_BYTE]    = _byte_mirror;
-    _mirrors[T_BOOLEAN] = _bool_mirror;
-    _mirrors[T_CHAR]    = _char_mirror;
-    _mirrors[T_LONG]    = _long_mirror;
-    _mirrors[T_SHORT]   = _short_mirror;
-    _mirrors[T_VOID]    = _void_mirror;
-  //_mirrors[T_OBJECT]  = _object_klass->java_mirror();
-  //_mirrors[T_ARRAY]   = _object_klass->java_mirror();
+      for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
+        BasicType bt = (BasicType)i;
+        if (!is_reference_type(bt)) {
+          oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, CHECK);
+          _mirrors[i] = OopHandle(vm_global(), m);
+        }
+      }
+    }
 }
 
 void Universe::fixup_mirrors(TRAPS) {
   // Bootstrap problem: all classes gets a mirror (java.lang.Class instance) assigned eagerly,
   // but we cannot do that for classes created before java.lang.Class is loaded. Here we simply
< prev index next >