1.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp Wed Jun 30 11:52:10 2010 -0400 1.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp Thu Jul 01 21:40:45 2010 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -32,7 +32,7 @@ 1.11 ParCompactionManager::_objarray_queues = NULL; 1.12 ObjectStartArray* ParCompactionManager::_start_array = NULL; 1.13 ParMarkBitMap* ParCompactionManager::_mark_bitmap = NULL; 1.14 -RegionTaskQueueSet* ParCompactionManager::_region_array = NULL; 1.15 +RegionTaskQueueSet* ParCompactionManager::_region_array = NULL; 1.16 1.17 ParCompactionManager::ParCompactionManager() : 1.18 _action(CopyAndUpdate) { 1.19 @@ -43,25 +43,9 @@ 1.20 _old_gen = heap->old_gen(); 1.21 _start_array = old_gen()->start_array(); 1.22 1.23 - 1.24 marking_stack()->initialize(); 1.25 - 1.26 - // We want the overflow stack to be permanent 1.27 - _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(10, true); 1.28 - 1.29 - _objarray_queue.initialize(); 1.30 - _objarray_overflow_stack = 1.31 - new (ResourceObj::C_HEAP) ObjArrayOverflowStack(10, true); 1.32 - 1.33 -#ifdef USE_RegionTaskQueueWithOverflow 1.34 + _objarray_stack.initialize(); 1.35 region_stack()->initialize(); 1.36 -#else 1.37 - region_stack()->initialize(); 1.38 - 1.39 - // We want the overflow stack to be permanent 1.40 - _region_overflow_stack = 1.41 - new (ResourceObj::C_HEAP) GrowableArray<size_t>(10, true); 1.42 -#endif 1.43 1.44 // Note that _revisit_klass_stack is allocated out of the 1.45 // C heap (as opposed to out of ResourceArena). 1.46 @@ -71,12 +55,9 @@ 1.47 // From some experiments (#klass/k)^2 for k = 10 seems a better fit, but this will 1.48 // have to do for now until we are able to investigate a more optimal setting. 1.49 _revisit_mdo_stack = new (ResourceObj::C_HEAP) GrowableArray<DataLayout*>(size*2, true); 1.50 - 1.51 } 1.52 1.53 ParCompactionManager::~ParCompactionManager() { 1.54 - delete _overflow_stack; 1.55 - delete _objarray_overflow_stack; 1.56 delete _revisit_klass_stack; 1.57 delete _revisit_mdo_stack; 1.58 // _manager_array and _stack_array are statics 1.59 @@ -108,12 +89,8 @@ 1.60 _manager_array[i] = new ParCompactionManager(); 1.61 guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager"); 1.62 stack_array()->register_queue(i, _manager_array[i]->marking_stack()); 1.63 - _objarray_queues->register_queue(i, &_manager_array[i]->_objarray_queue); 1.64 -#ifdef USE_RegionTaskQueueWithOverflow 1.65 - region_array()->register_queue(i, _manager_array[i]->region_stack()->task_queue()); 1.66 -#else 1.67 + _objarray_queues->register_queue(i, &_manager_array[i]->_objarray_stack); 1.68 region_array()->register_queue(i, _manager_array[i]->region_stack()); 1.69 -#endif 1.70 } 1.71 1.72 // The VMThread gets its own ParCompactionManager, which is not available 1.73 @@ -149,57 +126,6 @@ 1.74 return action() == ParCompactionManager::ResetObjects; 1.75 } 1.76 1.77 -// For now save on a stack 1.78 -void ParCompactionManager::save_for_scanning(oop m) { 1.79 - stack_push(m); 1.80 -} 1.81 - 1.82 -void ParCompactionManager::stack_push(oop obj) { 1.83 - 1.84 - if(!marking_stack()->push(obj)) { 1.85 - overflow_stack()->push(obj); 1.86 - } 1.87 -} 1.88 - 1.89 -oop ParCompactionManager::retrieve_for_scanning() { 1.90 - 1.91 - // Should not be used in the parallel case 1.92 - ShouldNotReachHere(); 1.93 - return NULL; 1.94 -} 1.95 - 1.96 -// Save region on a stack 1.97 -void ParCompactionManager::save_for_processing(size_t region_index) { 1.98 -#ifdef ASSERT 1.99 - const ParallelCompactData& sd = PSParallelCompact::summary_data(); 1.100 - ParallelCompactData::RegionData* const region_ptr = sd.region(region_index); 1.101 - assert(region_ptr->claimed(), "must be claimed"); 1.102 - assert(region_ptr->_pushed++ == 0, "should only be pushed once"); 1.103 -#endif 1.104 - region_stack_push(region_index); 1.105 -} 1.106 - 1.107 -void ParCompactionManager::region_stack_push(size_t region_index) { 1.108 - 1.109 -#ifdef USE_RegionTaskQueueWithOverflow 1.110 - region_stack()->save(region_index); 1.111 -#else 1.112 - if(!region_stack()->push(region_index)) { 1.113 - region_overflow_stack()->push(region_index); 1.114 - } 1.115 -#endif 1.116 -} 1.117 - 1.118 -bool ParCompactionManager::retrieve_for_processing(size_t& region_index) { 1.119 -#ifdef USE_RegionTaskQueueWithOverflow 1.120 - return region_stack()->retrieve(region_index); 1.121 -#else 1.122 - // Should not be used in the parallel case 1.123 - ShouldNotReachHere(); 1.124 - return false; 1.125 -#endif 1.126 -} 1.127 - 1.128 ParCompactionManager* 1.129 ParCompactionManager::gc_thread_compaction_manager(int index) { 1.130 assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range"); 1.131 @@ -218,8 +144,8 @@ 1.132 do { 1.133 // Drain the overflow stack first, to allow stealing from the marking stack. 1.134 oop obj; 1.135 - while (!overflow_stack()->is_empty()) { 1.136 - overflow_stack()->pop()->follow_contents(this); 1.137 + while (marking_stack()->pop_overflow(obj)) { 1.138 + obj->follow_contents(this); 1.139 } 1.140 while (marking_stack()->pop_local(obj)) { 1.141 obj->follow_contents(this); 1.142 @@ -227,11 +153,10 @@ 1.143 1.144 // Process ObjArrays one at a time to avoid marking stack bloat. 1.145 ObjArrayTask task; 1.146 - if (!_objarray_overflow_stack->is_empty()) { 1.147 - task = _objarray_overflow_stack->pop(); 1.148 + if (_objarray_stack.pop_overflow(task)) { 1.149 objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); 1.150 k->oop_follow_contents(this, task.obj(), task.index()); 1.151 - } else if (_objarray_queue.pop_local(task)) { 1.152 + } else if (_objarray_stack.pop_local(task)) { 1.153 objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); 1.154 k->oop_follow_contents(this, task.obj(), task.index()); 1.155 } 1.156 @@ -240,68 +165,18 @@ 1.157 assert(marking_stacks_empty(), "Sanity"); 1.158 } 1.159 1.160 -void ParCompactionManager::drain_region_overflow_stack() { 1.161 - size_t region_index = (size_t) -1; 1.162 - while(region_stack()->retrieve_from_overflow(region_index)) { 1.163 - PSParallelCompact::fill_and_update_region(this, region_index); 1.164 - } 1.165 -} 1.166 - 1.167 void ParCompactionManager::drain_region_stacks() { 1.168 -#ifdef ASSERT 1.169 - ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); 1.170 - assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); 1.171 - MutableSpace* to_space = heap->young_gen()->to_space(); 1.172 - MutableSpace* old_space = heap->old_gen()->object_space(); 1.173 - MutableSpace* perm_space = heap->perm_gen()->object_space(); 1.174 -#endif /* ASSERT */ 1.175 - 1.176 -#if 1 // def DO_PARALLEL - the serial code hasn't been updated 1.177 do { 1.178 - 1.179 -#ifdef USE_RegionTaskQueueWithOverflow 1.180 - // Drain overflow stack first, so other threads can steal from 1.181 - // claimed stack while we work. 1.182 - size_t region_index = (size_t) -1; 1.183 - while(region_stack()->retrieve_from_overflow(region_index)) { 1.184 + // Drain overflow stack first so other threads can steal. 1.185 + size_t region_index; 1.186 + while (region_stack()->pop_overflow(region_index)) { 1.187 PSParallelCompact::fill_and_update_region(this, region_index); 1.188 } 1.189 1.190 - while (region_stack()->retrieve_from_stealable_queue(region_index)) { 1.191 + while (region_stack()->pop_local(region_index)) { 1.192 PSParallelCompact::fill_and_update_region(this, region_index); 1.193 } 1.194 } while (!region_stack()->is_empty()); 1.195 -#else 1.196 - // Drain overflow stack first, so other threads can steal from 1.197 - // claimed stack while we work. 1.198 - while(!region_overflow_stack()->is_empty()) { 1.199 - size_t region_index = region_overflow_stack()->pop(); 1.200 - PSParallelCompact::fill_and_update_region(this, region_index); 1.201 - } 1.202 - 1.203 - size_t region_index = -1; 1.204 - // obj is a reference!!! 1.205 - while (region_stack()->pop_local(region_index)) { 1.206 - // It would be nice to assert about the type of objects we might 1.207 - // pop, but they can come from anywhere, unfortunately. 1.208 - PSParallelCompact::fill_and_update_region(this, region_index); 1.209 - } 1.210 - } while((region_stack()->size() != 0) || 1.211 - (region_overflow_stack()->length() != 0)); 1.212 -#endif 1.213 - 1.214 -#ifdef USE_RegionTaskQueueWithOverflow 1.215 - assert(region_stack()->is_empty(), "Sanity"); 1.216 -#else 1.217 - assert(region_stack()->size() == 0, "Sanity"); 1.218 - assert(region_overflow_stack()->length() == 0, "Sanity"); 1.219 -#endif 1.220 -#else 1.221 - oop obj; 1.222 - while (obj = retrieve_for_scanning()) { 1.223 - obj->follow_contents(this); 1.224 - } 1.225 -#endif 1.226 } 1.227 1.228 #ifdef ASSERT