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