Merge
This commit is contained in:
commit
ec13301b32
@ -4586,7 +4586,6 @@ g1_process_strong_roots(bool collecting_perm_gen,
|
|||||||
// keep entries (which are added by the marking threads) on them
|
// keep entries (which are added by the marking threads) on them
|
||||||
// live until they can be processed at the end of marking.
|
// live until they can be processed at the end of marking.
|
||||||
ref_processor()->weak_oops_do(&buf_scan_non_heap_roots);
|
ref_processor()->weak_oops_do(&buf_scan_non_heap_roots);
|
||||||
ref_processor()->oops_do(&buf_scan_non_heap_roots);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish up any enqueued closure apps (attributed as object copy time).
|
// Finish up any enqueued closure apps (attributed as object copy time).
|
||||||
|
@ -909,10 +909,6 @@ void ParallelScavengeHeap::verify(bool allow_dirty, bool silent, VerifyOption op
|
|||||||
}
|
}
|
||||||
young_gen()->verify(allow_dirty);
|
young_gen()->verify(allow_dirty);
|
||||||
}
|
}
|
||||||
if (!silent) {
|
|
||||||
gclog_or_tty->print("ref_proc ");
|
|
||||||
}
|
|
||||||
ReferenceProcessor::verify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParallelScavengeHeap::print_heap_change(size_t prev_used) {
|
void ParallelScavengeHeap::print_heap_change(size_t prev_used) {
|
||||||
|
@ -80,10 +80,6 @@ void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
|
|||||||
Universe::oops_do(&mark_and_push_closure);
|
Universe::oops_do(&mark_and_push_closure);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case reference_processing:
|
|
||||||
ReferenceProcessor::oops_do(&mark_and_push_closure);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case jni_handles:
|
case jni_handles:
|
||||||
JNIHandles::oops_do(&mark_and_push_closure);
|
JNIHandles::oops_do(&mark_and_push_closure);
|
||||||
break;
|
break;
|
||||||
|
@ -98,8 +98,7 @@ class MarkFromRootsTask : public GCTask {
|
|||||||
management = 6,
|
management = 6,
|
||||||
jvmti = 7,
|
jvmti = 7,
|
||||||
system_dictionary = 8,
|
system_dictionary = 8,
|
||||||
reference_processing = 9,
|
code_cache = 9
|
||||||
code_cache = 10
|
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
RootType _root_type;
|
RootType _root_type;
|
||||||
|
@ -516,7 +516,6 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
|||||||
{
|
{
|
||||||
ParallelScavengeHeap::ParStrongRootsScope psrs;
|
ParallelScavengeHeap::ParStrongRootsScope psrs;
|
||||||
Universe::oops_do(mark_and_push_closure());
|
Universe::oops_do(mark_and_push_closure());
|
||||||
ReferenceProcessor::oops_do(mark_and_push_closure());
|
|
||||||
JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles
|
JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles
|
||||||
CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true);
|
CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true);
|
||||||
Threads::oops_do(mark_and_push_closure(), &each_active_code_blob);
|
Threads::oops_do(mark_and_push_closure(), &each_active_code_blob);
|
||||||
@ -623,7 +622,6 @@ void PSMarkSweep::mark_sweep_phase3() {
|
|||||||
|
|
||||||
// General strong roots.
|
// General strong roots.
|
||||||
Universe::oops_do(adjust_root_pointer_closure());
|
Universe::oops_do(adjust_root_pointer_closure());
|
||||||
ReferenceProcessor::oops_do(adjust_root_pointer_closure());
|
|
||||||
JNIHandles::oops_do(adjust_root_pointer_closure()); // Global (strong) JNI handles
|
JNIHandles::oops_do(adjust_root_pointer_closure()); // Global (strong) JNI handles
|
||||||
Threads::oops_do(adjust_root_pointer_closure(), NULL);
|
Threads::oops_do(adjust_root_pointer_closure(), NULL);
|
||||||
ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
|
ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
|
||||||
|
@ -2445,7 +2445,6 @@ void PSParallelCompact::adjust_roots() {
|
|||||||
|
|
||||||
// General strong roots.
|
// General strong roots.
|
||||||
Universe::oops_do(adjust_root_pointer_closure());
|
Universe::oops_do(adjust_root_pointer_closure());
|
||||||
ReferenceProcessor::oops_do(adjust_root_pointer_closure());
|
|
||||||
JNIHandles::oops_do(adjust_root_pointer_closure()); // Global (strong) JNI handles
|
JNIHandles::oops_do(adjust_root_pointer_closure()); // Global (strong) JNI handles
|
||||||
Threads::oops_do(adjust_root_pointer_closure(), NULL);
|
Threads::oops_do(adjust_root_pointer_closure(), NULL);
|
||||||
ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
|
ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
|
||||||
|
@ -55,7 +55,6 @@ void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
|
|||||||
switch (_root_type) {
|
switch (_root_type) {
|
||||||
case universe:
|
case universe:
|
||||||
Universe::oops_do(&roots_closure);
|
Universe::oops_do(&roots_closure);
|
||||||
ReferenceProcessor::oops_do(&roots_closure);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case jni_handles:
|
case jni_handles:
|
||||||
|
@ -1269,10 +1269,6 @@ void GenCollectedHeap::verify(bool allow_dirty, bool silent, VerifyOption option
|
|||||||
gclog_or_tty->print("remset ");
|
gclog_or_tty->print("remset ");
|
||||||
}
|
}
|
||||||
rem_set()->verify();
|
rem_set()->verify();
|
||||||
if (!silent) {
|
|
||||||
gclog_or_tty->print("ref_proc ");
|
|
||||||
}
|
|
||||||
ReferenceProcessor::verify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenCollectedHeap::print() const { print_on(tty); }
|
void GenCollectedHeap::print() const { print_on(tty); }
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
|
|
||||||
ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
|
ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
|
||||||
ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL;
|
ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL;
|
||||||
oop ReferenceProcessor::_sentinelRef = NULL;
|
|
||||||
const int subclasses_of_ref = REF_PHANTOM - REF_OTHER;
|
const int subclasses_of_ref = REF_PHANTOM - REF_OTHER;
|
||||||
|
|
||||||
// List of discovered references.
|
// List of discovered references.
|
||||||
@ -43,7 +42,7 @@ class DiscoveredList {
|
|||||||
public:
|
public:
|
||||||
DiscoveredList() : _len(0), _compressed_head(0), _oop_head(NULL) { }
|
DiscoveredList() : _len(0), _compressed_head(0), _oop_head(NULL) { }
|
||||||
oop head() const {
|
oop head() const {
|
||||||
return UseCompressedOops ? oopDesc::decode_heap_oop_not_null(_compressed_head) :
|
return UseCompressedOops ? oopDesc::decode_heap_oop(_compressed_head) :
|
||||||
_oop_head;
|
_oop_head;
|
||||||
}
|
}
|
||||||
HeapWord* adr_head() {
|
HeapWord* adr_head() {
|
||||||
@ -53,12 +52,12 @@ public:
|
|||||||
void set_head(oop o) {
|
void set_head(oop o) {
|
||||||
if (UseCompressedOops) {
|
if (UseCompressedOops) {
|
||||||
// Must compress the head ptr.
|
// Must compress the head ptr.
|
||||||
_compressed_head = oopDesc::encode_heap_oop_not_null(o);
|
_compressed_head = oopDesc::encode_heap_oop(o);
|
||||||
} else {
|
} else {
|
||||||
_oop_head = o;
|
_oop_head = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool empty() const { return head() == ReferenceProcessor::sentinel_ref(); }
|
bool empty() const { return head() == NULL; }
|
||||||
size_t length() { return _len; }
|
size_t length() { return _len; }
|
||||||
void set_length(size_t len) { _len = len; }
|
void set_length(size_t len) { _len = len; }
|
||||||
void inc_length(size_t inc) { _len += inc; assert(_len > 0, "Error"); }
|
void inc_length(size_t inc) { _len += inc; assert(_len > 0, "Error"); }
|
||||||
@ -76,21 +75,9 @@ void referenceProcessor_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ReferenceProcessor::init_statics() {
|
void ReferenceProcessor::init_statics() {
|
||||||
assert(_sentinelRef == NULL, "should be initialized precisely once");
|
|
||||||
EXCEPTION_MARK;
|
|
||||||
_sentinelRef = instanceKlass::cast(
|
|
||||||
SystemDictionary::Reference_klass())->
|
|
||||||
allocate_permanent_instance(THREAD);
|
|
||||||
|
|
||||||
// Initialize the master soft ref clock.
|
// Initialize the master soft ref clock.
|
||||||
java_lang_ref_SoftReference::set_clock(os::javaTimeMillis());
|
java_lang_ref_SoftReference::set_clock(os::javaTimeMillis());
|
||||||
|
|
||||||
if (HAS_PENDING_EXCEPTION) {
|
|
||||||
Handle ex(THREAD, PENDING_EXCEPTION);
|
|
||||||
vm_exit_during_initialization(ex);
|
|
||||||
}
|
|
||||||
assert(_sentinelRef != NULL && _sentinelRef->is_oop(),
|
|
||||||
"Just constructed it!");
|
|
||||||
_always_clear_soft_ref_policy = new AlwaysClearPolicy();
|
_always_clear_soft_ref_policy = new AlwaysClearPolicy();
|
||||||
_default_soft_ref_policy = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
|
_default_soft_ref_policy = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
|
||||||
NOT_COMPILER2(LRUCurrentHeapPolicy());
|
NOT_COMPILER2(LRUCurrentHeapPolicy());
|
||||||
@ -130,10 +117,9 @@ ReferenceProcessor::ReferenceProcessor(MemRegion span,
|
|||||||
_discoveredWeakRefs = &_discoveredSoftRefs[_max_num_q];
|
_discoveredWeakRefs = &_discoveredSoftRefs[_max_num_q];
|
||||||
_discoveredFinalRefs = &_discoveredWeakRefs[_max_num_q];
|
_discoveredFinalRefs = &_discoveredWeakRefs[_max_num_q];
|
||||||
_discoveredPhantomRefs = &_discoveredFinalRefs[_max_num_q];
|
_discoveredPhantomRefs = &_discoveredFinalRefs[_max_num_q];
|
||||||
assert(sentinel_ref() != NULL, "_sentinelRef is NULL");
|
// Initialized all entries to NULL
|
||||||
// Initialized all entries to _sentinelRef
|
|
||||||
for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
|
for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
|
||||||
_discoveredSoftRefs[i].set_head(sentinel_ref());
|
_discoveredSoftRefs[i].set_head(NULL);
|
||||||
_discoveredSoftRefs[i].set_length(0);
|
_discoveredSoftRefs[i].set_length(0);
|
||||||
}
|
}
|
||||||
// If we do barreirs, cache a copy of the barrier set.
|
// If we do barreirs, cache a copy of the barrier set.
|
||||||
@ -167,10 +153,6 @@ void ReferenceProcessor::weak_oops_do(OopClosure* f) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReferenceProcessor::oops_do(OopClosure* f) {
|
|
||||||
f->do_oop(adr_sentinel_ref());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReferenceProcessor::update_soft_ref_master_clock() {
|
void ReferenceProcessor::update_soft_ref_master_clock() {
|
||||||
// Update (advance) the soft ref master clock field. This must be done
|
// Update (advance) the soft ref master clock field. This must be done
|
||||||
// after processing the soft ref list.
|
// after processing the soft ref list.
|
||||||
@ -283,8 +265,6 @@ void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
JNIHandles::weak_oops_do(is_alive, keep_alive);
|
JNIHandles::weak_oops_do(is_alive, keep_alive);
|
||||||
// Finally remember to keep sentinel around
|
|
||||||
keep_alive->do_oop(adr_sentinel_ref());
|
|
||||||
complete_gc->do_void();
|
complete_gc->do_void();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,21 +314,22 @@ void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
|
|||||||
gclog_or_tty->print_cr("ReferenceProcessor::enqueue_discovered_reflist list "
|
gclog_or_tty->print_cr("ReferenceProcessor::enqueue_discovered_reflist list "
|
||||||
INTPTR_FORMAT, (address)refs_list.head());
|
INTPTR_FORMAT, (address)refs_list.head());
|
||||||
}
|
}
|
||||||
oop obj = refs_list.head();
|
|
||||||
|
oop obj = NULL;
|
||||||
|
oop next = refs_list.head();
|
||||||
// Walk down the list, copying the discovered field into
|
// Walk down the list, copying the discovered field into
|
||||||
// the next field and clearing it (except for the last
|
// the next field and clearing it.
|
||||||
// non-sentinel object which is treated specially to avoid
|
while (obj != next) {
|
||||||
// confusion with an active reference).
|
obj = next;
|
||||||
while (obj != sentinel_ref()) {
|
|
||||||
assert(obj->is_instanceRef(), "should be reference object");
|
assert(obj->is_instanceRef(), "should be reference object");
|
||||||
oop next = java_lang_ref_Reference::discovered(obj);
|
next = java_lang_ref_Reference::discovered(obj);
|
||||||
if (TraceReferenceGC && PrintGCDetails) {
|
if (TraceReferenceGC && PrintGCDetails) {
|
||||||
gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next " INTPTR_FORMAT,
|
gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next " INTPTR_FORMAT,
|
||||||
obj, next);
|
obj, next);
|
||||||
}
|
}
|
||||||
assert(java_lang_ref_Reference::next(obj) == NULL,
|
assert(java_lang_ref_Reference::next(obj) == NULL,
|
||||||
"The reference should not be enqueued");
|
"The reference should not be enqueued");
|
||||||
if (next == sentinel_ref()) { // obj is last
|
if (next == obj) { // obj is last
|
||||||
// Swap refs_list into pendling_list_addr and
|
// Swap refs_list into pendling_list_addr and
|
||||||
// set obj's next to what we read from pending_list_addr.
|
// set obj's next to what we read from pending_list_addr.
|
||||||
oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
|
oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
|
||||||
@ -366,7 +347,6 @@ void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
|
|||||||
java_lang_ref_Reference::set_next(obj, next);
|
java_lang_ref_Reference::set_next(obj, next);
|
||||||
}
|
}
|
||||||
java_lang_ref_Reference::set_discovered(obj, (oop) NULL);
|
java_lang_ref_Reference::set_discovered(obj, (oop) NULL);
|
||||||
obj = next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,10 +356,9 @@ public:
|
|||||||
RefProcEnqueueTask(ReferenceProcessor& ref_processor,
|
RefProcEnqueueTask(ReferenceProcessor& ref_processor,
|
||||||
DiscoveredList discovered_refs[],
|
DiscoveredList discovered_refs[],
|
||||||
HeapWord* pending_list_addr,
|
HeapWord* pending_list_addr,
|
||||||
oop sentinel_ref,
|
|
||||||
int n_queues)
|
int n_queues)
|
||||||
: EnqueueTask(ref_processor, discovered_refs,
|
: EnqueueTask(ref_processor, discovered_refs,
|
||||||
pending_list_addr, sentinel_ref, n_queues)
|
pending_list_addr, n_queues)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void work(unsigned int work_id) {
|
virtual void work(unsigned int work_id) {
|
||||||
@ -396,7 +375,7 @@ public:
|
|||||||
j++, index += _n_queues) {
|
j++, index += _n_queues) {
|
||||||
_ref_processor.enqueue_discovered_reflist(
|
_ref_processor.enqueue_discovered_reflist(
|
||||||
_refs_lists[index], _pending_list_addr);
|
_refs_lists[index], _pending_list_addr);
|
||||||
_refs_lists[index].set_head(_sentinel_ref);
|
_refs_lists[index].set_head(NULL);
|
||||||
_refs_lists[index].set_length(0);
|
_refs_lists[index].set_length(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -408,13 +387,13 @@ void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr
|
|||||||
if (_processing_is_mt && task_executor != NULL) {
|
if (_processing_is_mt && task_executor != NULL) {
|
||||||
// Parallel code
|
// Parallel code
|
||||||
RefProcEnqueueTask tsk(*this, _discoveredSoftRefs,
|
RefProcEnqueueTask tsk(*this, _discoveredSoftRefs,
|
||||||
pending_list_addr, sentinel_ref(), _max_num_q);
|
pending_list_addr, _max_num_q);
|
||||||
task_executor->execute(tsk);
|
task_executor->execute(tsk);
|
||||||
} else {
|
} else {
|
||||||
// Serial code: call the parent class's implementation
|
// Serial code: call the parent class's implementation
|
||||||
for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
|
for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
|
||||||
enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr);
|
enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr);
|
||||||
_discoveredSoftRefs[i].set_head(sentinel_ref());
|
_discoveredSoftRefs[i].set_head(NULL);
|
||||||
_discoveredSoftRefs[i].set_length(0);
|
_discoveredSoftRefs[i].set_length(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -428,7 +407,7 @@ public:
|
|||||||
BoolObjectClosure* is_alive);
|
BoolObjectClosure* is_alive);
|
||||||
|
|
||||||
// End Of List.
|
// End Of List.
|
||||||
inline bool has_next() const { return _next != ReferenceProcessor::sentinel_ref(); }
|
inline bool has_next() const { return _ref != NULL; }
|
||||||
|
|
||||||
// Get oop to the Reference object.
|
// Get oop to the Reference object.
|
||||||
inline oop obj() const { return _ref; }
|
inline oop obj() const { return _ref; }
|
||||||
@ -468,11 +447,15 @@ public:
|
|||||||
inline void update_discovered() {
|
inline void update_discovered() {
|
||||||
// First _prev_next ref actually points into DiscoveredList (gross).
|
// First _prev_next ref actually points into DiscoveredList (gross).
|
||||||
if (UseCompressedOops) {
|
if (UseCompressedOops) {
|
||||||
|
if (!oopDesc::is_null(*(narrowOop*)_prev_next)) {
|
||||||
_keep_alive->do_oop((narrowOop*)_prev_next);
|
_keep_alive->do_oop((narrowOop*)_prev_next);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!oopDesc::is_null(*(oop*)_prev_next)) {
|
||||||
_keep_alive->do_oop((oop*)_prev_next);
|
_keep_alive->do_oop((oop*)_prev_next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NULL out referent pointer.
|
// NULL out referent pointer.
|
||||||
inline void clear_referent() { oop_store_raw(_referent_addr, NULL); }
|
inline void clear_referent() { oop_store_raw(_referent_addr, NULL); }
|
||||||
@ -488,6 +471,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
DiscoveredList& _refs_list;
|
DiscoveredList& _refs_list;
|
||||||
HeapWord* _prev_next;
|
HeapWord* _prev_next;
|
||||||
|
oop _prev;
|
||||||
oop _ref;
|
oop _ref;
|
||||||
HeapWord* _discovered_addr;
|
HeapWord* _discovered_addr;
|
||||||
oop _next;
|
oop _next;
|
||||||
@ -509,6 +493,7 @@ inline DiscoveredListIterator::DiscoveredListIterator(DiscoveredList& refs_li
|
|||||||
BoolObjectClosure* is_alive)
|
BoolObjectClosure* is_alive)
|
||||||
: _refs_list(refs_list),
|
: _refs_list(refs_list),
|
||||||
_prev_next(refs_list.adr_head()),
|
_prev_next(refs_list.adr_head()),
|
||||||
|
_prev(NULL),
|
||||||
_ref(refs_list.head()),
|
_ref(refs_list.head()),
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
_first_seen(refs_list.head()),
|
_first_seen(refs_list.head()),
|
||||||
@ -517,7 +502,7 @@ inline DiscoveredListIterator::DiscoveredListIterator(DiscoveredList& refs_li
|
|||||||
_processed(0),
|
_processed(0),
|
||||||
_removed(0),
|
_removed(0),
|
||||||
#endif
|
#endif
|
||||||
_next(refs_list.head()),
|
_next(NULL),
|
||||||
_keep_alive(keep_alive),
|
_keep_alive(keep_alive),
|
||||||
_is_alive(is_alive)
|
_is_alive(is_alive)
|
||||||
{ }
|
{ }
|
||||||
@ -544,26 +529,43 @@ inline void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referen
|
|||||||
|
|
||||||
inline void DiscoveredListIterator::next() {
|
inline void DiscoveredListIterator::next() {
|
||||||
_prev_next = _discovered_addr;
|
_prev_next = _discovered_addr;
|
||||||
|
_prev = _ref;
|
||||||
move_to_next();
|
move_to_next();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void DiscoveredListIterator::remove() {
|
inline void DiscoveredListIterator::remove() {
|
||||||
assert(_ref->is_oop(), "Dropping a bad reference");
|
assert(_ref->is_oop(), "Dropping a bad reference");
|
||||||
oop_store_raw(_discovered_addr, NULL);
|
oop_store_raw(_discovered_addr, NULL);
|
||||||
|
|
||||||
// First _prev_next ref actually points into DiscoveredList (gross).
|
// First _prev_next ref actually points into DiscoveredList (gross).
|
||||||
|
oop new_next;
|
||||||
|
if (_next == _ref) {
|
||||||
|
// At the end of the list, we should make _prev point to itself.
|
||||||
|
// If _ref is the first ref, then _prev_next will be in the DiscoveredList,
|
||||||
|
// and _prev will be NULL.
|
||||||
|
new_next = _prev;
|
||||||
|
} else {
|
||||||
|
new_next = _next;
|
||||||
|
}
|
||||||
|
|
||||||
if (UseCompressedOops) {
|
if (UseCompressedOops) {
|
||||||
// Remove Reference object from list.
|
// Remove Reference object from list.
|
||||||
oopDesc::encode_store_heap_oop_not_null((narrowOop*)_prev_next, _next);
|
oopDesc::encode_store_heap_oop((narrowOop*)_prev_next, new_next);
|
||||||
} else {
|
} else {
|
||||||
// Remove Reference object from list.
|
// Remove Reference object from list.
|
||||||
oopDesc::store_heap_oop((oop*)_prev_next, _next);
|
oopDesc::store_heap_oop((oop*)_prev_next, new_next);
|
||||||
}
|
}
|
||||||
NOT_PRODUCT(_removed++);
|
NOT_PRODUCT(_removed++);
|
||||||
_refs_list.dec_length(1);
|
_refs_list.dec_length(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void DiscoveredListIterator::move_to_next() {
|
inline void DiscoveredListIterator::move_to_next() {
|
||||||
|
if (_ref == _next) {
|
||||||
|
// End of the list.
|
||||||
|
_ref = NULL;
|
||||||
|
} else {
|
||||||
_ref = _next;
|
_ref = _next;
|
||||||
|
}
|
||||||
assert(_ref != _first_seen, "cyclic ref_list found");
|
assert(_ref != _first_seen, "cyclic ref_list found");
|
||||||
NOT_PRODUCT(_processed++);
|
NOT_PRODUCT(_processed++);
|
||||||
}
|
}
|
||||||
@ -725,24 +727,30 @@ ReferenceProcessor::process_phase3(DiscoveredList& refs_list,
|
|||||||
assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
|
assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
|
||||||
iter.next();
|
iter.next();
|
||||||
}
|
}
|
||||||
// Remember to keep sentinel pointer around
|
// Remember to update the next pointer of the last ref.
|
||||||
iter.update_discovered();
|
iter.update_discovered();
|
||||||
// Close the reachable set
|
// Close the reachable set
|
||||||
complete_gc->do_void();
|
complete_gc->do_void();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ReferenceProcessor::abandon_partial_discovered_list(DiscoveredList& refs_list) {
|
ReferenceProcessor::clear_discovered_references(DiscoveredList& refs_list) {
|
||||||
oop obj = refs_list.head();
|
oop obj = NULL;
|
||||||
while (obj != sentinel_ref()) {
|
oop next = refs_list.head();
|
||||||
oop discovered = java_lang_ref_Reference::discovered(obj);
|
while (next != obj) {
|
||||||
|
obj = next;
|
||||||
|
next = java_lang_ref_Reference::discovered(obj);
|
||||||
java_lang_ref_Reference::set_discovered_raw(obj, NULL);
|
java_lang_ref_Reference::set_discovered_raw(obj, NULL);
|
||||||
obj = discovered;
|
|
||||||
}
|
}
|
||||||
refs_list.set_head(sentinel_ref());
|
refs_list.set_head(NULL);
|
||||||
refs_list.set_length(0);
|
refs_list.set_length(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ReferenceProcessor::abandon_partial_discovered_list(DiscoveredList& refs_list) {
|
||||||
|
clear_discovered_references(refs_list);
|
||||||
|
}
|
||||||
|
|
||||||
void ReferenceProcessor::abandon_partial_discovery() {
|
void ReferenceProcessor::abandon_partial_discovery() {
|
||||||
// loop over the lists
|
// loop over the lists
|
||||||
for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
|
for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
|
||||||
@ -859,6 +867,9 @@ void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[])
|
|||||||
refs_to_move = MIN2(ref_lists[from_idx].length() - avg_refs,
|
refs_to_move = MIN2(ref_lists[from_idx].length() - avg_refs,
|
||||||
avg_refs - ref_lists[to_idx].length());
|
avg_refs - ref_lists[to_idx].length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(refs_to_move > 0, "otherwise the code below will fail");
|
||||||
|
|
||||||
oop move_head = ref_lists[from_idx].head();
|
oop move_head = ref_lists[from_idx].head();
|
||||||
oop move_tail = move_head;
|
oop move_tail = move_head;
|
||||||
oop new_head = move_head;
|
oop new_head = move_head;
|
||||||
@ -867,10 +878,24 @@ void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[])
|
|||||||
move_tail = new_head;
|
move_tail = new_head;
|
||||||
new_head = java_lang_ref_Reference::discovered(new_head);
|
new_head = java_lang_ref_Reference::discovered(new_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the chain to the to list.
|
||||||
|
if (ref_lists[to_idx].head() == NULL) {
|
||||||
|
// to list is empty. Make a loop at the end.
|
||||||
|
java_lang_ref_Reference::set_discovered(move_tail, move_tail);
|
||||||
|
} else {
|
||||||
java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head());
|
java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head());
|
||||||
|
}
|
||||||
ref_lists[to_idx].set_head(move_head);
|
ref_lists[to_idx].set_head(move_head);
|
||||||
ref_lists[to_idx].inc_length(refs_to_move);
|
ref_lists[to_idx].inc_length(refs_to_move);
|
||||||
|
|
||||||
|
// Remove the chain from the from list.
|
||||||
|
if (move_tail == new_head) {
|
||||||
|
// We found the end of the from list.
|
||||||
|
ref_lists[from_idx].set_head(NULL);
|
||||||
|
} else {
|
||||||
ref_lists[from_idx].set_head(new_head);
|
ref_lists[from_idx].set_head(new_head);
|
||||||
|
}
|
||||||
ref_lists[from_idx].dec_length(refs_to_move);
|
ref_lists[from_idx].dec_length(refs_to_move);
|
||||||
if (ref_lists[from_idx].length() == 0) {
|
if (ref_lists[from_idx].length() == 0) {
|
||||||
break;
|
break;
|
||||||
@ -1082,6 +1107,8 @@ ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
|
|||||||
// First we must make sure this object is only enqueued once. CAS in a non null
|
// First we must make sure this object is only enqueued once. CAS in a non null
|
||||||
// discovered_addr.
|
// discovered_addr.
|
||||||
oop current_head = refs_list.head();
|
oop current_head = refs_list.head();
|
||||||
|
// The last ref must have its discovered field pointing to itself.
|
||||||
|
oop next_discovered = (current_head != NULL) ? current_head : obj;
|
||||||
|
|
||||||
// Note: In the case of G1, this specific pre-barrier is strictly
|
// Note: In the case of G1, this specific pre-barrier is strictly
|
||||||
// not necessary because the only case we are interested in
|
// not necessary because the only case we are interested in
|
||||||
@ -1091,13 +1118,13 @@ ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
|
|||||||
// collector that might have need for a pre-barrier here.
|
// collector that might have need for a pre-barrier here.
|
||||||
if (_discovered_list_needs_barrier && !UseG1GC) {
|
if (_discovered_list_needs_barrier && !UseG1GC) {
|
||||||
if (UseCompressedOops) {
|
if (UseCompressedOops) {
|
||||||
_bs->write_ref_field_pre((narrowOop*)discovered_addr, current_head);
|
_bs->write_ref_field_pre((narrowOop*)discovered_addr, next_discovered);
|
||||||
} else {
|
} else {
|
||||||
_bs->write_ref_field_pre((oop*)discovered_addr, current_head);
|
_bs->write_ref_field_pre((oop*)discovered_addr, next_discovered);
|
||||||
}
|
}
|
||||||
guarantee(false, "Need to check non-G1 collector");
|
guarantee(false, "Need to check non-G1 collector");
|
||||||
}
|
}
|
||||||
oop retest = oopDesc::atomic_compare_exchange_oop(current_head, discovered_addr,
|
oop retest = oopDesc::atomic_compare_exchange_oop(next_discovered, discovered_addr,
|
||||||
NULL);
|
NULL);
|
||||||
if (retest == NULL) {
|
if (retest == NULL) {
|
||||||
// This thread just won the right to enqueue the object.
|
// This thread just won the right to enqueue the object.
|
||||||
@ -1106,7 +1133,7 @@ ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
|
|||||||
refs_list.set_head(obj);
|
refs_list.set_head(obj);
|
||||||
refs_list.inc_length(1);
|
refs_list.inc_length(1);
|
||||||
if (_discovered_list_needs_barrier) {
|
if (_discovered_list_needs_barrier) {
|
||||||
_bs->write_ref_field((void*)discovered_addr, current_head);
|
_bs->write_ref_field((void*)discovered_addr, next_discovered);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TraceReferenceGC) {
|
if (TraceReferenceGC) {
|
||||||
@ -1262,20 +1289,23 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
|
|||||||
// here: the field will be visited later when processing the discovered
|
// here: the field will be visited later when processing the discovered
|
||||||
// references.
|
// references.
|
||||||
oop current_head = list->head();
|
oop current_head = list->head();
|
||||||
|
// The last ref must have its discovered field pointing to itself.
|
||||||
|
oop next_discovered = (current_head != NULL) ? current_head : obj;
|
||||||
|
|
||||||
// As in the case further above, since we are over-writing a NULL
|
// As in the case further above, since we are over-writing a NULL
|
||||||
// pre-value, we can safely elide the pre-barrier here for the case of G1.
|
// pre-value, we can safely elide the pre-barrier here for the case of G1.
|
||||||
assert(discovered == NULL, "control point invariant");
|
assert(discovered == NULL, "control point invariant");
|
||||||
if (_discovered_list_needs_barrier && !UseG1GC) { // safe to elide for G1
|
if (_discovered_list_needs_barrier && !UseG1GC) { // safe to elide for G1
|
||||||
if (UseCompressedOops) {
|
if (UseCompressedOops) {
|
||||||
_bs->write_ref_field_pre((narrowOop*)discovered_addr, current_head);
|
_bs->write_ref_field_pre((narrowOop*)discovered_addr, next_discovered);
|
||||||
} else {
|
} else {
|
||||||
_bs->write_ref_field_pre((oop*)discovered_addr, current_head);
|
_bs->write_ref_field_pre((oop*)discovered_addr, next_discovered);
|
||||||
}
|
}
|
||||||
guarantee(false, "Need to check non-G1 collector");
|
guarantee(false, "Need to check non-G1 collector");
|
||||||
}
|
}
|
||||||
oop_store_raw(discovered_addr, current_head);
|
oop_store_raw(discovered_addr, next_discovered);
|
||||||
if (_discovered_list_needs_barrier) {
|
if (_discovered_list_needs_barrier) {
|
||||||
_bs->write_ref_field((void*)discovered_addr, current_head);
|
_bs->write_ref_field((void*)discovered_addr, next_discovered);
|
||||||
}
|
}
|
||||||
list->set_head(obj);
|
list->set_head(obj);
|
||||||
list->inc_length(1);
|
list->inc_length(1);
|
||||||
@ -1437,22 +1467,12 @@ void ReferenceProcessor::verify_ok_to_handle_reflists() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ReferenceProcessor::verify() {
|
|
||||||
guarantee(sentinel_ref() != NULL && sentinel_ref()->is_oop(), "Lost _sentinelRef");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
void ReferenceProcessor::clear_discovered_references() {
|
void ReferenceProcessor::clear_discovered_references() {
|
||||||
guarantee(!_discovering_refs, "Discovering refs?");
|
guarantee(!_discovering_refs, "Discovering refs?");
|
||||||
for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
|
for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
|
||||||
oop obj = _discoveredSoftRefs[i].head();
|
clear_discovered_references(_discoveredSoftRefs[i]);
|
||||||
while (obj != sentinel_ref()) {
|
|
||||||
oop next = java_lang_ref_Reference::discovered(obj);
|
|
||||||
java_lang_ref_Reference::set_discovered(obj, (oop) NULL);
|
|
||||||
obj = next;
|
|
||||||
}
|
|
||||||
_discoveredSoftRefs[i].set_head(sentinel_ref());
|
|
||||||
_discoveredSoftRefs[i].set_length(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PRODUCT
|
#endif // PRODUCT
|
||||||
|
@ -52,8 +52,6 @@ class DiscoveredList;
|
|||||||
|
|
||||||
class ReferenceProcessor : public CHeapObj {
|
class ReferenceProcessor : public CHeapObj {
|
||||||
protected:
|
protected:
|
||||||
// End of list marker
|
|
||||||
static oop _sentinelRef;
|
|
||||||
MemRegion _span; // (right-open) interval of heap
|
MemRegion _span; // (right-open) interval of heap
|
||||||
// subject to wkref discovery
|
// subject to wkref discovery
|
||||||
bool _discovering_refs; // true when discovery enabled
|
bool _discovering_refs; // true when discovery enabled
|
||||||
@ -106,8 +104,6 @@ class ReferenceProcessor : public CHeapObj {
|
|||||||
int max_num_q() { return _max_num_q; }
|
int max_num_q() { return _max_num_q; }
|
||||||
void set_active_mt_degree(int v) { _num_q = v; }
|
void set_active_mt_degree(int v) { _num_q = v; }
|
||||||
DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; }
|
DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; }
|
||||||
static oop sentinel_ref() { return _sentinelRef; }
|
|
||||||
static oop* adr_sentinel_ref() { return &_sentinelRef; }
|
|
||||||
ReferencePolicy* setup_policy(bool always_clear) {
|
ReferencePolicy* setup_policy(bool always_clear) {
|
||||||
_current_soft_ref_policy = always_clear ?
|
_current_soft_ref_policy = always_clear ?
|
||||||
_always_clear_soft_ref_policy : _default_soft_ref_policy;
|
_always_clear_soft_ref_policy : _default_soft_ref_policy;
|
||||||
@ -230,6 +226,7 @@ class ReferenceProcessor : public CHeapObj {
|
|||||||
HeapWord* discovered_addr);
|
HeapWord* discovered_addr);
|
||||||
void verify_ok_to_handle_reflists() PRODUCT_RETURN;
|
void verify_ok_to_handle_reflists() PRODUCT_RETURN;
|
||||||
|
|
||||||
|
void clear_discovered_references(DiscoveredList& refs_list);
|
||||||
void abandon_partial_discovered_list(DiscoveredList& refs_list);
|
void abandon_partial_discovered_list(DiscoveredList& refs_list);
|
||||||
|
|
||||||
// Calculate the number of jni handles.
|
// Calculate the number of jni handles.
|
||||||
@ -314,7 +311,6 @@ class ReferenceProcessor : public CHeapObj {
|
|||||||
|
|
||||||
// iterate over oops
|
// iterate over oops
|
||||||
void weak_oops_do(OopClosure* f); // weak roots
|
void weak_oops_do(OopClosure* f); // weak roots
|
||||||
static void oops_do(OopClosure* f); // strong root(s)
|
|
||||||
|
|
||||||
// Balance each of the discovered lists.
|
// Balance each of the discovered lists.
|
||||||
void balance_all_queues();
|
void balance_all_queues();
|
||||||
@ -340,7 +336,6 @@ class ReferenceProcessor : public CHeapObj {
|
|||||||
// debugging
|
// debugging
|
||||||
void verify_no_references_recorded() PRODUCT_RETURN;
|
void verify_no_references_recorded() PRODUCT_RETURN;
|
||||||
void verify_referent(oop obj) PRODUCT_RETURN;
|
void verify_referent(oop obj) PRODUCT_RETURN;
|
||||||
static void verify();
|
|
||||||
|
|
||||||
// clear the discovered lists (unlinking each entry).
|
// clear the discovered lists (unlinking each entry).
|
||||||
void clear_discovered_references() PRODUCT_RETURN;
|
void clear_discovered_references() PRODUCT_RETURN;
|
||||||
@ -524,12 +519,10 @@ protected:
|
|||||||
EnqueueTask(ReferenceProcessor& ref_processor,
|
EnqueueTask(ReferenceProcessor& ref_processor,
|
||||||
DiscoveredList refs_lists[],
|
DiscoveredList refs_lists[],
|
||||||
HeapWord* pending_list_addr,
|
HeapWord* pending_list_addr,
|
||||||
oop sentinel_ref,
|
|
||||||
int n_queues)
|
int n_queues)
|
||||||
: _ref_processor(ref_processor),
|
: _ref_processor(ref_processor),
|
||||||
_refs_lists(refs_lists),
|
_refs_lists(refs_lists),
|
||||||
_pending_list_addr(pending_list_addr),
|
_pending_list_addr(pending_list_addr),
|
||||||
_sentinel_ref(sentinel_ref),
|
|
||||||
_n_queues(n_queues)
|
_n_queues(n_queues)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -540,7 +533,6 @@ protected:
|
|||||||
ReferenceProcessor& _ref_processor;
|
ReferenceProcessor& _ref_processor;
|
||||||
DiscoveredList* _refs_lists;
|
DiscoveredList* _refs_lists;
|
||||||
HeapWord* _pending_list_addr;
|
HeapWord* _pending_list_addr;
|
||||||
oop _sentinel_ref;
|
|
||||||
int _n_queues;
|
int _n_queues;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -146,7 +146,6 @@ void SharedHeap::process_strong_roots(bool activate_scope,
|
|||||||
assert(_strong_roots_parity != 0, "must have called prologue code");
|
assert(_strong_roots_parity != 0, "must have called prologue code");
|
||||||
if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
|
if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
|
||||||
Universe::oops_do(roots);
|
Universe::oops_do(roots);
|
||||||
ReferenceProcessor::oops_do(roots);
|
|
||||||
// Consider perm-gen discovered lists to be strong.
|
// Consider perm-gen discovered lists to be strong.
|
||||||
perm_gen()->ref_processor()->weak_oops_do(roots);
|
perm_gen()->ref_processor()->weak_oops_do(roots);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user