annotate src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp @ 453:c96030fff130

6684579: SoftReference processing can be made more efficient Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not. Reviewed-by: jmasa
author ysr
date Thu, 20 Nov 2008 16:56:09 -0800
parents d1605aabd0a1
children 7d7a7c599c17
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
196
d1605aabd0a1 6719955: Update copyright year
xdono
parents: 113
diff changeset
2 * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_psPromotionManager.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 PSPromotionManager** PSPromotionManager::_manager_array = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 OopTaskQueueSet* PSPromotionManager::_stack_array_breadth = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 PSOldGen* PSPromotionManager::_old_gen = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
32 MutableSpace* PSPromotionManager::_young_space = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 void PSPromotionManager::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
35 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
36 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 _old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
39 _young_space = heap->young_gen()->to_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 assert(_manager_array == NULL, "Attempt to initialize twice");
a61af66fc99e Initial load
duke
parents:
diff changeset
42 _manager_array = NEW_C_HEAP_ARRAY(PSPromotionManager*, ParallelGCThreads+1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
43 guarantee(_manager_array != NULL, "Could not initialize promotion manager");
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 if (UseDepthFirstScavengeOrder) {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 _stack_array_depth = new OopStarTaskQueueSet(ParallelGCThreads);
a61af66fc99e Initial load
duke
parents:
diff changeset
47 guarantee(_stack_array_depth != NULL, "Count not initialize promotion manager");
a61af66fc99e Initial load
duke
parents:
diff changeset
48 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
49 _stack_array_breadth = new OopTaskQueueSet(ParallelGCThreads);
a61af66fc99e Initial load
duke
parents:
diff changeset
50 guarantee(_stack_array_breadth != NULL, "Count not initialize promotion manager");
a61af66fc99e Initial load
duke
parents:
diff changeset
51 }
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // Create and register the PSPromotionManager(s) for the worker threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
54 for(uint i=0; i<ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 _manager_array[i] = new PSPromotionManager();
a61af66fc99e Initial load
duke
parents:
diff changeset
56 guarantee(_manager_array[i] != NULL, "Could not create PSPromotionManager");
a61af66fc99e Initial load
duke
parents:
diff changeset
57 if (UseDepthFirstScavengeOrder) {
a61af66fc99e Initial load
duke
parents:
diff changeset
58 stack_array_depth()->register_queue(i, _manager_array[i]->claimed_stack_depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
59 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 stack_array_breadth()->register_queue(i, _manager_array[i]->claimed_stack_breadth());
a61af66fc99e Initial load
duke
parents:
diff changeset
61 }
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // The VMThread gets its own PSPromotionManager, which is not available
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // for work stealing.
a61af66fc99e Initial load
duke
parents:
diff changeset
66 _manager_array[ParallelGCThreads] = new PSPromotionManager();
a61af66fc99e Initial load
duke
parents:
diff changeset
67 guarantee(_manager_array[ParallelGCThreads] != NULL, "Could not create PSPromotionManager");
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
71 assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range");
a61af66fc99e Initial load
duke
parents:
diff changeset
72 assert(_manager_array != NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
73 return _manager_array[index];
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 PSPromotionManager* PSPromotionManager::vm_thread_promotion_manager() {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 assert(_manager_array != NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
78 return _manager_array[ParallelGCThreads];
a61af66fc99e Initial load
duke
parents:
diff changeset
79 }
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 void PSPromotionManager::pre_scavenge() {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
83 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 _young_space = heap->young_gen()->to_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 for(uint i=0; i<ParallelGCThreads+1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
88 manager_array(i)->reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 void PSPromotionManager::post_scavenge() {
a61af66fc99e Initial load
duke
parents:
diff changeset
93 #if PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
94 print_stats();
a61af66fc99e Initial load
duke
parents:
diff changeset
95 #endif // PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 for(uint i=0; i<ParallelGCThreads+1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 PSPromotionManager* manager = manager_array(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // the guarantees are a bit gratuitous but, if one fires, we'll
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // have a better idea of what went wrong
a61af66fc99e Initial load
duke
parents:
diff changeset
102 if (i < ParallelGCThreads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 guarantee((!UseDepthFirstScavengeOrder ||
a61af66fc99e Initial load
duke
parents:
diff changeset
104 manager->overflow_stack_depth()->length() <= 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
105 "promotion manager overflow stack must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
106 guarantee((UseDepthFirstScavengeOrder ||
a61af66fc99e Initial load
duke
parents:
diff changeset
107 manager->overflow_stack_breadth()->length() <= 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
108 "promotion manager overflow stack must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 guarantee((!UseDepthFirstScavengeOrder ||
a61af66fc99e Initial load
duke
parents:
diff changeset
111 manager->claimed_stack_depth()->size() <= 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
112 "promotion manager claimed stack must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
113 guarantee((UseDepthFirstScavengeOrder ||
a61af66fc99e Initial load
duke
parents:
diff changeset
114 manager->claimed_stack_breadth()->size() <= 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
115 "promotion manager claimed stack must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
116 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
117 guarantee((!UseDepthFirstScavengeOrder ||
a61af66fc99e Initial load
duke
parents:
diff changeset
118 manager->overflow_stack_depth()->length() <= 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
119 "VM Thread promotion manager overflow stack "
a61af66fc99e Initial load
duke
parents:
diff changeset
120 "must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
121 guarantee((UseDepthFirstScavengeOrder ||
a61af66fc99e Initial load
duke
parents:
diff changeset
122 manager->overflow_stack_breadth()->length() <= 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
123 "VM Thread promotion manager overflow stack "
a61af66fc99e Initial load
duke
parents:
diff changeset
124 "must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 guarantee((!UseDepthFirstScavengeOrder ||
a61af66fc99e Initial load
duke
parents:
diff changeset
127 manager->claimed_stack_depth()->size() <= 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
128 "VM Thread promotion manager claimed stack "
a61af66fc99e Initial load
duke
parents:
diff changeset
129 "must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
130 guarantee((UseDepthFirstScavengeOrder ||
a61af66fc99e Initial load
duke
parents:
diff changeset
131 manager->claimed_stack_breadth()->size() <= 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
132 "VM Thread promotion manager claimed stack "
a61af66fc99e Initial load
duke
parents:
diff changeset
133 "must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 manager->flush_labs();
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140 #if PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 void
a61af66fc99e Initial load
duke
parents:
diff changeset
143 PSPromotionManager::print_stats(uint i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 tty->print_cr("---- GC Worker %2d Stats", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
145 tty->print_cr(" total pushes %8d", _total_pushes);
a61af66fc99e Initial load
duke
parents:
diff changeset
146 tty->print_cr(" masked pushes %8d", _masked_pushes);
a61af66fc99e Initial load
duke
parents:
diff changeset
147 tty->print_cr(" overflow pushes %8d", _overflow_pushes);
a61af66fc99e Initial load
duke
parents:
diff changeset
148 tty->print_cr(" max overflow length %8d", _max_overflow_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
149 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
150 tty->print_cr(" arrays chunked %8d", _arrays_chunked);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 tty->print_cr(" array chunks processed %8d", _array_chunks_processed);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
153 tty->print_cr(" total steals %8d", _total_steals);
a61af66fc99e Initial load
duke
parents:
diff changeset
154 tty->print_cr(" masked steals %8d", _masked_steals);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 void
a61af66fc99e Initial load
duke
parents:
diff changeset
159 PSPromotionManager::print_stats() {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 tty->print_cr("== GC Tasks Stats (%s), GC %3d",
a61af66fc99e Initial load
duke
parents:
diff changeset
161 (UseDepthFirstScavengeOrder) ? "Depth-First" : "Breadth-First",
a61af66fc99e Initial load
duke
parents:
diff changeset
162 Universe::heap()->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 for (uint i = 0; i < ParallelGCThreads+1; ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 PSPromotionManager* manager = manager_array(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 manager->print_stats(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 #endif // PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 PSPromotionManager::PSPromotionManager() {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
174 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
175 _depth_first = UseDepthFirstScavengeOrder;
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // We set the old lab's start array.
a61af66fc99e Initial load
duke
parents:
diff changeset
178 _old_lab.set_start_array(old_gen()->start_array());
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 uint queue_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 if (depth_first()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 claimed_stack_depth()->initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
183 queue_size = claimed_stack_depth()->max_elems();
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // We want the overflow stack to be permanent
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
185 _overflow_stack_depth = new (ResourceObj::C_HEAP) GrowableArray<StarTask>(10, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
186 _overflow_stack_breadth = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
187 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 claimed_stack_breadth()->initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
189 queue_size = claimed_stack_breadth()->max_elems();
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // We want the overflow stack to be permanent
a61af66fc99e Initial load
duke
parents:
diff changeset
191 _overflow_stack_breadth = new (ResourceObj::C_HEAP) GrowableArray<oop>(10, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 _overflow_stack_depth = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 _totally_drain = (ParallelGCThreads == 1) || (GCDrainStackTargetSize == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
196 if (_totally_drain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 _target_stack_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // don't let the target stack size to be more than 1/4 of the entries
a61af66fc99e Initial load
duke
parents:
diff changeset
200 _target_stack_size = (uint) MIN2((uint) GCDrainStackTargetSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
201 (uint) (queue_size / 4));
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 _array_chunk_size = ParGCArrayScanChunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // let's choose 1.5x the chunk size
a61af66fc99e Initial load
duke
parents:
diff changeset
206 _min_array_size_for_chunking = 3 * _array_chunk_size / 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 void PSPromotionManager::reset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 assert(claimed_stack_empty(), "reset of non-empty claimed stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
213 assert(overflow_stack_empty(), "reset of non-empty overflow stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // We need to get an assert in here to make sure the labs are always flushed.
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
218 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 // Do not prefill the LAB's, save heap wastage!
a61af66fc99e Initial load
duke
parents:
diff changeset
221 HeapWord* lab_base = young_space()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
222 _young_lab.initialize(MemRegion(lab_base, (size_t)0));
a61af66fc99e Initial load
duke
parents:
diff changeset
223 _young_gen_is_full = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 lab_base = old_gen()->object_space()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
226 _old_lab.initialize(MemRegion(lab_base, (size_t)0));
a61af66fc99e Initial load
duke
parents:
diff changeset
227 _old_gen_is_full = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 _prefetch_queue.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231 #if PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
232 _total_pushes = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 _masked_pushes = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 _overflow_pushes = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 _max_overflow_length = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 _arrays_chunked = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
237 _array_chunks_processed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 _total_steals = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
239 _masked_steals = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 #endif // PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
243
0
a61af66fc99e Initial load
duke
parents:
diff changeset
244 void PSPromotionManager::drain_stacks_depth(bool totally_drain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 assert(depth_first(), "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
246 assert(overflow_stack_depth() != NULL, "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
247 totally_drain = totally_drain || _totally_drain;
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
250 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
251 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
252 MutableSpace* to_space = heap->young_gen()->to_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
253 MutableSpace* old_space = heap->old_gen()->object_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
254 MutableSpace* perm_space = heap->perm_gen()->object_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
255 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 do {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
258 StarTask p;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // Drain overflow stack first, so other threads can steal from
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // claimed stack while we work.
a61af66fc99e Initial load
duke
parents:
diff changeset
262 while(!overflow_stack_depth()->is_empty()) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
263 // linux compiler wants different overloaded operator= in taskqueue to
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
264 // assign to p that the other compilers don't like.
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
265 StarTask ptr = overflow_stack_depth()->pop();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
266 process_popped_location_depth(ptr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 if (totally_drain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 while (claimed_stack_depth()->pop_local(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 process_popped_location_depth(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
273 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
274 while (claimed_stack_depth()->size() > _target_stack_size &&
a61af66fc99e Initial load
duke
parents:
diff changeset
275 claimed_stack_depth()->pop_local(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 process_popped_location_depth(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279 } while( (totally_drain && claimed_stack_depth()->size() > 0) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
280 (overflow_stack_depth()->length() > 0) );
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282 assert(!totally_drain || claimed_stack_empty(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
283 assert(totally_drain ||
a61af66fc99e Initial load
duke
parents:
diff changeset
284 claimed_stack_depth()->size() <= _target_stack_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
285 "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
286 assert(overflow_stack_empty(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289 void PSPromotionManager::drain_stacks_breadth(bool totally_drain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 assert(!depth_first(), "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
291 assert(overflow_stack_breadth() != NULL, "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
292 totally_drain = totally_drain || _totally_drain;
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
295 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
296 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
297 MutableSpace* to_space = heap->young_gen()->to_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
298 MutableSpace* old_space = heap->old_gen()->object_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
299 MutableSpace* perm_space = heap->perm_gen()->object_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
300 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
303 oop obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // Drain overflow stack first, so other threads can steal from
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // claimed stack while we work.
a61af66fc99e Initial load
duke
parents:
diff changeset
307 while(!overflow_stack_breadth()->is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
308 obj = overflow_stack_breadth()->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
309 obj->copy_contents(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 if (totally_drain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // obj is a reference!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
314 while (claimed_stack_breadth()->pop_local(obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // It would be nice to assert about the type of objects we might
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // pop, but they can come from anywhere, unfortunately.
a61af66fc99e Initial load
duke
parents:
diff changeset
317 obj->copy_contents(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // obj is a reference!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
321 while (claimed_stack_breadth()->size() > _target_stack_size &&
a61af66fc99e Initial load
duke
parents:
diff changeset
322 claimed_stack_breadth()->pop_local(obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // It would be nice to assert about the type of objects we might
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // pop, but they can come from anywhere, unfortunately.
a61af66fc99e Initial load
duke
parents:
diff changeset
325 obj->copy_contents(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // If we could not find any other work, flush the prefetch queue
a61af66fc99e Initial load
duke
parents:
diff changeset
330 if (claimed_stack_breadth()->size() == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
331 (overflow_stack_breadth()->length() == 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
332 flush_prefetch_queue();
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334 } while((totally_drain && claimed_stack_breadth()->size() > 0) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
335 (overflow_stack_breadth()->length() > 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 assert(!totally_drain || claimed_stack_empty(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
338 assert(totally_drain ||
a61af66fc99e Initial load
duke
parents:
diff changeset
339 claimed_stack_breadth()->size() <= _target_stack_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
340 "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
341 assert(overflow_stack_empty(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 void PSPromotionManager::flush_labs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
345 assert(claimed_stack_empty(), "Attempt to flush lab with live stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
346 assert(overflow_stack_empty(), "Attempt to flush lab with live overflow stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // If either promotion lab fills up, we can flush the
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // lab but not refill it, so check first.
a61af66fc99e Initial load
duke
parents:
diff changeset
350 assert(!_young_lab.is_flushed() || _young_gen_is_full, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
351 if (!_young_lab.is_flushed())
a61af66fc99e Initial load
duke
parents:
diff changeset
352 _young_lab.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 assert(!_old_lab.is_flushed() || _old_gen_is_full, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
355 if (!_old_lab.is_flushed())
a61af66fc99e Initial load
duke
parents:
diff changeset
356 _old_lab.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // Let PSScavenge know if we overflowed
a61af66fc99e Initial load
duke
parents:
diff changeset
359 if (_young_gen_is_full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 PSScavenge::set_survivor_overflow(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 //
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // This method is pretty bulky. It would be nice to split it up
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // into smaller submethods, but we need to be careful not to hurt
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // performance.
a61af66fc99e Initial load
duke
parents:
diff changeset
368 //
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 oop PSPromotionManager::copy_to_survivor_space(oop o, bool depth_first) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
371 assert(PSScavenge::should_scavenge(&o), "Sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 oop new_obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // NOTE! We must be very careful with any methods that access the mark
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // in o. There may be multiple threads racing on it, and it may be forwarded
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // at any time. Do not use oop methods for accessing the mark!
a61af66fc99e Initial load
duke
parents:
diff changeset
378 markOop test_mark = o->mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // The same test as "o->is_forwarded()"
a61af66fc99e Initial load
duke
parents:
diff changeset
381 if (!test_mark->is_marked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 bool new_obj_is_tenured = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
383 size_t new_obj_size = o->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
384
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // Find the objects age, MT safe.
a61af66fc99e Initial load
duke
parents:
diff changeset
386 int age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
a61af66fc99e Initial load
duke
parents:
diff changeset
387 test_mark->displaced_mark_helper()->age() : test_mark->age();
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // Try allocating obj in to-space (unless too old)
a61af66fc99e Initial load
duke
parents:
diff changeset
390 if (age < PSScavenge::tenuring_threshold()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 new_obj = (oop) _young_lab.allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
392 if (new_obj == NULL && !_young_gen_is_full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // Do we allocate directly, or flush and refill?
a61af66fc99e Initial load
duke
parents:
diff changeset
394 if (new_obj_size > (YoungPLABSize / 2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // Allocate this object directly
a61af66fc99e Initial load
duke
parents:
diff changeset
396 new_obj = (oop)young_space()->cas_allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
397 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // Flush and fill
a61af66fc99e Initial load
duke
parents:
diff changeset
399 _young_lab.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 HeapWord* lab_base = young_space()->cas_allocate(YoungPLABSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 if (lab_base != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 _young_lab.initialize(MemRegion(lab_base, YoungPLABSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // Try the young lab allocation again.
a61af66fc99e Initial load
duke
parents:
diff changeset
405 new_obj = (oop) _young_lab.allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
406 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 _young_gen_is_full = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // Otherwise try allocating obj tenured
a61af66fc99e Initial load
duke
parents:
diff changeset
414 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
416 if (Universe::heap()->promotion_should_fail()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
417 return oop_promotion_failed(o, test_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419 #endif // #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 new_obj = (oop) _old_lab.allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
422 new_obj_is_tenured = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 if (!_old_gen_is_full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // Do we allocate directly, or flush and refill?
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if (new_obj_size > (OldPLABSize / 2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // Allocate this object directly
a61af66fc99e Initial load
duke
parents:
diff changeset
429 new_obj = (oop)old_gen()->cas_allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
430 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // Flush and fill
a61af66fc99e Initial load
duke
parents:
diff changeset
432 _old_lab.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 HeapWord* lab_base = old_gen()->cas_allocate(OldPLABSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
435 if(lab_base != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
436 _old_lab.initialize(MemRegion(lab_base, OldPLABSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // Try the old lab allocation again.
a61af66fc99e Initial load
duke
parents:
diff changeset
438 new_obj = (oop) _old_lab.allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // This is the promotion failed test, and code handling.
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // The code belongs here for two reasons. It is slightly
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // different thatn the code below, and cannot share the
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // CAS testing code. Keeping the code here also minimizes
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // the impact on the common case fast path code.
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 _old_gen_is_full = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
451 return oop_promotion_failed(o, test_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 assert(new_obj != NULL, "allocation should have succeeded");
a61af66fc99e Initial load
duke
parents:
diff changeset
457
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // Copy obj
a61af66fc99e Initial load
duke
parents:
diff changeset
459 Copy::aligned_disjoint_words((HeapWord*)o, (HeapWord*)new_obj, new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // Now we have to CAS in the header.
a61af66fc99e Initial load
duke
parents:
diff changeset
462 if (o->cas_forward_to(new_obj, test_mark)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // We won any races, we "own" this object.
a61af66fc99e Initial load
duke
parents:
diff changeset
464 assert(new_obj == o->forwardee(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // Increment age if obj still in new generation. Now that
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // we're dealing with a markOop that cannot change, it is
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // okay to use the non mt safe oop methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
469 if (!new_obj_is_tenured) {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 new_obj->incr_age();
a61af66fc99e Initial load
duke
parents:
diff changeset
471 assert(young_space()->contains(new_obj), "Attempt to push non-promoted obj");
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474 if (depth_first) {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // Do the size comparison first with new_obj_size, which we
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // already have. Hopefully, only a few objects are larger than
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // _min_array_size_for_chunking, and most of them will be arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // So, the is->objArray() test would be very infrequent.
a61af66fc99e Initial load
duke
parents:
diff changeset
479 if (new_obj_size > _min_array_size_for_chunking &&
a61af66fc99e Initial load
duke
parents:
diff changeset
480 new_obj->is_objArray() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
481 PSChunkLargeArrays) {
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // we'll chunk it
a61af66fc99e Initial load
duke
parents:
diff changeset
483 #if PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
484 ++_arrays_chunked;
a61af66fc99e Initial load
duke
parents:
diff changeset
485 #endif // PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
486 oop* const masked_o = mask_chunked_array_oop(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
487 push_depth(masked_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
488 #if PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
489 ++_masked_pushes;
a61af66fc99e Initial load
duke
parents:
diff changeset
490 #endif // PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
491 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // we'll just push its contents
a61af66fc99e Initial load
duke
parents:
diff changeset
493 new_obj->push_contents(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 push_breadth(new_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
498 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // We lost, someone else "owns" this object
a61af66fc99e Initial load
duke
parents:
diff changeset
500 guarantee(o->is_forwarded(), "Object must be forwarded if the cas failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
501
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // Unallocate the space used. NOTE! We may have directly allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // the object. If so, we cannot deallocate it, so we have to test!
a61af66fc99e Initial load
duke
parents:
diff changeset
504 if (new_obj_is_tenured) {
a61af66fc99e Initial load
duke
parents:
diff changeset
505 if (!_old_lab.unallocate_object(new_obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // The promotion lab failed to unallocate the object.
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // We need to overwrite the object with a filler that
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // contains no interior pointers.
a61af66fc99e Initial load
duke
parents:
diff changeset
509 MemRegion mr((HeapWord*)new_obj, new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // Clean this up and move to oopFactory (see bug 4718422)
a61af66fc99e Initial load
duke
parents:
diff changeset
511 SharedHeap::fill_region_with_object(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
513 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 if (!_young_lab.unallocate_object(new_obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // The promotion lab failed to unallocate the object.
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // We need to overwrite the object with a filler that
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // contains no interior pointers.
a61af66fc99e Initial load
duke
parents:
diff changeset
518 MemRegion mr((HeapWord*)new_obj, new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // Clean this up and move to oopFactory (see bug 4718422)
a61af66fc99e Initial load
duke
parents:
diff changeset
520 SharedHeap::fill_region_with_object(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
523
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // don't update this before the unallocation!
a61af66fc99e Initial load
duke
parents:
diff changeset
525 new_obj = o->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
527 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 assert(o->is_forwarded(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
529 new_obj = o->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
530 }
a61af66fc99e Initial load
duke
parents:
diff changeset
531
a61af66fc99e Initial load
duke
parents:
diff changeset
532 #ifdef DEBUG
a61af66fc99e Initial load
duke
parents:
diff changeset
533 // This code must come after the CAS test, or it will print incorrect
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // information.
a61af66fc99e Initial load
duke
parents:
diff changeset
535 if (TraceScavenge) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
536 gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (" SIZE_FORMAT ")}",
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
537 PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
538 new_obj->blueprint()->internal_name(), o, new_obj, new_obj->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
540 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 return new_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
544
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
545 template <class T> void PSPromotionManager::process_array_chunk_work(
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
546 oop obj,
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
547 int start, int end) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
548 assert(start < end, "invariant");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
549 T* const base = (T*)objArrayOop(obj)->base();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
550 T* p = base + start;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
551 T* const chunk_end = base + end;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
552 while (p < chunk_end) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
553 if (PSScavenge::should_scavenge(p)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
554 claim_or_forward_depth(p);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
555 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
556 ++p;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
557 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
558 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
559
0
a61af66fc99e Initial load
duke
parents:
diff changeset
560 void PSPromotionManager::process_array_chunk(oop old) {
a61af66fc99e Initial load
duke
parents:
diff changeset
561 assert(PSChunkLargeArrays, "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
562 assert(old->is_objArray(), "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
563 assert(old->is_forwarded(), "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
564
a61af66fc99e Initial load
duke
parents:
diff changeset
565 #if PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
566 ++_array_chunks_processed;
a61af66fc99e Initial load
duke
parents:
diff changeset
567 #endif // PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 oop const obj = old->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 int start;
a61af66fc99e Initial load
duke
parents:
diff changeset
572 int const end = arrayOop(old)->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
573 if (end > (int) _min_array_size_for_chunking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
574 // we'll chunk more
a61af66fc99e Initial load
duke
parents:
diff changeset
575 start = end - _array_chunk_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
576 assert(start > 0, "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
577 arrayOop(old)->set_length(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
578 push_depth(mask_chunked_array_oop(old));
a61af66fc99e Initial load
duke
parents:
diff changeset
579 #if PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
580 ++_masked_pushes;
a61af66fc99e Initial load
duke
parents:
diff changeset
581 #endif // PS_PM_STATS
a61af66fc99e Initial load
duke
parents:
diff changeset
582 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // this is the final chunk for this array
a61af66fc99e Initial load
duke
parents:
diff changeset
584 start = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
585 int const actual_length = arrayOop(obj)->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
586 arrayOop(old)->set_length(actual_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
588
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
589 if (UseCompressedOops) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
590 process_array_chunk_work<narrowOop>(obj, start, end);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
591 } else {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
592 process_array_chunk_work<oop>(obj, start, end);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
594 }
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
a61af66fc99e Initial load
duke
parents:
diff changeset
597 assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // Attempt to CAS in the header.
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // This tests if the header is still the same as when
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // this started. If it is the same (i.e., no forwarding
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // pointer has been installed), then this thread owns
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // it.
a61af66fc99e Initial load
duke
parents:
diff changeset
604 if (obj->cas_forward_to(obj, obj_mark)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // We won any races, we "own" this object.
a61af66fc99e Initial load
duke
parents:
diff changeset
606 assert(obj == obj->forwardee(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608 if (depth_first()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
609 obj->push_contents(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
610 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // Don't bother incrementing the age, just push
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // onto the claimed_stack..
a61af66fc99e Initial load
duke
parents:
diff changeset
613 push_breadth(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
615
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // Save the mark if needed
a61af66fc99e Initial load
duke
parents:
diff changeset
617 PSScavenge::oop_promotion_failed(obj, obj_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // We lost, someone else "owns" this object
a61af66fc99e Initial load
duke
parents:
diff changeset
620 guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // No unallocation to worry about.
a61af66fc99e Initial load
duke
parents:
diff changeset
623 obj = obj->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
625
a61af66fc99e Initial load
duke
parents:
diff changeset
626 #ifdef DEBUG
a61af66fc99e Initial load
duke
parents:
diff changeset
627 if (TraceScavenge) {
a61af66fc99e Initial load
duke
parents:
diff changeset
628 gclog_or_tty->print_cr("{%s %s 0x%x (%d)}",
a61af66fc99e Initial load
duke
parents:
diff changeset
629 "promotion-failure",
a61af66fc99e Initial load
duke
parents:
diff changeset
630 obj->blueprint()->internal_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
631 obj, obj->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636 return obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
637 }