< prev index next >
src/share/vm/gc/shared/referenceProcessor.cpp
Print this page
rev 11747 : [mq]: per.hotspot.patch
*** 287,329 ****
VoidClosure* complete_gc) {
JNIHandles::weak_oops_do(is_alive, keep_alive);
complete_gc->do_void();
}
!
! template <class T>
! bool enqueue_discovered_ref_helper(ReferenceProcessor* ref,
! AbstractRefProcTaskExecutor* task_executor) {
!
! // Remember old value of pending references list
! T* pending_list_addr = (T*)java_lang_ref_Reference::pending_list_addr();
! T old_pending_list_value = *pending_list_addr;
!
// Enqueue references that are not made active again, and
// clear the decks for the next collection (cycle).
! ref->enqueue_discovered_reflists((HeapWord*)pending_list_addr, task_executor);
! // Do the post-barrier on pending_list_addr missed in
! // enqueue_discovered_reflist.
! oopDesc::bs()->write_ref_field(pending_list_addr, oopDesc::load_decode_heap_oop(pending_list_addr));
// Stop treating discovered references specially.
! ref->disable_discovery();
!
! // Return true if new pending references were added
! return old_pending_list_value != *pending_list_addr;
! }
!
! bool ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
! if (UseCompressedOops) {
! return enqueue_discovered_ref_helper<narrowOop>(this, task_executor);
! } else {
! return enqueue_discovered_ref_helper<oop>(this, task_executor);
! }
}
! void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
! HeapWord* pending_list_addr) {
// Given a list of refs linked through the "discovered" field
// (java.lang.ref.Reference.discovered), self-loop their "next" field
// thus distinguishing them from active References, then
// prepend them to the pending list.
//
--- 287,306 ----
VoidClosure* complete_gc) {
JNIHandles::weak_oops_do(is_alive, keep_alive);
complete_gc->do_void();
}
! void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
// Enqueue references that are not made active again, and
// clear the decks for the next collection (cycle).
! enqueue_discovered_reflists(task_executor);
// Stop treating discovered references specially.
! disable_discovery();
}
! void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
// Given a list of refs linked through the "discovered" field
// (java.lang.ref.Reference.discovered), self-loop their "next" field
// thus distinguishing them from active References, then
// prepend them to the pending list.
//
*** 352,365 ****
java_lang_ref_Reference::set_next_raw(obj, obj);
if (next_d != obj) {
oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d);
} else {
// This is the last object.
! // Swap refs_list into pending_list_addr and
! // set obj's discovered to what we read from pending_list_addr.
! oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
! // Need post-barrier on pending_list_addr. See enqueue_discovered_ref_helper() above.
java_lang_ref_Reference::set_discovered_raw(obj, old); // old may be NULL
oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), old);
}
}
}
--- 329,341 ----
java_lang_ref_Reference::set_next_raw(obj, obj);
if (next_d != obj) {
oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d);
} else {
// This is the last object.
! // Swap refs_list into pending list and set obj's
! // discovered to what we read from the pending list.
! oop old = Universe::swap_reference_pending_list(refs_list.head());
java_lang_ref_Reference::set_discovered_raw(obj, old); // old may be NULL
oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), old);
}
}
}
*** 367,380 ****
// Parallel enqueue task
class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask {
public:
RefProcEnqueueTask(ReferenceProcessor& ref_processor,
DiscoveredList discovered_refs[],
- HeapWord* pending_list_addr,
int n_queues)
! : EnqueueTask(ref_processor, discovered_refs,
! pending_list_addr, n_queues)
{ }
virtual void work(unsigned int work_id) {
assert(work_id < (unsigned int)_ref_processor.max_num_q(), "Index out-of-bounds");
// Simplest first cut: static partitioning.
--- 343,354 ----
// Parallel enqueue task
class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask {
public:
RefProcEnqueueTask(ReferenceProcessor& ref_processor,
DiscoveredList discovered_refs[],
int n_queues)
! : EnqueueTask(ref_processor, discovered_refs, n_queues)
{ }
virtual void work(unsigned int work_id) {
assert(work_id < (unsigned int)_ref_processor.max_num_q(), "Index out-of-bounds");
// Simplest first cut: static partitioning.
*** 385,414 ****
// allocated and are indexed into.
assert(_n_queues == (int) _ref_processor.max_num_q(), "Different number not expected");
for (int j = 0;
j < ReferenceProcessor::number_of_subclasses_of_ref();
j++, index += _n_queues) {
! _ref_processor.enqueue_discovered_reflist(
! _refs_lists[index], _pending_list_addr);
_refs_lists[index].set_head(NULL);
_refs_lists[index].set_length(0);
}
}
};
// Enqueue references that are not made active again
! void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr,
! AbstractRefProcTaskExecutor* task_executor) {
if (_processing_is_mt && task_executor != NULL) {
// Parallel code
! RefProcEnqueueTask tsk(*this, _discovered_refs,
! pending_list_addr, _max_num_q);
task_executor->execute(tsk);
} else {
// Serial code: call the parent class's implementation
for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
! enqueue_discovered_reflist(_discovered_refs[i], pending_list_addr);
_discovered_refs[i].set_head(NULL);
_discovered_refs[i].set_length(0);
}
}
}
--- 359,385 ----
// allocated and are indexed into.
assert(_n_queues == (int) _ref_processor.max_num_q(), "Different number not expected");
for (int j = 0;
j < ReferenceProcessor::number_of_subclasses_of_ref();
j++, index += _n_queues) {
! _ref_processor.enqueue_discovered_reflist(_refs_lists[index]);
_refs_lists[index].set_head(NULL);
_refs_lists[index].set_length(0);
}
}
};
// Enqueue references that are not made active again
! void ReferenceProcessor::enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor) {
if (_processing_is_mt && task_executor != NULL) {
// Parallel code
! RefProcEnqueueTask tsk(*this, _discovered_refs, _max_num_q);
task_executor->execute(tsk);
} else {
// Serial code: call the parent class's implementation
for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
! enqueue_discovered_reflist(_discovered_refs[i]);
_discovered_refs[i].set_head(NULL);
_discovered_refs[i].set_length(0);
}
}
}
< prev index next >