annotate src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @ 1145:e018e6884bd8

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