1 #ifdef USE_PRAGMA_IDENT_HDR 2 #pragma ident "@(#)psCompactionManager.hpp 1.17 07/05/05 17:05:29 JVM" 3 #endif 4 /* 5 * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. 6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7 * 8 * This code is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License version 2 only, as 10 * published by the Free Software Foundation. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 23 * CA 95054 USA or visit www.sun.com if you need additional information or 24 * have any questions. 25 * 26 */ 27 28 // 29 // psPromotionManager is used by a single thread to manage object survival 30 // during a scavenge. The promotion manager contains thread local data only. 31 // 32 // NOTE! Be carefull when allocating the stacks on cheap. If you are going 33 // to use a promotion manager in more than one thread, the stacks MUST be 34 // on cheap. This can lead to memory leaks, though, as they are not auto 35 // deallocated. 36 // 37 // FIX ME FIX ME Add a destructor, and don't rely on the user to drain/flush/deallocate! 38 // 39 40 // Move to some global location 41 #define HAS_BEEN_MOVED 0x1501d01d 42 // End move to some global location 43 44 45 class MutableSpace; 46 class PSOldGen; 47 class ParCompactionManager; 48 class ObjectStartArray; 49 class ParallelCompactData; 50 class ParMarkBitMap; 51 52 // Move to it's own file if this works out. 53 54 class ParCompactionManager : public CHeapObj { 55 friend class ParallelTaskTerminator; 56 friend class ParMarkBitMap; 57 friend class PSParallelCompact; 58 friend class StealRegionCompactionTask; 59 friend class UpdateAndFillClosure; 60 friend class RefProcTaskExecutor; 61 62 public: 63 64 // ------------------------ Don't putback if not needed 65 // Actions that the compaction manager should take. 66 enum Action { 67 Update, 68 Copy, 69 UpdateAndCopy, 70 CopyAndUpdate, 71 VerifyUpdate, 72 ResetObjects, 73 NotValid 74 }; 75 // ------------------------ End don't putback if not needed 76 77 private: 78 static ParCompactionManager** _manager_array; 79 static OopTaskQueueSet* _stack_array; 80 static ObjectStartArray* _start_array; 81 static RegionTaskQueueSet* _region_array; 82 static PSOldGen* _old_gen; 83 84 OopTaskQueue _marking_stack; 85 GrowableArray<oop>* _overflow_stack; 86 // Is there a way to reuse the _marking_stack for the 87 // saving empty regions? For now just create a different 88 // type of TaskQueue. 89 90 #ifdef USE_RegionTaskQueueWithOverflow 91 RegionTaskQueueWithOverflow _region_stack; 92 #else 93 RegionTaskQueue _region_stack; 94 GrowableArray<size_t>* _region_overflow_stack; 95 #endif 96 97 #if 1 // does this happen enough to need a per thread stack? 98 GrowableArray<Klass*>* _revisit_klass_stack; 99 #endif 100 static ParMarkBitMap* _mark_bitmap; 101 102 Action _action; 103 104 static PSOldGen* old_gen() { return _old_gen; } 105 static ObjectStartArray* start_array() { return _start_array; } 106 static OopTaskQueueSet* stack_array() { return _stack_array; } 107 108 static void initialize(ParMarkBitMap* mbm); 109 110 protected: 111 // Array of tasks. Needed by the ParallelTaskTerminator. 112 static RegionTaskQueueSet* region_array() { return _region_array; } 113 OopTaskQueue* marking_stack() { return &_marking_stack; } 114 GrowableArray<oop>* overflow_stack() { return _overflow_stack; } 115 #ifdef USE_RegionTaskQueueWithOverflow 116 RegionTaskQueueWithOverflow* region_stack() { return &_region_stack; } 117 #else 118 RegionTaskQueue* region_stack() { return &_region_stack; } 119 GrowableArray<size_t>* region_overflow_stack() { 120 return _region_overflow_stack; 121 } 122 #endif 123 124 // Pushes onto the marking stack. If the marking stack is full, 125 // pushes onto the overflow stack. 126 void stack_push(oop obj); 127 // Do not implement an equivalent stack_pop. Deal with the 128 // marking stack and overflow stack directly. 129 130 // Pushes onto the region stack. If the region stack is full, 131 // pushes onto the region overflow stack. 132 void region_stack_push(size_t region_index); 133 public: 134 135 Action action() { return _action; } 136 void set_action(Action v) { _action = v; } 137 138 inline static ParCompactionManager* manager_array(int index); 139 140 ParCompactionManager(); 141 ~ParCompactionManager(); 142 143 void allocate_stacks(); 144 void deallocate_stacks(); 145 ParMarkBitMap* mark_bitmap() { return _mark_bitmap; } 146 147 // Take actions in preparation for a compaction. 148 static void reset(); 149 150 // void drain_stacks(); 151 152 bool should_update(); 153 bool should_copy(); 154 bool should_verify_only(); 155 bool should_reset_only(); 156 157 #if 1 158 // Probably stays as a growable array 159 GrowableArray<Klass*>* revisit_klass_stack() { return _revisit_klass_stack; } 160 #endif 161 162 // Save oop for later processing. Must not fail. 163 void save_for_scanning(oop m); 164 // Get a oop for scanning. If returns null, no oop were found. 165 oop retrieve_for_scanning(); 166 167 // Save region for later processing. Must not fail. 168 void save_for_processing(size_t region_index); 169 // Get a region for processing. If returns null, no region were found. 170 bool retrieve_for_processing(size_t& region_index); 171 172 // Access function for compaction managers 173 static ParCompactionManager* gc_thread_compaction_manager(int index); 174 175 static bool steal(int queue_num, int* seed, Task& t) { 176 return stack_array()->steal(queue_num, seed, t); 177 } 178 179 static bool steal(int queue_num, int* seed, RegionTask& t) { 180 return region_array()->steal(queue_num, seed, t); 181 } 182 183 // Process tasks remaining on any stack 184 void drain_marking_stacks(OopClosure *blk); 185 186 // Process tasks remaining on any stack 187 void drain_region_stacks(); 188 189 // Process tasks remaining on any stack 190 void drain_region_overflow_stack(); 191 192 // Debugging support 193 #ifdef ASSERT 194 bool stacks_have_been_allocated(); 195 #endif 196 }; 197 198 inline ParCompactionManager* ParCompactionManager::manager_array(int index) { 199 assert(_manager_array != NULL, "access of NULL manager_array"); 200 assert(index >= 0 && index <= (int)ParallelGCThreads, 201 "out of range manager_array access"); 202 return _manager_array[index]; 203 }