annotate src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp @ 2149:7e37af9d69ef

7011379: G1: overly long concurrent marking cycles Summary: This changeset introduces filtering of SATB buffers at the point when they are about to be enqueued. If this filtering clears enough entries on each buffer, the buffer can then be re-used and not enqueued. This cuts down the number of SATB buffers that need to be processed by the concurrent marking threads. Reviewed-by: johnc, ysr
author tonyp
date Wed, 19 Jan 2011 09:35:17 -0500
parents f95d63e2154a
children 1fb790245268
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1638
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. 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 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 579
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 579
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 579
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1836
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1836
diff changeset
26 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1836
diff changeset
27 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1836
diff changeset
28 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1836
diff changeset
29 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1836
diff changeset
30 #include "gc_implementation/shared/mutableSpace.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1836
diff changeset
31 #include "memory/memRegion.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1836
diff changeset
32 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1836
diff changeset
33 #include "oops/oop.psgc.inline.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 PSPromotionManager** PSPromotionManager::_manager_array = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
36 OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
37 PSOldGen* PSPromotionManager::_old_gen = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 MutableSpace* PSPromotionManager::_young_space = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 void PSPromotionManager::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
41 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
42 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 _old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
45 _young_space = heap->young_gen()->to_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 assert(_manager_array == NULL, "Attempt to initialize twice");
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _manager_array = NEW_C_HEAP_ARRAY(PSPromotionManager*, ParallelGCThreads+1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
49 guarantee(_manager_array != NULL, "Could not initialize promotion manager");
a61af66fc99e Initial load
duke
parents:
diff changeset
50
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
51 _stack_array_depth = new OopStarTaskQueueSet(ParallelGCThreads);
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
52 guarantee(_stack_array_depth != NULL, "Cound not initialize promotion manager");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // Create and register the PSPromotionManager(s) for the worker threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
55 for(uint i=0; i<ParallelGCThreads; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
56 _manager_array[i] = new PSPromotionManager();
a61af66fc99e Initial load
duke
parents:
diff changeset
57 guarantee(_manager_array[i] != NULL, "Could not create PSPromotionManager");
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
58 stack_array_depth()->register_queue(i, _manager_array[i]->claimed_stack_depth());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
59 }
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // The VMThread gets its own PSPromotionManager, which is not available
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // for work stealing.
a61af66fc99e Initial load
duke
parents:
diff changeset
63 _manager_array[ParallelGCThreads] = new PSPromotionManager();
a61af66fc99e Initial load
duke
parents:
diff changeset
64 guarantee(_manager_array[ParallelGCThreads] != NULL, "Could not create PSPromotionManager");
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range");
a61af66fc99e Initial load
duke
parents:
diff changeset
69 assert(_manager_array != NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
70 return _manager_array[index];
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 PSPromotionManager* PSPromotionManager::vm_thread_promotion_manager() {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 assert(_manager_array != NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
75 return _manager_array[ParallelGCThreads];
a61af66fc99e Initial load
duke
parents:
diff changeset
76 }
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78 void PSPromotionManager::pre_scavenge() {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
80 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 _young_space = heap->young_gen()->to_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 for(uint i=0; i<ParallelGCThreads+1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 manager_array(i)->reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 void PSPromotionManager::post_scavenge() {
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
90 TASKQUEUE_STATS_ONLY(if (PrintGCDetails && ParallelGCVerbose) print_stats());
1638
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
91 for (uint i = 0; i < ParallelGCThreads + 1; i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
92 PSPromotionManager* manager = manager_array(i);
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
93 assert(manager->claimed_stack_depth()->is_empty(), "should be empty");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
94 manager->flush_labs();
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
98 #if TASKQUEUE_STATS
0
a61af66fc99e Initial load
duke
parents:
diff changeset
99 void
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
100 PSPromotionManager::print_taskqueue_stats(uint i) const {
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
101 tty->print("%3u ", i);
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
102 _claimed_stack_depth.stats.print();
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
103 tty->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 void
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
107 PSPromotionManager::print_local_stats(uint i) const {
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
108 #define FMT " " SIZE_FORMAT_W(10)
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
109 tty->print_cr("%3u" FMT FMT FMT FMT, i, _masked_pushes, _masked_steals,
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
110 _arrays_chunked, _array_chunks_processed);
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
111 #undef FMT
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
112 }
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
113
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
114 static const char* const pm_stats_hdr[] = {
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
115 " --------masked------- arrays array",
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
116 "thr push steal chunked chunks",
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
117 "--- ---------- ---------- ---------- ----------"
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
118 };
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
119
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
120 void
0
a61af66fc99e Initial load
duke
parents:
diff changeset
121 PSPromotionManager::print_stats() {
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
122 tty->print_cr("== GC Tasks Stats, GC %3d",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
123 Universe::heap()->total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
124
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
125 tty->print("thr "); TaskQueueStats::print_header(1); tty->cr();
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
126 tty->print("--- "); TaskQueueStats::print_header(2); tty->cr();
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
127 for (uint i = 0; i < ParallelGCThreads + 1; ++i) {
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
128 manager_array(i)->print_taskqueue_stats(i);
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
129 }
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
130
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
131 const uint hlines = sizeof(pm_stats_hdr) / sizeof(pm_stats_hdr[0]);
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
132 for (uint i = 0; i < hlines; ++i) tty->print_cr(pm_stats_hdr[i]);
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
133 for (uint i = 0; i < ParallelGCThreads + 1; ++i) {
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
134 manager_array(i)->print_local_stats(i);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
138 void
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
139 PSPromotionManager::reset_stats() {
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
140 claimed_stack_depth()->stats.reset();
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
141 _masked_pushes = _masked_steals = 0;
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
142 _arrays_chunked = _array_chunks_processed = 0;
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
143 }
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
144 #endif // TASKQUEUE_STATS
0
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 PSPromotionManager::PSPromotionManager() {
a61af66fc99e Initial load
duke
parents:
diff changeset
147 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
148 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // We set the old lab's start array.
a61af66fc99e Initial load
duke
parents:
diff changeset
151 _old_lab.set_start_array(old_gen()->start_array());
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 uint queue_size;
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
154 claimed_stack_depth()->initialize();
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
155 queue_size = claimed_stack_depth()->max_elems();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 _totally_drain = (ParallelGCThreads == 1) || (GCDrainStackTargetSize == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 if (_totally_drain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
159 _target_stack_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // don't let the target stack size to be more than 1/4 of the entries
a61af66fc99e Initial load
duke
parents:
diff changeset
162 _target_stack_size = (uint) MIN2((uint) GCDrainStackTargetSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
163 (uint) (queue_size / 4));
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 _array_chunk_size = ParGCArrayScanChunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // let's choose 1.5x the chunk size
a61af66fc99e Initial load
duke
parents:
diff changeset
168 _min_array_size_for_chunking = 3 * _array_chunk_size / 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
172
a61af66fc99e Initial load
duke
parents:
diff changeset
173 void PSPromotionManager::reset() {
1638
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
174 assert(stacks_empty(), "reset of non-empty stack");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // We need to get an assert in here to make sure the labs are always flushed.
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
179 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Do not prefill the LAB's, save heap wastage!
a61af66fc99e Initial load
duke
parents:
diff changeset
182 HeapWord* lab_base = young_space()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
183 _young_lab.initialize(MemRegion(lab_base, (size_t)0));
a61af66fc99e Initial load
duke
parents:
diff changeset
184 _young_gen_is_full = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 lab_base = old_gen()->object_space()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
187 _old_lab.initialize(MemRegion(lab_base, (size_t)0));
a61af66fc99e Initial load
duke
parents:
diff changeset
188 _old_gen_is_full = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
189
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
190 TASKQUEUE_STATS_ONLY(reset_stats());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
192
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
193
0
a61af66fc99e Initial load
duke
parents:
diff changeset
194 void PSPromotionManager::drain_stacks_depth(bool totally_drain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 totally_drain = totally_drain || _totally_drain;
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
198 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
199 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
200 MutableSpace* to_space = heap->young_gen()->to_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
201 MutableSpace* old_space = heap->old_gen()->object_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
202 MutableSpace* perm_space = heap->perm_gen()->object_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
203 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
204
1638
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
205 OopStarTaskQueue* const tq = claimed_stack_depth();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
206 do {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
207 StarTask p;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // Drain overflow stack first, so other threads can steal from
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // claimed stack while we work.
1638
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
211 while (tq->pop_overflow(p)) {
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
212 process_popped_location_depth(p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 if (totally_drain) {
1638
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
216 while (tq->pop_local(p)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
217 process_popped_location_depth(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
219 } else {
1638
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
220 while (tq->size() > _target_stack_size && tq->pop_local(p)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
221 process_popped_location_depth(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
1638
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
224 } while (totally_drain && !tq->taskqueue_empty() || !tq->overflow_empty());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
225
1638
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
226 assert(!totally_drain || tq->taskqueue_empty(), "Sanity");
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
227 assert(totally_drain || tq->size() <= _target_stack_size, "Sanity");
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
228 assert(tq->overflow_empty(), "Sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231 void PSPromotionManager::flush_labs() {
1638
b2a00dd3117c 6957084: simplify TaskQueue overflow handling
jcoomes
parents: 1552
diff changeset
232 assert(stacks_empty(), "Attempt to flush lab with live stack");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // If either promotion lab fills up, we can flush the
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // lab but not refill it, so check first.
a61af66fc99e Initial load
duke
parents:
diff changeset
236 assert(!_young_lab.is_flushed() || _young_gen_is_full, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
237 if (!_young_lab.is_flushed())
a61af66fc99e Initial load
duke
parents:
diff changeset
238 _young_lab.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 assert(!_old_lab.is_flushed() || _old_gen_is_full, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
241 if (!_old_lab.is_flushed())
a61af66fc99e Initial load
duke
parents:
diff changeset
242 _old_lab.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // Let PSScavenge know if we overflowed
a61af66fc99e Initial load
duke
parents:
diff changeset
245 if (_young_gen_is_full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
246 PSScavenge::set_survivor_overflow(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 //
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // This method is pretty bulky. It would be nice to split it up
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // into smaller submethods, but we need to be careful not to hurt
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // performance.
a61af66fc99e Initial load
duke
parents:
diff changeset
254 //
a61af66fc99e Initial load
duke
parents:
diff changeset
255
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
256 oop PSPromotionManager::copy_to_survivor_space(oop o) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
257 assert(PSScavenge::should_scavenge(&o), "Sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
258
a61af66fc99e Initial load
duke
parents:
diff changeset
259 oop new_obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
260
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // NOTE! We must be very careful with any methods that access the mark
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // in o. There may be multiple threads racing on it, and it may be forwarded
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // at any time. Do not use oop methods for accessing the mark!
a61af66fc99e Initial load
duke
parents:
diff changeset
264 markOop test_mark = o->mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // The same test as "o->is_forwarded()"
a61af66fc99e Initial load
duke
parents:
diff changeset
267 if (!test_mark->is_marked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 bool new_obj_is_tenured = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
269 size_t new_obj_size = o->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // Find the objects age, MT safe.
a61af66fc99e Initial load
duke
parents:
diff changeset
272 int age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ?
a61af66fc99e Initial load
duke
parents:
diff changeset
273 test_mark->displaced_mark_helper()->age() : test_mark->age();
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // Try allocating obj in to-space (unless too old)
a61af66fc99e Initial load
duke
parents:
diff changeset
276 if (age < PSScavenge::tenuring_threshold()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 new_obj = (oop) _young_lab.allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
278 if (new_obj == NULL && !_young_gen_is_full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // Do we allocate directly, or flush and refill?
a61af66fc99e Initial load
duke
parents:
diff changeset
280 if (new_obj_size > (YoungPLABSize / 2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // Allocate this object directly
a61af66fc99e Initial load
duke
parents:
diff changeset
282 new_obj = (oop)young_space()->cas_allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
283 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // Flush and fill
a61af66fc99e Initial load
duke
parents:
diff changeset
285 _young_lab.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 HeapWord* lab_base = young_space()->cas_allocate(YoungPLABSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
288 if (lab_base != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 _young_lab.initialize(MemRegion(lab_base, YoungPLABSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // Try the young lab allocation again.
a61af66fc99e Initial load
duke
parents:
diff changeset
291 new_obj = (oop) _young_lab.allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
293 _young_gen_is_full = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
298
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // Otherwise try allocating obj tenured
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
302 if (Universe::heap()->promotion_should_fail()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
303 return oop_promotion_failed(o, test_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
305 #endif // #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
306
a61af66fc99e Initial load
duke
parents:
diff changeset
307 new_obj = (oop) _old_lab.allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 new_obj_is_tenured = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 if (!_old_gen_is_full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // Do we allocate directly, or flush and refill?
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if (new_obj_size > (OldPLABSize / 2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // Allocate this object directly
a61af66fc99e Initial load
duke
parents:
diff changeset
315 new_obj = (oop)old_gen()->cas_allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
316 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // Flush and fill
a61af66fc99e Initial load
duke
parents:
diff changeset
318 _old_lab.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 HeapWord* lab_base = old_gen()->cas_allocate(OldPLABSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 if(lab_base != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 _old_lab.initialize(MemRegion(lab_base, OldPLABSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // Try the old lab allocation again.
a61af66fc99e Initial load
duke
parents:
diff changeset
324 new_obj = (oop) _old_lab.allocate(new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
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 // This is the promotion failed test, and code handling.
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // The code belongs here for two reasons. It is slightly
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // different thatn the code below, and cannot share the
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // CAS testing code. Keeping the code here also minimizes
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // the impact on the common case fast path code.
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 _old_gen_is_full = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
337 return oop_promotion_failed(o, test_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 assert(new_obj != NULL, "allocation should have succeeded");
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // Copy obj
a61af66fc99e Initial load
duke
parents:
diff changeset
345 Copy::aligned_disjoint_words((HeapWord*)o, (HeapWord*)new_obj, new_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // Now we have to CAS in the header.
a61af66fc99e Initial load
duke
parents:
diff changeset
348 if (o->cas_forward_to(new_obj, test_mark)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // We won any races, we "own" this object.
a61af66fc99e Initial load
duke
parents:
diff changeset
350 assert(new_obj == o->forwardee(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // Increment age if obj still in new generation. Now that
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // we're dealing with a markOop that cannot change, it is
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // okay to use the non mt safe oop methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
355 if (!new_obj_is_tenured) {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 new_obj->incr_age();
a61af66fc99e Initial load
duke
parents:
diff changeset
357 assert(young_space()->contains(new_obj), "Attempt to push non-promoted obj");
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
360 // Do the size comparison first with new_obj_size, which we
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
361 // already have. Hopefully, only a few objects are larger than
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
362 // _min_array_size_for_chunking, and most of them will be arrays.
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
363 // So, the is->objArray() test would be very infrequent.
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
364 if (new_obj_size > _min_array_size_for_chunking &&
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
365 new_obj->is_objArray() &&
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
366 PSChunkLargeArrays) {
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
367 // we'll chunk it
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
368 oop* const masked_o = mask_chunked_array_oop(o);
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
369 push_depth(masked_o);
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
370 TASKQUEUE_STATS_ONLY(++_arrays_chunked; ++_masked_pushes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
371 } else {
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
372 // we'll just push its contents
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
373 new_obj->push_contents(this);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // We lost, someone else "owns" this object
a61af66fc99e Initial load
duke
parents:
diff changeset
377 guarantee(o->is_forwarded(), "Object must be forwarded if the cas failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
378
481
7d7a7c599c17 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 196
diff changeset
379 // Try to deallocate the space. If it was directly allocated we cannot
7d7a7c599c17 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 196
diff changeset
380 // deallocate it, so we have to test. If the deallocation fails,
7d7a7c599c17 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 196
diff changeset
381 // overwrite with a filler object.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
382 if (new_obj_is_tenured) {
a61af66fc99e Initial load
duke
parents:
diff changeset
383 if (!_old_lab.unallocate_object(new_obj)) {
481
7d7a7c599c17 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 196
diff changeset
384 CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
481
7d7a7c599c17 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 196
diff changeset
386 } else if (!_young_lab.unallocate_object(new_obj)) {
7d7a7c599c17 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 196
diff changeset
387 CollectedHeap::fill_with_object((HeapWord*) new_obj, new_obj_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // don't update this before the unallocation!
a61af66fc99e Initial load
duke
parents:
diff changeset
391 new_obj = o->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
393 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 assert(o->is_forwarded(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
395 new_obj = o->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 #ifdef DEBUG
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // This code must come after the CAS test, or it will print incorrect
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // information.
a61af66fc99e Initial load
duke
parents:
diff changeset
401 if (TraceScavenge) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
402 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
403 PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
404 new_obj->blueprint()->internal_name(), o, new_obj, new_obj->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 return new_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
411 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
412 oop obj,
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
413 int start, int end) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
414 assert(start < end, "invariant");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
415 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
416 T* p = base + start;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
417 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
418 while (p < chunk_end) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
419 if (PSScavenge::should_scavenge(p)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
420 claim_or_forward_depth(p);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
421 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
422 ++p;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
423 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
424 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
425
0
a61af66fc99e Initial load
duke
parents:
diff changeset
426 void PSPromotionManager::process_array_chunk(oop old) {
a61af66fc99e Initial load
duke
parents:
diff changeset
427 assert(PSChunkLargeArrays, "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
428 assert(old->is_objArray(), "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
429 assert(old->is_forwarded(), "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
430
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
431 TASKQUEUE_STATS_ONLY(++_array_chunks_processed);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 oop const obj = old->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 int start;
a61af66fc99e Initial load
duke
parents:
diff changeset
436 int const end = arrayOop(old)->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
437 if (end > (int) _min_array_size_for_chunking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // we'll chunk more
a61af66fc99e Initial load
duke
parents:
diff changeset
439 start = end - _array_chunk_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
440 assert(start > 0, "invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
441 arrayOop(old)->set_length(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
442 push_depth(mask_chunked_array_oop(old));
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1638
diff changeset
443 TASKQUEUE_STATS_ONLY(++_masked_pushes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
444 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // this is the final chunk for this array
a61af66fc99e Initial load
duke
parents:
diff changeset
446 start = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
447 int const actual_length = arrayOop(obj)->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
448 arrayOop(old)->set_length(actual_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
451 if (UseCompressedOops) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
452 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
453 } else {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
454 process_array_chunk_work<oop>(obj, start, end);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457
a61af66fc99e Initial load
duke
parents:
diff changeset
458 oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // Attempt to CAS in the header.
a61af66fc99e Initial load
duke
parents:
diff changeset
462 // This tests if the header is still the same as when
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // this started. If it is the same (i.e., no forwarding
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // pointer has been installed), then this thread owns
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // it.
a61af66fc99e Initial load
duke
parents:
diff changeset
466 if (obj->cas_forward_to(obj, obj_mark)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // We won any races, we "own" this object.
a61af66fc99e Initial load
duke
parents:
diff changeset
468 assert(obj == obj->forwardee(), "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
469
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1665
diff changeset
470 obj->push_contents(this);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
471
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // Save the mark if needed
a61af66fc99e Initial load
duke
parents:
diff changeset
473 PSScavenge::oop_promotion_failed(obj, obj_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
474 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // We lost, someone else "owns" this object
a61af66fc99e Initial load
duke
parents:
diff changeset
476 guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // No unallocation to worry about.
a61af66fc99e Initial load
duke
parents:
diff changeset
479 obj = obj->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 #ifdef DEBUG
a61af66fc99e Initial load
duke
parents:
diff changeset
483 if (TraceScavenge) {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 gclog_or_tty->print_cr("{%s %s 0x%x (%d)}",
a61af66fc99e Initial load
duke
parents:
diff changeset
485 "promotion-failure",
a61af66fc99e Initial load
duke
parents:
diff changeset
486 obj->blueprint()->internal_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
487 obj, obj->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
488
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
491
a61af66fc99e Initial load
duke
parents:
diff changeset
492 return obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }