8186777: Make Klass::_java_mirror an OopHandle
Summary: Add indirection for fetching mirror so that GC doesn't have to follow CLD::_klasses
Reviewed-by: hseigel, thartmann, eosterlund, stefank
Contributed-by: coleen.phillimore@oracle.com, rickard.backman@oracle.com
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -3291,6 +3291,7 @@
ldr(dst, Address(dst, ConstMethod::constants_offset()));
ldr(dst, Address(dst, ConstantPool::pool_holder_offset_in_bytes()));
ldr(dst, Address(dst, mirror_offset));
+ resolve_oop_handle(dst);
}
void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) {
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -2297,6 +2297,7 @@
ConstantPoolCacheEntry::f1_offset())));
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
__ ldr(obj, Address(obj, mirror_offset));
+ __ resolve_oop_handle(obj);
}
}
--- a/src/hotspot/cpu/arm/macroAssembler_arm.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -2899,6 +2899,7 @@
ldr(tmp, Address(tmp, ConstMethod::constants_offset()));
ldr(tmp, Address(tmp, ConstantPool::pool_holder_offset_in_bytes()));
ldr(mirror, Address(tmp, mirror_offset));
+ resolve_oop_handle(mirror);
}
--- a/src/hotspot/cpu/arm/templateTable_arm.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/arm/templateTable_arm.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -2963,6 +2963,7 @@
cp_base_offset + ConstantPoolCacheEntry::f1_offset()));
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
__ ldr(Robj, Address(Robj, mirror_offset));
+ __ resolve_oop_handle(Robj);
}
}
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -3382,6 +3382,7 @@
ld(mirror, in_bytes(ConstMethod::constants_offset()), const_method);
ld(mirror, ConstantPool::pool_holder_offset_in_bytes(), mirror);
ld(mirror, in_bytes(Klass::java_mirror_offset()), mirror);
+ resolve_oop_handle(mirror);
}
// Clear Array
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -2224,6 +2224,7 @@
if (is_static) {
__ ld(Robj, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::f1_offset()), Rcache);
__ ld(Robj, in_bytes(Klass::java_mirror_offset()), Robj);
+ __ resolve_oop_handle(Robj);
// Acquire not needed here. Following access has an address dependency on this value.
}
}
--- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -4671,6 +4671,7 @@
mem2reg_opt(mirror, Address(mirror, ConstMethod::constants_offset()));
mem2reg_opt(mirror, Address(mirror, ConstantPool::pool_holder_offset_in_bytes()));
mem2reg_opt(mirror, Address(mirror, Klass::java_mirror_offset()));
+ resolve_oop_handle(mirror);
}
//---------------------------------------------------------------
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -2382,6 +2382,7 @@
if (is_static) {
__ mem2reg_opt(obj, Address(cache, index, cp_base_offset + ConstantPoolCacheEntry::f1_offset()));
__ mem2reg_opt(obj, Address(obj, Klass::java_mirror_offset()));
+ __ resolve_oop_handle(obj);
}
}
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -3844,6 +3844,7 @@
ld_ptr(mirror, in_bytes(ConstMethod::constants_offset()), mirror);
ld_ptr(mirror, ConstantPool::pool_holder_offset_in_bytes(), mirror);
ld_ptr(mirror, mirror_offset, mirror);
+ resolve_oop_handle(mirror);
}
void MacroAssembler::load_klass(Register src_oop, Register klass) {
--- a/src/hotspot/cpu/sparc/templateTable_sparc.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/sparc/templateTable_sparc.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -2049,6 +2049,7 @@
__ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::f1_offset(), Robj);
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
__ ld_ptr( Robj, mirror_offset, Robj);
+ __ resolve_oop_handle(Robj);
}
}
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -6617,6 +6617,7 @@
movptr(mirror, Address(mirror, ConstMethod::constants_offset()));
movptr(mirror, Address(mirror, ConstantPool::pool_holder_offset_in_bytes()));
movptr(mirror, Address(mirror, mirror_offset));
+ resolve_oop_handle(mirror);
}
void MacroAssembler::load_klass(Register dst, Register src) {
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -2665,6 +2665,7 @@
ConstantPoolCacheEntry::f1_offset())));
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
__ movptr(obj, Address(obj, mirror_offset));
+ __ resolve_oop_handle(obj);
}
}
--- a/src/hotspot/share/c1/c1_LIRGenerator.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -1304,7 +1304,9 @@
// FIXME T_ADDRESS should actually be T_METADATA but it can't because the
// meaning of these two is mixed up (see JDK-8026837).
__ move(new LIR_Address(rcvr.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), temp, info);
- __ move_wide(new LIR_Address(temp, in_bytes(Klass::java_mirror_offset()), T_OBJECT), result);
+ __ move_wide(new LIR_Address(temp, in_bytes(Klass::java_mirror_offset()), T_ADDRESS), result);
+ // mirror = ((OopHandle)mirror)->resolve();
+ __ move_wide(new LIR_Address(result, T_OBJECT), result);
}
// java.lang.Class::isPrimitive()
--- a/src/hotspot/share/classfile/classLoaderData.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/classfile/classLoaderData.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -98,7 +98,8 @@
_keep_alive((is_anonymous || h_class_loader.is_null()) ? 1 : 0),
_metaspace(NULL), _unloading(false), _klasses(NULL),
_modules(NULL), _packages(NULL),
- _claimed(0), _jmethod_ids(NULL), _handles(), _deallocate_list(NULL),
+ _claimed(0), _modified_oops(true), _accumulated_modified_oops(false),
+ _jmethod_ids(NULL), _handles(), _deallocate_list(NULL),
_next(NULL), _dependencies(dependencies),
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
Monitor::_safepoint_check_never)) {
@@ -207,7 +208,7 @@
oops_do(&cl);
return cl.found();
}
-#endif
+#endif // ASSERT
bool ClassLoaderData::claim() {
if (_claimed == 1) {
@@ -236,19 +237,19 @@
}
}
-void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
+void ClassLoaderData::oops_do(OopClosure* f, bool must_claim, bool clear_mod_oops) {
if (must_claim && !claim()) {
return;
}
+ // Only clear modified_oops after the ClassLoaderData is claimed.
+ if (clear_mod_oops) {
+ clear_modified_oops();
+ }
+
f->do_oop(&_class_loader);
_dependencies.oops_do(f);
-
_handles.oops_do(f);
-
- if (klass_closure != NULL) {
- classes_do(klass_closure);
- }
}
void ClassLoaderData::Dependencies::oops_do(OopClosure* f) {
@@ -368,6 +369,9 @@
// Must handle over GC point.
Handle dependency(THREAD, to);
from_cld->_dependencies.add(dependency, CHECK);
+
+ // Added a potentially young gen oop to the ClassLoaderData
+ record_modified_oops();
}
@@ -764,6 +768,7 @@
OopHandle ClassLoaderData::add_handle(Handle h) {
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
+ record_modified_oops();
return OopHandle(_handles.add(h()));
}
@@ -875,8 +880,7 @@
if (Verbose) {
Klass* k = _klasses;
while (k != NULL) {
- out->print_cr("klass " PTR_FORMAT ", %s, CT: %d, MUT: %d", k, k->name()->as_C_string(),
- k->has_modified_oops(), k->has_accumulated_modified_oops());
+ out->print_cr("klass " PTR_FORMAT ", %s", p2i(k), k->name()->as_C_string());
assert(k != k->next_link(), "no loops!");
k = k->next_link();
}
@@ -1003,25 +1007,25 @@
}
-void ClassLoaderDataGraph::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
+void ClassLoaderDataGraph::oops_do(OopClosure* f, bool must_claim) {
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
- cld->oops_do(f, klass_closure, must_claim);
+ cld->oops_do(f, must_claim);
}
}
-void ClassLoaderDataGraph::keep_alive_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
+void ClassLoaderDataGraph::keep_alive_oops_do(OopClosure* f, bool must_claim) {
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
if (cld->keep_alive()) {
- cld->oops_do(f, klass_closure, must_claim);
+ cld->oops_do(f, must_claim);
}
}
}
-void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
+void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, bool must_claim) {
if (ClassUnloading) {
- keep_alive_oops_do(f, klass_closure, must_claim);
+ keep_alive_oops_do(f, must_claim);
} else {
- oops_do(f, klass_closure, must_claim);
+ oops_do(f, must_claim);
}
}
--- a/src/hotspot/share/classfile/classLoaderData.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/classfile/classLoaderData.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -87,9 +87,9 @@
static void purge();
static void clear_claimed_marks();
// oops do
- static void oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim);
- static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
- static void always_strong_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
+ static void oops_do(OopClosure* f, bool must_claim);
+ static void keep_alive_oops_do(OopClosure* blk, bool must_claim);
+ static void always_strong_oops_do(OopClosure* blk, bool must_claim);
// cld do
static void cld_do(CLDClosure* cl);
static void cld_unloading_do(CLDClosure* cl);
@@ -230,10 +230,16 @@
Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup.
bool _unloading; // true if this class loader goes away
bool _is_anonymous; // if this CLD is for an anonymous class
+
+ // Remembered sets support for the oops in the class loader data.
+ bool _modified_oops; // Card Table Equivalent (YC/CMS support)
+ bool _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
+
s2 _keep_alive; // if this CLD is kept alive without a keep_alive_object().
// Used for anonymous classes and the boot class
// loader. _keep_alive does not need to be volatile or
// atomic since there is one unique CLD per anonymous class.
+
volatile int _claimed; // true if claimed, for example during GC traces.
// To avoid applying oop closure more than once.
// Has to be an int because we cas it.
@@ -276,6 +282,19 @@
bool claimed() const { return _claimed == 1; }
bool claim();
+ // The CLD are not placed in the Heap, so the Card Table or
+ // the Mod Union Table can't be used to mark when CLD have modified oops.
+ // The CT and MUT bits saves this information for the whole class loader data.
+ void clear_modified_oops() { _modified_oops = false; }
+ public:
+ void record_modified_oops() { _modified_oops = true; }
+ bool has_modified_oops() { return _modified_oops; }
+
+ void accumulate_modified_oops() { if (has_modified_oops()) _accumulated_modified_oops = true; }
+ void clear_accumulated_modified_oops() { _accumulated_modified_oops = false; }
+ bool has_accumulated_modified_oops() { return _accumulated_modified_oops; }
+ private:
+
void unload();
bool keep_alive() const { return _keep_alive > 0; }
void classes_do(void f(Klass*));
@@ -346,8 +365,7 @@
inline unsigned int identity_hash() const { return (unsigned int)(((intptr_t)this) >> 3); }
- // Used when tracing from klasses.
- void oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim);
+ void oops_do(OopClosure* f, bool must_claim, bool clear_modified_oops = false);
void classes_do(KlassClosure* klass_closure);
Klass* klasses() { return _klasses; }
--- a/src/hotspot/share/classfile/javaClasses.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/classfile/javaClasses.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -889,7 +889,7 @@
// Setup indirection from klass->mirror
// after any exceptions can happen during allocations.
- k->set_java_mirror(mirror());
+ k->set_java_mirror(mirror);
// Set the module field in the java_lang_Class instance. This must be done
// after the mirror is set.
--- a/src/hotspot/share/gc/cms/cmsOopClosures.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/cms/cmsOopClosures.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,12 +48,7 @@
// because some CMS OopClosures derive from OopsInGenClosure. It would be
// good to get rid of them completely.
class MetadataAwareOopsInGenClosure: public OopsInGenClosure {
- KlassToOopClosure _klass_closure;
public:
- MetadataAwareOopsInGenClosure() {
- _klass_closure.initialize(this);
- }
-
virtual bool do_metadata() { return do_metadata_nv(); }
inline bool do_metadata_nv() { return true; }
--- a/src/hotspot/share/gc/cms/cmsOopClosures.inline.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/cms/cmsOopClosures.inline.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -40,10 +40,8 @@
inline void MetadataAwareOopsInGenClosure::do_klass(Klass* k) { do_klass_nv(k); }
inline void MetadataAwareOopsInGenClosure::do_cld_nv(ClassLoaderData* cld) {
- assert(_klass_closure._oop_closure == this, "Must be");
-
bool claim = true; // Must claim the class loader data before processing.
- cld->oops_do(_klass_closure._oop_closure, &_klass_closure, claim);
+ cld->oops_do(this, claim);
}
// Decode the oop and call do_oop on it.
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -1553,9 +1553,10 @@
assert(_collectorState != Idling || _modUnionTable.isAllClear(),
"_modUnionTable should be clear if the baton was not passed");
_modUnionTable.clear_all();
- assert(_collectorState != Idling || _ct->klass_rem_set()->mod_union_is_clear(),
+ assert(_collectorState != Idling || _ct->cld_rem_set()->mod_union_is_clear(),
"mod union for klasses should be clear if the baton was passed");
- _ct->klass_rem_set()->clear_mod_union();
+ _ct->cld_rem_set()->clear_mod_union();
+
// We must adjust the allocation statistics being maintained
// in the free list space. We do so by reading and clearing
@@ -2025,7 +2026,7 @@
// that information. Tell the young collection to save the union of all
// modified klasses.
if (duringMarking) {
- _ct->klass_rem_set()->set_accumulate_modified_oops(true);
+ _ct->cld_rem_set()->set_accumulate_modified_oops(true);
}
bool registerClosure = duringMarking;
@@ -2101,7 +2102,7 @@
assert(haveFreelistLocks(), "must have freelist locks");
assert_lock_strong(bitMapLock());
- _ct->klass_rem_set()->set_accumulate_modified_oops(false);
+ _ct->cld_rem_set()->set_accumulate_modified_oops(false);
_cmsGen->gc_epilogue_work(full);
@@ -2380,18 +2381,18 @@
}
}
-class VerifyKlassOopsKlassClosure : public KlassClosure {
- class VerifyKlassOopsClosure : public OopClosure {
+class VerifyCLDOopsCLDClosure : public CLDClosure {
+ class VerifyCLDOopsClosure : public OopClosure {
CMSBitMap* _bitmap;
public:
- VerifyKlassOopsClosure(CMSBitMap* bitmap) : _bitmap(bitmap) { }
+ VerifyCLDOopsClosure(CMSBitMap* bitmap) : _bitmap(bitmap) { }
void do_oop(oop* p) { guarantee(*p == NULL || _bitmap->isMarked((HeapWord*) *p), "Should be marked"); }
void do_oop(narrowOop* p) { ShouldNotReachHere(); }
} _oop_closure;
public:
- VerifyKlassOopsKlassClosure(CMSBitMap* bitmap) : _oop_closure(bitmap) {}
- void do_klass(Klass* k) {
- k->oops_do(&_oop_closure);
+ VerifyCLDOopsCLDClosure(CMSBitMap* bitmap) : _oop_closure(bitmap) {}
+ void do_cld(ClassLoaderData* cld) {
+ cld->oops_do(&_oop_closure, false, false);
}
};
@@ -2437,8 +2438,8 @@
assert(verification_mark_stack()->isEmpty(), "Should have been drained");
verify_work_stacks_empty();
- VerifyKlassOopsKlassClosure verify_klass_oops(verification_mark_bm());
- ClassLoaderDataGraph::classes_do(&verify_klass_oops);
+ VerifyCLDOopsCLDClosure verify_cld_oops(verification_mark_bm());
+ ClassLoaderDataGraph::cld_do(&verify_cld_oops);
// Marking completed -- now verify that each bit marked in
// verification_mark_bm() is also marked in markBitMap(); flag all
@@ -2911,7 +2912,7 @@
" or no bits are set in the gc_prologue before the start of the next "
"subsequent marking phase.");
- assert(_ct->klass_rem_set()->mod_union_is_clear(), "Must be");
+ assert(_ct->cld_rem_set()->mod_union_is_clear(), "Must be");
// Save the end of the used_region of the constituent generations
// to be used to limit the extent of sweep in each generation.
@@ -3848,7 +3849,7 @@
}
}
- preclean_klasses(&mrias_cl, _cmsGen->freelistLock());
+ preclean_cld(&mrias_cl, _cmsGen->freelistLock());
curNumCards = preclean_card_table(_cmsGen, &smoac_cl);
cumNumCards += curNumCards;
@@ -4067,21 +4068,21 @@
return cumNumDirtyCards;
}
-class PrecleanKlassClosure : public KlassClosure {
- KlassToOopClosure _cm_klass_closure;
+class PrecleanCLDClosure : public CLDClosure {
+ MetadataAwareOopsInGenClosure* _cm_closure;
public:
- PrecleanKlassClosure(OopClosure* oop_closure) : _cm_klass_closure(oop_closure) {}
- void do_klass(Klass* k) {
- if (k->has_accumulated_modified_oops()) {
- k->clear_accumulated_modified_oops();
-
- _cm_klass_closure.do_klass(k);
+ PrecleanCLDClosure(MetadataAwareOopsInGenClosure* oop_closure) : _cm_closure(oop_closure) {}
+ void do_cld(ClassLoaderData* cld) {
+ if (cld->has_accumulated_modified_oops()) {
+ cld->clear_accumulated_modified_oops();
+
+ _cm_closure->do_cld(cld);
}
}
};
// The freelist lock is needed to prevent asserts, is it really needed?
-void CMSCollector::preclean_klasses(MarkRefsIntoAndScanClosure* cl, Mutex* freelistLock) {
+void CMSCollector::preclean_cld(MarkRefsIntoAndScanClosure* cl, Mutex* freelistLock) {
cl->set_freelistLock(freelistLock);
@@ -4089,8 +4090,8 @@
// SSS: Add equivalent to ScanMarkedObjectsAgainCarefullyClosure::do_yield_check and should_abort_preclean?
// SSS: We should probably check if precleaning should be aborted, at suitable intervals?
- PrecleanKlassClosure preclean_klass_closure(cl);
- ClassLoaderDataGraph::classes_do(&preclean_klass_closure);
+ PrecleanCLDClosure preclean_closure(cl);
+ ClassLoaderDataGraph::cld_do(&preclean_closure);
verify_work_stacks_empty();
verify_overflow_empty();
@@ -4250,7 +4251,7 @@
// Call isAllClear() under bitMapLock
assert(_modUnionTable.isAllClear(),
"Should be clear by end of the final marking");
- assert(_ct->klass_rem_set()->mod_union_is_clear(),
+ assert(_ct->cld_rem_set()->mod_union_is_clear(),
"Should be clear by end of the final marking");
}
@@ -4332,26 +4333,26 @@
void do_work_steal(int i, ParMarkRefsIntoAndScanClosure* cl, int* seed);
};
-class RemarkKlassClosure : public KlassClosure {
- KlassToOopClosure _cm_klass_closure;
+class RemarkCLDClosure : public CLDClosure {
+ CLDToOopClosure _cm_closure;
public:
- RemarkKlassClosure(OopClosure* oop_closure) : _cm_klass_closure(oop_closure) {}
- void do_klass(Klass* k) {
- // Check if we have modified any oops in the Klass during the concurrent marking.
- if (k->has_accumulated_modified_oops()) {
- k->clear_accumulated_modified_oops();
+ RemarkCLDClosure(OopClosure* oop_closure) : _cm_closure(oop_closure) {}
+ void do_cld(ClassLoaderData* cld) {
+ // Check if we have modified any oops in the CLD during the concurrent marking.
+ if (cld->has_accumulated_modified_oops()) {
+ cld->clear_accumulated_modified_oops();
// We could have transfered the current modified marks to the accumulated marks,
// like we do with the Card Table to Mod Union Table. But it's not really necessary.
- } else if (k->has_modified_oops()) {
+ } else if (cld->has_modified_oops()) {
// Don't clear anything, this info is needed by the next young collection.
} else {
- // No modified oops in the Klass.
+ // No modified oops in the ClassLoaderData.
return;
}
// The klass has modified fields, need to scan the klass.
- _cm_klass_closure.do_klass(k);
+ _cm_closure.do_cld(cld);
}
};
@@ -4439,24 +4440,24 @@
log_trace(gc, task)("Finished unhandled CLD scanning work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
}
- // ---------- dirty klass scanning ----------
+ // We might have added oops to ClassLoaderData::_handles during the
+ // concurrent marking phase. These oops do not always point to newly allocated objects
+ // that are guaranteed to be kept alive. Hence,
+ // we do have to revisit the _handles block during the remark phase.
+
+ // ---------- dirty CLD scanning ----------
if (worker_id == 0) { // Single threaded at the moment.
_timer.reset();
_timer.start();
// Scan all classes that was dirtied during the concurrent marking phase.
- RemarkKlassClosure remark_klass_closure(&par_mrias_cl);
- ClassLoaderDataGraph::classes_do(&remark_klass_closure);
+ RemarkCLDClosure remark_closure(&par_mrias_cl);
+ ClassLoaderDataGraph::cld_do(&remark_closure);
_timer.stop();
- log_trace(gc, task)("Finished dirty klass scanning work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
- }
-
- // We might have added oops to ClassLoaderData::_handles during the
- // concurrent marking phase. These oops point to newly allocated objects
- // that are guaranteed to be kept alive. Either by the direct allocation
- // code, or when the young collector processes the roots. Hence,
- // we don't have to revisit the _handles block during the remark phase.
+ log_trace(gc, task)("Finished dirty CLD scanning work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
+ }
+
// ---------- rescan dirty cards ------------
_timer.reset();
@@ -4981,23 +4982,21 @@
verify_work_stacks_empty();
}
+ // We might have added oops to ClassLoaderData::_handles during the
+ // concurrent marking phase. These oops do not point to newly allocated objects
+ // that are guaranteed to be kept alive. Hence,
+ // we do have to revisit the _handles block during the remark phase.
{
- GCTraceTime(Trace, gc, phases) t("Dirty Klass Scan", _gc_timer_cm);
+ GCTraceTime(Trace, gc, phases) t("Dirty CLD Scan", _gc_timer_cm);
verify_work_stacks_empty();
- RemarkKlassClosure remark_klass_closure(&mrias_cl);
- ClassLoaderDataGraph::classes_do(&remark_klass_closure);
+ RemarkCLDClosure remark_closure(&mrias_cl);
+ ClassLoaderDataGraph::cld_do(&remark_closure);
verify_work_stacks_empty();
}
- // We might have added oops to ClassLoaderData::_handles during the
- // concurrent marking phase. These oops point to newly allocated objects
- // that are guaranteed to be kept alive. Either by the direct allocation
- // code, or when the young collector processes the roots. Hence,
- // we don't have to revisit the _handles block during the remark phase.
-
verify_work_stacks_empty();
// Restore evacuated mark words, if any, used for overflow list links
restore_preserved_marks_if_any();
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -777,7 +777,7 @@
// Does precleaning work, returning a quantity indicative of
// the amount of "useful work" done.
size_t preclean_work(bool clean_refs, bool clean_survivors);
- void preclean_klasses(MarkRefsIntoAndScanClosure* cl, Mutex* freelistLock);
+ void preclean_cld(MarkRefsIntoAndScanClosure* cl, Mutex* freelistLock);
void abortable_preclean(); // Preclean while looking for possible abort
void initialize_sequential_subtasks_for_young_gen_rescan(int i);
// Helper function for above; merge-sorts the per-thread plab samples
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -493,7 +493,7 @@
ParScanClosure::ParScanClosure(ParNewGeneration* g,
ParScanThreadState* par_scan_state) :
- OopsInKlassOrGenClosure(g), _par_scan_state(par_scan_state), _g(g) {
+ OopsInClassLoaderDataOrGenClosure(g), _par_scan_state(par_scan_state), _g(g) {
_boundary = _g->reserved().end();
}
@@ -601,11 +601,8 @@
par_scan_state.set_young_old_boundary(_young_old_boundary);
- KlassScanClosure klass_scan_closure(&par_scan_state.to_space_root_closure(),
- gch->rem_set()->klass_rem_set());
- CLDToKlassAndOopClosure cld_scan_closure(&klass_scan_closure,
- &par_scan_state.to_space_root_closure(),
- false);
+ CLDScanClosure cld_scan_closure(&par_scan_state.to_space_root_closure(),
+ gch->rem_set()->cld_rem_set()->accumulate_modified_oops());
par_scan_state.start_strong_roots();
gch->young_process_roots(_strong_roots_scope,
--- a/src/hotspot/share/gc/cms/parOopClosures.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/cms/parOopClosures.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
typedef GenericTaskQueueSet<ObjToScanQueue, mtGC> ObjToScanQueueSet;
class ParallelTaskTerminator;
-class ParScanClosure: public OopsInKlassOrGenClosure {
+class ParScanClosure: public OopsInClassLoaderDataOrGenClosure {
protected:
ParScanThreadState* _par_scan_state;
ParNewGeneration* _g;
--- a/src/hotspot/share/gc/cms/parOopClosures.inline.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/cms/parOopClosures.inline.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -126,8 +126,8 @@
(void)_par_scan_state->trim_queues(10 * ParallelGCThreads);
}
}
- if (is_scanning_a_klass()) {
- do_klass_barrier();
+ if (is_scanning_a_cld()) {
+ do_cld_barrier();
} else if (gc_barrier) {
// Now call parent closure
par_do_barrier(p);
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -63,7 +63,6 @@
class GenerationSpec;
class G1ParScanThreadState;
class G1ParScanThreadStateSet;
-class G1KlassScanClosure;
class G1ParScanThreadState;
class ObjectClosure;
class SpaceClosure;
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -161,18 +161,18 @@
void reset_count() { _count = 0; };
};
-class VerifyKlassClosure: public KlassClosure {
+class VerifyCLDClosure: public CLDClosure {
YoungRefCounterClosure _young_ref_counter_closure;
OopClosure *_oop_closure;
public:
- VerifyKlassClosure(G1CollectedHeap* g1h, OopClosure* cl) : _young_ref_counter_closure(g1h), _oop_closure(cl) {}
- void do_klass(Klass* k) {
- k->oops_do(_oop_closure);
+ VerifyCLDClosure(G1CollectedHeap* g1h, OopClosure* cl) : _young_ref_counter_closure(g1h), _oop_closure(cl) {}
+ void do_cld(ClassLoaderData* cld) {
+ cld->oops_do(_oop_closure, false);
_young_ref_counter_closure.reset_count();
- k->oops_do(&_young_ref_counter_closure);
+ cld->oops_do(&_young_ref_counter_closure, false);
if (_young_ref_counter_closure.count() > 0) {
- guarantee(k->has_modified_oops(), "Klass " PTR_FORMAT ", has young refs but is not dirty.", p2i(k));
+ guarantee(cld->has_modified_oops(), "CLD " PTR_FORMAT ", has young %d refs but is not dirty.", p2i(cld), _young_ref_counter_closure.count());
}
}
};
@@ -390,8 +390,7 @@
log_debug(gc, verify)("Roots");
VerifyRootsClosure rootsCl(vo);
- VerifyKlassClosure klassCl(_g1h, &rootsCl);
- CLDToKlassAndOopClosure cldCl(&klassCl, &rootsCl, false);
+ VerifyCLDClosure cldCl(_g1h, &rootsCl);
// We apply the relevant closures to all the oops in the
// system dictionary, class loader data graph, the string table
--- a/src/hotspot/share/gc/g1/g1OopClosures.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/g1/g1OopClosures.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
_g1(g1),
_par_scan_state(par_scan_state),
_worker_id(par_scan_state->worker_id()),
- _scanned_klass(NULL),
+ _scanned_cld(NULL),
_cm(_g1->concurrent_mark())
{ }
@@ -42,20 +42,20 @@
_g1(g1), _par_scan_state(par_scan_state), _from(NULL)
{ }
-void G1KlassScanClosure::do_klass(Klass* klass) {
- // If the klass has not been dirtied we know that there's
+void G1CLDScanClosure::do_cld(ClassLoaderData* cld) {
+ // If the class loader data has not been dirtied we know that there's
// no references into the young gen and we can skip it.
- if (!_process_only_dirty || klass->has_modified_oops()) {
- // Clean the klass since we're going to scavenge all the metadata.
- klass->clear_modified_oops();
+ if (!_process_only_dirty || cld->has_modified_oops()) {
- // Tell the closure that this klass is the Klass to scavenge
+ // Tell the closure that this class loader data is the CLD to scavenge
// and is the one to dirty if oops are left pointing into the young gen.
- _closure->set_scanned_klass(klass);
+ _closure->set_scanned_cld(cld);
- klass->oops_do(_closure);
+ // Clean the cld since we're going to scavenge all the metadata.
+ // Clear modified oops only if this cld is claimed.
+ cld->oops_do(_closure, _must_claim, /*clear_modified_oops*/true);
- _closure->set_scanned_klass(NULL);
+ _closure->set_scanned_cld(NULL);
}
_count++;
}
--- a/src/hotspot/share/gc/g1/g1OopClosures.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/g1/g1OopClosures.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -107,7 +107,7 @@
G1CollectedHeap* _g1;
G1ParScanThreadState* _par_scan_state;
uint _worker_id; // Cache value from par_scan_state.
- Klass* _scanned_klass;
+ ClassLoaderData* _scanned_cld;
G1ConcurrentMark* _cm;
// Mark the object if it's not already marked. This is used to mark
@@ -124,13 +124,13 @@
~G1ParCopyHelper() { }
public:
- void set_scanned_klass(Klass* k) { _scanned_klass = k; }
- template <class T> inline void do_klass_barrier(T* p, oop new_obj);
+ void set_scanned_cld(ClassLoaderData* cld) { _scanned_cld = cld; }
+ inline void do_cld_barrier(oop new_obj);
};
enum G1Barrier {
G1BarrierNone,
- G1BarrierKlass
+ G1BarrierCLD
};
enum G1Mark {
@@ -150,14 +150,16 @@
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
};
-class G1KlassScanClosure : public KlassClosure {
+class G1CLDScanClosure : public CLDClosure {
G1ParCopyHelper* _closure;
bool _process_only_dirty;
+ bool _must_claim;
int _count;
public:
- G1KlassScanClosure(G1ParCopyHelper* closure, bool process_only_dirty)
- : _process_only_dirty(process_only_dirty), _closure(closure), _count(0) {}
- void do_klass(Klass* klass);
+ G1CLDScanClosure(G1ParCopyHelper* closure,
+ bool process_only_dirty, bool must_claim)
+ : _process_only_dirty(process_only_dirty), _must_claim(must_claim), _closure(closure), _count(0) {}
+ void do_cld(ClassLoaderData* cld);
};
// Closure for iterating over object fields during concurrent marking
--- a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -195,10 +195,9 @@
}
}
-template <class T>
-void G1ParCopyHelper::do_klass_barrier(T* p, oop new_obj) {
+void G1ParCopyHelper::do_cld_barrier(oop new_obj) {
if (_g1->heap_region_containing(new_obj)->is_young()) {
- _scanned_klass->record_modified_oops();
+ _scanned_cld->record_modified_oops();
}
}
@@ -249,8 +248,8 @@
mark_forwarded_object(obj, forwardee);
}
- if (barrier == G1BarrierKlass) {
- do_klass_barrier(p, forwardee);
+ if (barrier == G1BarrierCLD) {
+ do_cld_barrier(forwardee);
}
} else {
if (state.is_humongous()) {
@@ -267,5 +266,4 @@
}
}
}
-
#endif // SHARE_VM_GC_G1_G1OOPCLOSURES_INLINE_HPP
--- a/src/hotspot/share/gc/g1/g1SharedClosures.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/g1/g1SharedClosures.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,18 +34,17 @@
template <G1Mark Mark, bool use_ext = false>
class G1SharedClosures VALUE_OBJ_CLASS_SPEC {
public:
- G1ParCopyClosure<G1BarrierNone, Mark, use_ext> _oops;
- G1ParCopyClosure<G1BarrierKlass, Mark, use_ext> _oop_in_klass;
- G1KlassScanClosure _klass_in_cld_closure;
- CLDToKlassAndOopClosure _clds;
- G1CodeBlobClosure _codeblobs;
- BufferingOopClosure _buffered_oops;
+ G1ParCopyClosure<G1BarrierNone, Mark, use_ext> _oops;
+ G1ParCopyClosure<G1BarrierCLD, Mark, use_ext> _oops_in_cld;
- G1SharedClosures(G1CollectedHeap* g1h, G1ParScanThreadState* pss, bool process_only_dirty_klasses, bool must_claim_cld) :
+ G1CLDScanClosure _clds;
+ G1CodeBlobClosure _codeblobs;
+ BufferingOopClosure _buffered_oops;
+
+ G1SharedClosures(G1CollectedHeap* g1h, G1ParScanThreadState* pss, bool process_only_dirty, bool must_claim_cld) :
_oops(g1h, pss),
- _oop_in_klass(g1h, pss),
- _klass_in_cld_closure(&_oop_in_klass, process_only_dirty_klasses),
- _clds(&_klass_in_cld_closure, &_oops, must_claim_cld),
+ _oops_in_cld(g1h, pss),
+ _clds(&_oops_in_cld, process_only_dirty, must_claim_cld),
_codeblobs(&_oops),
_buffered_oops(&_oops) {}
};
--- a/src/hotspot/share/gc/parallel/pcTasks.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/parallel/pcTasks.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -81,7 +81,6 @@
ParCompactionManager* cm =
ParCompactionManager::gc_thread_compaction_manager(which);
ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm);
- ParCompactionManager::FollowKlassClosure follow_klass_closure(&mark_and_push_closure);
switch (_root_type) {
case universe:
@@ -117,7 +116,7 @@
break;
case class_loader_data:
- ClassLoaderDataGraph::always_strong_oops_do(&mark_and_push_closure, &follow_klass_closure, true);
+ ClassLoaderDataGraph::always_strong_oops_do(&mark_and_push_closure, true);
break;
case code_cache:
--- a/src/hotspot/share/gc/parallel/psCompactionManager.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -196,17 +196,6 @@
FollowStackClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
virtual void do_void();
};
-
- // The one and only place to start following the classes.
- // Should only be applied to the ClassLoaderData klasses list.
- class FollowKlassClosure : public KlassClosure {
- private:
- MarkAndPushClosure* _mark_and_push_closure;
- public:
- FollowKlassClosure(MarkAndPushClosure* mark_and_push_closure) :
- _mark_and_push_closure(mark_and_push_closure) { }
- void do_klass(Klass* klass);
- };
};
inline ParCompactionManager* ParCompactionManager::manager_array(uint index) {
--- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -98,15 +98,10 @@
_compaction_manager->follow_marking_stacks();
}
-inline void ParCompactionManager::FollowKlassClosure::do_klass(Klass* klass) {
- klass->oops_do(_mark_and_push_closure);
-}
-
inline void ParCompactionManager::follow_class_loader(ClassLoaderData* cld) {
MarkAndPushClosure mark_and_push_closure(this);
- FollowKlassClosure follow_klass_closure(&mark_and_push_closure);
- cld->oops_do(&mark_and_push_closure, &follow_klass_closure, true);
+ cld->oops_do(&mark_and_push_closure, true);
}
inline void ParCompactionManager::follow_contents(oop obj) {
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -838,11 +838,6 @@
bool PSParallelCompact::IsAliveClosure::do_object_b(oop p) { return mark_bitmap()->is_marked(p); }
-void PSParallelCompact::AdjustKlassClosure::do_klass(Klass* klass) {
- PSParallelCompact::AdjustPointerClosure closure(_cm);
- klass->oops_do(&closure);
-}
-
void PSParallelCompact::post_initialize() {
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
MemRegion mr = heap->reserved_region();
@@ -2162,7 +2157,6 @@
ClassLoaderDataGraph::clear_claimed_marks();
PSParallelCompact::AdjustPointerClosure oop_closure(cm);
- PSParallelCompact::AdjustKlassClosure klass_closure(cm);
// General strong roots.
Universe::oops_do(&oop_closure);
@@ -2172,7 +2166,7 @@
Management::oops_do(&oop_closure);
JvmtiExport::oops_do(&oop_closure);
SystemDictionary::oops_do(&oop_closure);
- ClassLoaderDataGraph::oops_do(&oop_closure, &klass_closure, true);
+ ClassLoaderDataGraph::oops_do(&oop_closure, true);
// Now adjust pointers in remaining weak roots. (All of which should
// have been cleared if they pointed to non-surviving objects.)
--- a/src/hotspot/share/gc/parallel/psScavenge.inline.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/parallel/psScavenge.inline.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -85,15 +85,15 @@
typedef PSRootsClosure</*promote_immediately=*/false> PSScavengeRootsClosure;
typedef PSRootsClosure</*promote_immediately=*/true> PSPromoteRootsClosure;
-// Scavenges a single oop in a Klass.
-class PSScavengeFromKlassClosure: public OopClosure {
+// Scavenges a single oop in a ClassLoaderData.
+class PSScavengeFromCLDClosure: public OopClosure {
private:
PSPromotionManager* _pm;
- // Used to redirty a scanned klass if it has oops
+ // Used to redirty a scanned cld if it has oops
// pointing to the young generation after being scanned.
- Klass* _scanned_klass;
+ ClassLoaderData* _scanned_cld;
public:
- PSScavengeFromKlassClosure(PSPromotionManager* pm) : _pm(pm), _scanned_klass(NULL) { }
+ PSScavengeFromCLDClosure(PSPromotionManager* pm) : _pm(pm), _scanned_cld(NULL) { }
void do_oop(narrowOop* p) { ShouldNotReachHere(); }
void do_oop(oop* p) {
ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();
@@ -111,48 +111,46 @@
oopDesc::encode_store_heap_oop_not_null(p, new_obj);
if (PSScavenge::is_obj_in_young(new_obj)) {
- do_klass_barrier();
+ do_cld_barrier();
}
}
}
- void set_scanned_klass(Klass* klass) {
- assert(_scanned_klass == NULL || klass == NULL, "Should always only handling one klass at a time");
- _scanned_klass = klass;
+ void set_scanned_cld(ClassLoaderData* cld) {
+ assert(_scanned_cld == NULL || cld == NULL, "Should always only handling one cld at a time");
+ _scanned_cld = cld;
}
private:
- void do_klass_barrier() {
- assert(_scanned_klass != NULL, "Should not be called without having a scanned klass");
- _scanned_klass->record_modified_oops();
+ void do_cld_barrier() {
+ assert(_scanned_cld != NULL, "Should not be called without having a scanned cld");
+ _scanned_cld->record_modified_oops();
}
-
};
-// Scavenges the oop in a Klass.
-class PSScavengeKlassClosure: public KlassClosure {
+// Scavenges the oop in a ClassLoaderData.
+class PSScavengeCLDClosure: public CLDClosure {
private:
- PSScavengeFromKlassClosure _oop_closure;
+ PSScavengeFromCLDClosure _oop_closure;
protected:
public:
- PSScavengeKlassClosure(PSPromotionManager* pm) : _oop_closure(pm) { }
- void do_klass(Klass* klass) {
- // If the klass has not been dirtied we know that there's
+ PSScavengeCLDClosure(PSPromotionManager* pm) : _oop_closure(pm) { }
+ void do_cld(ClassLoaderData* cld) {
+ // If the cld has not been dirtied we know that there's
// no references into the young gen and we can skip it.
- if (klass->has_modified_oops()) {
- // Clean the klass since we're going to scavenge all the metadata.
- klass->clear_modified_oops();
-
- // Setup the promotion manager to redirty this klass
+ if (cld->has_modified_oops()) {
+ // Setup the promotion manager to redirty this cld
// if references are left in the young gen.
- _oop_closure.set_scanned_klass(klass);
+ _oop_closure.set_scanned_cld(cld);
- klass->oops_do(&_oop_closure);
+ // Clean the cld since we're going to scavenge all the metadata.
+ cld->oops_do(&_oop_closure, false, /*clear_modified_oops*/true);
- _oop_closure.set_scanned_klass(NULL);
+ _oop_closure.set_scanned_cld(NULL);
}
}
};
+
#endif // SHARE_VM_GC_PARALLEL_PSSCAVENGE_INLINE_HPP
--- a/src/hotspot/share/gc/parallel/psTasks.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/parallel/psTasks.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -79,8 +79,8 @@
case class_loader_data:
{
- PSScavengeKlassClosure klass_closure(pm);
- ClassLoaderDataGraph::oops_do(&roots_closure, &klass_closure, false);
+ PSScavengeCLDClosure cld_closure(pm);
+ ClassLoaderDataGraph::cld_do(&cld_closure);
}
break;
--- a/src/hotspot/share/gc/serial/defNewGeneration.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -121,7 +121,7 @@
}
ScanClosure::ScanClosure(DefNewGeneration* g, bool gc_barrier) :
- OopsInKlassOrGenClosure(g), _g(g), _gc_barrier(gc_barrier)
+ OopsInClassLoaderDataOrGenClosure(g), _g(g), _gc_barrier(gc_barrier)
{
_boundary = _g->reserved().end();
}
@@ -130,7 +130,7 @@
void ScanClosure::do_oop(narrowOop* p) { ScanClosure::do_oop_work(p); }
FastScanClosure::FastScanClosure(DefNewGeneration* g, bool gc_barrier) :
- OopsInKlassOrGenClosure(g), _g(g), _gc_barrier(gc_barrier)
+ OopsInClassLoaderDataOrGenClosure(g), _g(g), _gc_barrier(gc_barrier)
{
_boundary = _g->reserved().end();
}
@@ -138,30 +138,28 @@
void FastScanClosure::do_oop(oop* p) { FastScanClosure::do_oop_work(p); }
void FastScanClosure::do_oop(narrowOop* p) { FastScanClosure::do_oop_work(p); }
-void KlassScanClosure::do_klass(Klass* klass) {
+void CLDScanClosure::do_cld(ClassLoaderData* cld) {
NOT_PRODUCT(ResourceMark rm);
- log_develop_trace(gc, scavenge)("KlassScanClosure::do_klass " PTR_FORMAT ", %s, dirty: %s",
- p2i(klass),
- klass->external_name(),
- klass->has_modified_oops() ? "true" : "false");
+ log_develop_trace(gc, scavenge)("CLDScanClosure::do_cld " PTR_FORMAT ", %s, dirty: %s",
+ p2i(cld),
+ cld->loader_name(),
+ cld->has_modified_oops() ? "true" : "false");
- // If the klass has not been dirtied we know that there's
+ // If the cld has not been dirtied we know that there's
// no references into the young gen and we can skip it.
- if (klass->has_modified_oops()) {
+ if (cld->has_modified_oops()) {
if (_accumulate_modified_oops) {
- klass->accumulate_modified_oops();
+ cld->accumulate_modified_oops();
}
- // Clear this state since we're going to scavenge all the metadata.
- klass->clear_modified_oops();
-
- // Tell the closure which Klass is being scanned so that it can be dirtied
+ // Tell the closure which CLD is being scanned so that it can be dirtied
// if oops are left pointing into the young gen.
- _scavenge_closure->set_scanned_klass(klass);
+ _scavenge_closure->set_scanned_cld(cld);
- klass->oops_do(_scavenge_closure);
+ // Clean the cld since we're going to scavenge all the metadata.
+ cld->oops_do(_scavenge_closure, false, /*clear_modified_oops*/true);
- _scavenge_closure->set_scanned_klass(NULL);
+ _scavenge_closure->set_scanned_cld(NULL);
}
}
@@ -177,12 +175,6 @@
void FilteringClosure::do_oop(oop* p) { FilteringClosure::do_oop_work(p); }
void FilteringClosure::do_oop(narrowOop* p) { FilteringClosure::do_oop_work(p); }
-KlassScanClosure::KlassScanClosure(OopsInKlassOrGenClosure* scavenge_closure,
- KlassRemSet* klass_rem_set)
- : _scavenge_closure(scavenge_closure),
- _accumulate_modified_oops(klass_rem_set->accumulate_modified_oops()) {}
-
-
DefNewGeneration::DefNewGeneration(ReservedSpace rs,
size_t initial_size,
const char* policy)
@@ -629,11 +621,8 @@
FastScanClosure fsc_with_no_gc_barrier(this, false);
FastScanClosure fsc_with_gc_barrier(this, true);
- KlassScanClosure klass_scan_closure(&fsc_with_no_gc_barrier,
- gch->rem_set()->klass_rem_set());
- CLDToKlassAndOopClosure cld_scan_closure(&klass_scan_closure,
- &fsc_with_no_gc_barrier,
- false);
+ CLDScanClosure cld_scan_closure(&fsc_with_no_gc_barrier,
+ gch->rem_set()->cld_rem_set()->accumulate_modified_oops());
set_promo_failure_scan_stack_closure(&fsc_with_no_gc_barrier);
FastEvacuateFollowersClosure evacuate_followers(gch,
--- a/src/hotspot/share/gc/shared/cardTableRS.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/shared/cardTableRS.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -34,16 +34,16 @@
#include "runtime/os.hpp"
#include "utilities/macros.hpp"
-class HasAccumulatedModifiedOopsClosure : public KlassClosure {
+class HasAccumulatedModifiedOopsClosure : public CLDClosure {
bool _found;
public:
HasAccumulatedModifiedOopsClosure() : _found(false) {}
- void do_klass(Klass* klass) {
+ void do_cld(ClassLoaderData* cld) {
if (_found) {
return;
}
- if (klass->has_accumulated_modified_oops()) {
+ if (cld->has_accumulated_modified_oops()) {
_found = true;
}
}
@@ -52,28 +52,29 @@
}
};
-bool KlassRemSet::mod_union_is_clear() {
+bool CLDRemSet::mod_union_is_clear() {
HasAccumulatedModifiedOopsClosure closure;
- ClassLoaderDataGraph::classes_do(&closure);
+ ClassLoaderDataGraph::cld_do(&closure);
return !closure.found();
}
-class ClearKlassModUnionClosure : public KlassClosure {
+class ClearCLDModUnionClosure : public CLDClosure {
public:
- void do_klass(Klass* klass) {
- if (klass->has_accumulated_modified_oops()) {
- klass->clear_accumulated_modified_oops();
+ void do_cld(ClassLoaderData* cld) {
+ if (cld->has_accumulated_modified_oops()) {
+ cld->clear_accumulated_modified_oops();
}
}
};
-void KlassRemSet::clear_mod_union() {
- ClearKlassModUnionClosure closure;
- ClassLoaderDataGraph::classes_do(&closure);
+void CLDRemSet::clear_mod_union() {
+ ClearCLDModUnionClosure closure;
+ ClassLoaderDataGraph::cld_do(&closure);
}
+
CardTableRS::CardTableRS(MemRegion whole_heap) :
_bs(NULL),
_cur_youngergen_card_val(youngergenP1_card)
--- a/src/hotspot/share/gc/shared/cardTableRS.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/shared/cardTableRS.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,11 @@
class Space;
class OopsInGenClosure;
-// Helper to remember modified oops in all klasses.
-class KlassRemSet {
+// Helper to remember modified oops in all clds.
+class CLDRemSet {
bool _accumulate_modified_oops;
public:
- KlassRemSet() : _accumulate_modified_oops(false) {}
+ CLDRemSet() : _accumulate_modified_oops(false) {}
void set_accumulate_modified_oops(bool value) { _accumulate_modified_oops = value; }
bool accumulate_modified_oops() { return _accumulate_modified_oops; }
bool mod_union_is_clear();
@@ -64,7 +64,7 @@
return CardTableModRefBSForCTRS::card_is_dirty_wrt_gen_iter(cv);
}
- KlassRemSet _klass_rem_set;
+ CLDRemSet _cld_rem_set;
BarrierSet* _bs;
CardTableModRefBSForCTRS* _ct_bs;
@@ -121,7 +121,7 @@
// Set the barrier set.
void set_bs(BarrierSet* bs) { _bs = bs; }
- KlassRemSet* klass_rem_set() { return &_klass_rem_set; }
+ CLDRemSet* cld_rem_set() { return &_cld_rem_set; }
CardTableModRefBSForCTRS* ct_bs() { return _ct_bs; }
--- a/src/hotspot/share/gc/shared/genOopClosures.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/shared/genOopClosures.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -81,24 +81,25 @@
};
-// Super class for scan closures. It contains code to dirty scanned Klasses.
-class OopsInKlassOrGenClosure: public OopsInGenClosure {
- Klass* _scanned_klass;
+// Super class for scan closures. It contains code to dirty scanned class loader data.
+class OopsInClassLoaderDataOrGenClosure: public OopsInGenClosure {
+ ClassLoaderData* _scanned_cld;
public:
- OopsInKlassOrGenClosure(Generation* g) : OopsInGenClosure(g), _scanned_klass(NULL) {}
- void set_scanned_klass(Klass* k) {
- assert(k == NULL || _scanned_klass == NULL, "Must be");
- _scanned_klass = k;
+ OopsInClassLoaderDataOrGenClosure(Generation* g) : OopsInGenClosure(g), _scanned_cld(NULL) {}
+ void set_scanned_cld(ClassLoaderData* cld) {
+ assert(cld == NULL || _scanned_cld == NULL, "Must be");
+ _scanned_cld = cld;
}
- bool is_scanning_a_klass() { return _scanned_klass != NULL; }
- void do_klass_barrier();
+ bool is_scanning_a_cld() { return _scanned_cld != NULL; }
+ void do_cld_barrier();
};
+
// Closure for scanning DefNewGeneration.
//
// This closure will perform barrier store calls for ALL
// pointers in scanned oops.
-class ScanClosure: public OopsInKlassOrGenClosure {
+class ScanClosure: public OopsInClassLoaderDataOrGenClosure {
protected:
DefNewGeneration* _g;
HeapWord* _boundary;
@@ -117,7 +118,7 @@
// This closure only performs barrier store calls on
// pointers into the DefNewGeneration. This is less
// precise, but faster, than a ScanClosure
-class FastScanClosure: public OopsInKlassOrGenClosure {
+class FastScanClosure: public OopsInClassLoaderDataOrGenClosure {
protected:
DefNewGeneration* _g;
HeapWord* _boundary;
@@ -131,14 +132,15 @@
inline void do_oop_nv(narrowOop* p);
};
-class KlassScanClosure: public KlassClosure {
- OopsInKlassOrGenClosure* _scavenge_closure;
+class CLDScanClosure: public CLDClosure {
+ OopsInClassLoaderDataOrGenClosure* _scavenge_closure;
// true if the the modified oops state should be saved.
- bool _accumulate_modified_oops;
+ bool _accumulate_modified_oops;
public:
- KlassScanClosure(OopsInKlassOrGenClosure* scavenge_closure,
- KlassRemSet* klass_rem_set_policy);
- void do_klass(Klass* k);
+ CLDScanClosure(OopsInClassLoaderDataOrGenClosure* scavenge_closure,
+ bool accumulate_modified_oops) :
+ _scavenge_closure(scavenge_closure), _accumulate_modified_oops(accumulate_modified_oops) {}
+ void do_cld(ClassLoaderData* cld);
};
class FilteringClosure: public ExtendedOopClosure {
--- a/src/hotspot/share/gc/shared/genOopClosures.inline.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/gc/shared/genOopClosures.inline.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,9 +68,11 @@
}
}
-inline void OopsInKlassOrGenClosure::do_klass_barrier() {
- assert(_scanned_klass != NULL, "Must be");
- _scanned_klass->record_modified_oops();
+inline void OopsInClassLoaderDataOrGenClosure::do_cld_barrier() {
+ assert(_scanned_cld != NULL, "Must be");
+ if (!_scanned_cld->has_modified_oops()) {
+ _scanned_cld->record_modified_oops();
+ }
}
// NOTE! Any changes made here should also be made
@@ -87,8 +89,8 @@
oopDesc::encode_store_heap_oop_not_null(p, new_obj);
}
- if (is_scanning_a_klass()) {
- do_klass_barrier();
+ if (is_scanning_a_cld()) {
+ do_cld_barrier();
} else if (_gc_barrier) {
// Now call parent closure
do_barrier(p);
@@ -111,8 +113,8 @@
oop new_obj = obj->is_forwarded() ? obj->forwardee()
: _g->copy_to_survivor_space(obj);
oopDesc::encode_store_heap_oop_not_null(p, new_obj);
- if (is_scanning_a_klass()) {
- do_klass_barrier();
+ if (is_scanning_a_cld()) {
+ do_cld_barrier();
} else if (_gc_barrier) {
// Now call parent closure
do_barrier(p);
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -412,6 +412,7 @@
} else if (strcmp(vmField.typeString, "address") == 0 ||
strcmp(vmField.typeString, "intptr_t") == 0 ||
strcmp(vmField.typeString, "uintptr_t") == 0 ||
+ strcmp(vmField.typeString, "OopHandle") == 0 ||
strcmp(vmField.typeString, "size_t") == 0 ||
// All foo* types are addresses.
vmField.typeString[strlen(vmField.typeString) - 1] == '*') {
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
#include "jvmci/vmStructs_compiler_runtime.hpp"
#include "jvmci/vmStructs_jvmci.hpp"
#include "oops/oop.hpp"
+#include "oops/oopHandle.hpp"
#include "oops/objArrayKlass.hpp"
#include "runtime/globals.hpp"
#include "runtime/sharedRuntime.hpp"
@@ -192,7 +193,7 @@
nonstatic_field(Klass, _name, Symbol*) \
nonstatic_field(Klass, _prototype_header, markOop) \
nonstatic_field(Klass, _next_sibling, Klass*) \
- nonstatic_field(Klass, _java_mirror, oop) \
+ nonstatic_field(Klass, _java_mirror, OopHandle) \
nonstatic_field(Klass, _modifier_flags, jint) \
nonstatic_field(Klass, _access_flags, AccessFlags) \
\
--- a/src/hotspot/share/memory/iterator.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/memory/iterator.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,17 +29,8 @@
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
-void KlassToOopClosure::do_klass(Klass* k) {
- assert(_oop_closure != NULL, "Not initialized?");
- k->oops_do(_oop_closure);
-}
-
void CLDToOopClosure::do_cld(ClassLoaderData* cld) {
- cld->oops_do(_oop_closure, &_klass_closure, _must_claim_cld);
-}
-
-void CLDToKlassAndOopClosure::do_cld(ClassLoaderData* cld) {
- cld->oops_do(_oop_closure, _klass_closure, _must_claim_cld);
+ cld->oops_do(_oop_closure, _must_claim_cld);
}
void ObjectToOopClosure::do_object(oop obj) {
--- a/src/hotspot/share/memory/iterator.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/memory/iterator.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -138,67 +138,27 @@
virtual void do_cld(ClassLoaderData* cld) = 0;
};
-class KlassToOopClosure : public KlassClosure {
- friend class MetadataAwareOopClosure;
- friend class MetadataAwareOopsInGenClosure;
-
- OopClosure* _oop_closure;
-
- // Used when _oop_closure couldn't be set in an initialization list.
- void initialize(OopClosure* oop_closure) {
- assert(_oop_closure == NULL, "Should only be called once");
- _oop_closure = oop_closure;
- }
-
- public:
- KlassToOopClosure(OopClosure* oop_closure = NULL) : _oop_closure(oop_closure) {}
-
- virtual void do_klass(Klass* k);
-};
class CLDToOopClosure : public CLDClosure {
OopClosure* _oop_closure;
- KlassToOopClosure _klass_closure;
bool _must_claim_cld;
public:
CLDToOopClosure(OopClosure* oop_closure, bool must_claim_cld = true) :
_oop_closure(oop_closure),
- _klass_closure(oop_closure),
_must_claim_cld(must_claim_cld) {}
void do_cld(ClassLoaderData* cld);
};
-class CLDToKlassAndOopClosure : public CLDClosure {
- friend class G1CollectedHeap;
- protected:
- OopClosure* _oop_closure;
- KlassClosure* _klass_closure;
- bool _must_claim_cld;
- public:
- CLDToKlassAndOopClosure(KlassClosure* klass_closure,
- OopClosure* oop_closure,
- bool must_claim_cld) :
- _oop_closure(oop_closure),
- _klass_closure(klass_closure),
- _must_claim_cld(must_claim_cld) {}
- void do_cld(ClassLoaderData* cld);
-};
-
// The base class for all concurrent marking closures,
// that participates in class unloading.
// It's used to proxy through the metadata to the oops defined in them.
class MetadataAwareOopClosure: public ExtendedOopClosure {
- KlassToOopClosure _klass_closure;
public:
- MetadataAwareOopClosure() : ExtendedOopClosure() {
- _klass_closure.initialize(this);
- }
- MetadataAwareOopClosure(ReferenceProcessor* rp) : ExtendedOopClosure(rp) {
- _klass_closure.initialize(this);
- }
+ MetadataAwareOopClosure() : ExtendedOopClosure() { }
+ MetadataAwareOopClosure(ReferenceProcessor* rp) : ExtendedOopClosure(rp) { }
bool do_metadata_nv() { return true; }
virtual bool do_metadata() { return do_metadata_nv(); }
--- a/src/hotspot/share/memory/iterator.inline.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/memory/iterator.inline.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,10 +37,8 @@
#include "utilities/debug.hpp"
inline void MetadataAwareOopClosure::do_cld_nv(ClassLoaderData* cld) {
- assert(_klass_closure._oop_closure == this, "Must be");
-
bool claim = true; // Must claim the class loader data before processing.
- cld->oops_do(_klass_closure._oop_closure, &_klass_closure, claim);
+ cld->oops_do(this, claim);
}
inline void MetadataAwareOopClosure::do_klass_nv(Klass* k) {
--- a/src/hotspot/share/oops/instanceKlass.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/oops/instanceKlass.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -285,6 +285,9 @@
java_lang_Class::set_klass(java_mirror(), NULL);
}
+ // Also remove mirror from handles
+ loader_data->remove_handle(_java_mirror);
+
// Need to take this class off the class loader data list.
loader_data->remove_class(this);
--- a/src/hotspot/share/oops/klass.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/oops/klass.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -43,9 +43,16 @@
#include "trace/traceMacros.hpp"
#include "utilities/macros.hpp"
#include "utilities/stack.inline.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/g1/g1SATBCardTableModRefBS.hpp"
-#endif // INCLUDE_ALL_GCS
+
+void Klass::set_java_mirror(Handle m) {
+ assert(!m.is_null(), "New mirror should never be null.");
+ assert(_java_mirror.resolve() == NULL, "should only be used to initialize mirror");
+ _java_mirror = class_loader_data()->add_handle(m);
+}
+
+oop Klass::java_mirror() const {
+ return _java_mirror.resolve();
+}
bool Klass::is_cloneable() const {
return _access_flags.is_cloneable_fast() ||
@@ -441,51 +448,6 @@
}
}
-void Klass::klass_update_barrier_set(oop v) {
- record_modified_oops();
-}
-
-// This barrier is used by G1 to remember the old oop values, so
-// that we don't forget any objects that were live at the snapshot at
-// the beginning. This function is only used when we write oops into Klasses.
-void Klass::klass_update_barrier_set_pre(oop* p, oop v) {
-#if INCLUDE_ALL_GCS
- if (UseG1GC) {
- oop obj = *p;
- if (obj != NULL) {
- G1SATBCardTableModRefBS::enqueue(obj);
- }
- }
-#endif
-}
-
-void Klass::klass_oop_store(oop* p, oop v) {
- assert(!Universe::heap()->is_in_reserved((void*)p), "Should store pointer into metadata");
- assert(v == NULL || Universe::heap()->is_in_reserved((void*)v), "Should store pointer to an object");
-
- // do the store
- if (always_do_update_barrier) {
- klass_oop_store((volatile oop*)p, v);
- } else {
- klass_update_barrier_set_pre(p, v);
- *p = v;
- klass_update_barrier_set(v);
- }
-}
-
-void Klass::klass_oop_store(volatile oop* p, oop v) {
- assert(!Universe::heap()->is_in_reserved((void*)p), "Should store pointer into metadata");
- assert(v == NULL || Universe::heap()->is_in_reserved((void*)v), "Should store pointer to an object");
-
- klass_update_barrier_set_pre((oop*)p, v); // Cast away volatile.
- OrderAccess::release_store_ptr(p, v);
- klass_update_barrier_set(v);
-}
-
-void Klass::oops_do(OopClosure* cl) {
- cl->do_oop(&_java_mirror);
-}
-
void Klass::metaspace_pointers_do(MetaspaceClosure* it) {
if (log_is_enabled(Trace, cds)) {
ResourceMark rm;
@@ -532,7 +494,8 @@
ResourceMark rm;
log_trace(cds, unshareable)("remove java_mirror: %s", external_name());
}
- set_java_mirror(NULL);
+ // Just null out the mirror. The class_loader_data() no longer exists.
+ _java_mirror = NULL;
}
void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
--- a/src/hotspot/share/oops/klass.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/oops/klass.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -30,6 +30,7 @@
#include "memory/memRegion.hpp"
#include "oops/metadata.hpp"
#include "oops/oop.hpp"
+#include "oops/oopHandle.hpp"
#include "trace/traceMacros.hpp"
#include "utilities/accessFlags.hpp"
#include "utilities/macros.hpp"
@@ -119,7 +120,7 @@
// Ordered list of all primary supertypes
Klass* _primary_supers[_primary_super_limit];
// java/lang/Class instance mirroring this class
- oop _java_mirror;
+ OopHandle _java_mirror;
// Superclass
Klass* _super;
// First subclass (NULL if none); _subklass->next_sibling() is next one
@@ -148,10 +149,6 @@
// vtable length
int _vtable_len;
- // Remembered sets support for the oops in the klasses.
- jbyte _modified_oops; // Card Table Equivalent (YC/CMS support)
- jbyte _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
-
private:
// This is an index into FileMapHeader::_classpath_entry_table[], to
// associate this class with the JAR file where it's loaded from during
@@ -228,13 +225,15 @@
}
}
- // store an oop into a field of a Klass
- void klass_oop_store(oop* p, oop v);
- void klass_oop_store(volatile oop* p, oop v);
+ // java mirror
+ oop java_mirror() const;
+ void set_java_mirror(Handle m);
- // java mirror
- oop java_mirror() const { return _java_mirror; }
- void set_java_mirror(oop m) { klass_oop_store(&_java_mirror, m); }
+ // Temporary mirror switch used by RedefineClasses
+ // Both mirrors are on the ClassLoaderData::_handles list already so no
+ // barriers are needed.
+ void set_java_mirror_handle(OopHandle mirror) { _java_mirror = mirror; }
+ OopHandle java_mirror_handle() const { return _java_mirror; }
// modifier flags
jint modifier_flags() const { return _modifier_flags; }
@@ -260,17 +259,6 @@
ClassLoaderData* class_loader_data() const { return _class_loader_data; }
void set_class_loader_data(ClassLoaderData* loader_data) { _class_loader_data = loader_data; }
- // The Klasses are not placed in the Heap, so the Card Table or
- // the Mod Union Table can't be used to mark when klasses have modified oops.
- // The CT and MUT bits saves this information for the individual Klasses.
- void record_modified_oops() { _modified_oops = 1; }
- void clear_modified_oops() { _modified_oops = 0; }
- bool has_modified_oops() { return _modified_oops == 1; }
-
- void accumulate_modified_oops() { if (has_modified_oops()) _accumulated_modified_oops = 1; }
- void clear_accumulated_modified_oops() { _accumulated_modified_oops = 0; }
- bool has_accumulated_modified_oops() { return _accumulated_modified_oops == 1; }
-
int shared_classpath_index() const {
return _shared_class_path_index;
};
@@ -598,9 +586,6 @@
TRACE_DEFINE_TRACE_ID_METHODS;
- // garbage collection support
- void oops_do(OopClosure* cl);
-
virtual void metaspace_pointers_do(MetaspaceClosure* iter);
virtual MetaspaceObj::Type type() const { return ClassType; }
@@ -687,11 +672,6 @@
static Klass* decode_klass_not_null(narrowKlass v);
static Klass* decode_klass(narrowKlass v);
-
- private:
- // barriers used by klass_oop_store
- void klass_update_barrier_set(oop v);
- void klass_update_barrier_set_pre(oop* p, oop v);
};
// Helper to convert the oop iterate macro suffixes into bool values that can be used by template functions.
--- a/src/hotspot/share/opto/library_call.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/opto/library_call.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -3453,7 +3453,8 @@
// Given a klass oop, load its java mirror (a java.lang.Class oop).
Node* LibraryCallKit::load_mirror_from_klass(Node* klass) {
Node* p = basic_plus_adr(klass, in_bytes(Klass::java_mirror_offset()));
- return make_load(NULL, p, TypeInstPtr::MIRROR, T_OBJECT, MemNode::unordered);
+ Node* load = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
+ return make_load(NULL, load, TypeInstPtr::MIRROR, T_OBJECT, MemNode::unordered);
}
//-----------------------load_klass_from_mirror_common-------------------------
--- a/src/hotspot/share/opto/memnode.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/opto/memnode.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -1771,6 +1771,23 @@
Opcode() == Op_LoadKlass,
"Field accesses must be precise" );
// For klass/static loads, we expect the _type to be precise
+ } else if (tp->base() == Type::RawPtr && adr->is_Load() && off == 0) {
+ /* With mirrors being an indirect in the Klass*
+ * the VM is now using two loads. LoadKlass(LoadP(LoadP(Klass, mirror_offset), zero_offset))
+ * The LoadP from the Klass has a RawPtr type (see LibraryCallKit::load_mirror_from_klass).
+ *
+ * So check the type and klass of the node before the LoadP.
+ */
+ Node* adr2 = adr->in(MemNode::Address);
+ const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr();
+ if (tkls != NULL && !StressReflectiveCode) {
+ ciKlass* klass = tkls->klass();
+ if (klass->is_loaded() && tkls->klass_is_exact() && tkls->offset() == in_bytes(Klass::java_mirror_offset())) {
+ assert(adr->Opcode() == Op_LoadP, "must load an oop from _java_mirror");
+ assert(Opcode() == Op_LoadP, "must load an oop from _java_mirror");
+ return TypeInstPtr::make(klass->java_mirror());
+ }
+ }
}
const TypeKlassPtr *tkls = tp->isa_klassptr();
@@ -1798,12 +1815,6 @@
}
const Type* aift = load_array_final_field(tkls, klass);
if (aift != NULL) return aift;
- if (tkls->offset() == in_bytes(Klass::java_mirror_offset())) {
- // The field is Klass::_java_mirror. Return its (constant) value.
- // (Folds up the 2nd indirection in anObjConstant.getClass().)
- assert(Opcode() == Op_LoadP, "must load an oop from _java_mirror");
- return TypeInstPtr::make(klass->java_mirror());
- }
}
// We can still check if we are loading from the primary_supers array at a
@@ -2203,22 +2214,24 @@
// This improves reflective code, often making the Class
// mirror go completely dead. (Current exception: Class
// mirrors may appear in debug info, but we could clean them out by
- // introducing a new debug info operator for Klass*.java_mirror).
+ // introducing a new debug info operator for Klass.java_mirror).
+
if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass()
&& offset == java_lang_Class::klass_offset_in_bytes()) {
- // We are loading a special hidden field from a Class mirror,
- // the field which points to its Klass or ArrayKlass metaobject.
if (base->is_Load()) {
- Node* adr2 = base->in(MemNode::Address);
- const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr();
- if (tkls != NULL && !tkls->empty()
- && (tkls->klass()->is_instance_klass() ||
+ Node* base2 = base->in(MemNode::Address);
+ if (base2->is_Load()) { /* direct load of a load which is the oophandle */
+ Node* adr2 = base2->in(MemNode::Address);
+ const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr();
+ if (tkls != NULL && !tkls->empty()
+ && (tkls->klass()->is_instance_klass() ||
tkls->klass()->is_array_klass())
- && adr2->is_AddP()
- ) {
- int mirror_field = in_bytes(Klass::java_mirror_offset());
- if (tkls->offset() == mirror_field) {
- return adr2->in(AddPNode::Base);
+ && adr2->is_AddP()
+ ) {
+ int mirror_field = in_bytes(Klass::java_mirror_offset());
+ if (tkls->offset() == mirror_field) {
+ return adr2->in(AddPNode::Base);
+ }
}
}
}
--- a/src/hotspot/share/opto/subnode.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/opto/subnode.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -877,8 +877,8 @@
}
static inline Node* isa_java_mirror_load(PhaseGVN* phase, Node* n) {
- // Return the klass node for
- // LoadP(AddP(foo:Klass, #java_mirror))
+ // Return the klass node for (indirect load from OopHandle)
+ // LoadP(LoadP(AddP(foo:Klass, #java_mirror)))
// or NULL if not matching.
if (n->Opcode() != Op_LoadP) return NULL;
@@ -886,6 +886,10 @@
if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL;
Node* adr = n->in(MemNode::Address);
+ // First load from OopHandle
+ if (adr->Opcode() != Op_LoadP || !phase->type(adr)->isa_rawptr()) return NULL;
+ adr = adr->in(MemNode::Address);
+
intptr_t off = 0;
Node* k = AddPNode::Ideal_base_and_offset(adr, phase, off);
if (k == NULL) return NULL;
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -3026,8 +3026,7 @@
// Preloaded classes and loader from the system dictionary
blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS);
SystemDictionary::always_strong_oops_do(&blk);
- KlassToOopClosure klass_blk(&blk);
- ClassLoaderDataGraph::always_strong_oops_do(&blk, &klass_blk, false);
+ ClassLoaderDataGraph::always_strong_oops_do(&blk, false);
if (blk.stopped()) {
return false;
}
--- a/src/hotspot/share/prims/jvmtiThreadState.hpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/prims/jvmtiThreadState.hpp Tue Oct 03 16:42:04 2017 -0400
@@ -411,21 +411,21 @@
private:
JvmtiThreadState* _state;
Klass* _scratch_class;
- Handle _scratch_mirror;
+ OopHandle _scratch_mirror;
public:
RedefineVerifyMark(Klass* the_class, Klass* scratch_class,
JvmtiThreadState *state) : _state(state), _scratch_class(scratch_class)
{
_state->set_class_versions_map(the_class, scratch_class);
- _scratch_mirror = Handle(Thread::current(), _scratch_class->java_mirror());
- _scratch_class->set_java_mirror(the_class->java_mirror());
+ _scratch_mirror = _scratch_class->java_mirror_handle();
+ _scratch_class->set_java_mirror_handle(the_class->java_mirror_handle());
}
~RedefineVerifyMark() {
// Restore the scratch class's mirror, so when scratch_class is removed
// the correct mirror pointing to it can be cleared.
- _scratch_class->set_java_mirror(_scratch_mirror());
+ _scratch_class->set_java_mirror_handle(_scratch_mirror);
_state->clear_class_versions_map();
}
};
--- a/src/hotspot/share/runtime/vmStructs.cpp Fri Sep 29 10:44:58 2017 +0200
+++ b/src/hotspot/share/runtime/vmStructs.cpp Tue Oct 03 16:42:04 2017 -0400
@@ -277,7 +277,7 @@
nonstatic_field(Klass, _secondary_super_cache, Klass*) \
nonstatic_field(Klass, _secondary_supers, Array<Klass*>*) \
nonstatic_field(Klass, _primary_supers[0], Klass*) \
- nonstatic_field(Klass, _java_mirror, oop) \
+ nonstatic_field(Klass, _java_mirror, OopHandle) \
nonstatic_field(Klass, _modifier_flags, jint) \
nonstatic_field(Klass, _super, Klass*) \
nonstatic_field(Klass, _subklass, Klass*) \
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java Fri Sep 29 10:44:58 2017 +0200
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java Tue Oct 03 16:42:04 2017 -0400
@@ -51,7 +51,7 @@
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("Klass");
- javaMirror = new OopField(type.getOopField("_java_mirror"), 0);
+ javaMirror = type.getAddressField("_java_mirror");
superField = new MetadataField(type.getAddressField("_super"), 0);
layoutHelper = new IntField(type.getJIntField("_layout_helper"), 0);
name = type.getAddressField("_name");
@@ -88,7 +88,7 @@
public boolean isKlass() { return true; }
// Fields
- private static OopField javaMirror;
+ private static AddressField javaMirror;
private static MetadataField superField;
private static IntField layoutHelper;
private static AddressField name;
@@ -109,7 +109,15 @@
}
// Accessors for declared fields
- public Instance getJavaMirror() { return (Instance) javaMirror.getValue(this); }
+ public Instance getJavaMirror() {
+ Address handle = javaMirror.getValue(getAddress());
+ if (handle != null) {
+ // Load through the handle
+ OopHandle refs = handle.getOopHandleAt(0);
+ return (Instance)VM.getVM().getObjectHeap().newOop(refs);
+ }
+ return null;
+ }
public Klass getSuper() { return (Klass) superField.getValue(this); }
public Klass getJavaSuper() { return null; }
public int getLayoutHelper() { return (int) layoutHelper.getValue(this); }
@@ -185,7 +193,7 @@
}
public void iterateFields(MetadataVisitor visitor) {
- visitor.doOop(javaMirror, true);
+ // visitor.doOop(javaMirror, true);
visitor.doMetadata(superField, true);
visitor.doInt(layoutHelper, true);
// visitor.doOop(name, true);
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java Fri Sep 29 10:44:58 2017 +0200
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -138,21 +138,6 @@
return true;
}
- private boolean isValidObjectFieldDisplacement(Constant base, long displacement) {
- if (base instanceof HotSpotMetaspaceConstant) {
- MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
- if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
- if (displacement == runtime.getConfig().classMirrorOffset) {
- // Klass::_java_mirror is valid for all Klass* values
- return true;
- }
- } else {
- throw new IllegalArgumentException(String.valueOf(metaspaceObject));
- }
- }
- return false;
- }
-
private static long asRawPointer(Constant base) {
if (base instanceof HotSpotMetaspaceConstantImpl) {
MetaspaceWrapperObject meta = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
@@ -202,7 +187,7 @@
if (base instanceof HotSpotMetaspaceConstant) {
MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
- if (displacement == runtime.getConfig().classMirrorOffset) {
+ if (displacement == runtime.getConfig().classMirrorHandleOffset) {
assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
}
}
@@ -294,10 +279,18 @@
Object o = readRawObject(base, displacement, runtime.getConfig().useCompressedOops);
return HotSpotObjectConstantImpl.forObject(o);
}
- if (!isValidObjectFieldDisplacement(base, displacement)) {
- return null;
+ if (base instanceof HotSpotMetaspaceConstant) {
+ MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
+ if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
+ if (displacement == runtime.getConfig().classMirrorHandleOffset) {
+ // Klass::_java_mirror is valid for all Klass* values
+ return HotSpotObjectConstantImpl.forObject(((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror());
+ }
+ } else {
+ throw new IllegalArgumentException(String.valueOf(metaspaceObject));
+ }
}
- return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, false));
+ return null;
}
@Override
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Fri Sep 29 10:44:58 2017 +0200
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,7 @@
/**
* The offset of the _java_mirror field (of type {@link Class}) in a Klass.
*/
- final int classMirrorOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "oop");
+ final int classMirrorHandleOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle");
final int klassAccessFlagsOffset = getFieldOffset("Klass::_access_flags", Integer.class, "AccessFlags");
final int klassLayoutHelperOffset = getFieldOffset("Klass::_layout_helper", Integer.class, "jint");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Fri Sep 29 10:44:58 2017 +0200
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -280,14 +280,14 @@
}
if (offset == -1) {
try {
- offset = getFieldOffset(name, Integer.class, "jobject");
+ offset = getFieldOffset(name, Integer.class, "OopHandle");
isHandle = true;
} catch (JVMCIError e) {
}
}
if (offset == -1) {
- throw new JVMCIError("cannot get offset of field " + name + " with type oop or jobject");
+ throw new JVMCIError("cannot get offset of field " + name + " with type oop or OopHandle");
}
classMirrorOffset = offset;
classMirrorIsHandle = isHandle;
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java Fri Sep 29 10:44:58 2017 +0200
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -110,7 +110,7 @@
test(asm -> {
ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
Register klass = asm.emitLoadPointer((HotSpotConstant) constantReflection.asObjectHub(type));
- Register ret = asm.emitLoadPointer(klass, config.classMirrorOffset);
+ Register ret = asm.emitLoadPointer(asm.emitLoadPointer(klass, config.classMirrorHandleOffset), 0);
asm.emitPointerRet(ret);
});
}
@@ -123,7 +123,7 @@
HotSpotConstant hub = (HotSpotConstant) constantReflection.asObjectHub(type);
Register narrowKlass = asm.emitLoadPointer((HotSpotConstant) hub.compress());
Register klass = asm.emitUncompressPointer(narrowKlass, config.narrowKlassBase, config.narrowKlassShift);
- Register ret = asm.emitLoadPointer(klass, config.classMirrorOffset);
+ Register ret = asm.emitLoadPointer(asm.emitLoadPointer(klass, config.classMirrorHandleOffset), 0);
asm.emitPointerRet(ret);
});
}
@@ -135,7 +135,7 @@
HotSpotConstant hub = (HotSpotConstant) constantReflection.asObjectHub(type);
DataSectionReference ref = asm.emitDataItem(hub);
Register klass = asm.emitLoadPointer(ref);
- Register ret = asm.emitLoadPointer(klass, config.classMirrorOffset);
+ Register ret = asm.emitLoadPointer(asm.emitLoadPointer(klass, config.classMirrorHandleOffset), 0);
asm.emitPointerRet(ret);
});
}
@@ -150,7 +150,7 @@
DataSectionReference ref = asm.emitDataItem(narrowHub);
Register narrowKlass = asm.emitLoadNarrowPointer(ref);
Register klass = asm.emitUncompressPointer(narrowKlass, config.narrowKlassBase, config.narrowKlassShift);
- Register ret = asm.emitLoadPointer(klass, config.classMirrorOffset);
+ Register ret = asm.emitLoadPointer(asm.emitLoadPointer(klass, config.classMirrorHandleOffset), 0);
asm.emitPointerRet(ret);
});
}
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestHotSpotVMConfig.java Fri Sep 29 10:44:58 2017 +0200
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestHotSpotVMConfig.java Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
public final long narrowKlassBase = getFieldValue("CompilerToVM::Data::Universe_narrow_klass_base", Long.class, "address");
public final int narrowKlassShift = getFieldValue("CompilerToVM::Data::Universe_narrow_klass_shift", Integer.class, "int");
- public final int classMirrorOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "oop");
+ public final int classMirrorHandleOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle");
public final int MARKID_DEOPT_HANDLER_ENTRY = getConstant("CodeInstaller::DEOPT_HANDLER_ENTRY", Integer.class);
public final long handleDeoptStub = getFieldValue("CompilerToVM::Data::SharedRuntime_deopt_blob_unpack", Long.class, "address");
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderData.java Fri Sep 29 10:44:58 2017 +0200
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderData.java Tue Oct 03 16:42:04 2017 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,7 +64,7 @@
@DataProvider(name = "positiveObject")
public static Object[][] getPositiveObjectJavaKind() {
HotSpotJVMCIRuntimeProvider runtime = (HotSpotJVMCIRuntimeProvider) JVMCI.getRuntime();
- int offset = new HotSpotVMConfigAccess(runtime.getConfigStore()).getFieldOffset("Klass::_java_mirror", Integer.class, "oop");
+ int offset = new HotSpotVMConfigAccess(runtime.getConfigStore()).getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle");
Constant wrappedKlassPointer = ((HotSpotResolvedObjectType) runtime.fromClass(TestClass.class)).klass();
return new Object[][]{new Object[]{JavaKind.Object, wrappedKlassPointer, (long) offset, TEST_CLASS_CONSTANT, 0}};
}