8204585: Remove IN_ARCHIVE_ROOT from Access API

Replaced Access API with API on heap.

Co-authored-by: Stefan Karlsson <stefan.karlsson@oracle.com>
Reviewed-by: jiangli, coleenp, tschatzl
This commit is contained in:
Kim Barrett 2018-06-12 18:12:59 -04:00
parent ea01772a00
commit df34500027
14 changed files with 71 additions and 59 deletions

View file

@ -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
@ -809,12 +808,8 @@ void java_lang_Class::fixup_mirror(Klass* k, TRAPS) {
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 @@ oop java_lang_Class::process_archived_mirror(Klass* k, oop mirror,
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 @@ void java_lang_Class::restore_archived_mirror(Klass *k, Handle mirror,
// - 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 @@ void java_lang_Class::restore_archived_mirror(Klass *k, Handle mirror,
ResourceMark rm;
log_trace(cds, mirror)("Restored %s archived mirror " PTR_FORMAT, k->external_name(), p2i(mirror()));
return true;
}
#endif // INCLUDE_CDS_JAVA_HEAP

View file

@ -229,8 +229,9 @@ class java_lang_Class : AllStatic {
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);

View file

@ -50,7 +50,7 @@ class G1BarrierSet: public CardTableBarrierSet {
// 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);

View file

@ -54,15 +54,14 @@ inline void G1BarrierSet::write_ref_field_post(T* field, oop new_val) {
}
}
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 @@ template <typename T>
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 @@ template <typename T>
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 @@ template <DecoratorSet decorators, typename BarrierSetT>
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;
}

View file

@ -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 @@ void G1CollectedHeap::dealloc_archive_regions(MemRegion* ranges, size_t count) {
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.

View file

@ -699,6 +699,8 @@ public:
// 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!).

View file

@ -45,7 +45,6 @@ ZBarrierSetAssembler* ZBarrierSet::assembler() {
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) {

View file

@ -1910,6 +1910,11 @@ oop MetaspaceShared::archive_heap_object(oop obj, Thread* THREAD) {
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 @@ public:
"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);
}
}

View file

@ -111,6 +111,7 @@ class MetaspaceShared : AllStatic {
}
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

View file

@ -379,8 +379,7 @@ void Access<decorators>::verify_decorators() {
(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
));
}

View file

@ -192,10 +192,8 @@ const DecoratorSet IN_HEAP = UCONST64(1) << 20;
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 @@ namespace AccessInternal {
((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 @@ namespace AccessInternal {
((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;
}
}

View file

@ -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 @@ void ConstantPoolCache::deallocate_contents(ClassLoaderData* data) {
#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

View file

@ -529,20 +529,19 @@ void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protec
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 @@ void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protec
#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");

View file

@ -244,7 +244,6 @@ protected:
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