8204585: Remove IN_ARCHIVE_ROOT from Access API
Summary: Replaced Access API with API on heap.
Reviewed-by: jiangli, coleenp, tschatzl
Contributed-by: stefan.karlsson@oracle.com, kim.barrett@oracle.com
--- a/src/hotspot/share/classfile/javaClasses.cpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/classfile/javaClasses.cpp Tue Jun 12 18:12:59 2018 -0400
@@ -63,7 +63,6 @@
#include "runtime/vframe.inline.hpp"
#include "utilities/align.hpp"
#include "utilities/preserveException.hpp"
-
#if INCLUDE_JVMCI
#include "jvmci/jvmciJavaClasses.hpp"
#endif
@@ -798,7 +797,7 @@
// During bootstrap, java.lang.Class wasn't loaded so static field
// offsets were computed without the size added it. Go back and
// update all the static field offsets to included the size.
- for (JavaFieldStream fs(InstanceKlass::cast(k)); !fs.done(); fs.next()) {
+ for (JavaFieldStream fs(InstanceKlass::cast(k)); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) {
int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
fs.set_offset(real_offset);
@@ -809,12 +808,8 @@
if (k->is_shared() && k->has_raw_archived_mirror()) {
if (MetaspaceShared::open_archive_heap_region_mapped()) {
- oop m = k->archived_java_mirror();
- assert(m != NULL, "archived mirror is NULL");
- assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
- Handle m_h(THREAD, m);
- // restore_archived_mirror() clears the klass' _has_raw_archived_mirror flag
- restore_archived_mirror(k, m_h, Handle(), Handle(), Handle(), CHECK);
+ bool present = restore_archived_mirror(k, Handle(), Handle(), Handle(), CHECK);
+ assert(present, "Missing archived mirror for %s", k->external_name());
return;
} else {
k->set_java_mirror_handle(NULL);
@@ -1207,11 +1202,23 @@
return archived_mirror;
}
-// After the archived mirror object is restored, the shared klass'
-// _has_raw_archived_mirror flag is cleared
-void java_lang_Class::restore_archived_mirror(Klass *k, Handle mirror,
+// Returns true if the mirror is updated, false if no archived mirror
+// data is present. After the archived mirror object is restored, the
+// shared klass' _has_raw_archived_mirror flag is cleared.
+bool java_lang_Class::restore_archived_mirror(Klass *k,
Handle class_loader, Handle module,
Handle protection_domain, TRAPS) {
+ oop m = MetaspaceShared::materialize_archived_object(k->archived_java_mirror_raw());
+
+ if (m == NULL) {
+ return false;
+ }
+
+ log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
+
+ // mirror is archived, restore
+ assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
+ Handle mirror(THREAD, m);
// The java.lang.Class field offsets were archived and reloaded from archive.
// No need to put classes on the fixup_mirror_list before java.lang.Class
@@ -1221,7 +1228,7 @@
// - local static final fields with initial values were initialized at dump time
// create the init_lock
- typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
+ typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_(false));
set_init_lock(mirror(), r);
if (protection_domain.not_null()) {
@@ -1241,6 +1248,8 @@
ResourceMark rm;
log_trace(cds, mirror)("Restored %s archived mirror " PTR_FORMAT, k->external_name(), p2i(mirror()));
+
+ return true;
}
#endif // INCLUDE_CDS_JAVA_HEAP
--- a/src/hotspot/share/classfile/javaClasses.hpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/classfile/javaClasses.hpp Tue Jun 12 18:12:59 2018 -0400
@@ -229,8 +229,9 @@
static oop archive_mirror(Klass* k, TRAPS) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
static oop process_archived_mirror(Klass* k, oop mirror, oop archived_mirror, Thread *THREAD)
NOT_CDS_JAVA_HEAP_RETURN_(NULL);
- static void restore_archived_mirror(Klass *k, Handle mirror, Handle class_loader, Handle module,
- Handle protection_domain, TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
+ static bool restore_archived_mirror(Klass *k, Handle class_loader, Handle module,
+ Handle protection_domain,
+ TRAPS) NOT_CDS_JAVA_HEAP_RETURN_(false);
static void fixup_module_field(Klass* k, Handle module);
--- a/src/hotspot/share/gc/g1/g1BarrierSet.hpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1BarrierSet.hpp Tue Jun 12 18:12:59 2018 -0400
@@ -50,7 +50,7 @@
// pre-marking object graph.
static void enqueue(oop pre_val);
- static void enqueue_if_weak_or_archive(DecoratorSet decorators, oop value);
+ static void enqueue_if_weak(DecoratorSet decorators, oop value);
template <class T> void write_ref_array_pre_work(T* dst, size_t count);
virtual void write_ref_array_pre(oop* dst, size_t count, bool dest_uninitialized);
--- a/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp Tue Jun 12 18:12:59 2018 -0400
@@ -54,15 +54,14 @@
}
}
-inline void G1BarrierSet::enqueue_if_weak_or_archive(DecoratorSet decorators, oop value) {
+inline void G1BarrierSet::enqueue_if_weak(DecoratorSet decorators, oop value) {
assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known");
- // Archive roots need to be enqueued since they add subgraphs to the
- // Java heap that were not there at the snapshot when marking started.
- // Weak and phantom references also need enqueueing for similar reasons.
- const bool in_archive_root = (decorators & IN_ARCHIVE_ROOT) != 0;
+ // Loading from a weak or phantom reference needs enqueueing, as
+ // the object may not have been reachable (part of the snapshot)
+ // when marking started.
const bool on_strong_oop_ref = (decorators & ON_STRONG_OOP_REF) != 0;
const bool peek = (decorators & AS_NO_KEEPALIVE) != 0;
- const bool needs_enqueue = in_archive_root || (!peek && !on_strong_oop_ref);
+ const bool needs_enqueue = (!peek && !on_strong_oop_ref);
if (needs_enqueue && value != NULL) {
enqueue(value);
@@ -74,7 +73,7 @@
inline oop G1BarrierSet::AccessBarrier<decorators, BarrierSetT>::
oop_load_not_in_heap(T* addr) {
oop value = ModRef::oop_load_not_in_heap(addr);
- enqueue_if_weak_or_archive(decorators, value);
+ enqueue_if_weak(decorators, value);
return value;
}
@@ -83,7 +82,7 @@
inline oop G1BarrierSet::AccessBarrier<decorators, BarrierSetT>::
oop_load_in_heap(T* addr) {
oop value = ModRef::oop_load_in_heap(addr);
- enqueue_if_weak_or_archive(decorators, value);
+ enqueue_if_weak(decorators, value);
return value;
}
@@ -91,7 +90,7 @@
inline oop G1BarrierSet::AccessBarrier<decorators, BarrierSetT>::
oop_load_in_heap_at(oop base, ptrdiff_t offset) {
oop value = ModRef::oop_load_in_heap_at(base, offset);
- enqueue_if_weak_or_archive(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
+ enqueue_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
return value;
}
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Tue Jun 12 18:12:59 2018 -0400
@@ -78,6 +78,7 @@
#include "logging/log.hpp"
#include "memory/allocation.hpp"
#include "memory/iterator.hpp"
+#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "oops/access.inline.hpp"
#include "oops/compressedOops.inline.hpp"
@@ -823,6 +824,18 @@
decrease_used(size_used);
}
+oop G1CollectedHeap::materialize_archived_object(oop obj) {
+ assert(obj != NULL, "archived obj is NULL");
+ assert(MetaspaceShared::is_archive_object(obj), "must be archived object");
+
+ // Loading an archived object makes it strongly reachable. If it is
+ // loaded during concurrent marking, it must be enqueued to the SATB
+ // queue, shading the previously white object gray.
+ G1BarrierSet::enqueue(obj);
+
+ return obj;
+}
+
HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size) {
ResourceMark rm; // For retrieving the thread names in log messages.
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Tue Jun 12 18:12:59 2018 -0400
@@ -699,6 +699,8 @@
// mapping failed, with the same non-overlapping and sorted MemRegion array.
void dealloc_archive_regions(MemRegion* range, size_t count);
+ oop materialize_archived_object(oop obj);
+
private:
// Shrink the garbage-first heap by at most the given size (in bytes!).
--- a/src/hotspot/share/gc/z/zBarrierSet.cpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/gc/z/zBarrierSet.cpp Tue Jun 12 18:12:59 2018 -0400
@@ -45,7 +45,6 @@
bool ZBarrierSet::barrier_needed(DecoratorSet decorators, BasicType type) {
assert((decorators & AS_RAW) == 0, "Unexpected decorator");
assert((decorators & AS_NO_KEEPALIVE) == 0, "Unexpected decorator");
- assert((decorators & IN_ARCHIVE_ROOT) == 0, "Unexpected decorator");
//assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Unexpected decorator");
if (type == T_OBJECT || type == T_ARRAY) {
--- a/src/hotspot/share/memory/metaspaceShared.cpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/memory/metaspaceShared.cpp Tue Jun 12 18:12:59 2018 -0400
@@ -1910,6 +1910,11 @@
return archived_oop;
}
+oop MetaspaceShared::materialize_archived_object(oop obj) {
+ assert(obj != NULL, "sanity");
+ return G1CollectedHeap::heap()->materialize_archived_object(obj);
+}
+
void MetaspaceShared::archive_klass_objects(Thread* THREAD) {
int i;
for (i = 0; i < _global_klass_objects->length(); i++) {
@@ -1980,7 +1985,7 @@
"Archived heap object is not allowed");
assert(MetaspaceShared::open_archive_heap_region_mapped(),
"Open archive heap region is not mapped");
- RootAccess<IN_ARCHIVE_ROOT>::oop_store(p, CompressedOops::decode_not_null(o));
+ *p = CompressedOops::decode_not_null(o);
}
}
--- a/src/hotspot/share/memory/metaspaceShared.hpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/memory/metaspaceShared.hpp Tue Jun 12 18:12:59 2018 -0400
@@ -111,6 +111,7 @@
}
static oop find_archived_heap_object(oop obj);
static oop archive_heap_object(oop obj, Thread* THREAD);
+ static oop materialize_archived_object(oop obj);
static void archive_klass_objects(Thread* THREAD);
#endif
--- a/src/hotspot/share/oops/access.hpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/oops/access.hpp Tue Jun 12 18:12:59 2018 -0400
@@ -379,8 +379,7 @@
(location_decorators ^ IN_ROOT) == 0 ||
(location_decorators ^ IN_HEAP) == 0 ||
(location_decorators ^ (IN_HEAP | IN_HEAP_ARRAY)) == 0 ||
- (location_decorators ^ (IN_ROOT | IN_CONCURRENT_ROOT)) == 0 ||
- (location_decorators ^ (IN_ROOT | IN_ARCHIVE_ROOT)) == 0
+ (location_decorators ^ (IN_ROOT | IN_CONCURRENT_ROOT)) == 0
));
}
--- a/src/hotspot/share/oops/accessDecorators.hpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/oops/accessDecorators.hpp Tue Jun 12 18:12:59 2018 -0400
@@ -192,10 +192,8 @@
const DecoratorSet IN_HEAP_ARRAY = UCONST64(1) << 21;
const DecoratorSet IN_ROOT = UCONST64(1) << 22;
const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 23;
-const DecoratorSet IN_ARCHIVE_ROOT = UCONST64(1) << 24;
const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_HEAP_ARRAY |
- IN_ROOT | IN_CONCURRENT_ROOT |
- IN_ARCHIVE_ROOT;
+ IN_ROOT | IN_CONCURRENT_ROOT;
// == Value Decorators ==
// * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
@@ -245,9 +243,7 @@
((IN_HEAP_ARRAY & barrier_strength_default) != 0 ? IN_HEAP : INTERNAL_EMPTY);
static const DecoratorSet conc_root_is_root = heap_array_is_in_heap |
((IN_CONCURRENT_ROOT & heap_array_is_in_heap) != 0 ? IN_ROOT : INTERNAL_EMPTY);
- static const DecoratorSet archive_root_is_root = conc_root_is_root |
- ((IN_ARCHIVE_ROOT & conc_root_is_root) != 0 ? IN_ROOT : INTERNAL_EMPTY);
- static const DecoratorSet value = archive_root_is_root | BT_BUILDTIME_DECORATORS;
+ static const DecoratorSet value = conc_root_is_root | BT_BUILDTIME_DECORATORS;
};
// This function implements the above DecoratorFixup rules, but without meta
@@ -268,9 +264,7 @@
((IN_HEAP_ARRAY & barrier_strength_default) != 0 ? IN_HEAP : INTERNAL_EMPTY);
DecoratorSet conc_root_is_root = heap_array_is_in_heap |
((IN_CONCURRENT_ROOT & heap_array_is_in_heap) != 0 ? IN_ROOT : INTERNAL_EMPTY);
- DecoratorSet archive_root_is_root = conc_root_is_root |
- ((IN_ARCHIVE_ROOT & conc_root_is_root) != 0 ? IN_ROOT : INTERNAL_EMPTY);
- DecoratorSet value = archive_root_is_root | BT_BUILDTIME_DECORATORS;
+ DecoratorSet value = conc_root_is_root | BT_BUILDTIME_DECORATORS;
return value;
}
}
--- a/src/hotspot/share/oops/cpCache.cpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/oops/cpCache.cpp Tue Jun 12 18:12:59 2018 -0400
@@ -32,6 +32,7 @@
#include "logging/log.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/metaspaceClosure.hpp"
+#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/access.inline.hpp"
@@ -743,16 +744,15 @@
#if INCLUDE_CDS_JAVA_HEAP
oop ConstantPoolCache::archived_references() {
- // Loading an archive root forces the oop to become strongly reachable.
- // For example, if it is loaded during concurrent marking in a SATB
- // collector, it will be enqueued to the SATB queue, effectively
- // shading the previously white object gray.
- return RootAccess<IN_ARCHIVE_ROOT>::oop_load(&_archived_references);
+ if (CompressedOops::is_null(_archived_references)) {
+ return NULL;
+ }
+ return MetaspaceShared::materialize_archived_object(CompressedOops::decode_not_null(_archived_references));
}
void ConstantPoolCache::set_archived_references(oop o) {
assert(DumpSharedSpaces, "called only during runtime");
- RootAccess<IN_ARCHIVE_ROOT>::oop_store(&_archived_references, o);
+ _archived_references = CompressedOops::encode(o);
}
#endif
--- a/src/hotspot/share/oops/klass.cpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/oops/klass.cpp Tue Jun 12 18:12:59 2018 -0400
@@ -529,20 +529,19 @@
Handle module_handle(THREAD, ((module_entry != NULL) ? module_entry->module() : (oop)NULL));
if (this->has_raw_archived_mirror()) {
+ ResourceMark rm;
log_debug(cds, mirror)("%s has raw archived mirror", external_name());
if (MetaspaceShared::open_archive_heap_region_mapped()) {
- oop m = archived_java_mirror();
- log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
- if (m != NULL) {
- // mirror is archived, restore
- assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
- Handle m_h(THREAD, m);
- java_lang_Class::restore_archived_mirror(this, m_h, loader, module_handle, protection_domain, CHECK);
+ bool present = java_lang_Class::restore_archived_mirror(this, loader, module_handle,
+ protection_domain,
+ CHECK);
+ if (present) {
return;
}
}
// No archived mirror data
+ log_debug(cds, mirror)("No archived mirror data for %s", external_name());
_java_mirror = NULL;
this->clear_has_raw_archived_mirror();
}
@@ -558,18 +557,10 @@
#if INCLUDE_CDS_JAVA_HEAP
// Used at CDS dump time to access the archived mirror. No GC barrier.
oop Klass::archived_java_mirror_raw() {
- assert(DumpSharedSpaces, "called only during runtime");
assert(has_raw_archived_mirror(), "must have raw archived mirror");
return CompressedOops::decode(_archived_mirror);
}
-// Used at CDS runtime to get the archived mirror from shared class. Uses GC barrier.
-oop Klass::archived_java_mirror() {
- assert(UseSharedSpaces, "UseSharedSpaces expected.");
- assert(has_raw_archived_mirror(), "must have raw archived mirror");
- return RootAccess<IN_ARCHIVE_ROOT>::oop_load(&_archived_mirror);
-}
-
// No GC barrier
void Klass::set_archived_java_mirror_raw(oop m) {
assert(DumpSharedSpaces, "called only during runtime");
--- a/src/hotspot/share/oops/klass.hpp Tue Jun 12 14:08:24 2018 -0700
+++ b/src/hotspot/share/oops/klass.hpp Tue Jun 12 18:12:59 2018 -0400
@@ -244,7 +244,6 @@
void set_java_mirror(Handle m);
oop archived_java_mirror_raw() NOT_CDS_JAVA_HEAP_RETURN_(NULL); // no GC barrier
- oop archived_java_mirror() NOT_CDS_JAVA_HEAP_RETURN_(NULL); // accessor with GC barrier
void set_archived_java_mirror_raw(oop m) NOT_CDS_JAVA_HEAP_RETURN; // no GC barrier
// Temporary mirror switch used by RedefineClasses