hotspot/src/share/vm/memory/universe.cpp
changeset 46819 780e16a64a50
parent 46116 94a8161e3509
parent 46810 7dad333205cd
child 47106 bed18a111b90
--- a/hotspot/src/share/vm/memory/universe.cpp	Thu Aug 24 16:37:10 2017 +0200
+++ b/hotspot/src/share/vm/memory/universe.cpp	Wed Aug 16 21:47:17 2017 +0200
@@ -41,8 +41,10 @@
 #include "gc/shared/space.hpp"
 #include "interpreter/interpreter.hpp"
 #include "logging/log.hpp"
+#include "logging/logStream.hpp"
 #include "memory/filemap.hpp"
 #include "memory/metadataFactory.hpp"
+#include "memory/metaspaceClosure.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
@@ -56,6 +58,7 @@
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayKlass.hpp"
+#include "prims/resolvedMethodTable.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/commandLineFlagConstraintList.hpp"
@@ -71,8 +74,11 @@
 #include "runtime/timerTrace.hpp"
 #include "runtime/vm_operations.hpp"
 #include "services/memoryService.hpp"
+#include "utilities/align.hpp"
 #include "utilities/copy.hpp"
+#include "utilities/debug.hpp"
 #include "utilities/events.hpp"
+#include "utilities/formatBuffer.hpp"
 #include "utilities/hashtable.inline.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
@@ -218,6 +224,37 @@
   debug_only(f->do_oop((oop*)&_fullgc_alot_dummy_array);)
 }
 
+void LatestMethodCache::metaspace_pointers_do(MetaspaceClosure* it) {
+  it->push(&_klass);
+}
+
+void Universe::metaspace_pointers_do(MetaspaceClosure* it) {
+  it->push(&_boolArrayKlassObj);
+  it->push(&_byteArrayKlassObj);
+  it->push(&_charArrayKlassObj);
+  it->push(&_intArrayKlassObj);
+  it->push(&_shortArrayKlassObj);
+  it->push(&_longArrayKlassObj);
+  it->push(&_singleArrayKlassObj);
+  it->push(&_doubleArrayKlassObj);
+  for (int i = 0; i < T_VOID+1; i++) {
+    it->push(&_typeArrayKlassObjs[i]);
+  }
+  it->push(&_objectArrayKlassObj);
+
+  it->push(&_the_empty_int_array);
+  it->push(&_the_empty_short_array);
+  it->push(&_the_empty_klass_array);
+  it->push(&_the_empty_method_array);
+  it->push(&_the_array_interfaces_array);
+
+  _finalizer_register_cache->metaspace_pointers_do(it);
+  _loader_addClass_cache->metaspace_pointers_do(it);
+  _pd_implies_cache->metaspace_pointers_do(it);
+  _throw_illegal_access_error_cache->metaspace_pointers_do(it);
+  _do_stack_walk_cache->metaspace_pointers_do(it);
+}
+
 // Serialize metadata in and out of CDS archive, not oops.
 void Universe::serialize(SerializeClosure* f, bool do_all) {
 
@@ -263,11 +300,14 @@
 
 void initialize_basic_type_klass(Klass* k, TRAPS) {
   Klass* ok = SystemDictionary::Object_klass();
+#if INCLUDE_CDS
   if (UseSharedSpaces) {
     ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
     assert(k->super() == ok, "u3");
     k->restore_unshareable_info(loader_data, Handle(), CHECK);
-  } else {
+  } else
+#endif
+  {
     k->initialize_supers(ok, CHECK);
   }
   k->append_to_sibling_list();
@@ -280,6 +320,8 @@
 
     { MutexLocker mc(Compile_lock);
 
+      java_lang_Class::allocate_fixup_lists();
+
       // determine base vtable size; without that we cannot create the array klasses
       compute_base_vtable_size();
 
@@ -321,14 +363,17 @@
     _the_null_string            = StringTable::intern("null", CHECK);
     _the_min_jint_string       = StringTable::intern("-2147483648", CHECK);
 
+#if INCLUDE_CDS
     if (UseSharedSpaces) {
       // Verify shared interfaces array.
       assert(_the_array_interfaces_array->at(0) ==
              SystemDictionary::Cloneable_klass(), "u3");
       assert(_the_array_interfaces_array->at(1) ==
              SystemDictionary::Serializable_klass(), "u3");
-      MetaspaceShared::fixup_shared_string_regions();
-    } else {
+      MetaspaceShared::fixup_mapped_heap_regions();
+    } else
+#endif
+    {
       // Set up shared interfaces array.  (Do this before supers are set up.)
       _the_array_interfaces_array->at_put(0, SystemDictionary::Cloneable_klass());
       _the_array_interfaces_array->at_put(1, SystemDictionary::Serializable_klass());
@@ -410,30 +455,6 @@
 
 }
 
-// CDS support for patching vtables in metadata in the shared archive.
-// All types inherited from Metadata have vtables, but not types inherited
-// from MetaspaceObj, because the latter does not have virtual functions.
-// If the metadata type has a vtable, it cannot be shared in the read-only
-// section of the CDS archive, because the vtable pointer is patched.
-static inline void add_vtable(void** list, int* n, void* o, int count) {
-  guarantee((*n) < count, "vtable list too small");
-  void* vtable = dereference_vptr(o);
-  assert(*(void**)(vtable) != NULL, "invalid vtable");
-  list[(*n)++] = vtable;
-}
-
-void Universe::init_self_patching_vtbl_list(void** list, int count) {
-  int n = 0;
-  { InstanceKlass o;          add_vtable(list, &n, &o, count); }
-  { InstanceClassLoaderKlass o; add_vtable(list, &n, &o, count); }
-  { InstanceMirrorKlass o;    add_vtable(list, &n, &o, count); }
-  { InstanceRefKlass o;       add_vtable(list, &n, &o, count); }
-  { TypeArrayKlass o;         add_vtable(list, &n, &o, count); }
-  { ObjArrayKlass o;          add_vtable(list, &n, &o, count); }
-  { Method o;                 add_vtable(list, &n, &o, count); }
-  { ConstantPool o;           add_vtable(list, &n, &o, count); }
-}
-
 void Universe::initialize_basic_type_mirrors(TRAPS) {
     assert(_int_mirror==NULL, "basic type mirrors already initialized");
     _int_mirror     =
@@ -484,9 +505,8 @@
     Klass* k = list->at(i);
     assert(k->is_klass(), "List should only hold classes");
     EXCEPTION_MARK;
-    KlassHandle kh(THREAD, k);
-    java_lang_Class::fixup_mirror(kh, CATCH);
-}
+    java_lang_Class::fixup_mirror(k, CATCH);
+  }
   delete java_lang_Class::fixup_mirror_list();
   java_lang_Class::set_fixup_mirror_list(NULL);
 }
@@ -534,7 +554,7 @@
   log_trace(ref)("Callback to run finalizers on exit");
   {
     PRESERVE_EXCEPTION_MARK;
-    KlassHandle finalizer_klass(THREAD, SystemDictionary::Finalizer_klass());
+    Klass* finalizer_klass = SystemDictionary::Finalizer_klass();
     JavaValue result(T_VOID);
     JavaCalls::call_static(
       &result,
@@ -553,34 +573,31 @@
 // 1) we specified true to initialize_vtable and
 // 2) this ran after gc was enabled
 // In case those ever change we use handles for oops
-void Universe::reinitialize_vtable_of(KlassHandle k_h, TRAPS) {
+void Universe::reinitialize_vtable_of(Klass* ko, TRAPS) {
   // init vtable of k and all subclasses
-  Klass* ko = k_h();
-  klassVtable* vt = ko->vtable();
-  if (vt) vt->initialize_vtable(false, CHECK);
+  ko->vtable().initialize_vtable(false, CHECK);
   if (ko->is_instance_klass()) {
-    for (KlassHandle s_h(THREAD, ko->subklass());
-         s_h() != NULL;
-         s_h = KlassHandle(THREAD, s_h()->next_sibling())) {
-      reinitialize_vtable_of(s_h, CHECK);
+    for (Klass* sk = ko->subklass();
+         sk != NULL;
+         sk = sk->next_sibling()) {
+      reinitialize_vtable_of(sk, CHECK);
     }
   }
 }
 
 
-void initialize_itable_for_klass(Klass* k, TRAPS) {
-  InstanceKlass::cast(k)->itable()->initialize_itable(false, CHECK);
+void initialize_itable_for_klass(InstanceKlass* k, TRAPS) {
+  k->itable().initialize_itable(false, CHECK);
 }
 
 
 void Universe::reinitialize_itables(TRAPS) {
-  SystemDictionary::classes_do(initialize_itable_for_klass, CHECK);
-
+  ClassLoaderDataGraph::dictionary_classes_do(initialize_itable_for_klass, CHECK);
 }
 
 
 bool Universe::on_page_boundary(void* addr) {
-  return ((uintptr_t) addr) % os::vm_page_size() == 0;
+  return is_aligned(addr, os::vm_page_size());
 }
 
 
@@ -619,20 +636,22 @@
     // return default
     return default_err;
   } else {
+    Thread* THREAD = Thread::current();
+    Handle default_err_h(THREAD, default_err);
     // get the error object at the slot and set set it to NULL so that the
     // array isn't keeping it alive anymore.
-    oop exc = preallocated_out_of_memory_errors()->obj_at(next);
-    assert(exc != NULL, "slot has been used already");
+    Handle exc(THREAD, preallocated_out_of_memory_errors()->obj_at(next));
+    assert(exc() != NULL, "slot has been used already");
     preallocated_out_of_memory_errors()->obj_at_put(next, NULL);
 
     // use the message from the default error
-    oop msg = java_lang_Throwable::message(default_err);
+    oop msg = java_lang_Throwable::message(default_err_h());
     assert(msg != NULL, "no message");
-    java_lang_Throwable::set_message(exc, msg);
+    java_lang_Throwable::set_message(exc(), msg);
 
     // populate the stack trace and return it.
     java_lang_Throwable::fill_in_stack_trace_of_preallocated_backtrace(exc);
-    return exc;
+    return exc();
   }
 }
 
@@ -695,6 +714,7 @@
   Universe::_throw_illegal_access_error_cache = new LatestMethodCache();
   Universe::_do_stack_walk_cache = new LatestMethodCache();
 
+#if INCLUDE_CDS
   if (UseSharedSpaces) {
     // Read the data structures supporting the shared spaces (shared
     // system dictionary, symbol table, etc.).  After that, access to
@@ -703,18 +723,24 @@
     // currently mapped regions.
     MetaspaceShared::initialize_shared_spaces();
     StringTable::create_table();
-  } else {
+  } else
+#endif
+  {
     SymbolTable::create_table();
     StringTable::create_table();
 
+#if INCLUDE_CDS
     if (DumpSharedSpaces) {
       MetaspaceShared::prepare_for_dumping();
     }
+#endif
   }
   if (strlen(VerifySubSet) > 0) {
     Universe::initialize_verify_flags();
   }
 
+  ResolvedMethodTable::create_table();
+
   return JNI_OK;
 }
 
@@ -786,10 +812,11 @@
 
     Universe::set_narrow_ptrs_base(Universe::narrow_oop_base());
 
-    if (log_is_enabled(Info, gc, heap, coops)) {
+    LogTarget(Info, gc, heap, coops) lt;
+    if (lt.is_enabled()) {
       ResourceMark rm;
-      outputStream* logst = Log(gc, heap, coops)::info_stream();
-      Universe::print_compressed_oops_mode(logst);
+      LogStream ls(lt);
+      Universe::print_compressed_oops_mode(&ls);
     }
 
     // Tell tests in which mode we run.
@@ -842,11 +869,11 @@
          "actual alignment " SIZE_FORMAT " must be within maximum heap alignment " SIZE_FORMAT,
          alignment, Arguments::conservative_max_heap_alignment());
 
-  size_t total_reserved = align_size_up(heap_size, alignment);
+  size_t total_reserved = align_up(heap_size, alignment);
   assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
       "heap size is too big for compressed oops");
 
-  bool use_large_pages = UseLargePages && is_size_aligned(alignment, os::large_page_size());
+  bool use_large_pages = UseLargePages && is_aligned(alignment, os::large_page_size());
   assert(!UseLargePages
       || UseParallelGC
       || use_large_pages, "Wrong alignment to use large pages");
@@ -897,10 +924,10 @@
       return "Non-zero disjoint base";
     case HeapBasedNarrowOop:
       return "Non-zero based";
+    default:
+      ShouldNotReachHere();
+      return "";
   }
-
-  ShouldNotReachHere();
-  return "";
 }
 
 
@@ -990,28 +1017,26 @@
     Interpreter::initialize();      // needed for interpreter entry points
     if (!UseSharedSpaces) {
       HandleMark hm(THREAD);
-      KlassHandle ok_h(THREAD, SystemDictionary::Object_klass());
-      Universe::reinitialize_vtable_of(ok_h, CHECK_false);
+      Klass* ok = SystemDictionary::Object_klass();
+      Universe::reinitialize_vtable_of(ok, CHECK_false);
       Universe::reinitialize_itables(CHECK_false);
     }
   }
 
   HandleMark hm(THREAD);
-  Klass* k;
-  instanceKlassHandle k_h;
   // Setup preallocated empty java.lang.Class array
   Universe::_the_empty_class_klass_array = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_false);
 
   // Setup preallocated OutOfMemoryError errors
-  k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_OutOfMemoryError(), true, CHECK_false);
-  k_h = instanceKlassHandle(THREAD, k);
-  Universe::_out_of_memory_error_java_heap = k_h->allocate_instance(CHECK_false);
-  Universe::_out_of_memory_error_metaspace = k_h->allocate_instance(CHECK_false);
-  Universe::_out_of_memory_error_class_metaspace = k_h->allocate_instance(CHECK_false);
-  Universe::_out_of_memory_error_array_size = k_h->allocate_instance(CHECK_false);
+  Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_OutOfMemoryError(), true, CHECK_false);
+  InstanceKlass* ik = InstanceKlass::cast(k);
+  Universe::_out_of_memory_error_java_heap = ik->allocate_instance(CHECK_false);
+  Universe::_out_of_memory_error_metaspace = ik->allocate_instance(CHECK_false);
+  Universe::_out_of_memory_error_class_metaspace = ik->allocate_instance(CHECK_false);
+  Universe::_out_of_memory_error_array_size = ik->allocate_instance(CHECK_false);
   Universe::_out_of_memory_error_gc_overhead_limit =
-    k_h->allocate_instance(CHECK_false);
-  Universe::_out_of_memory_error_realloc_objects = k_h->allocate_instance(CHECK_false);
+    ik->allocate_instance(CHECK_false);
+  Universe::_out_of_memory_error_realloc_objects = ik->allocate_instance(CHECK_false);
 
   // Setup preallocated cause message for delayed StackOverflowError
   if (StackReservedPages > 0) {
@@ -1032,8 +1057,8 @@
     vmSymbols::java_lang_VirtualMachineError(), true, CHECK_false);
   bool linked = InstanceKlass::cast(k)->link_class_or_fail(CHECK_false);
   if (!linked) {
-    tty->print_cr("Unable to link/verify VirtualMachineError class");
-    return false; // initialization failed
+     tty->print_cr("Unable to link/verify VirtualMachineError class");
+     return false; // initialization failed
   }
   Universe::_virtual_machine_error_instance =
     InstanceKlass::cast(k)->allocate_instance(CHECK_false);
@@ -1066,12 +1091,12 @@
     // Setup the array of errors that have preallocated backtrace
     k = Universe::_out_of_memory_error_java_heap->klass();
     assert(k->name() == vmSymbols::java_lang_OutOfMemoryError(), "should be out of memory error");
-    k_h = instanceKlassHandle(THREAD, k);
+    ik = InstanceKlass::cast(k);
 
     int len = (StackTraceInThrowable) ? (int)PreallocatedOutOfMemoryErrorCount : 0;
-    Universe::_preallocated_out_of_memory_error_array = oopFactory::new_objArray(k_h(), len, CHECK_false);
+    Universe::_preallocated_out_of_memory_error_array = oopFactory::new_objArray(ik, len, CHECK_false);
     for (int i=0; i<len; i++) {
-      oop err = k_h->allocate_instance(CHECK_false);
+      oop err = ik->allocate_instance(CHECK_false);
       Handle err_h = Handle(THREAD, err);
       java_lang_Throwable::allocate_backtrace(err_h, CHECK_false);
       Universe::preallocated_out_of_memory_errors()->obj_at_put(i, err_h());
@@ -1124,20 +1149,22 @@
 }
 
 void Universe::print_heap_before_gc() {
-  Log(gc, heap) log;
-  if (log.is_debug()) {
-    log.debug("Heap before GC invocations=%u (full %u):", heap()->total_collections(), heap()->total_full_collections());
+  LogTarget(Debug, gc, heap) lt;
+  if (lt.is_enabled()) {
+    LogStream ls(lt);
+    ls.print("Heap before GC invocations=%u (full %u):", heap()->total_collections(), heap()->total_full_collections());
     ResourceMark rm;
-    heap()->print_on(log.debug_stream());
+    heap()->print_on(&ls);
   }
 }
 
 void Universe::print_heap_after_gc() {
-  Log(gc, heap) log;
-  if (log.is_debug()) {
-    log.debug("Heap after GC invocations=%u (full %u):", heap()->total_collections(), heap()->total_full_collections());
+  LogTarget(Debug, gc, heap) lt;
+  if (lt.is_enabled()) {
+    LogStream ls(lt);
+    ls.print("Heap after GC invocations=%u (full %u):", heap()->total_collections(), heap()->total_full_collections());
     ResourceMark rm;
-    heap()->print_on(log.debug_stream());
+    heap()->print_on(&ls);
   }
 }