src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Fri Oct 17 16:15:59 2014
--- new/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Fri Oct 17 16:15:59 2014
*** 67,100 ****
--- 67,111 ----
Generation* old_gen_,
int thread_num_,
ObjToScanQueueSet* work_queue_set_,
Stack<oop, mtGC>* overflow_stacks_,
size_t desired_plab_sz_,
- ParallelTaskTerminator& term_) :
! _to_space(to_space_), _old_gen(old_gen_), _young_gen(young_gen_), _thread_num(thread_num_),
! _work_queue(work_queue_set_->queue(thread_num_)), _to_space_full(false),
! : _to_space(to_space_),
! _old_gen(old_gen_),
+ _young_gen(young_gen_),
+ _thread_num(thread_num_),
+ _work_queue(work_queue_set_->queue(thread_num_)),
+ _to_space_full(false),
_overflow_stack(overflow_stacks_ ? overflow_stacks_ + thread_num_ : NULL),
_ageTable(false), // false ==> not the global age table, no perf data.
_to_space_alloc_buffer(desired_plab_sz_),
! _to_space_closure(young_gen_, this), _old_gen_closure(young_gen_, this),
! _to_space_root_closure(young_gen_, this), _old_gen_root_closure(young_gen_, this),
! _to_space_closure(young_gen_, this),
! _old_gen_closure(young_gen_, this),
+ _to_space_root_closure(young_gen_, this),
+ _old_gen_root_closure(young_gen_, this),
_older_gen_closure(young_gen_, this),
! _evacuate_followers(this, &_to_space_closure, &_old_gen_closure,
! &_to_space_root_closure, young_gen_, &_old_gen_root_closure,
! work_queue_set_, &term_),
! _is_alive_closure(young_gen_), _scan_weak_ref_closure(young_gen_, this),
! _evacuate_followers(this,
! &_to_space_closure,
! &_old_gen_closure,
! &_to_space_root_closure,
+ young_gen_,
+ &_old_gen_root_closure,
+ work_queue_set_,
+ &term_),
+ _is_alive_closure(young_gen_),
+ _scan_weak_ref_closure(young_gen_, this),
_keep_alive_closure(&_scan_weak_ref_closure),
_strong_roots_time(0.0), _term_time(0.0)
! _term_time(0.0) {
+ _strong_roots_time(0.0),
#if TASKQUEUE_STATS
_term_attempts = 0;
_overflow_refills = 0;
_overflow_refill_objs = 0;
#endif // TASKQUEUE_STATS
! _survivor_chunk_array = (ChunkArray*) old_gen()->get_data_recorder(thread_num());
(ChunkArray*) old_gen()->get_data_recorder(thread_num());
_hash_seed = 17; // Might want to take time-based random value.
_start = os::elapsedTime();
_old_gen_closure.set_generation(old_gen_);
_old_gen_root_closure.set_generation(old_gen_);
}
*** 153,163 ****
--- 164,173 ----
// object is in old generation
obj->oop_iterate_range(&_old_gen_closure, start, end);
}
}
void ParScanThreadState::trim_queues(int max_size) {
ObjToScanQueue* queue = work_queue();
do {
while (queue->size() > (juint)max_size) {
oop obj_to_scan;
*** 221,239 ****
--- 231,246 ----
overflow_stack()->push(p);
assert(young_gen()->overflow_list() == NULL, "Error");
}
HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz) {
// Otherwise, if the object is small enough, try to reallocate the
// buffer.
+ // If the object is small enough, try to reallocate the buffer.
HeapWord* obj = NULL;
if (!_to_space_full) {
ParGCAllocBuffer* const plab = to_space_alloc_buffer();
Space* const sp = to_space();
! if (word_sz * 100 < ParallelGCBufferWastePct * plab->word_sz()) {
ParallelGCBufferWastePct * plab->word_sz()) {
// Is small enough; abandon this buffer and start a new one.
plab->retire(false, false);
size_t buf_size = plab->word_sz();
HeapWord* buf_space = sp->par_allocate(buf_size);
if (buf_space == NULL) {
*** 271,283 ****
--- 278,288 ----
}
}
return obj;
}
void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj,
size_t word_sz) {
+ void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj, size_t word_sz) {
// Is the alloc in the current alloc buffer?
if (to_space_alloc_buffer()->contains(obj)) {
assert(to_space_alloc_buffer()->contains(obj + word_sz - 1),
"Should contain whole object.");
to_space_alloc_buffer()->undo_allocation(obj, word_sz);
*** 299,309 ****
--- 304,314 ----
ParScanThreadStateSet(int num_threads,
Space& to_space,
ParNewGeneration& gen,
Generation& old_gen,
ObjToScanQueueSet& queue_set,
- Stack<oop, mtGC>* overflow_stacks_,
size_t desired_plab_sz,
ParallelTaskTerminator& term);
~ParScanThreadStateSet() { TASKQUEUE_STATS_ONLY(reset_stats()); }
*** 330,348 ****
--- 335,356 ----
public:
bool is_valid(int id) const { return id < length(); }
ParallelTaskTerminator* terminator() { return &_term; }
};
ParScanThreadStateSet::ParScanThreadStateSet(
! int num_threads, Space& to_space, ParNewGeneration& gen,
! Generation& old_gen, ObjToScanQueueSet& queue_set,
+ ParScanThreadStateSet::ParScanThreadStateSet(int num_threads,
+ Space& to_space,
! ParNewGeneration& gen,
! Generation& old_gen,
+ ObjToScanQueueSet& queue_set,
Stack<oop, mtGC>* overflow_stacks,
size_t desired_plab_sz, ParallelTaskTerminator& term)
+ size_t desired_plab_sz,
+ ParallelTaskTerminator& term)
: ResourceArray(sizeof(ParScanThreadState), num_threads),
- _gen(gen), _old_gen(old_gen), _term(term)
{
+ _old_gen(old_gen),
+ _term(term) {
assert(num_threads > 0, "sanity check!");
assert(ParGCUseLocalOverflow == (overflow_stacks != NULL),
"overflow_stack allocation mismatch");
// Initialize states.
for (int i = 0; i < num_threads; ++i) {
*** 350,361 ****
--- 358,368 ----
ParScanThreadState(&to_space, &gen, &old_gen, i, &queue_set,
overflow_stacks, desired_plab_sz, term);
}
}
! inline ParScanThreadState& ParScanThreadStateSet::thread_state(int i) {
{
assert(i >= 0 && i < length(), "sanity check!");
return ((ParScanThreadState*)_data)[i];
}
void ParScanThreadStateSet::trace_promotion_failed(YoungGCTracer& gc_tracer) {
*** 365,415 ****
--- 372,416 ----
thread_state(i).promotion_failed_info().reset();
}
}
}
! void ParScanThreadStateSet::reset(int active_threads, bool promotion_failed) {
{
_term.reset_for_reuse(active_threads);
if (promotion_failed) {
for (int i = 0; i < length(); ++i) {
thread_state(i).print_promotion_failure_size();
}
}
}
#if TASKQUEUE_STATS
void
! ParScanThreadState::reset_stats() {
{
taskqueue_stats().reset();
_term_attempts = 0;
_overflow_refills = 0;
_overflow_refill_objs = 0;
}
! void ParScanThreadStateSet::reset_stats() {
{
for (int i = 0; i < length(); ++i) {
thread_state(i).reset_stats();
}
}
! void ParScanThreadStateSet::print_termination_stats_hdr(outputStream* const st) {
ParScanThreadStateSet::print_termination_stats_hdr(outputStream* const st)
{
st->print_raw_cr("GC Termination Stats");
st->print_raw_cr(" elapsed --strong roots-- "
"-------termination-------");
st->print_raw_cr("thr ms ms % "
" ms % attempts");
st->print_raw_cr("--- --------- --------- ------ "
"--------- ------ --------");
}
! void ParScanThreadStateSet::print_termination_stats(outputStream* const st) {
{
print_termination_stats_hdr(st);
for (int i = 0; i < length(); ++i) {
const ParScanThreadState & pss = thread_state(i);
const double elapsed_ms = pss.elapsed_time() * 1000.0;
*** 421,439 ****
--- 422,438 ----
term_ms, term_ms * 100 / elapsed_ms, pss.term_attempts());
}
}
// Print stats related to work queue activity.
! void ParScanThreadStateSet::print_taskqueue_stats_hdr(outputStream* const st) {
{
st->print_raw_cr("GC Task Stats");
st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr();
st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr();
}
! void ParScanThreadStateSet::print_taskqueue_stats(outputStream* const st) {
{
print_taskqueue_stats_hdr(st);
TaskQueueStats totals;
for (int i = 0; i < length(); ++i) {
const ParScanThreadState & pss = thread_state(i);
*** 451,462 ****
--- 450,460 ----
DEBUG_ONLY(totals.verify());
}
#endif // TASKQUEUE_STATS
! void ParScanThreadStateSet::flush() {
{
// Work in this loop should be kept as lightweight as
// possible since this might otherwise become a bottleneck
// to scaling. Should we add heavy-weight work into this
// loop, consider parallelizing the loop into the worker threads.
for (int i = 0; i < length(); ++i) {
*** 488,500 ****
--- 486,499 ----
CFLS_LAB::compute_desired_plab_size();
}
}
ParScanClosure::ParScanClosure(ParNewGeneration* g,
- ParScanThreadState* par_scan_state) :
OopsInKlassOrGenClosure(g), _par_scan_state(par_scan_state), _g(g)
{
+ : OopsInKlassOrGenClosure(g),
+ _par_scan_state(par_scan_state),
+ _g(g) {
_boundary = _g->reserved().end();
}
void ParScanWithBarrierClosure::do_oop(oop* p) { ParScanClosure::do_oop_work(p, true, false); }
void ParScanWithBarrierClosure::do_oop(narrowOop* p) { ParScanClosure::do_oop_work(p, true, false); }
*** 508,552 ****
--- 507,549 ----
void ParRootScanWithoutBarrierClosure::do_oop(oop* p) { ParScanClosure::do_oop_work(p, false, true); }
void ParRootScanWithoutBarrierClosure::do_oop(narrowOop* p) { ParScanClosure::do_oop_work(p, false, true); }
ParScanWeakRefClosure::ParScanWeakRefClosure(ParNewGeneration* g,
ParScanThreadState* par_scan_state)
- : ScanWeakRefClosure(g), _par_scan_state(par_scan_state)
{}
+ _par_scan_state(par_scan_state) {
+ }
void ParScanWeakRefClosure::do_oop(oop* p) { ParScanWeakRefClosure::do_oop_work(p); }
void ParScanWeakRefClosure::do_oop(narrowOop* p) { ParScanWeakRefClosure::do_oop_work(p); }
#ifdef WIN32
#pragma warning(disable: 4786) /* identifier was truncated to '255' characters in the browser information */
#endif
! ParEvacuateFollowersClosure::ParEvacuateFollowersClosure(ParScanThreadState* par_scan_state,
! ParScanThreadState* par_scan_state_,
! ParScanWithoutBarrierClosure* to_space_closure_,
! ParScanWithBarrierClosure* old_gen_closure_,
! ParRootScanWithoutBarrierClosure* to_space_root_closure_,
! ParNewGeneration* par_gen_,
! ParRootScanWithBarrierTwoGensClosure* old_gen_root_closure_,
ObjToScanQueueSet* task_queues_,
ParallelTaskTerminator* terminator_) :
! _par_scan_state(par_scan_state_),
! _to_space_closure(to_space_closure_),
! _old_gen_closure(old_gen_closure_),
! _to_space_root_closure(to_space_root_closure_),
! _old_gen_root_closure(old_gen_root_closure_),
_par_gen(par_gen_),
_task_queues(task_queues_),
_terminator(terminator_)
{}
! ParScanWithoutBarrierClosure* to_space_closure,
! ParScanWithBarrierClosure* old_gen_closure,
! ParRootScanWithoutBarrierClosure* to_space_root_closure,
! ParNewGeneration* par_gen,
! ParRootScanWithBarrierTwoGensClosure* old_gen_root_closure,
! ObjToScanQueueSet* task_queues,
+ ParallelTaskTerminator* terminator)
+ : _par_scan_state(par_scan_state),
+ _to_space_closure(to_space_closure),
! _old_gen_closure(old_gen_closure),
! _to_space_root_closure(to_space_root_closure),
! _old_gen_root_closure(old_gen_root_closure),
! _par_gen(par_gen),
! _task_queues(task_queues),
+ _terminator(terminator) {
+ }
void ParEvacuateFollowersClosure::do_void() {
ObjToScanQueue* work_q = par_scan_state()->work_queue();
while (true) {
// Scan to-space and old-gen objs until we run out of both.
oop obj_to_scan;
par_scan_state()->trim_queues(0);
// We have no local work, attempt to steal from other threads.
*** 575,591 ****
--- 572,590 ----
"Broken overflow list?");
// Finish the last termination pause.
par_scan_state()->end_term_time();
}
- ParNewGenTask::ParNewGenTask(ParNewGeneration* young_gen, Generation* old_gen,
HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) :
! AbstractGangTask("ParNewGeneration collection"),
+ Generation* old_gen,
! HeapWord* young_old_boundary,
+ ParScanThreadStateSet* state_set)
+ : AbstractGangTask("ParNewGeneration collection"),
_young_gen(young_gen), _old_gen(old_gen),
_young_old_boundary(young_old_boundary),
! _state_set(state_set) {
- {}
// Reset the terminator for the given number of
// active threads.
void ParNewGenTask::set_for_termination(int active_workers) {
_state_set->reset(active_workers, _young_gen->promotion_failed());
*** 639,650 ****
--- 638,648 ----
ParNewGeneration::
ParNewGeneration(ReservedSpace rs, size_t initial_byte_size)
: DefNewGeneration(rs, initial_byte_size, "PCopy"),
_overflow_list(NULL),
_is_alive_closure(this),
! _plab_stats(YoungPLABSize, PLABWeight) {
{
NOT_PRODUCT(_overflow_counter = ParGCWorkQueueOverflowInterval;)
NOT_PRODUCT(_num_par_pushes = 0;)
_task_queues = new ObjToScanQueueSet(ParallelGCThreads);
guarantee(_task_queues != NULL, "task_queues allocation failure.");
*** 652,667 ****
--- 650,665 ----
ObjToScanQueue *q = new ObjToScanQueue();
guarantee(q != NULL, "work_queue Allocation failure.");
_task_queues->register_queue(i1, q);
}
! for (uint i2 = 0; i2 < ParallelGCThreads; i2++) {
_task_queues->queue(i2)->initialize();
+ }
_overflow_stacks = NULL;
if (ParGCUseLocalOverflow) {
// typedef to workaround NEW_C_HEAP_ARRAY macro, which can not deal
// with ','
typedef Stack<oop, mtGC> GCOopStack;
_overflow_stacks = NEW_C_HEAP_ARRAY(GCOopStack, ParallelGCThreads, mtGC);
*** 683,694 ****
--- 681,693 ----
#ifdef _MSC_VER
#pragma warning( pop )
#endif
// ParNewGeneration::
- ParKeepAliveClosure::ParKeepAliveClosure(ParScanWeakRefClosure* cl) :
DefNewGeneration::KeepAliveClosure(cl), _par_cl(cl) {}
+ : DefNewGeneration::KeepAliveClosure(cl), _par_cl(cl) {
+ }
template <class T>
void /*ParNewGeneration::*/ParKeepAliveClosure::do_oop_work(T* p) {
#ifdef ASSERT
{
*** 710,721 ****
--- 709,721 ----
void /*ParNewGeneration::*/ParKeepAliveClosure::do_oop(oop* p) { ParKeepAliveClosure::do_oop_work(p); }
void /*ParNewGeneration::*/ParKeepAliveClosure::do_oop(narrowOop* p) { ParKeepAliveClosure::do_oop_work(p); }
// ParNewGeneration::
- KeepAliveClosure::KeepAliveClosure(ScanWeakRefClosure* cl) :
DefNewGeneration::KeepAliveClosure(cl) {}
+ : DefNewGeneration::KeepAliveClosure(cl) {
+ }
template <class T>
void /*ParNewGeneration::*/KeepAliveClosure::do_oop_work(T* p) {
#ifdef ASSERT
{
*** 780,805 ****
--- 780,803 ----
Generation& _old_gen;
HeapWord* _young_old_boundary;
ParScanThreadStateSet& _state_set;
};
! ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(ProcessTask& task,
! ProcessTask& task, ParNewGeneration& young_gen,
! ParNewGeneration& young_gen,
Generation& old_gen,
HeapWord* young_old_boundary,
ParScanThreadStateSet& state_set)
: AbstractGangTask("ParNewGeneration parallel reference processing"),
_young_gen(young_gen),
_task(task),
_old_gen(old_gen),
_young_old_boundary(young_old_boundary),
! _state_set(state_set) {
{
}
! void ParNewRefProcTaskProxy::work(uint worker_id) {
{
ResourceMark rm;
HandleMark hm;
ParScanThreadState& par_scan_state = _state_set.thread_state(worker_id);
par_scan_state.set_young_old_boundary(_young_old_boundary);
_task.work(worker_id, par_scan_state.is_alive_closure(),
*** 812,833 ****
--- 810,828 ----
EnqueueTask& _task;
public:
ParNewRefEnqueueTaskProxy(EnqueueTask& task)
: AbstractGangTask("ParNewGeneration parallel reference enqueue"),
! _task(task) {
- { }
! virtual void work(uint worker_id) {
{
_task.work(worker_id);
}
};
void ParNewRefProcTaskExecutor::execute(ProcessTask& task)
{
+ void ParNewRefProcTaskExecutor::execute(ProcessTask& task) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
assert(gch->kind() == CollectedHeap::GenCollectedHeap,
"not a generational heap");
FlexibleWorkGang* workers = gch->workers();
assert(workers != NULL, "Need parallel worker threads.");
*** 837,874 ****
--- 832,869 ----
workers->run_task(&rp_task);
_state_set.reset(0 /* bad value in debug if not reset */,
_generation.promotion_failed());
}
! void ParNewRefProcTaskExecutor::execute(EnqueueTask& task) {
{
GenCollectedHeap* gch = GenCollectedHeap::heap();
FlexibleWorkGang* workers = gch->workers();
assert(workers != NULL, "Need parallel worker threads.");
ParNewRefEnqueueTaskProxy enq_task(task);
workers->run_task(&enq_task);
}
! void ParNewRefProcTaskExecutor::set_single_threaded_mode() {
{
_state_set.flush();
GenCollectedHeap* gch = GenCollectedHeap::heap();
gch->set_par_threads(0); // 0 ==> non-parallel.
gch->save_marks();
}
! ScanClosureWithParBarrier::ScanClosureWithParBarrier(ParNewGeneration* g,
ScanClosureWithParBarrier(ParNewGeneration* g, bool gc_barrier) :
ScanClosure(g, gc_barrier) {}
+ bool gc_barrier)
+ : ScanClosure(g, gc_barrier) {
+ }
EvacuateFollowersClosureGeneral::
EvacuateFollowersClosureGeneral(GenCollectedHeap* gch,
OopsInGenClosure* cur,
- OopsInGenClosure* older) :
! : _gch(gch),
_scan_cur_or_nonheap(cur), _scan_older(older)
{}
+ _scan_cur_or_nonheap(cur),
+ _scan_older(older) {
+ }
void EvacuateFollowersClosureGeneral::do_void() {
do {
// Beware: this call will lead to closure applications via virtual
// calls.
*** 881,891 ****
--- 876,888 ----
// A Generation that does parallel young-gen collection.
bool ParNewGeneration::_avoid_promotion_undo = false;
- void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer) {
+ ParScanThreadStateSet& thread_state_set,
+ ParNewTracer& gc_tracer) {
assert(_promo_failure_scan_stack.is_empty(), "post condition");
_promo_failure_scan_stack.clear(true); // Clear cached segments.
remove_forwarding_pointers();
if (PrintGCDetails) {
*** 1189,1200 ****
--- 1186,1196 ----
if (forward_ptr != NULL) {
// someone else beat us to it.
return real_forwardee(old);
}
! new_obj = _old_gen->par_promote(par_scan_state->thread_num(), old, m, sz);
old, m, sz);
if (new_obj == NULL) {
// promotion failed, forward to self
_promotion_failed = true;
new_obj = old;
*** 1221,1231 ****
--- 1217,1230 ----
// This code must come after the CAS test, or it will print incorrect
// information.
if (TraceScavenge) {
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
is_in_reserved(new_obj) ? "copying" : "tenuring",
new_obj->klass()->internal_name(), (void *)old, (void *)new_obj, new_obj->size());
+ new_obj->klass()->internal_name(),
+ (void *)old,
+ (void *)new_obj,
+ new_obj->size());
}
#endif
if (forward_ptr == NULL) {
oop obj_to_push = new_obj;
*** 1342,1352 ****
--- 1341,1354 ----
// This code must come after the CAS test, or it will print incorrect
// information.
if (TraceScavenge) {
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
is_in_reserved(new_obj) ? "copying" : "tenuring",
new_obj->klass()->internal_name(), (void *)old, (void *)new_obj, new_obj->size());
+ new_obj->klass()->internal_name(),
+ (void*)old,
+ (void*)new_obj,
+ new_obj->size());
}
#endif
// Now attempt to install the forwarding pointer (atomically).
// We have to copy the mark word before overwriting with forwarding
*** 1504,1514 ****
--- 1506,1518 ----
size_t objsFromOverflow = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
(size_t)ParGCDesiredObjsFromOverflowList);
assert(!UseCompressedOops, "Error");
assert(par_scan_state->overflow_stack() == NULL, "Error");
! if (_overflow_list == NULL) return false;
! if (_overflow_list == NULL) {
+ return false;
+ }
// Otherwise, there was something there; try claiming the list.
oop prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
// Trim off a prefix of at most objsFromOverflow items
Thread* tid = Thread::current();
src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File