annotate src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @ 1951:899bbbdcb6ea

6997298: fatal error: must own lock CMS_markBitMap_lock during heap dump Summary: Since we are at a stop-world pause, the existing CMS-phase checks are sufficient for safety, and the locking check can be safely elided. Elaborated documentation comment to the case where class unloading and verification are disabled, and the query happens when we aren't in the sweeping phase, where the answer "false" would be (almost everywhere) too pessimistic. Reviewed-by: jmasa, johnc, tonyp
author ysr
date Fri, 05 Nov 2010 13:20:37 -0700
parents a7214d79fcf1
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1387
diff changeset
2 * Copyright (c) 2001, 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: 1387
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1387
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: 1387
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
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_parNewGeneration.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 #ifdef _MSC_VER
a61af66fc99e Initial load
duke
parents:
diff changeset
29 #pragma warning( push )
a61af66fc99e Initial load
duke
parents:
diff changeset
30 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
a61af66fc99e Initial load
duke
parents:
diff changeset
31 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
32 ParScanThreadState::ParScanThreadState(Space* to_space_,
a61af66fc99e Initial load
duke
parents:
diff changeset
33 ParNewGeneration* gen_,
a61af66fc99e Initial load
duke
parents:
diff changeset
34 Generation* old_gen_,
a61af66fc99e Initial load
duke
parents:
diff changeset
35 int thread_num_,
a61af66fc99e Initial load
duke
parents:
diff changeset
36 ObjToScanQueueSet* work_queue_set_,
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
37 Stack<oop>* overflow_stacks_,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
38 size_t desired_plab_sz_,
a61af66fc99e Initial load
duke
parents:
diff changeset
39 ParallelTaskTerminator& term_) :
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
40 _to_space(to_space_), _old_gen(old_gen_), _young_gen(gen_), _thread_num(thread_num_),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
41 _work_queue(work_queue_set_->queue(thread_num_)), _to_space_full(false),
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
42 _overflow_stack(overflow_stacks_ ? overflow_stacks_ + thread_num_ : NULL),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
43 _ageTable(false), // false ==> not the global age table, no perf data.
a61af66fc99e Initial load
duke
parents:
diff changeset
44 _to_space_alloc_buffer(desired_plab_sz_),
a61af66fc99e Initial load
duke
parents:
diff changeset
45 _to_space_closure(gen_, this), _old_gen_closure(gen_, this),
a61af66fc99e Initial load
duke
parents:
diff changeset
46 _to_space_root_closure(gen_, this), _old_gen_root_closure(gen_, this),
a61af66fc99e Initial load
duke
parents:
diff changeset
47 _older_gen_closure(gen_, this),
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _evacuate_followers(this, &_to_space_closure, &_old_gen_closure,
a61af66fc99e Initial load
duke
parents:
diff changeset
49 &_to_space_root_closure, gen_, &_old_gen_root_closure,
a61af66fc99e Initial load
duke
parents:
diff changeset
50 work_queue_set_, &term_),
a61af66fc99e Initial load
duke
parents:
diff changeset
51 _is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this),
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _keep_alive_closure(&_scan_weak_ref_closure),
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
53 _promotion_failure_size(0),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
54 _strong_roots_time(0.0), _term_time(0.0)
a61af66fc99e Initial load
duke
parents:
diff changeset
55 {
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
56 #if TASKQUEUE_STATS
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
57 _term_attempts = 0;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
58 _overflow_refills = 0;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
59 _overflow_refill_objs = 0;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
60 #endif // TASKQUEUE_STATS
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
61
0
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _survivor_chunk_array =
a61af66fc99e Initial load
duke
parents:
diff changeset
63 (ChunkArray*) old_gen()->get_data_recorder(thread_num());
a61af66fc99e Initial load
duke
parents:
diff changeset
64 _hash_seed = 17; // Might want to take time-based random value.
a61af66fc99e Initial load
duke
parents:
diff changeset
65 _start = os::elapsedTime();
a61af66fc99e Initial load
duke
parents:
diff changeset
66 _old_gen_closure.set_generation(old_gen_);
a61af66fc99e Initial load
duke
parents:
diff changeset
67 _old_gen_root_closure.set_generation(old_gen_);
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69 #ifdef _MSC_VER
a61af66fc99e Initial load
duke
parents:
diff changeset
70 #pragma warning( pop )
a61af66fc99e Initial load
duke
parents:
diff changeset
71 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 void ParScanThreadState::record_survivor_plab(HeapWord* plab_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
74 size_t plab_word_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
75 ChunkArray* sca = survivor_chunk_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
76 if (sca != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // A non-null SCA implies that we want the PLAB data recorded.
a61af66fc99e Initial load
duke
parents:
diff changeset
78 sca->record_sample(plab_start, plab_word_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
79 }
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 bool ParScanThreadState::should_be_partially_scanned(oop new_obj, oop old_obj) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 return new_obj->is_objArray() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
84 arrayOop(new_obj)->length() > ParGCArrayScanChunk &&
a61af66fc99e Initial load
duke
parents:
diff changeset
85 new_obj != old_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 void ParScanThreadState::scan_partial_array_and_push_remainder(oop old) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 assert(old->is_objArray(), "must be obj array");
a61af66fc99e Initial load
duke
parents:
diff changeset
90 assert(old->is_forwarded(), "must be forwarded");
a61af66fc99e Initial load
duke
parents:
diff changeset
91 assert(Universe::heap()->is_in_reserved(old), "must be in heap.");
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
92 assert(!old_gen()->is_in(old), "must be in young generation.");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 objArrayOop obj = objArrayOop(old->forwardee());
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // Process ParGCArrayScanChunk elements now
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // and push the remainder back onto queue
a61af66fc99e Initial load
duke
parents:
diff changeset
97 int start = arrayOop(old)->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
98 int end = obj->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
99 int remainder = end - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 assert(start <= end, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
101 if (remainder > 2 * ParGCArrayScanChunk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Test above combines last partial chunk with a full chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
103 end = start + ParGCArrayScanChunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 arrayOop(old)->set_length(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // Push remainder.
a61af66fc99e Initial load
duke
parents:
diff changeset
106 bool ok = work_queue()->push(old);
a61af66fc99e Initial load
duke
parents:
diff changeset
107 assert(ok, "just popped, push must be okay");
a61af66fc99e Initial load
duke
parents:
diff changeset
108 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // Restore length so that it can be used if there
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // is a promotion failure and forwarding pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // must be removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
112 arrayOop(old)->set_length(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
114
0
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // process our set of indices (include header in first chunk)
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
116 // should make sure end is even (aligned to HeapWord in case of compressed oops)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
117 if ((HeapWord *)obj < young_old_boundary()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // object is in to_space
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
119 obj->oop_iterate_range(&_to_space_closure, start, end);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
120 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // object is in old generation
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
122 obj->oop_iterate_range(&_old_gen_closure, start, end);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 void ParScanThreadState::trim_queues(int max_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
128 ObjToScanQueue* queue = work_queue();
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
129 do {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
130 while (queue->size() > (juint)max_size) {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
131 oop obj_to_scan;
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
132 if (queue->pop_local(obj_to_scan)) {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
133 if ((HeapWord *)obj_to_scan < young_old_boundary()) {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
134 if (obj_to_scan->is_objArray() &&
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
135 obj_to_scan->is_forwarded() &&
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
136 obj_to_scan->forwardee() != obj_to_scan) {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
137 scan_partial_array_and_push_remainder(obj_to_scan);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
138 } else {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
139 // object is in to_space
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
140 obj_to_scan->oop_iterate(&_to_space_closure);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
141 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
142 } else {
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
143 // object is in old generation
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
144 obj_to_scan->oop_iterate(&_old_gen_closure);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
148 // For the case of compressed oops, we have a private, non-shared
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
149 // overflow stack, so we eagerly drain it so as to more evenly
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
150 // distribute load early. Note: this may be good to do in
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
151 // general rather than delay for the final stealing phase.
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
152 // If applicable, we'll transfer a set of objects over to our
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
153 // work queue, allowing them to be stolen and draining our
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
154 // private overflow stack.
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
155 } while (ParGCTrimOverflow && young_gen()->take_from_overflow_list(this));
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
156 }
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
157
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
158 bool ParScanThreadState::take_from_overflow_stack() {
695
becb17ad5e51 6824570: ParNew: Fix memory leak introduced in 6819891
ysr
parents: 679
diff changeset
159 assert(ParGCUseLocalOverflow, "Else should not call");
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
160 assert(young_gen()->overflow_list() == NULL, "Error");
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
161 ObjToScanQueue* queue = work_queue();
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
162 Stack<oop>* const of_stack = overflow_stack();
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
163 const size_t num_overflow_elems = of_stack->size();
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
164 const size_t space_available = queue->max_elems() - queue->size();
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
165 const size_t num_take_elems = MIN3(space_available / 4,
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
166 ParGCDesiredObjsFromOverflowList,
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
167 num_overflow_elems);
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
168 // Transfer the most recent num_take_elems from the overflow
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
169 // stack to our work queue.
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
170 for (size_t i = 0; i != num_take_elems; i++) {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
171 oop cur = of_stack->pop();
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
172 oop obj_to_push = cur->forwardee();
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
173 assert(Universe::heap()->is_in_reserved(cur), "Should be in heap");
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
174 assert(!old_gen()->is_in_reserved(cur), "Should be in young gen");
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
175 assert(Universe::heap()->is_in_reserved(obj_to_push), "Should be in heap");
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
176 if (should_be_partially_scanned(obj_to_push, cur)) {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
177 assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
178 obj_to_push = cur;
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
179 }
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
180 bool ok = queue->push(obj_to_push);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
181 assert(ok, "Should have succeeded");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
183 assert(young_gen()->overflow_list() == NULL, "Error");
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
184 return num_take_elems > 0; // was something transferred?
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
185 }
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
186
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
187 void ParScanThreadState::push_on_overflow_stack(oop p) {
695
becb17ad5e51 6824570: ParNew: Fix memory leak introduced in 6819891
ysr
parents: 679
diff changeset
188 assert(ParGCUseLocalOverflow, "Else should not call");
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
189 overflow_stack()->push(p);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
190 assert(young_gen()->overflow_list() == NULL, "Error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
192
a61af66fc99e Initial load
duke
parents:
diff changeset
193 HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz) {
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // Otherwise, if the object is small enough, try to reallocate the
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
197 HeapWord* obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 if (!_to_space_full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
199 ParGCAllocBuffer* const plab = to_space_alloc_buffer();
a61af66fc99e Initial load
duke
parents:
diff changeset
200 Space* const sp = to_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
201 if (word_sz * 100 <
a61af66fc99e Initial load
duke
parents:
diff changeset
202 ParallelGCBufferWastePct * plab->word_sz()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // Is small enough; abandon this buffer and start a new one.
a61af66fc99e Initial load
duke
parents:
diff changeset
204 plab->retire(false, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 size_t buf_size = plab->word_sz();
a61af66fc99e Initial load
duke
parents:
diff changeset
206 HeapWord* buf_space = sp->par_allocate(buf_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 if (buf_space == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 const size_t min_bytes =
a61af66fc99e Initial load
duke
parents:
diff changeset
209 ParGCAllocBuffer::min_size() << LogHeapWordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
210 size_t free_bytes = sp->free();
a61af66fc99e Initial load
duke
parents:
diff changeset
211 while(buf_space == NULL && free_bytes >= min_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 buf_size = free_bytes >> LogHeapWordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
213 assert(buf_size == (size_t)align_object_size(buf_size),
a61af66fc99e Initial load
duke
parents:
diff changeset
214 "Invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
215 buf_space = sp->par_allocate(buf_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
216 free_bytes = sp->free();
a61af66fc99e Initial load
duke
parents:
diff changeset
217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
219 if (buf_space != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 plab->set_word_size(buf_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
221 plab->set_buf(buf_space);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 record_survivor_plab(buf_space, buf_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 obj = plab->allocate(word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // Note that we cannot compare buf_size < word_sz below
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // because of AlignmentReserve (see ParGCAllocBuffer::allocate()).
a61af66fc99e Initial load
duke
parents:
diff changeset
226 assert(obj != NULL || plab->words_remaining() < word_sz,
a61af66fc99e Initial load
duke
parents:
diff changeset
227 "Else should have been able to allocate");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // It's conceivable that we may be able to use the
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // buffer we just grabbed for subsequent small requests
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // even if not for this one.
a61af66fc99e Initial load
duke
parents:
diff changeset
231 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // We're used up.
a61af66fc99e Initial load
duke
parents:
diff changeset
233 _to_space_full = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // Too large; allocate the object individually.
a61af66fc99e Initial load
duke
parents:
diff changeset
238 obj = sp->par_allocate(word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 return obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
246 size_t word_sz) {
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // Is the alloc in the current alloc buffer?
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (to_space_alloc_buffer()->contains(obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 assert(to_space_alloc_buffer()->contains(obj + word_sz - 1),
a61af66fc99e Initial load
duke
parents:
diff changeset
250 "Should contain whole object.");
a61af66fc99e Initial load
duke
parents:
diff changeset
251 to_space_alloc_buffer()->undo_allocation(obj, word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
252 } else {
481
7d7a7c599c17 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 457
diff changeset
253 CollectedHeap::fill_with_object(obj, word_sz);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
257 void ParScanThreadState::print_and_clear_promotion_failure_size() {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
258 if (_promotion_failure_size != 0) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
259 if (PrintPromotionFailure) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
260 gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ",
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
261 _thread_num, _promotion_failure_size);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
262 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
263 _promotion_failure_size = 0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
264 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
265 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
266
0
a61af66fc99e Initial load
duke
parents:
diff changeset
267 class ParScanThreadStateSet: private ResourceArray {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // Initializes states for the specified number of threads;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 ParScanThreadStateSet(int num_threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
271 Space& to_space,
a61af66fc99e Initial load
duke
parents:
diff changeset
272 ParNewGeneration& gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
273 Generation& old_gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
274 ObjToScanQueueSet& queue_set,
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
275 Stack<oop>* overflow_stacks_,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
276 size_t desired_plab_sz,
a61af66fc99e Initial load
duke
parents:
diff changeset
277 ParallelTaskTerminator& term);
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
278
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
279 ~ParScanThreadStateSet() { TASKQUEUE_STATS_ONLY(reset_stats()); }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
280
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
281 inline ParScanThreadState& thread_state(int i);
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
282
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
283 void reset(bool promotion_failed);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
284 void flush();
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
285
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
286 #if TASKQUEUE_STATS
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
287 static void
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
288 print_termination_stats_hdr(outputStream* const st = gclog_or_tty);
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
289 void print_termination_stats(outputStream* const st = gclog_or_tty);
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
290 static void
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
291 print_taskqueue_stats_hdr(outputStream* const st = gclog_or_tty);
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
292 void print_taskqueue_stats(outputStream* const st = gclog_or_tty);
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
293 void reset_stats();
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
294 #endif // TASKQUEUE_STATS
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
295
0
a61af66fc99e Initial load
duke
parents:
diff changeset
296 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
297 ParallelTaskTerminator& _term;
a61af66fc99e Initial load
duke
parents:
diff changeset
298 ParNewGeneration& _gen;
a61af66fc99e Initial load
duke
parents:
diff changeset
299 Generation& _next_gen;
a61af66fc99e Initial load
duke
parents:
diff changeset
300 };
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 ParScanThreadStateSet::ParScanThreadStateSet(
a61af66fc99e Initial load
duke
parents:
diff changeset
304 int num_threads, Space& to_space, ParNewGeneration& gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
305 Generation& old_gen, ObjToScanQueueSet& queue_set,
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
306 Stack<oop>* overflow_stacks,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
307 size_t desired_plab_sz, ParallelTaskTerminator& term)
a61af66fc99e Initial load
duke
parents:
diff changeset
308 : ResourceArray(sizeof(ParScanThreadState), num_threads),
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
309 _gen(gen), _next_gen(old_gen), _term(term)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
310 {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 assert(num_threads > 0, "sanity check!");
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
312 assert(ParGCUseLocalOverflow == (overflow_stacks != NULL),
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
313 "overflow_stack allocation mismatch");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // Initialize states.
a61af66fc99e Initial load
duke
parents:
diff changeset
315 for (int i = 0; i < num_threads; ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
316 new ((ParScanThreadState*)_data + i)
a61af66fc99e Initial load
duke
parents:
diff changeset
317 ParScanThreadState(&to_space, &gen, &old_gen, i, &queue_set,
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
318 overflow_stacks, desired_plab_sz, term);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
322 inline ParScanThreadState& ParScanThreadStateSet::thread_state(int i)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
323 {
a61af66fc99e Initial load
duke
parents:
diff changeset
324 assert(i >= 0 && i < length(), "sanity check!");
a61af66fc99e Initial load
duke
parents:
diff changeset
325 return ((ParScanThreadState*)_data)[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
329 void ParScanThreadStateSet::reset(bool promotion_failed)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
330 {
a61af66fc99e Initial load
duke
parents:
diff changeset
331 _term.reset_for_reuse();
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
332 if (promotion_failed) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
333 for (int i = 0; i < length(); ++i) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
334 thread_state(i).print_and_clear_promotion_failure_size();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
335 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
336 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
339 #if TASKQUEUE_STATS
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
340 void
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
341 ParScanThreadState::reset_stats()
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
342 {
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
343 taskqueue_stats().reset();
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
344 _term_attempts = 0;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
345 _overflow_refills = 0;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
346 _overflow_refill_objs = 0;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
347 }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
348
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
349 void ParScanThreadStateSet::reset_stats()
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
350 {
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
351 for (int i = 0; i < length(); ++i) {
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
352 thread_state(i).reset_stats();
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
353 }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
354 }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
355
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
356 void
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
357 ParScanThreadStateSet::print_termination_stats_hdr(outputStream* const st)
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
358 {
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
359 st->print_raw_cr("GC Termination Stats");
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
360 st->print_raw_cr(" elapsed --strong roots-- "
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
361 "-------termination-------");
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
362 st->print_raw_cr("thr ms ms % "
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
363 " ms % attempts");
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
364 st->print_raw_cr("--- --------- --------- ------ "
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
365 "--------- ------ --------");
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
366 }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
367
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
368 void ParScanThreadStateSet::print_termination_stats(outputStream* const st)
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
369 {
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
370 print_termination_stats_hdr(st);
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
371
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
372 for (int i = 0; i < length(); ++i) {
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
373 const ParScanThreadState & pss = thread_state(i);
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
374 const double elapsed_ms = pss.elapsed_time() * 1000.0;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
375 const double s_roots_ms = pss.strong_roots_time() * 1000.0;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
376 const double term_ms = pss.term_time() * 1000.0;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
377 st->print_cr("%3d %9.2f %9.2f %6.2f "
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
378 "%9.2f %6.2f " SIZE_FORMAT_W(8),
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
379 i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms,
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
380 term_ms, term_ms * 100 / elapsed_ms, pss.term_attempts());
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
381 }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
382 }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
383
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
384 // Print stats related to work queue activity.
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
385 void ParScanThreadStateSet::print_taskqueue_stats_hdr(outputStream* const st)
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
386 {
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
387 st->print_raw_cr("GC Task Stats");
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
388 st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr();
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
389 st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr();
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
390 }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
391
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
392 void ParScanThreadStateSet::print_taskqueue_stats(outputStream* const st)
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
393 {
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
394 print_taskqueue_stats_hdr(st);
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
395
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
396 TaskQueueStats totals;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
397 for (int i = 0; i < length(); ++i) {
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
398 const ParScanThreadState & pss = thread_state(i);
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
399 const TaskQueueStats & stats = pss.taskqueue_stats();
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
400 st->print("%3d ", i); stats.print(st); st->cr();
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
401 totals += stats;
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
402
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
403 if (pss.overflow_refills() > 0) {
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
404 st->print_cr(" " SIZE_FORMAT_W(10) " overflow refills "
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
405 SIZE_FORMAT_W(10) " overflow objects",
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
406 pss.overflow_refills(), pss.overflow_refill_objs());
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
407 }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
408 }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
409 st->print("tot "); totals.print(st); st->cr();
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
410
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
411 DEBUG_ONLY(totals.verify());
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
412 }
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
413 #endif // TASKQUEUE_STATS
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
414
0
a61af66fc99e Initial load
duke
parents:
diff changeset
415 void ParScanThreadStateSet::flush()
a61af66fc99e Initial load
duke
parents:
diff changeset
416 {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
417 // Work in this loop should be kept as lightweight as
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
418 // possible since this might otherwise become a bottleneck
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
419 // to scaling. Should we add heavy-weight work into this
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
420 // loop, consider parallelizing the loop into the worker threads.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
421 for (int i = 0; i < length(); ++i) {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
422 ParScanThreadState& par_scan_state = thread_state(i);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // Flush stats related to To-space PLAB activity and
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // retire the last buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
426 par_scan_state.to_space_alloc_buffer()->
a61af66fc99e Initial load
duke
parents:
diff changeset
427 flush_stats_and_retire(_gen.plab_stats(),
a61af66fc99e Initial load
duke
parents:
diff changeset
428 false /* !retain */);
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // Every thread has its own age table. We need to merge
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // them all into one.
a61af66fc99e Initial load
duke
parents:
diff changeset
432 ageTable *local_table = par_scan_state.age_table();
a61af66fc99e Initial load
duke
parents:
diff changeset
433 _gen.age_table()->merge(local_table);
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // Inform old gen that we're done.
a61af66fc99e Initial load
duke
parents:
diff changeset
436 _next_gen.par_promote_alloc_done(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
437 _next_gen.par_oop_since_save_marks_iterate_done(i);
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
438 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
439
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
440 if (UseConcMarkSweepGC && ParallelGCThreads > 0) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
441 // We need to call this even when ResizeOldPLAB is disabled
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
442 // so as to avoid breaking some asserts. While we may be able
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
443 // to avoid this by reorganizing the code a bit, I am loathe
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
444 // to do that unless we find cases where ergo leads to bad
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
445 // performance.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
446 CFLS_LAB::compute_desired_plab_size();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
447 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
449
a61af66fc99e Initial load
duke
parents:
diff changeset
450 ParScanClosure::ParScanClosure(ParNewGeneration* g,
a61af66fc99e Initial load
duke
parents:
diff changeset
451 ParScanThreadState* par_scan_state) :
a61af66fc99e Initial load
duke
parents:
diff changeset
452 OopsInGenClosure(g), _par_scan_state(par_scan_state), _g(g)
a61af66fc99e Initial load
duke
parents:
diff changeset
453 {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 assert(_g->level() == 0, "Optimized for youngest generation");
a61af66fc99e Initial load
duke
parents:
diff changeset
455 _boundary = _g->reserved().end();
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
458 void ParScanWithBarrierClosure::do_oop(oop* p) { ParScanClosure::do_oop_work(p, true, false); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
459 void ParScanWithBarrierClosure::do_oop(narrowOop* p) { ParScanClosure::do_oop_work(p, true, false); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
460
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
461 void ParScanWithoutBarrierClosure::do_oop(oop* p) { ParScanClosure::do_oop_work(p, false, false); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
462 void ParScanWithoutBarrierClosure::do_oop(narrowOop* p) { ParScanClosure::do_oop_work(p, false, false); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
463
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
464 void ParRootScanWithBarrierTwoGensClosure::do_oop(oop* p) { ParScanClosure::do_oop_work(p, true, true); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
465 void ParRootScanWithBarrierTwoGensClosure::do_oop(narrowOop* p) { ParScanClosure::do_oop_work(p, true, true); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
466
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
467 void ParRootScanWithoutBarrierClosure::do_oop(oop* p) { ParScanClosure::do_oop_work(p, false, true); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
468 void ParRootScanWithoutBarrierClosure::do_oop(narrowOop* p) { ParScanClosure::do_oop_work(p, false, true); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
469
0
a61af66fc99e Initial load
duke
parents:
diff changeset
470 ParScanWeakRefClosure::ParScanWeakRefClosure(ParNewGeneration* g,
a61af66fc99e Initial load
duke
parents:
diff changeset
471 ParScanThreadState* par_scan_state)
a61af66fc99e Initial load
duke
parents:
diff changeset
472 : ScanWeakRefClosure(g), _par_scan_state(par_scan_state)
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
473 {}
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
474
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
475 void ParScanWeakRefClosure::do_oop(oop* p) { ParScanWeakRefClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
476 void ParScanWeakRefClosure::do_oop(narrowOop* p) { ParScanWeakRefClosure::do_oop_work(p); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 #ifdef WIN32
a61af66fc99e Initial load
duke
parents:
diff changeset
479 #pragma warning(disable: 4786) /* identifier was truncated to '255' characters in the browser information */
a61af66fc99e Initial load
duke
parents:
diff changeset
480 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 ParEvacuateFollowersClosure::ParEvacuateFollowersClosure(
a61af66fc99e Initial load
duke
parents:
diff changeset
483 ParScanThreadState* par_scan_state_,
a61af66fc99e Initial load
duke
parents:
diff changeset
484 ParScanWithoutBarrierClosure* to_space_closure_,
a61af66fc99e Initial load
duke
parents:
diff changeset
485 ParScanWithBarrierClosure* old_gen_closure_,
a61af66fc99e Initial load
duke
parents:
diff changeset
486 ParRootScanWithoutBarrierClosure* to_space_root_closure_,
a61af66fc99e Initial load
duke
parents:
diff changeset
487 ParNewGeneration* par_gen_,
a61af66fc99e Initial load
duke
parents:
diff changeset
488 ParRootScanWithBarrierTwoGensClosure* old_gen_root_closure_,
a61af66fc99e Initial load
duke
parents:
diff changeset
489 ObjToScanQueueSet* task_queues_,
a61af66fc99e Initial load
duke
parents:
diff changeset
490 ParallelTaskTerminator* terminator_) :
a61af66fc99e Initial load
duke
parents:
diff changeset
491
a61af66fc99e Initial load
duke
parents:
diff changeset
492 _par_scan_state(par_scan_state_),
a61af66fc99e Initial load
duke
parents:
diff changeset
493 _to_space_closure(to_space_closure_),
a61af66fc99e Initial load
duke
parents:
diff changeset
494 _old_gen_closure(old_gen_closure_),
a61af66fc99e Initial load
duke
parents:
diff changeset
495 _to_space_root_closure(to_space_root_closure_),
a61af66fc99e Initial load
duke
parents:
diff changeset
496 _old_gen_root_closure(old_gen_root_closure_),
a61af66fc99e Initial load
duke
parents:
diff changeset
497 _par_gen(par_gen_),
a61af66fc99e Initial load
duke
parents:
diff changeset
498 _task_queues(task_queues_),
a61af66fc99e Initial load
duke
parents:
diff changeset
499 _terminator(terminator_)
a61af66fc99e Initial load
duke
parents:
diff changeset
500 {}
a61af66fc99e Initial load
duke
parents:
diff changeset
501
a61af66fc99e Initial load
duke
parents:
diff changeset
502 void ParEvacuateFollowersClosure::do_void() {
a61af66fc99e Initial load
duke
parents:
diff changeset
503 ObjToScanQueue* work_q = par_scan_state()->work_queue();
a61af66fc99e Initial load
duke
parents:
diff changeset
504
a61af66fc99e Initial load
duke
parents:
diff changeset
505 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // Scan to-space and old-gen objs until we run out of both.
a61af66fc99e Initial load
duke
parents:
diff changeset
508 oop obj_to_scan;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 par_scan_state()->trim_queues(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
510
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // We have no local work, attempt to steal from other threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // attempt to steal work from promoted.
a61af66fc99e Initial load
duke
parents:
diff changeset
514 if (task_queues()->steal(par_scan_state()->thread_num(),
a61af66fc99e Initial load
duke
parents:
diff changeset
515 par_scan_state()->hash_seed(),
a61af66fc99e Initial load
duke
parents:
diff changeset
516 obj_to_scan)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
517 bool res = work_q->push(obj_to_scan);
a61af66fc99e Initial load
duke
parents:
diff changeset
518 assert(res, "Empty queue should have room for a push.");
a61af66fc99e Initial load
duke
parents:
diff changeset
519
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // if successful, goto Start.
a61af66fc99e Initial load
duke
parents:
diff changeset
521 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // try global overflow list.
a61af66fc99e Initial load
duke
parents:
diff changeset
524 } else if (par_gen()->take_from_overflow_list(par_scan_state())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
525 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
527
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // Otherwise, offer termination.
a61af66fc99e Initial load
duke
parents:
diff changeset
529 par_scan_state()->start_term_time();
a61af66fc99e Initial load
duke
parents:
diff changeset
530 if (terminator()->offer_termination()) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
531 par_scan_state()->end_term_time();
a61af66fc99e Initial load
duke
parents:
diff changeset
532 }
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
533 assert(par_gen()->_overflow_list == NULL && par_gen()->_num_par_pushes == 0,
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
534 "Broken overflow list?");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // Finish the last termination pause.
a61af66fc99e Initial load
duke
parents:
diff changeset
536 par_scan_state()->end_term_time();
a61af66fc99e Initial load
duke
parents:
diff changeset
537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* next_gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
540 HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) :
a61af66fc99e Initial load
duke
parents:
diff changeset
541 AbstractGangTask("ParNewGeneration collection"),
a61af66fc99e Initial load
duke
parents:
diff changeset
542 _gen(gen), _next_gen(next_gen),
a61af66fc99e Initial load
duke
parents:
diff changeset
543 _young_old_boundary(young_old_boundary),
a61af66fc99e Initial load
duke
parents:
diff changeset
544 _state_set(state_set)
a61af66fc99e Initial load
duke
parents:
diff changeset
545 {}
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547 void ParNewGenTask::work(int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
548 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // Since this is being done in a separate thread, need new resource
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // and handle marks.
a61af66fc99e Initial load
duke
parents:
diff changeset
551 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
552 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // We would need multiple old-gen queues otherwise.
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
554 assert(gch->n_gens() == 2, "Par young collection currently only works with one older gen.");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
555
a61af66fc99e Initial load
duke
parents:
diff changeset
556 Generation* old_gen = gch->next_gen(_gen);
a61af66fc99e Initial load
duke
parents:
diff changeset
557
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
558 ParScanThreadState& par_scan_state = _state_set->thread_state(i);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
559 par_scan_state.set_young_old_boundary(_young_old_boundary);
a61af66fc99e Initial load
duke
parents:
diff changeset
560
a61af66fc99e Initial load
duke
parents:
diff changeset
561 par_scan_state.start_strong_roots();
a61af66fc99e Initial load
duke
parents:
diff changeset
562 gch->gen_process_strong_roots(_gen->level(),
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 695
diff changeset
563 true, // Process younger gens, if any,
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 695
diff changeset
564 // as strong roots.
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 695
diff changeset
565 false, // no scope; this is parallel code
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 695
diff changeset
566 false, // not collecting perm generation.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
567 SharedHeap::SO_AllClasses,
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 695
diff changeset
568 &par_scan_state.to_space_root_closure(),
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 695
diff changeset
569 true, // walk *all* scavengable nmethods
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 695
diff changeset
570 &par_scan_state.older_gen_closure());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
571 par_scan_state.end_strong_roots();
a61af66fc99e Initial load
duke
parents:
diff changeset
572
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // "evacuate followers".
a61af66fc99e Initial load
duke
parents:
diff changeset
574 par_scan_state.evacuate_followers_closure().do_void();
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 #ifdef _MSC_VER
a61af66fc99e Initial load
duke
parents:
diff changeset
578 #pragma warning( push )
a61af66fc99e Initial load
duke
parents:
diff changeset
579 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
a61af66fc99e Initial load
duke
parents:
diff changeset
580 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
581 ParNewGeneration::
a61af66fc99e Initial load
duke
parents:
diff changeset
582 ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level)
a61af66fc99e Initial load
duke
parents:
diff changeset
583 : DefNewGeneration(rs, initial_byte_size, level, "PCopy"),
a61af66fc99e Initial load
duke
parents:
diff changeset
584 _overflow_list(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
585 _is_alive_closure(this),
a61af66fc99e Initial load
duke
parents:
diff changeset
586 _plab_stats(YoungPLABSize, PLABWeight)
a61af66fc99e Initial load
duke
parents:
diff changeset
587 {
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
588 NOT_PRODUCT(_overflow_counter = ParGCWorkQueueOverflowInterval;)
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
589 NOT_PRODUCT(_num_par_pushes = 0;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
590 _task_queues = new ObjToScanQueueSet(ParallelGCThreads);
a61af66fc99e Initial load
duke
parents:
diff changeset
591 guarantee(_task_queues != NULL, "task_queues allocation failure.");
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 for (uint i1 = 0; i1 < ParallelGCThreads; i1++) {
1665
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1552
diff changeset
594 ObjToScanQueue *q = new ObjToScanQueue();
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1552
diff changeset
595 guarantee(q != NULL, "work_queue Allocation failure.");
a93a9eda13f7 6962947: shared TaskQueue statistics
jcoomes
parents: 1552
diff changeset
596 _task_queues->register_queue(i1, q);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 for (uint i2 = 0; i2 < ParallelGCThreads; i2++)
a61af66fc99e Initial load
duke
parents:
diff changeset
600 _task_queues->queue(i2)->initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
601
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
602 _overflow_stacks = NULL;
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
603 if (ParGCUseLocalOverflow) {
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
604 _overflow_stacks = NEW_C_HEAP_ARRAY(Stack<oop>, ParallelGCThreads);
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
605 for (size_t i = 0; i < ParallelGCThreads; ++i) {
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
606 new (_overflow_stacks + i) Stack<oop>();
695
becb17ad5e51 6824570: ParNew: Fix memory leak introduced in 6819891
ysr
parents: 679
diff changeset
607 }
becb17ad5e51 6824570: ParNew: Fix memory leak introduced in 6819891
ysr
parents: 679
diff changeset
608 }
becb17ad5e51 6824570: ParNew: Fix memory leak introduced in 6819891
ysr
parents: 679
diff changeset
609
0
a61af66fc99e Initial load
duke
parents:
diff changeset
610 if (UsePerfData) {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
612 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 const char* cname =
a61af66fc99e Initial load
duke
parents:
diff changeset
615 PerfDataManager::counter_name(_gen_counters->name_space(), "threads");
a61af66fc99e Initial load
duke
parents:
diff changeset
616 PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None,
a61af66fc99e Initial load
duke
parents:
diff changeset
617 ParallelGCThreads, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
620 #ifdef _MSC_VER
a61af66fc99e Initial load
duke
parents:
diff changeset
621 #pragma warning( pop )
a61af66fc99e Initial load
duke
parents:
diff changeset
622 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // ParNewGeneration::
a61af66fc99e Initial load
duke
parents:
diff changeset
625 ParKeepAliveClosure::ParKeepAliveClosure(ParScanWeakRefClosure* cl) :
a61af66fc99e Initial load
duke
parents:
diff changeset
626 DefNewGeneration::KeepAliveClosure(cl), _par_cl(cl) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
627
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
628 template <class T>
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
629 void /*ParNewGeneration::*/ParKeepAliveClosure::do_oop_work(T* p) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
630 #ifdef ASSERT
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
631 {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
632 assert(!oopDesc::is_null(*p), "expected non-null ref");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
633 oop obj = oopDesc::load_decode_heap_oop_not_null(p);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
634 // We never expect to see a null reference being processed
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
635 // as a weak reference.
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
636 assert(obj->is_oop(), "expected an oop while scanning weak refs");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
637 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
638 #endif // ASSERT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 _par_cl->do_oop_nv(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
641
a61af66fc99e Initial load
duke
parents:
diff changeset
642 if (Universe::heap()->is_in_reserved(p)) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
643 oop obj = oopDesc::load_decode_heap_oop_not_null(p);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
644 _rs->write_ref_field_gc_par(p, obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
648 void /*ParNewGeneration::*/ParKeepAliveClosure::do_oop(oop* p) { ParKeepAliveClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
649 void /*ParNewGeneration::*/ParKeepAliveClosure::do_oop(narrowOop* p) { ParKeepAliveClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
650
0
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // ParNewGeneration::
a61af66fc99e Initial load
duke
parents:
diff changeset
652 KeepAliveClosure::KeepAliveClosure(ScanWeakRefClosure* cl) :
a61af66fc99e Initial load
duke
parents:
diff changeset
653 DefNewGeneration::KeepAliveClosure(cl) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
654
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
655 template <class T>
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
656 void /*ParNewGeneration::*/KeepAliveClosure::do_oop_work(T* p) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
657 #ifdef ASSERT
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
658 {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
659 assert(!oopDesc::is_null(*p), "expected non-null ref");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
660 oop obj = oopDesc::load_decode_heap_oop_not_null(p);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
661 // We never expect to see a null reference being processed
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
662 // as a weak reference.
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
663 assert(obj->is_oop(), "expected an oop while scanning weak refs");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
664 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
665 #endif // ASSERT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
666
a61af66fc99e Initial load
duke
parents:
diff changeset
667 _cl->do_oop_nv(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 if (Universe::heap()->is_in_reserved(p)) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
670 oop obj = oopDesc::load_decode_heap_oop_not_null(p);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
671 _rs->write_ref_field_gc_par(p, obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
674
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
675 void /*ParNewGeneration::*/KeepAliveClosure::do_oop(oop* p) { KeepAliveClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
676 void /*ParNewGeneration::*/KeepAliveClosure::do_oop(narrowOop* p) { KeepAliveClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
677
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
678 template <class T> void ScanClosureWithParBarrier::do_oop_work(T* p) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
679 T heap_oop = oopDesc::load_heap_oop(p);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
680 if (!oopDesc::is_null(heap_oop)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
681 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
682 if ((HeapWord*)obj < _boundary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 assert(!_g->to()->is_in_reserved(obj), "Scanning field twice?");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
684 oop new_obj = obj->is_forwarded()
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
685 ? obj->forwardee()
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
686 : _g->DefNewGeneration::copy_to_survivor_space(obj);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
687 oopDesc::encode_store_heap_oop_not_null(p, new_obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
689 if (_gc_barrier) {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // If p points to a younger generation, mark the card.
a61af66fc99e Initial load
duke
parents:
diff changeset
691 if ((HeapWord*)obj < _gen_boundary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 _rs->write_ref_field_gc_par(p, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
698 void ScanClosureWithParBarrier::do_oop(oop* p) { ScanClosureWithParBarrier::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
699 void ScanClosureWithParBarrier::do_oop(narrowOop* p) { ScanClosureWithParBarrier::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 6
diff changeset
700
0
a61af66fc99e Initial load
duke
parents:
diff changeset
701 class ParNewRefProcTaskProxy: public AbstractGangTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
702 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
703 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
704 ParNewRefProcTaskProxy(ProcessTask& task, ParNewGeneration& gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
705 Generation& next_gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
706 HeapWord* young_old_boundary,
a61af66fc99e Initial load
duke
parents:
diff changeset
707 ParScanThreadStateSet& state_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
708
a61af66fc99e Initial load
duke
parents:
diff changeset
709 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
710 virtual void work(int i);
a61af66fc99e Initial load
duke
parents:
diff changeset
711
a61af66fc99e Initial load
duke
parents:
diff changeset
712 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
713 ParNewGeneration& _gen;
a61af66fc99e Initial load
duke
parents:
diff changeset
714 ProcessTask& _task;
a61af66fc99e Initial load
duke
parents:
diff changeset
715 Generation& _next_gen;
a61af66fc99e Initial load
duke
parents:
diff changeset
716 HeapWord* _young_old_boundary;
a61af66fc99e Initial load
duke
parents:
diff changeset
717 ParScanThreadStateSet& _state_set;
a61af66fc99e Initial load
duke
parents:
diff changeset
718 };
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(
a61af66fc99e Initial load
duke
parents:
diff changeset
721 ProcessTask& task, ParNewGeneration& gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
722 Generation& next_gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
723 HeapWord* young_old_boundary,
a61af66fc99e Initial load
duke
parents:
diff changeset
724 ParScanThreadStateSet& state_set)
a61af66fc99e Initial load
duke
parents:
diff changeset
725 : AbstractGangTask("ParNewGeneration parallel reference processing"),
a61af66fc99e Initial load
duke
parents:
diff changeset
726 _gen(gen),
a61af66fc99e Initial load
duke
parents:
diff changeset
727 _task(task),
a61af66fc99e Initial load
duke
parents:
diff changeset
728 _next_gen(next_gen),
a61af66fc99e Initial load
duke
parents:
diff changeset
729 _young_old_boundary(young_old_boundary),
a61af66fc99e Initial load
duke
parents:
diff changeset
730 _state_set(state_set)
a61af66fc99e Initial load
duke
parents:
diff changeset
731 {
a61af66fc99e Initial load
duke
parents:
diff changeset
732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
733
a61af66fc99e Initial load
duke
parents:
diff changeset
734 void ParNewRefProcTaskProxy::work(int i)
a61af66fc99e Initial load
duke
parents:
diff changeset
735 {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
737 HandleMark hm;
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
738 ParScanThreadState& par_scan_state = _state_set.thread_state(i);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
739 par_scan_state.set_young_old_boundary(_young_old_boundary);
a61af66fc99e Initial load
duke
parents:
diff changeset
740 _task.work(i, par_scan_state.is_alive_closure(),
a61af66fc99e Initial load
duke
parents:
diff changeset
741 par_scan_state.keep_alive_closure(),
a61af66fc99e Initial load
duke
parents:
diff changeset
742 par_scan_state.evacuate_followers_closure());
a61af66fc99e Initial load
duke
parents:
diff changeset
743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
744
a61af66fc99e Initial load
duke
parents:
diff changeset
745 class ParNewRefEnqueueTaskProxy: public AbstractGangTask {
a61af66fc99e Initial load
duke
parents:
diff changeset
746 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
a61af66fc99e Initial load
duke
parents:
diff changeset
747 EnqueueTask& _task;
a61af66fc99e Initial load
duke
parents:
diff changeset
748
a61af66fc99e Initial load
duke
parents:
diff changeset
749 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
750 ParNewRefEnqueueTaskProxy(EnqueueTask& task)
a61af66fc99e Initial load
duke
parents:
diff changeset
751 : AbstractGangTask("ParNewGeneration parallel reference enqueue"),
a61af66fc99e Initial load
duke
parents:
diff changeset
752 _task(task)
a61af66fc99e Initial load
duke
parents:
diff changeset
753 { }
a61af66fc99e Initial load
duke
parents:
diff changeset
754
a61af66fc99e Initial load
duke
parents:
diff changeset
755 virtual void work(int i)
a61af66fc99e Initial load
duke
parents:
diff changeset
756 {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 _task.work(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
759 };
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762 void ParNewRefProcTaskExecutor::execute(ProcessTask& task)
a61af66fc99e Initial load
duke
parents:
diff changeset
763 {
a61af66fc99e Initial load
duke
parents:
diff changeset
764 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
765 assert(gch->kind() == CollectedHeap::GenCollectedHeap,
a61af66fc99e Initial load
duke
parents:
diff changeset
766 "not a generational heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
767 WorkGang* workers = gch->workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
768 assert(workers != NULL, "Need parallel worker threads.");
a61af66fc99e Initial load
duke
parents:
diff changeset
769 ParNewRefProcTaskProxy rp_task(task, _generation, *_generation.next_gen(),
a61af66fc99e Initial load
duke
parents:
diff changeset
770 _generation.reserved().end(), _state_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
771 workers->run_task(&rp_task);
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
772 _state_set.reset(_generation.promotion_failed());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
774
a61af66fc99e Initial load
duke
parents:
diff changeset
775 void ParNewRefProcTaskExecutor::execute(EnqueueTask& task)
a61af66fc99e Initial load
duke
parents:
diff changeset
776 {
a61af66fc99e Initial load
duke
parents:
diff changeset
777 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
778 WorkGang* workers = gch->workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
779 assert(workers != NULL, "Need parallel worker threads.");
a61af66fc99e Initial load
duke
parents:
diff changeset
780 ParNewRefEnqueueTaskProxy enq_task(task);
a61af66fc99e Initial load
duke
parents:
diff changeset
781 workers->run_task(&enq_task);
a61af66fc99e Initial load
duke
parents:
diff changeset
782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
783
a61af66fc99e Initial load
duke
parents:
diff changeset
784 void ParNewRefProcTaskExecutor::set_single_threaded_mode()
a61af66fc99e Initial load
duke
parents:
diff changeset
785 {
a61af66fc99e Initial load
duke
parents:
diff changeset
786 _state_set.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
787 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
788 gch->set_par_threads(0); // 0 ==> non-parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
789 gch->save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
791
a61af66fc99e Initial load
duke
parents:
diff changeset
792 ScanClosureWithParBarrier::
a61af66fc99e Initial load
duke
parents:
diff changeset
793 ScanClosureWithParBarrier(ParNewGeneration* g, bool gc_barrier) :
a61af66fc99e Initial load
duke
parents:
diff changeset
794 ScanClosure(g, gc_barrier) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
795
a61af66fc99e Initial load
duke
parents:
diff changeset
796 EvacuateFollowersClosureGeneral::
a61af66fc99e Initial load
duke
parents:
diff changeset
797 EvacuateFollowersClosureGeneral(GenCollectedHeap* gch, int level,
a61af66fc99e Initial load
duke
parents:
diff changeset
798 OopsInGenClosure* cur,
a61af66fc99e Initial load
duke
parents:
diff changeset
799 OopsInGenClosure* older) :
a61af66fc99e Initial load
duke
parents:
diff changeset
800 _gch(gch), _level(level),
a61af66fc99e Initial load
duke
parents:
diff changeset
801 _scan_cur_or_nonheap(cur), _scan_older(older)
a61af66fc99e Initial load
duke
parents:
diff changeset
802 {}
a61af66fc99e Initial load
duke
parents:
diff changeset
803
a61af66fc99e Initial load
duke
parents:
diff changeset
804 void EvacuateFollowersClosureGeneral::do_void() {
a61af66fc99e Initial load
duke
parents:
diff changeset
805 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // Beware: this call will lead to closure applications via virtual
a61af66fc99e Initial load
duke
parents:
diff changeset
807 // calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
808 _gch->oop_since_save_marks_iterate(_level,
a61af66fc99e Initial load
duke
parents:
diff changeset
809 _scan_cur_or_nonheap,
a61af66fc99e Initial load
duke
parents:
diff changeset
810 _scan_older);
a61af66fc99e Initial load
duke
parents:
diff changeset
811 } while (!_gch->no_allocs_since_save_marks(_level));
a61af66fc99e Initial load
duke
parents:
diff changeset
812 }
a61af66fc99e Initial load
duke
parents:
diff changeset
813
a61af66fc99e Initial load
duke
parents:
diff changeset
814
a61af66fc99e Initial load
duke
parents:
diff changeset
815 bool ParNewGeneration::_avoid_promotion_undo = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
816
a61af66fc99e Initial load
duke
parents:
diff changeset
817 void ParNewGeneration::adjust_desired_tenuring_threshold() {
a61af66fc99e Initial load
duke
parents:
diff changeset
818 // Set the desired survivor size to half the real survivor space
a61af66fc99e Initial load
duke
parents:
diff changeset
819 _tenuring_threshold =
a61af66fc99e Initial load
duke
parents:
diff changeset
820 age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
822
a61af66fc99e Initial load
duke
parents:
diff changeset
823 // A Generation that does parallel young-gen collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
824
a61af66fc99e Initial load
duke
parents:
diff changeset
825 void ParNewGeneration::collect(bool full,
a61af66fc99e Initial load
duke
parents:
diff changeset
826 bool clear_all_soft_refs,
a61af66fc99e Initial load
duke
parents:
diff changeset
827 size_t size,
a61af66fc99e Initial load
duke
parents:
diff changeset
828 bool is_tlab) {
a61af66fc99e Initial load
duke
parents:
diff changeset
829 assert(full || size > 0, "otherwise we don't want to collect");
a61af66fc99e Initial load
duke
parents:
diff changeset
830 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
831 assert(gch->kind() == CollectedHeap::GenCollectedHeap,
a61af66fc99e Initial load
duke
parents:
diff changeset
832 "not a CMS generational heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
833 AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
834 WorkGang* workers = gch->workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
835 _next_gen = gch->next_gen(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
836 assert(_next_gen != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
837 "This must be the youngest gen, and not the only gen");
a61af66fc99e Initial load
duke
parents:
diff changeset
838 assert(gch->n_gens() == 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
839 "Par collection currently only works with single older gen.");
a61af66fc99e Initial load
duke
parents:
diff changeset
840 // Do we have to avoid promotion_undo?
a61af66fc99e Initial load
duke
parents:
diff changeset
841 if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
842 set_avoid_promotion_undo(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
844
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // If the next generation is too full to accomodate worst-case promotion
a61af66fc99e Initial load
duke
parents:
diff changeset
846 // from this generation, pass on collection; let the next generation
a61af66fc99e Initial load
duke
parents:
diff changeset
847 // do it.
a61af66fc99e Initial load
duke
parents:
diff changeset
848 if (!collection_attempt_is_safe()) {
1888
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1836
diff changeset
849 gch->set_incremental_collection_failed(); // slight lie, in that we did not even attempt one
0
a61af66fc99e Initial load
duke
parents:
diff changeset
850 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
851 }
a61af66fc99e Initial load
duke
parents:
diff changeset
852 assert(to()->is_empty(), "Else not collection_attempt_is_safe");
a61af66fc99e Initial load
duke
parents:
diff changeset
853
a61af66fc99e Initial load
duke
parents:
diff changeset
854 init_assuming_no_promotion_failure();
a61af66fc99e Initial load
duke
parents:
diff changeset
855
a61af66fc99e Initial load
duke
parents:
diff changeset
856 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
857 set_survivor_overflow(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
858 size_policy->minor_collection_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 TraceTime t1("GC", PrintGC && !PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // Capture heap used before collection (for printing).
a61af66fc99e Initial load
duke
parents:
diff changeset
863 size_t gch_prev_used = gch->used();
a61af66fc99e Initial load
duke
parents:
diff changeset
864
a61af66fc99e Initial load
duke
parents:
diff changeset
865 SpecializationStats::clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
866
a61af66fc99e Initial load
duke
parents:
diff changeset
867 age_table()->clear();
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
868 to()->clear(SpaceDecorator::Mangle);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 gch->save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
871 assert(workers != NULL, "Need parallel worker threads.");
a61af66fc99e Initial load
duke
parents:
diff changeset
872 ParallelTaskTerminator _term(workers->total_workers(), task_queues());
a61af66fc99e Initial load
duke
parents:
diff changeset
873 ParScanThreadStateSet thread_state_set(workers->total_workers(),
a61af66fc99e Initial load
duke
parents:
diff changeset
874 *to(), *this, *_next_gen, *task_queues(),
695
becb17ad5e51 6824570: ParNew: Fix memory leak introduced in 6819891
ysr
parents: 679
diff changeset
875 _overflow_stacks, desired_plab_sz(), _term);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 ParNewGenTask tsk(this, _next_gen, reserved().end(), &thread_state_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
878 int n_workers = workers->total_workers();
a61af66fc99e Initial load
duke
parents:
diff changeset
879 gch->set_par_threads(n_workers);
a61af66fc99e Initial load
duke
parents:
diff changeset
880 gch->rem_set()->prepare_for_younger_refs_iterate(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // It turns out that even when we're using 1 thread, doing the work in a
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // separate thread causes wide variance in run times. We can't help this
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // in the multi-threaded case, but we special-case n=1 here to get
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // repeatable measurements of the 1-thread overhead of the parallel code.
a61af66fc99e Initial load
duke
parents:
diff changeset
885 if (n_workers > 1) {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 695
diff changeset
886 GenCollectedHeap::StrongRootsScope srs(gch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
887 workers->run_task(&tsk);
a61af66fc99e Initial load
duke
parents:
diff changeset
888 } else {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 695
diff changeset
889 GenCollectedHeap::StrongRootsScope srs(gch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
890 tsk.work(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
891 }
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
892 thread_state_set.reset(promotion_failed());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
893
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // Process (weak) reference objects found during scavenge.
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
895 ReferenceProcessor* rp = ref_processor();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
896 IsAliveClosure is_alive(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
897 ScanWeakRefClosure scan_weak_ref(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 KeepAliveClosure keep_alive(&scan_weak_ref);
a61af66fc99e Initial load
duke
parents:
diff changeset
899 ScanClosure scan_without_gc_barrier(this, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
900 ScanClosureWithParBarrier scan_with_gc_barrier(this, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
901 set_promo_failure_scan_stack_closure(&scan_without_gc_barrier);
a61af66fc99e Initial load
duke
parents:
diff changeset
902 EvacuateFollowersClosureGeneral evacuate_followers(gch, _level,
a61af66fc99e Initial load
duke
parents:
diff changeset
903 &scan_without_gc_barrier, &scan_with_gc_barrier);
457
27a80744a83b 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 454
diff changeset
904 rp->setup_policy(clear_all_soft_refs);
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
905 if (rp->processing_is_mt()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
906 ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
907 rp->process_discovered_references(&is_alive, &keep_alive,
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
908 &evacuate_followers, &task_executor);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
909 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
910 thread_state_set.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
911 gch->set_par_threads(0); // 0 ==> non-parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
912 gch->save_marks();
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
913 rp->process_discovered_references(&is_alive, &keep_alive,
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
914 &evacuate_followers, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
916 if (!promotion_failed()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
917 // Swap the survivor spaces.
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
918 eden()->clear(SpaceDecorator::Mangle);
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
919 from()->clear(SpaceDecorator::Mangle);
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
920 if (ZapUnusedHeapArea) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
921 // This is now done here because of the piece-meal mangling which
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
922 // can check for valid mangling at intermediate points in the
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
923 // collection(s). When a minor collection fails to collect
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
924 // sufficient space resizing of the young generation can occur
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
925 // an redistribute the spaces in the young generation. Mangle
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
926 // here so that unzapped regions don't get distributed to
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
927 // other spaces.
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
928 to()->mangle_unused_area();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 167
diff changeset
929 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
930 swap_spaces();
a61af66fc99e Initial load
duke
parents:
diff changeset
931
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1145
diff changeset
932 // A successful scavenge should restart the GC time limit count which is
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1145
diff changeset
933 // for full GC's.
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1145
diff changeset
934 size_policy->reset_gc_overhead_limit_count();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1145
diff changeset
935
0
a61af66fc99e Initial load
duke
parents:
diff changeset
936 assert(to()->is_empty(), "to space should be empty now");
a61af66fc99e Initial load
duke
parents:
diff changeset
937 } else {
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
938 assert(_promo_failure_scan_stack.is_empty(), "post condition");
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
939 _promo_failure_scan_stack.clear(true); // Clear cached segments.
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
940
0
a61af66fc99e Initial load
duke
parents:
diff changeset
941 remove_forwarding_pointers();
a61af66fc99e Initial load
duke
parents:
diff changeset
942 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
943 gclog_or_tty->print(" (promotion failed)");
a61af66fc99e Initial load
duke
parents:
diff changeset
944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // All the spaces are in play for mark-sweep.
a61af66fc99e Initial load
duke
parents:
diff changeset
946 swap_spaces(); // Make life simpler for CMS || rescan; see 6483690.
a61af66fc99e Initial load
duke
parents:
diff changeset
947 from()->set_next_compaction_space(to());
1888
a7214d79fcf1 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 1836
diff changeset
948 gch->set_incremental_collection_failed();
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
949 // Inform the next generation that a promotion failure occurred.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
950 _next_gen->promotion_failure_occurred();
6
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
951
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
952 // Reset the PromotionFailureALot counters.
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
953 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
955 // set new iteration safe limit for the survivor spaces
a61af66fc99e Initial load
duke
parents:
diff changeset
956 from()->set_concurrent_iteration_safe_limit(from()->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
957 to()->set_concurrent_iteration_safe_limit(to()->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
958
a61af66fc99e Initial load
duke
parents:
diff changeset
959 adjust_desired_tenuring_threshold();
a61af66fc99e Initial load
duke
parents:
diff changeset
960 if (ResizePLAB) {
a61af66fc99e Initial load
duke
parents:
diff changeset
961 plab_stats()->adjust_desired_plab_sz();
a61af66fc99e Initial load
duke
parents:
diff changeset
962 }
a61af66fc99e Initial load
duke
parents:
diff changeset
963
a61af66fc99e Initial load
duke
parents:
diff changeset
964 if (PrintGC && !PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
965 gch->print_heap_change(gch_prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967
1712
2d6b74c9a797 6976378: ParNew: stats are printed unconditionally in debug builds
jcoomes
parents: 1710
diff changeset
968 if (PrintGCDetails && ParallelGCVerbose) {
2d6b74c9a797 6976378: ParNew: stats are printed unconditionally in debug builds
jcoomes
parents: 1710
diff changeset
969 TASKQUEUE_STATS_ONLY(thread_state_set.print_termination_stats());
2d6b74c9a797 6976378: ParNew: stats are printed unconditionally in debug builds
jcoomes
parents: 1710
diff changeset
970 TASKQUEUE_STATS_ONLY(thread_state_set.print_taskqueue_stats());
2d6b74c9a797 6976378: ParNew: stats are printed unconditionally in debug builds
jcoomes
parents: 1710
diff changeset
971 }
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
972
0
a61af66fc99e Initial load
duke
parents:
diff changeset
973 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
974 size_policy->minor_collection_end(gch->gc_cause());
a61af66fc99e Initial load
duke
parents:
diff changeset
975 size_policy->avg_survived()->sample(from()->used());
a61af66fc99e Initial load
duke
parents:
diff changeset
976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 update_time_of_last_gc(os::javaTimeMillis());
a61af66fc99e Initial load
duke
parents:
diff changeset
979
a61af66fc99e Initial load
duke
parents:
diff changeset
980 SpecializationStats::print();
a61af66fc99e Initial load
duke
parents:
diff changeset
981
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
982 rp->set_enqueuing_is_done(true);
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
983 if (rp->processing_is_mt()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
984 ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
985 rp->enqueue_discovered_references(&task_executor);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
986 } else {
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
987 rp->enqueue_discovered_references(NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
988 }
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
989 rp->verify_no_references_recorded();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
991
a61af66fc99e Initial load
duke
parents:
diff changeset
992 static int sum;
a61af66fc99e Initial load
duke
parents:
diff changeset
993 void ParNewGeneration::waste_some_time() {
a61af66fc99e Initial load
duke
parents:
diff changeset
994 for (int i = 0; i < 100; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
995 sum += i;
a61af66fc99e Initial load
duke
parents:
diff changeset
996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
998
a61af66fc99e Initial load
duke
parents:
diff changeset
999 static const oop ClaimedForwardPtr = oop(0x4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1000
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 // Because of concurrency, there are times where an object for which
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 // "is_forwarded()" is true contains an "interim" forwarding pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 // value. Such a value will soon be overwritten with a real value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 // This method requires "obj" to have a forwarding pointer, and waits, if
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // necessary for a real one to be inserted, and returns it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 oop ParNewGeneration::real_forwardee(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 oop forward_ptr = obj->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 if (forward_ptr != ClaimedForwardPtr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 return forward_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 return real_forwardee_slow(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1015
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 oop ParNewGeneration::real_forwardee_slow(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 // Spin-read if it is claimed but not yet written by another thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 oop forward_ptr = obj->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 while (forward_ptr == ClaimedForwardPtr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 waste_some_time();
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 assert(obj->is_forwarded(), "precondition");
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 forward_ptr = obj->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 return forward_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1026
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 bool ParNewGeneration::is_legal_forward_ptr(oop p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 return
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 (_avoid_promotion_undo && p == ClaimedForwardPtr)
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 || Universe::heap()->is_in_reserved(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 void ParNewGeneration::preserve_mark_if_necessary(oop obj, markOop m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 if ((m != markOopDesc::prototype()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 (!UseBiasedLocking || (m != markOopDesc::biased_locking_prototype()))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 MutexLocker ml(ParGCRareEvent_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 DefNewGeneration::preserve_mark_if_necessary(obj, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1042
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 // Multiple GC threads may try to promote an object. If the object
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 // is successfully promoted, a forwarding pointer will be installed in
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 // the object in the young generation. This method claims the right
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // to install the forwarding pointer before it copies the object,
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 // thus avoiding the need to undo the copy as in
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 // copy_to_survivor_space_avoiding_with_undo.
a61af66fc99e Initial load
duke
parents:
diff changeset
1049
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 oop ParNewGeneration::copy_to_survivor_space_avoiding_promotion_undo(
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // In the sequential version, this assert also says that the object is
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // not forwarded. That might not be the case here. It is the case that
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 // the caller observed it to be not forwarded at some time in the past.
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 assert(is_in_reserved(old), "shouldn't be scavenging this oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
1056
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // The sequential code read "old->age()" below. That doesn't work here,
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 // since the age is in the mark word, and that might be overwritten with
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 // a forwarding pointer by a parallel thread. So we must save the mark
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // word in a local and then analyze it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 oopDesc dummyOld;
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 dummyOld.set_mark(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 assert(!dummyOld.is_forwarded(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 "should not be called with forwarding pointer mark word.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1065
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 oop new_obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 oop forward_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // Try allocating obj in to-space (unless too old)
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 if (dummyOld.age() < tenuring_threshold()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 set_survivor_overflow(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // Either to-space is full or we decided to promote
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // try allocating obj tenured
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 // Attempt to install a null forwarding pointer (atomically),
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 // to claim the right to install the real forwarding pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 forward_ptr = old->forward_to_atomic(ClaimedForwardPtr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 if (forward_ptr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // someone else beat us to it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 return real_forwardee(old);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1088
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 old, m, sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1091
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // promotion failed, forward to self
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 _promotion_failed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 new_obj = old;
a61af66fc99e Initial load
duke
parents:
diff changeset
1096
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 preserve_mark_if_necessary(old, m);
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
1098 // Log the size of the maiden promotion failure
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
1099 par_scan_state->log_promotion_failure(sz);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1101
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 old->forward_to(new_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 forward_ptr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // Is in to-space; do copying ourselves.
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 forward_ptr = old->forward_to_atomic(new_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // Restore the mark word copied above.
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 new_obj->set_mark(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // Increment age if obj still in new generation
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 new_obj->incr_age();
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 par_scan_state->age_table()->add(new_obj, sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 assert(new_obj != NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1115
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 if (forward_ptr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 oop obj_to_push = new_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 if (par_scan_state->should_be_partially_scanned(obj_to_push, old)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 // Length field used as index of next element to be scanned.
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 // Real length can be obtained from real_forwardee()
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 arrayOop(old)->set_length(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 obj_to_push = old;
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 assert(obj_to_push->is_forwarded() && obj_to_push->forwardee() != obj_to_push,
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 "push forwarded object");
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // Push it on one of the queues of to-be-scanned objects.
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1127 bool simulate_overflow = false;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1128 NOT_PRODUCT(
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1129 if (ParGCWorkQueueOverflowALot && should_simulate_overflow()) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1130 // simulate a stack overflow
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1131 simulate_overflow = true;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1132 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1133 )
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1134 if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // Add stats for overflow pushes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 if (Verbose && PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 gclog_or_tty->print("queue overflow!\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 }
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1139 push_on_overflow_list(old, par_scan_state);
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
1140 TASKQUEUE_STATS_ONLY(par_scan_state->taskqueue_stats().record_overflow(0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1142
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 return new_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1145
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // Oops. Someone beat us to it. Undo the allocation. Where did we
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // allocate it?
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 if (is_in_reserved(new_obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 // Must be in to_space.
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 assert(to()->is_in_reserved(new_obj), "Checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 if (forward_ptr == ClaimedForwardPtr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // Wait to get the real forwarding pointer value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 forward_ptr = real_forwardee(old);
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 par_scan_state->undo_alloc_in_to_space((HeapWord*)new_obj, sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1157
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 return forward_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // Multiple GC threads may try to promote the same object. If two
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 // or more GC threads copy the object, only one wins the race to install
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 // the forwarding pointer. The other threads have to undo their copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
1165
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 oop ParNewGeneration::copy_to_survivor_space_with_undo(
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1168
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // In the sequential version, this assert also says that the object is
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 // not forwarded. That might not be the case here. It is the case that
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // the caller observed it to be not forwarded at some time in the past.
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 assert(is_in_reserved(old), "shouldn't be scavenging this oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
1173
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // The sequential code read "old->age()" below. That doesn't work here,
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // since the age is in the mark word, and that might be overwritten with
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 // a forwarding pointer by a parallel thread. So we must save the mark
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // word here, install it in a local oopDesc, and then analyze it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 oopDesc dummyOld;
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 dummyOld.set_mark(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 assert(!dummyOld.is_forwarded(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 "should not be called with forwarding pointer mark word.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1182
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 bool failed_to_promote = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 oop new_obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 oop forward_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1186
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 // Try allocating obj in to-space (unless too old)
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 if (dummyOld.age() < tenuring_threshold()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 set_survivor_overflow(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1194
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // Either to-space is full or we decided to promote
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // try allocating obj tenured
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 old, m, sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1200
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 if (new_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // promotion failed, forward to self
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 forward_ptr = old->forward_to_atomic(old);
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 new_obj = old;
a61af66fc99e Initial load
duke
parents:
diff changeset
1205
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 if (forward_ptr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 return forward_ptr; // someone else succeeded
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1209
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 _promotion_failed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 failed_to_promote = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1212
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 preserve_mark_if_necessary(old, m);
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
1214 // Log the size of the maiden promotion failure
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 989
diff changeset
1215 par_scan_state->log_promotion_failure(sz);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 // Is in to-space; do copying ourselves.
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 // Restore the mark word copied above.
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 new_obj->set_mark(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 // Increment age if new_obj still in new generation
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 new_obj->incr_age();
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 par_scan_state->age_table()->add(new_obj, sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 assert(new_obj != NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1227
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // Now attempt to install the forwarding pointer (atomically).
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 // We have to copy the mark word before overwriting with forwarding
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 // ptr, so we can restore it below in the copy.
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 if (!failed_to_promote) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 forward_ptr = old->forward_to_atomic(new_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1234
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 if (forward_ptr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 oop obj_to_push = new_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 if (par_scan_state->should_be_partially_scanned(obj_to_push, old)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // Length field used as index of next element to be scanned.
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 // Real length can be obtained from real_forwardee()
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 arrayOop(old)->set_length(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 obj_to_push = old;
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 assert(obj_to_push->is_forwarded() && obj_to_push->forwardee() != obj_to_push,
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 "push forwarded object");
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 // Push it on one of the queues of to-be-scanned objects.
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1246 bool simulate_overflow = false;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1247 NOT_PRODUCT(
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1248 if (ParGCWorkQueueOverflowALot && should_simulate_overflow()) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1249 // simulate a stack overflow
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1250 simulate_overflow = true;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1251 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1252 )
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1253 if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 // Add stats for overflow pushes.
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1255 push_on_overflow_list(old, par_scan_state);
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
1256 TASKQUEUE_STATS_ONLY(par_scan_state->taskqueue_stats().record_overflow(0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1258
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 return new_obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1261
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 // Oops. Someone beat us to it. Undo the allocation. Where did we
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // allocate it?
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 if (is_in_reserved(new_obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 // Must be in to_space.
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 assert(to()->is_in_reserved(new_obj), "Checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 par_scan_state->undo_alloc_in_to_space((HeapWord*)new_obj, sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 assert(!_avoid_promotion_undo, "Should not be here if avoiding.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 _next_gen->par_promote_alloc_undo(par_scan_state->thread_num(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 (HeapWord*)new_obj, sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1273
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 return forward_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1276
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1277 #ifndef PRODUCT
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1278 // It's OK to call this multi-threaded; the worst thing
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1279 // that can happen is that we'll get a bunch of closely
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1280 // spaced simulated oveflows, but that's OK, in fact
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1281 // probably good as it would exercise the overflow code
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1282 // under contention.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1283 bool ParNewGeneration::should_simulate_overflow() {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1284 if (_overflow_counter-- <= 0) { // just being defensive
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1285 _overflow_counter = ParGCWorkQueueOverflowInterval;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1286 return true;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1287 } else {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1288 return false;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1289 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1290 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1291 #endif
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1292
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1293 // In case we are using compressed oops, we need to be careful.
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1294 // If the object being pushed is an object array, then its length
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1295 // field keeps track of the "grey boundary" at which the next
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1296 // incremental scan will be done (see ParGCArrayScanChunk).
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1297 // When using compressed oops, this length field is kept in the
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1298 // lower 32 bits of the erstwhile klass word and cannot be used
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1299 // for the overflow chaining pointer (OCP below). As such the OCP
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1300 // would itself need to be compressed into the top 32-bits in this
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1301 // case. Unfortunately, see below, in the event that we have a
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1302 // promotion failure, the node to be pushed on the list can be
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1303 // outside of the Java heap, so the heap-based pointer compression
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1304 // would not work (we would have potential aliasing between C-heap
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1305 // and Java-heap pointers). For this reason, when using compressed
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1306 // oops, we simply use a worker-thread-local, non-shared overflow
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1307 // list in the form of a growable array, with a slightly different
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1308 // overflow stack draining strategy. If/when we start using fat
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1309 // stacks here, we can go back to using (fat) pointer chains
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1310 // (although some performance comparisons would be useful since
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1311 // single global lists have their own performance disadvantages
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1312 // as we were made painfully aware not long ago, see 6786503).
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1313 #define BUSY (oop(0x1aff1aff))
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1314 void ParNewGeneration::push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state) {
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1315 assert(is_in_reserved(from_space_obj), "Should be from this generation");
695
becb17ad5e51 6824570: ParNew: Fix memory leak introduced in 6819891
ysr
parents: 679
diff changeset
1316 if (ParGCUseLocalOverflow) {
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1317 // In the case of compressed oops, we use a private, not-shared
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1318 // overflow stack.
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1319 par_scan_state->push_on_overflow_stack(from_space_obj);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1320 } else {
695
becb17ad5e51 6824570: ParNew: Fix memory leak introduced in 6819891
ysr
parents: 679
diff changeset
1321 assert(!UseCompressedOops, "Error");
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1322 // if the object has been forwarded to itself, then we cannot
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1323 // use the klass pointer for the linked list. Instead we have
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1324 // to allocate an oopDesc in the C-Heap and use that for the linked list.
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1325 // XXX This is horribly inefficient when a promotion failure occurs
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1326 // and should be fixed. XXX FIX ME !!!
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1327 #ifndef PRODUCT
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1328 Atomic::inc_ptr(&_num_par_pushes);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1329 assert(_num_par_pushes > 0, "Tautology");
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1330 #endif
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1331 if (from_space_obj->forwardee() == from_space_obj) {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1332 oopDesc* listhead = NEW_C_HEAP_ARRAY(oopDesc, 1);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1333 listhead->forward_to(from_space_obj);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1334 from_space_obj = listhead;
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1335 }
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1336 oop observed_overflow_list = _overflow_list;
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1337 oop cur_overflow_list;
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1338 do {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1339 cur_overflow_list = observed_overflow_list;
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1340 if (cur_overflow_list != BUSY) {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1341 from_space_obj->set_klass_to_list_ptr(cur_overflow_list);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1342 } else {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1343 from_space_obj->set_klass_to_list_ptr(NULL);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1344 }
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1345 observed_overflow_list =
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1346 (oop)Atomic::cmpxchg_ptr(from_space_obj, &_overflow_list, cur_overflow_list);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1347 } while (cur_overflow_list != observed_overflow_list);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1350
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1351 bool ParNewGeneration::take_from_overflow_list(ParScanThreadState* par_scan_state) {
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1352 bool res;
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1353
695
becb17ad5e51 6824570: ParNew: Fix memory leak introduced in 6819891
ysr
parents: 679
diff changeset
1354 if (ParGCUseLocalOverflow) {
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1355 res = par_scan_state->take_from_overflow_stack();
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1356 } else {
695
becb17ad5e51 6824570: ParNew: Fix memory leak introduced in 6819891
ysr
parents: 679
diff changeset
1357 assert(!UseCompressedOops, "Error");
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1358 res = take_from_overflow_list_work(par_scan_state);
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1359 }
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1360 return res;
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1361 }
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1362
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1363
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1364 // *NOTE*: The overflow list manipulation code here and
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1365 // in CMSCollector:: are very similar in shape,
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1366 // except that in the CMS case we thread the objects
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1367 // directly into the list via their mark word, and do
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1368 // not need to deal with special cases below related
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1369 // to chunking of object arrays and promotion failure
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1370 // handling.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1371 // CR 6797058 has been filed to attempt consolidation of
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1372 // the common code.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1373 // Because of the common code, if you make any changes in
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1374 // the code below, please check the CMS version to see if
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1375 // similar changes might be needed.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1376 // See CMSCollector::par_take_from_overflow_list() for
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1377 // more extensive documentation comments.
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1378 bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan_state) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 ObjToScanQueue* work_q = par_scan_state->work_queue();
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 // How many to take?
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1381 size_t objsFromOverflow = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1382 (size_t)ParGCDesiredObjsFromOverflowList);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1383
1836
894b1d7c7e01 6423256: GC stacks should use a better data structure
jcoomes
parents: 1833
diff changeset
1384 assert(!UseCompressedOops, "Error");
679
cea947c8a988 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 579
diff changeset
1385 assert(par_scan_state->overflow_stack() == NULL, "Error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 if (_overflow_list == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1387
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // Otherwise, there was something there; try claiming the list.
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1389 oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1390 // Trim off a prefix of at most objsFromOverflow items
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1391 Thread* tid = Thread::current();
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1392 size_t spin_count = (size_t)ParallelGCThreads;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1393 size_t sleep_time_millis = MAX2((size_t)1, objsFromOverflow/100);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1394 for (size_t spin = 0; prefix == BUSY && spin < spin_count; spin++) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1395 // someone grabbed it before we did ...
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1396 // ... we spin for a short while...
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1397 os::sleep(tid, sleep_time_millis, false);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1398 if (_overflow_list == NULL) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1399 // nothing left to take
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1400 return false;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1401 } else if (_overflow_list != BUSY) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1402 // try and grab the prefix
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1403 prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1404 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 }
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1406 if (prefix == NULL || prefix == BUSY) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1407 // Nothing to take or waited long enough
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1408 if (prefix == NULL) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1409 // Write back the NULL in case we overwrote it with BUSY above
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1410 // and it is still the same value.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1411 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1412 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1413 return false;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1414 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1415 assert(prefix != NULL && prefix != BUSY, "Error");
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1416 size_t i = 1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 oop cur = prefix;
167
feeb96a45707 6696264: assert("narrow oop can never be zero") for GCBasher & ParNewGC
coleenp
parents: 113
diff changeset
1418 while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 i++; cur = oop(cur->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1421
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 // Reattach remaining (suffix) to overflow list
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1423 if (cur->klass_or_null() == NULL) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1424 // Write back the NULL in lieu of the BUSY we wrote
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1425 // above and it is still the same value.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1426 if (_overflow_list == BUSY) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1427 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 }
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1429 } else {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1430 assert(cur->klass_or_null() != BUSY, "Error");
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1431 oop suffix = oop(cur->klass()); // suffix will be put back on global list
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1432 cur->set_klass_to_list_ptr(NULL); // break off suffix
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1433 // It's possible that the list is still in the empty(busy) state
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1434 // we left it in a short while ago; in that case we may be
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1435 // able to place back the suffix.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1436 oop observed_overflow_list = _overflow_list;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1437 oop cur_overflow_list = observed_overflow_list;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1438 bool attached = false;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1439 while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1440 observed_overflow_list =
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1441 (oop) Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1442 if (cur_overflow_list == observed_overflow_list) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1443 attached = true;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1444 break;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1445 } else cur_overflow_list = observed_overflow_list;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1446 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1447 if (!attached) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1448 // Too bad, someone else got in in between; we'll need to do a splice.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1449 // Find the last item of suffix list
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1450 oop last = suffix;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1451 while (last->klass_or_null() != NULL) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1452 last = oop(last->klass());
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1453 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1454 // Atomically prepend suffix to current overflow list
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1455 observed_overflow_list = _overflow_list;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1456 do {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1457 cur_overflow_list = observed_overflow_list;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1458 if (cur_overflow_list != BUSY) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1459 // Do the splice ...
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1460 last->set_klass_to_list_ptr(cur_overflow_list);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1461 } else { // cur_overflow_list == BUSY
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1462 last->set_klass_to_list_ptr(NULL);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1463 }
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1464 observed_overflow_list =
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1465 (oop)Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1466 } while (cur_overflow_list != observed_overflow_list);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1469
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // Push objects on prefix list onto this thread's work queue
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1471 assert(prefix != NULL && prefix != BUSY, "program logic");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 cur = prefix;
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1473 ssize_t n = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 while (cur != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 oop obj_to_push = cur->forwardee();
454
df4305d4c1a1 6774607: SIGSEGV or (!is_null(v),"oop value can never be zero") assertion when running with CMS and COOPs
ysr
parents: 453
diff changeset
1476 oop next = oop(cur->klass_or_null());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 cur->set_klass(obj_to_push->klass());
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1478 // This may be an array object that is self-forwarded. In that case, the list pointer
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1479 // space, cur, is not in the Java heap, but rather in the C-heap and should be freed.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1480 if (!is_in_reserved(cur)) {
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1481 // This can become a scaling bottleneck when there is work queue overflow coincident
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1482 // with promotion failure.
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1483 oopDesc* f = cur;
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1484 FREE_C_HEAP_ARRAY(oopDesc, f);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1485 } else if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1487 obj_to_push = cur;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 }
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1489 bool ok = work_q->push(obj_to_push);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1490 assert(ok, "Should have succeeded");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 cur = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 n++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 }
1710
94251661de76 6970376: ParNew: shared TaskQueue statistics
jcoomes
parents: 1665
diff changeset
1494 TASKQUEUE_STATS_ONLY(par_scan_state->note_overflow_refill(n));
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1495 #ifndef PRODUCT
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1496 assert(_num_par_pushes >= n, "Too many pops?");
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1497 Atomic::add_ptr(-(intptr_t)n, &_num_par_pushes);
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1498 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 }
534
5cfd8d19e546 6786503: Overflow list performance can be improved
ysr
parents: 481
diff changeset
1501 #undef BUSY
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1502
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 void ParNewGeneration::ref_processor_init()
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 if (_ref_processor == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 // Allocate and initialize a reference processor
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 _ref_processor = ReferenceProcessor::create_ref_processor(
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 _reserved, // span
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 refs_discovery_is_atomic(), // atomic_discovery
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 refs_discovery_is_mt(), // mt_discovery
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 NULL, // is_alive_non_header
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 ParallelGCThreads,
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 ParallelRefProcEnabled);
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1516
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 const char* ParNewGeneration::name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 return "par new generation";
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 }
1833
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1712
diff changeset
1520
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1712
diff changeset
1521 bool ParNewGeneration::in_use() {
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1712
diff changeset
1522 return UseParNewGC && ParallelGCThreads > 0;
8b10f48633dc 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 1712
diff changeset
1523 }