Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp @ 1091:6aa7255741f3
6906727: UseCompressedOops: some card-marking fixes related to object arrays
Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17).
Reviewed-by: kvn, coleenp, jmasa
author | ysr |
---|---|
date | Thu, 03 Dec 2009 15:01:57 -0800 |
parents | d1605aabd0a1 |
children | c18cbe5936b8 |
rev | line source |
---|---|
0 | 1 /* |
196 | 2 * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 // | |
26 // psPromotionManager is used by a single thread to manage object survival | |
27 // during a scavenge. The promotion manager contains thread local data only. | |
28 // | |
29 // NOTE! Be carefull when allocating the stacks on cheap. If you are going | |
30 // to use a promotion manager in more than one thread, the stacks MUST be | |
31 // on cheap. This can lead to memory leaks, though, as they are not auto | |
32 // deallocated. | |
33 // | |
34 // FIX ME FIX ME Add a destructor, and don't rely on the user to drain/flush/deallocate! | |
35 // | |
36 | |
37 // Move to some global location | |
38 #define HAS_BEEN_MOVED 0x1501d01d | |
39 // End move to some global location | |
40 | |
41 class MutableSpace; | |
42 class PSOldGen; | |
43 class ParCompactionManager; | |
44 | |
45 #define PS_PM_STATS 0 | |
46 | |
47 class PSPromotionManager : public CHeapObj { | |
48 friend class PSScavenge; | |
49 friend class PSRefProcTaskExecutor; | |
50 private: | |
51 static PSPromotionManager** _manager_array; | |
52 static OopStarTaskQueueSet* _stack_array_depth; | |
53 static OopTaskQueueSet* _stack_array_breadth; | |
54 static PSOldGen* _old_gen; | |
55 static MutableSpace* _young_space; | |
56 | |
57 #if PS_PM_STATS | |
58 uint _total_pushes; | |
59 uint _masked_pushes; | |
60 | |
61 uint _overflow_pushes; | |
62 uint _max_overflow_length; | |
63 | |
64 uint _arrays_chunked; | |
65 uint _array_chunks_processed; | |
66 | |
67 uint _total_steals; | |
68 uint _masked_steals; | |
69 | |
70 void print_stats(uint i); | |
71 static void print_stats(); | |
72 #endif // PS_PM_STATS | |
73 | |
74 PSYoungPromotionLAB _young_lab; | |
75 PSOldPromotionLAB _old_lab; | |
76 bool _young_gen_is_full; | |
77 bool _old_gen_is_full; | |
78 PrefetchQueue _prefetch_queue; | |
79 | |
80 OopStarTaskQueue _claimed_stack_depth; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
81 GrowableArray<StarTask>* _overflow_stack_depth; |
0 | 82 OopTaskQueue _claimed_stack_breadth; |
83 GrowableArray<oop>* _overflow_stack_breadth; | |
84 | |
85 bool _depth_first; | |
86 bool _totally_drain; | |
87 uint _target_stack_size; | |
88 | |
89 uint _array_chunk_size; | |
90 uint _min_array_size_for_chunking; | |
91 | |
92 // Accessors | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
93 static PSOldGen* old_gen() { return _old_gen; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
94 static MutableSpace* young_space() { return _young_space; } |
0 | 95 |
96 inline static PSPromotionManager* manager_array(int index); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
97 template <class T> inline void claim_or_forward_internal_depth(T* p); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
98 template <class T> inline void claim_or_forward_internal_breadth(T* p); |
0 | 99 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
100 GrowableArray<StarTask>* overflow_stack_depth() { return _overflow_stack_depth; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
101 GrowableArray<oop>* overflow_stack_breadth() { return _overflow_stack_breadth; } |
0 | 102 |
103 // On the task queues we push reference locations as well as | |
104 // partially-scanned arrays (in the latter case, we push an oop to | |
105 // the from-space image of the array and the length on the | |
106 // from-space image indicates how many entries on the array we still | |
107 // need to scan; this is basically how ParNew does partial array | |
108 // scanning too). To be able to distinguish between reference | |
109 // locations and partially-scanned array oops we simply mask the | |
110 // latter oops with 0x01. The next three methods do the masking, | |
111 // unmasking, and checking whether the oop is masked or not. Notice | |
112 // that the signature of the mask and unmask methods looks a bit | |
113 // strange, as they accept and return different types (oop and | |
114 // oop*). This is because of the difference in types between what | |
115 // the task queue holds (oop*) and oops to partially-scanned arrays | |
116 // (oop). We do all the necessary casting in the mask / unmask | |
117 // methods to avoid sprinkling the rest of the code with more casts. | |
118 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
119 // These are added to the taskqueue so PS_CHUNKED_ARRAY_OOP_MASK (or any |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
120 // future masks) can't conflict with COMPRESSED_OOP_MASK |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
121 #define PS_CHUNKED_ARRAY_OOP_MASK 0x2 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
122 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
123 bool is_oop_masked(StarTask p) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
124 // If something is marked chunked it's always treated like wide oop* |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
125 return (((intptr_t)(oop*)p) & PS_CHUNKED_ARRAY_OOP_MASK) == |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
126 PS_CHUNKED_ARRAY_OOP_MASK; |
0 | 127 } |
128 | |
129 oop* mask_chunked_array_oop(oop obj) { | |
130 assert(!is_oop_masked((oop*) obj), "invariant"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
131 oop* ret = (oop*) ((uintptr_t)obj | PS_CHUNKED_ARRAY_OOP_MASK); |
0 | 132 assert(is_oop_masked(ret), "invariant"); |
133 return ret; | |
134 } | |
135 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
136 oop unmask_chunked_array_oop(StarTask p) { |
0 | 137 assert(is_oop_masked(p), "invariant"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
138 assert(!p.is_narrow(), "chunked array oops cannot be narrow"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
139 oop *chunk = (oop*)p; // cast p to oop (uses conversion operator) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
140 oop ret = oop((oop*)((uintptr_t)chunk & ~PS_CHUNKED_ARRAY_OOP_MASK)); |
0 | 141 assert(!is_oop_masked((oop*) ret), "invariant"); |
142 return ret; | |
143 } | |
144 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
145 template <class T> void process_array_chunk_work(oop obj, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
146 int start, int end); |
0 | 147 void process_array_chunk(oop old); |
148 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
149 template <class T> void push_depth(T* p) { |
0 | 150 assert(depth_first(), "pre-condition"); |
151 | |
152 #if PS_PM_STATS | |
153 ++_total_pushes; | |
154 #endif // PS_PM_STATS | |
155 | |
156 if (!claimed_stack_depth()->push(p)) { | |
157 overflow_stack_depth()->push(p); | |
158 #if PS_PM_STATS | |
159 ++_overflow_pushes; | |
160 uint stack_length = (uint) overflow_stack_depth()->length(); | |
161 if (stack_length > _max_overflow_length) { | |
162 _max_overflow_length = stack_length; | |
163 } | |
164 #endif // PS_PM_STATS | |
165 } | |
166 } | |
167 | |
168 void push_breadth(oop o) { | |
169 assert(!depth_first(), "pre-condition"); | |
170 | |
171 #if PS_PM_STATS | |
172 ++_total_pushes; | |
173 #endif // PS_PM_STATS | |
174 | |
175 if(!claimed_stack_breadth()->push(o)) { | |
176 overflow_stack_breadth()->push(o); | |
177 #if PS_PM_STATS | |
178 ++_overflow_pushes; | |
179 uint stack_length = (uint) overflow_stack_breadth()->length(); | |
180 if (stack_length > _max_overflow_length) { | |
181 _max_overflow_length = stack_length; | |
182 } | |
183 #endif // PS_PM_STATS | |
184 } | |
185 } | |
186 | |
187 protected: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
188 static OopStarTaskQueueSet* stack_array_depth() { return _stack_array_depth; } |
0 | 189 static OopTaskQueueSet* stack_array_breadth() { return _stack_array_breadth; } |
190 | |
191 public: | |
192 // Static | |
193 static void initialize(); | |
194 | |
195 static void pre_scavenge(); | |
196 static void post_scavenge(); | |
197 | |
198 static PSPromotionManager* gc_thread_promotion_manager(int index); | |
199 static PSPromotionManager* vm_thread_promotion_manager(); | |
200 | |
201 static bool steal_depth(int queue_num, int* seed, StarTask& t) { | |
202 assert(stack_array_depth() != NULL, "invariant"); | |
203 return stack_array_depth()->steal(queue_num, seed, t); | |
204 } | |
205 | |
206 static bool steal_breadth(int queue_num, int* seed, Task& t) { | |
207 assert(stack_array_breadth() != NULL, "invariant"); | |
208 return stack_array_breadth()->steal(queue_num, seed, t); | |
209 } | |
210 | |
211 PSPromotionManager(); | |
212 | |
213 // Accessors | |
214 OopStarTaskQueue* claimed_stack_depth() { | |
215 return &_claimed_stack_depth; | |
216 } | |
217 OopTaskQueue* claimed_stack_breadth() { | |
218 return &_claimed_stack_breadth; | |
219 } | |
220 | |
221 bool young_gen_is_full() { return _young_gen_is_full; } | |
222 | |
223 bool old_gen_is_full() { return _old_gen_is_full; } | |
224 void set_old_gen_is_full(bool state) { _old_gen_is_full = state; } | |
225 | |
226 // Promotion methods | |
227 oop copy_to_survivor_space(oop o, bool depth_first); | |
228 oop oop_promotion_failed(oop obj, markOop obj_mark); | |
229 | |
230 void reset(); | |
231 | |
232 void flush_labs(); | |
233 void drain_stacks(bool totally_drain) { | |
234 if (depth_first()) { | |
235 drain_stacks_depth(totally_drain); | |
236 } else { | |
237 drain_stacks_breadth(totally_drain); | |
238 } | |
239 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
240 public: |
0 | 241 void drain_stacks_cond_depth() { |
242 if (claimed_stack_depth()->size() > _target_stack_size) { | |
243 drain_stacks_depth(false); | |
244 } | |
245 } | |
246 void drain_stacks_depth(bool totally_drain); | |
247 void drain_stacks_breadth(bool totally_drain); | |
248 | |
249 bool claimed_stack_empty() { | |
250 if (depth_first()) { | |
251 return claimed_stack_depth()->size() <= 0; | |
252 } else { | |
253 return claimed_stack_breadth()->size() <= 0; | |
254 } | |
255 } | |
256 bool overflow_stack_empty() { | |
257 if (depth_first()) { | |
258 return overflow_stack_depth()->length() <= 0; | |
259 } else { | |
260 return overflow_stack_breadth()->length() <= 0; | |
261 } | |
262 } | |
263 bool stacks_empty() { | |
264 return claimed_stack_empty() && overflow_stack_empty(); | |
265 } | |
266 bool depth_first() { | |
267 return _depth_first; | |
268 } | |
269 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
270 inline void process_popped_location_depth(StarTask p); |
0 | 271 |
272 inline void flush_prefetch_queue(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
273 template <class T> inline void claim_or_forward_depth(T* p); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
274 template <class T> inline void claim_or_forward_breadth(T* p); |
0 | 275 |
276 #if PS_PM_STATS | |
277 void increment_steals(oop* p = NULL) { | |
278 _total_steals += 1; | |
279 if (p != NULL && is_oop_masked(p)) { | |
280 _masked_steals += 1; | |
281 } | |
282 } | |
283 #endif // PS_PM_STATS | |
284 }; |