8194741: Refactor oops in constant pool from CDS to use the Access API
Reviewed-by: coleenp, jiangli
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp Wed Jan 10 22:43:42 2018 +0100
@@ -54,7 +54,7 @@
// pre-marking object graph.
static void enqueue(oop pre_val);
- static void enqueue_if_weak(DecoratorSet decorators, oop value);
+ static void enqueue_if_weak_or_archive(DecoratorSet decorators, oop value);
template <class T> void write_ref_array_pre_work(T* dst, int count);
virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized);
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp Wed Jan 10 22:43:42 2018 +0100
@@ -60,12 +60,17 @@
_byte_map[card_index] = val;
}
-inline void G1SATBCardTableModRefBS::enqueue_if_weak(DecoratorSet decorators, oop value) {
+inline void G1SATBCardTableModRefBS::enqueue_if_weak_or_archive(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;
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);
- if (!peek && !on_strong_oop_ref && value != NULL) {
+ if (needs_enqueue && value != NULL) {
enqueue(value);
}
}
@@ -75,7 +80,7 @@
inline oop G1SATBCardTableLoggingModRefBS::AccessBarrier<decorators, BarrierSetT>::
oop_load_not_in_heap(T* addr) {
oop value = ModRef::oop_load_not_in_heap(addr);
- enqueue_if_weak(decorators, value);
+ enqueue_if_weak_or_archive(decorators, value);
return value;
}
@@ -84,7 +89,7 @@
inline oop G1SATBCardTableLoggingModRefBS::AccessBarrier<decorators, BarrierSetT>::
oop_load_in_heap(T* addr) {
oop value = ModRef::oop_load_in_heap(addr);
- enqueue_if_weak(decorators, value);
+ enqueue_if_weak_or_archive(decorators, value);
return value;
}
@@ -92,7 +97,7 @@
inline oop G1SATBCardTableLoggingModRefBS::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(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
+ enqueue_if_weak_or_archive(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
return value;
}
--- a/src/hotspot/share/oops/access.hpp Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/oops/access.hpp Wed Jan 10 22:43:42 2018 +0100
@@ -200,12 +200,14 @@
const DecoratorSet IN_HEAP_ARRAY = UCONST64(1) << 19;
const DecoratorSet IN_ROOT = UCONST64(1) << 20;
const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 21;
+const DecoratorSet IN_ARCHIVE_ROOT = UCONST64(1) << 22;
const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_HEAP_ARRAY |
- IN_ROOT | IN_CONCURRENT_ROOT;
+ IN_ROOT | IN_CONCURRENT_ROOT |
+ IN_ARCHIVE_ROOT;
// == Value Decorators ==
// * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
-const DecoratorSet OOP_NOT_NULL = UCONST64(1) << 22;
+const DecoratorSet OOP_NOT_NULL = UCONST64(1) << 23;
const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;
// == Arraycopy Decorators ==
--- a/src/hotspot/share/oops/access.inline.hpp Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/oops/access.inline.hpp Wed Jan 10 22:43:42 2018 +0100
@@ -788,7 +788,9 @@
((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 value = conc_root_is_root | BT_BUILDTIME_DECORATORS;
+ 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;
};
// Step 2: Reduce types.
@@ -1082,7 +1084,8 @@
(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_CONCURRENT_ROOT)) == 0 ||
+ (location_decorators ^ (IN_ROOT | IN_ARCHIVE_ROOT)) == 0
));
}
--- a/src/hotspot/share/oops/constantPool.cpp Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/oops/constantPool.cpp Wed Jan 10 22:43:42 2018 +0100
@@ -49,9 +49,6 @@
#include "runtime/signature.hpp"
#include "runtime/vframe.hpp"
#include "utilities/copy.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/g1/g1SATBCardTableModRefBS.hpp"
-#endif // INCLUDE_ALL_GCS
ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, TRAPS) {
Array<u1>* tags = MetadataFactory::new_array<u1>(loader_data, length, 0, CHECK_NULL);
@@ -330,17 +327,13 @@
if (SystemDictionary::Object_klass_loaded()) {
ClassLoaderData* loader_data = pool_holder()->class_loader_data();
#if INCLUDE_CDS_JAVA_HEAP
- if (MetaspaceShared::open_archive_heap_region_mapped() &&
- _cache->archived_references() != NULL) {
+ if (MetaspaceShared::open_archive_heap_region_mapped()) {
oop archived = _cache->archived_references();
- // Make sure GC knows the cached object is now live. This is necessary after
- // initial GC marking and during concurrent marking as strong roots are only
- // scanned during initial marking (at the start of the GC marking).
- assert(UseG1GC, "Requires G1 GC");
- G1SATBCardTableModRefBS::enqueue(archived);
- // Create handle for the archived resolved reference array object
- Handle refs_handle(THREAD, (oop)archived);
- set_resolved_references(loader_data->add_handle(refs_handle));
+ if (archived != NULL) {
+ // Create handle for the archived resolved reference array object
+ Handle refs_handle(THREAD, archived);
+ set_resolved_references(loader_data->add_handle(refs_handle));
+ }
} else
#endif
{
--- a/src/hotspot/share/oops/cpCache.cpp Fri Jan 12 16:19:56 2018 +0100
+++ b/src/hotspot/share/oops/cpCache.cpp Wed Jan 10 22:43:42 2018 +0100
@@ -33,6 +33,7 @@
#include "memory/metaspaceClosure.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
+#include "oops/access.inline.hpp"
#include "oops/cpCache.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
@@ -753,13 +754,16 @@
#if INCLUDE_CDS_JAVA_HEAP
oop ConstantPoolCache::archived_references() {
- assert(UseSharedSpaces, "UseSharedSpaces expected.");
- return oopDesc::decode_heap_oop(_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);
}
void ConstantPoolCache::set_archived_references(oop o) {
assert(DumpSharedSpaces, "called only during runtime");
- _archived_references = oopDesc::encode_heap_oop(o);
+ RootAccess<IN_ARCHIVE_ROOT>::oop_store(&_archived_references, o);
}
#endif