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

7011379: G1: overly long concurrent marking cycles Summary: This changeset introduces filtering of SATB buffers at the point when they are about to be enqueued. If this filtering clears enough entries on each buffer, the buffer can then be re-used and not enqueued. This cuts down the number of SATB buffers that need to be processed by the concurrent marking threads. Reviewed-by: johnc, ysr
author tonyp
date Wed, 19 Jan 2011 09:35:17 -0500
parents f95d63e2154a
children bca17e38de00
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1612
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 605
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 605
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 605
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1706
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1706
diff changeset
26 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1706
diff changeset
27 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1706
diff changeset
28 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1706
diff changeset
29 #include "gc_implementation/parallelScavenge/psTasks.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1706
diff changeset
30 #include "gc_implementation/parallelScavenge/psYoungGen.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1706
diff changeset
31 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1706
diff changeset
32 #include "oops/oop.psgc.inline.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // Checks an individual oop for missing precise marks. Mark
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // may be either dirty or newgen.
a61af66fc99e Initial load
duke
parents:
diff changeset
36 class CheckForUnmarkedOops : public OopClosure {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
37 private:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
38 PSYoungGen* _young_gen;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
39 CardTableExtension* _card_table;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
40 HeapWord* _unmarked_addr;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
41 jbyte* _unmarked_card;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
42
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
43 protected:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
44 template <class T> void do_oop_work(T* p) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
45 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: 0
diff changeset
46 if (_young_gen->is_in_reserved(obj) &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
47 !_card_table->addr_is_marked_imprecise(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // Don't overwrite the first missing card mark
a61af66fc99e Initial load
duke
parents:
diff changeset
49 if (_unmarked_addr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 _unmarked_addr = (HeapWord*)p;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 _unmarked_card = _card_table->byte_for(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
52 }
a61af66fc99e Initial load
duke
parents:
diff changeset
53 }
a61af66fc99e Initial load
duke
parents:
diff changeset
54 }
a61af66fc99e Initial load
duke
parents:
diff changeset
55
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
56 public:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
57 CheckForUnmarkedOops(PSYoungGen* young_gen, CardTableExtension* card_table) :
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
58 _young_gen(young_gen), _card_table(card_table), _unmarked_addr(NULL) { }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
59
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
60 virtual void do_oop(oop* p) { CheckForUnmarkedOops::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
61 virtual void do_oop(narrowOop* p) { CheckForUnmarkedOops::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
62
0
a61af66fc99e Initial load
duke
parents:
diff changeset
63 bool has_unmarked_oop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 return _unmarked_addr != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66 };
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // Checks all objects for the existance of some type of mark,
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // precise or imprecise, dirty or newgen.
a61af66fc99e Initial load
duke
parents:
diff changeset
70 class CheckForUnmarkedObjects : public ObjectClosure {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
71 private:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
72 PSYoungGen* _young_gen;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
73 CardTableExtension* _card_table;
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
76 CheckForUnmarkedObjects() {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 _young_gen = heap->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
81 _card_table = (CardTableExtension*)heap->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // No point in asserting barrier set type here. Need to make CardTableExtension
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // a unique barrier set type.
a61af66fc99e Initial load
duke
parents:
diff changeset
84 }
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // Card marks are not precise. The current system can leave us with
605
98cb887364d3 6810672: Comment typos
twisti
parents: 269
diff changeset
87 // a mismash of precise marks and beginning of object marks. This means
0
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // we test for missing precise marks first. If any are found, we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // fail unless the object head is also unmarked.
a61af66fc99e Initial load
duke
parents:
diff changeset
90 virtual void do_object(oop obj) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
91 CheckForUnmarkedOops object_check(_young_gen, _card_table);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
92 obj->oop_iterate(&object_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
93 if (object_check.has_unmarked_oop()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 assert(_card_table->addr_is_marked_imprecise(obj), "Found unmarked young_gen object");
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97 };
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // Checks for precise marking of oops as newgen.
a61af66fc99e Initial load
duke
parents:
diff changeset
100 class CheckForPreciseMarks : public OopClosure {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
101 private:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
102 PSYoungGen* _young_gen;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
103 CardTableExtension* _card_table;
a61af66fc99e Initial load
duke
parents:
diff changeset
104
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
105 protected:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
106 template <class T> void do_oop_work(T* p) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
107 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: 0
diff changeset
108 if (_young_gen->is_in_reserved(obj)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
109 assert(_card_table->addr_is_marked_precise(p), "Found unmarked precise oop");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
110 _card_table->set_card_newgen(p);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
111 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
112 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
113
0
a61af66fc99e Initial load
duke
parents:
diff changeset
114 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
115 CheckForPreciseMarks( PSYoungGen* young_gen, CardTableExtension* card_table ) :
a61af66fc99e Initial load
duke
parents:
diff changeset
116 _young_gen(young_gen), _card_table(card_table) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
117
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
118 virtual void do_oop(oop* p) { CheckForPreciseMarks::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
119 virtual void do_oop(narrowOop* p) { CheckForPreciseMarks::do_oop_work(p); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
120 };
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // We get passed the space_top value to prevent us from traversing into
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // the old_gen promotion labs, which cannot be safely parsed.
a61af66fc99e Initial load
duke
parents:
diff changeset
124 void CardTableExtension::scavenge_contents(ObjectStartArray* start_array,
a61af66fc99e Initial load
duke
parents:
diff changeset
125 MutableSpace* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
126 HeapWord* space_top,
a61af66fc99e Initial load
duke
parents:
diff changeset
127 PSPromotionManager* pm)
a61af66fc99e Initial load
duke
parents:
diff changeset
128 {
a61af66fc99e Initial load
duke
parents:
diff changeset
129 assert(start_array != NULL && sp != NULL && pm != NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
130 assert(start_array->covered_region().contains(sp->used_region()),
a61af66fc99e Initial load
duke
parents:
diff changeset
131 "ObjectStartArray does not cover space");
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 if (sp->not_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 oop* sp_top = (oop*)space_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 oop* prev_top = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 jbyte* current_card = byte_for(sp->bottom());
a61af66fc99e Initial load
duke
parents:
diff changeset
137 jbyte* end_card = byte_for(sp_top - 1); // sp_top is exclusive
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // scan card marking array
a61af66fc99e Initial load
duke
parents:
diff changeset
139 while (current_card <= end_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 jbyte value = *current_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // skip clean cards
a61af66fc99e Initial load
duke
parents:
diff changeset
142 if (card_is_clean(value)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
143 current_card++;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // we found a non-clean card
a61af66fc99e Initial load
duke
parents:
diff changeset
146 jbyte* first_nonclean_card = current_card++;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 oop* bottom = (oop*)addr_for(first_nonclean_card);
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // find object starting on card
a61af66fc99e Initial load
duke
parents:
diff changeset
149 oop* bottom_obj = (oop*)start_array->object_start((HeapWord*)bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // bottom_obj = (oop*)start_array->object_start((HeapWord*)bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 assert(bottom_obj <= bottom, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // make sure we don't scan oops we already looked at
a61af66fc99e Initial load
duke
parents:
diff changeset
153 if (bottom < prev_top) bottom = prev_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // figure out when to stop scanning
a61af66fc99e Initial load
duke
parents:
diff changeset
155 jbyte* first_clean_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
156 oop* top;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 bool restart_scanning;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
159 restart_scanning = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // find a clean card
a61af66fc99e Initial load
duke
parents:
diff changeset
161 while (current_card <= end_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
162 value = *current_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
163 if (card_is_clean(value)) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 current_card++;
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // check if we reached the end, if so we are done
a61af66fc99e Initial load
duke
parents:
diff changeset
167 if (current_card >= end_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
168 first_clean_card = end_card + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
169 current_card++;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 top = sp_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
171 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // we have a clean card, find object starting on that card
a61af66fc99e Initial load
duke
parents:
diff changeset
173 first_clean_card = current_card++;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 top = (oop*)addr_for(first_clean_card);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 oop* top_obj = (oop*)start_array->object_start((HeapWord*)top);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // top_obj = (oop*)start_array->object_start((HeapWord*)top);
a61af66fc99e Initial load
duke
parents:
diff changeset
177 assert(top_obj <= top, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
178 if (oop(top_obj)->is_objArray() || oop(top_obj)->is_typeArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // an arrayOop is starting on the clean card - since we do exact store
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // checks for objArrays we are done
a61af66fc99e Initial load
duke
parents:
diff changeset
181 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // otherwise, it is possible that the object starting on the clean card
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // spans the entire card, and that the store happened on a later card.
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // figure out where the object ends
a61af66fc99e Initial load
duke
parents:
diff changeset
185 top = top_obj + oop(top_obj)->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
186 jbyte* top_card = CardTableModRefBS::byte_for(top - 1); // top is exclusive
a61af66fc99e Initial load
duke
parents:
diff changeset
187 if (top_card > first_clean_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // object ends a different card
a61af66fc99e Initial load
duke
parents:
diff changeset
189 current_card = top_card + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
190 if (card_is_clean(*top_card)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // the ending card is clean, we are done
a61af66fc99e Initial load
duke
parents:
diff changeset
192 first_clean_card = top_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // the ending card is not clean, continue scanning at start of do-while
a61af66fc99e Initial load
duke
parents:
diff changeset
195 restart_scanning = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // object ends on the clean card, we are done.
a61af66fc99e Initial load
duke
parents:
diff changeset
199 assert(first_clean_card == top_card, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 } while (restart_scanning);
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // we know which cards to scan, now clear them
a61af66fc99e Initial load
duke
parents:
diff changeset
205 while (first_nonclean_card < first_clean_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 *first_nonclean_card++ = clean_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // scan oops in objects
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
209 do {
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
210 oop(bottom_obj)->push_contents(pm);
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
211 bottom_obj += oop(bottom_obj)->size();
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
212 assert(bottom_obj <= sp_top, "just checking");
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
213 } while (bottom_obj < top);
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
214 pm->drain_stacks_cond_depth();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // remember top oop* scanned
a61af66fc99e Initial load
duke
parents:
diff changeset
216 prev_top = top;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 void CardTableExtension::scavenge_contents_parallel(ObjectStartArray* start_array,
a61af66fc99e Initial load
duke
parents:
diff changeset
223 MutableSpace* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
224 HeapWord* space_top,
a61af66fc99e Initial load
duke
parents:
diff changeset
225 PSPromotionManager* pm,
a61af66fc99e Initial load
duke
parents:
diff changeset
226 uint stripe_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 int ssize = 128; // Naked constant! Work unit = 64k.
a61af66fc99e Initial load
duke
parents:
diff changeset
228 int dirty_card_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 oop* sp_top = (oop*)space_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 jbyte* start_card = byte_for(sp->bottom());
a61af66fc99e Initial load
duke
parents:
diff changeset
232 jbyte* end_card = byte_for(sp_top - 1) + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 oop* last_scanned = NULL; // Prevent scanning objects more than once
a61af66fc99e Initial load
duke
parents:
diff changeset
234 for (jbyte* slice = start_card; slice < end_card; slice += ssize*ParallelGCThreads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
235 jbyte* worker_start_card = slice + stripe_number * ssize;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 if (worker_start_card >= end_card)
a61af66fc99e Initial load
duke
parents:
diff changeset
237 return; // We're done.
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 jbyte* worker_end_card = worker_start_card + ssize;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 if (worker_end_card > end_card)
a61af66fc99e Initial load
duke
parents:
diff changeset
241 worker_end_card = end_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // We do not want to scan objects more than once. In order to accomplish
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // this, we assert that any object with an object head inside our 'slice'
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // belongs to us. We may need to extend the range of scanned cards if the
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // last object continues into the next 'slice'.
a61af66fc99e Initial load
duke
parents:
diff changeset
247 //
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // Note! ending cards are exclusive!
a61af66fc99e Initial load
duke
parents:
diff changeset
249 HeapWord* slice_start = addr_for(worker_start_card);
a61af66fc99e Initial load
duke
parents:
diff changeset
250 HeapWord* slice_end = MIN2((HeapWord*) sp_top, addr_for(worker_end_card));
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // If there are not objects starting within the chunk, skip it.
a61af66fc99e Initial load
duke
parents:
diff changeset
253 if (!start_array->object_starts_in_range(slice_start, slice_end)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
254 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
605
98cb887364d3 6810672: Comment typos
twisti
parents: 269
diff changeset
256 // Update our beginning addr
0
a61af66fc99e Initial load
duke
parents:
diff changeset
257 HeapWord* first_object = start_array->object_start(slice_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
258 debug_only(oop* first_object_within_slice = (oop*) first_object;)
a61af66fc99e Initial load
duke
parents:
diff changeset
259 if (first_object < slice_start) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 last_scanned = (oop*)(first_object + oop(first_object)->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
261 debug_only(first_object_within_slice = last_scanned;)
a61af66fc99e Initial load
duke
parents:
diff changeset
262 worker_start_card = byte_for(last_scanned);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // Update the ending addr
a61af66fc99e Initial load
duke
parents:
diff changeset
266 if (slice_end < (HeapWord*)sp_top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // The subtraction is important! An object may start precisely at slice_end.
a61af66fc99e Initial load
duke
parents:
diff changeset
268 HeapWord* last_object = start_array->object_start(slice_end - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 slice_end = last_object + oop(last_object)->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // worker_end_card is exclusive, so bump it one past the end of last_object's
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // covered span.
a61af66fc99e Initial load
duke
parents:
diff changeset
272 worker_end_card = byte_for(slice_end) + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
273
a61af66fc99e Initial load
duke
parents:
diff changeset
274 if (worker_end_card > end_card)
a61af66fc99e Initial load
duke
parents:
diff changeset
275 worker_end_card = end_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 assert(slice_end <= (HeapWord*)sp_top, "Last object in slice crosses space boundary");
a61af66fc99e Initial load
duke
parents:
diff changeset
279 assert(is_valid_card_address(worker_start_card), "Invalid worker start card");
a61af66fc99e Initial load
duke
parents:
diff changeset
280 assert(is_valid_card_address(worker_end_card), "Invalid worker end card");
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // Note that worker_start_card >= worker_end_card is legal, and happens when
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // an object spans an entire slice.
a61af66fc99e Initial load
duke
parents:
diff changeset
283 assert(worker_start_card <= end_card, "worker start card beyond end card");
a61af66fc99e Initial load
duke
parents:
diff changeset
284 assert(worker_end_card <= end_card, "worker end card beyond end card");
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 jbyte* current_card = worker_start_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
287 while (current_card < worker_end_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 // Find an unclean card.
a61af66fc99e Initial load
duke
parents:
diff changeset
289 while (current_card < worker_end_card && card_is_clean(*current_card)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 current_card++;
a61af66fc99e Initial load
duke
parents:
diff changeset
291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
292 jbyte* first_unclean_card = current_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // Find the end of a run of contiguous unclean cards
a61af66fc99e Initial load
duke
parents:
diff changeset
295 while (current_card < worker_end_card && !card_is_clean(*current_card)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 while (current_card < worker_end_card && !card_is_clean(*current_card)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
297 current_card++;
a61af66fc99e Initial load
duke
parents:
diff changeset
298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
299
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if (current_card < worker_end_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // Some objects may be large enough to span several cards. If such
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // an object has more than one dirty card, separated by a clean card,
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // we will attempt to scan it twice. The test against "last_scanned"
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // prevents the redundant object scan, but it does not prevent newly
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // marked cards from being cleaned.
a61af66fc99e Initial load
duke
parents:
diff changeset
306 HeapWord* last_object_in_dirty_region = start_array->object_start(addr_for(current_card)-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
307 size_t size_of_last_object = oop(last_object_in_dirty_region)->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
308 HeapWord* end_of_last_object = last_object_in_dirty_region + size_of_last_object;
a61af66fc99e Initial load
duke
parents:
diff changeset
309 jbyte* ending_card_of_last_object = byte_for(end_of_last_object);
a61af66fc99e Initial load
duke
parents:
diff changeset
310 assert(ending_card_of_last_object <= worker_end_card, "ending_card_of_last_object is greater than worker_end_card");
a61af66fc99e Initial load
duke
parents:
diff changeset
311 if (ending_card_of_last_object > current_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // This means the object spans the next complete card.
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // We need to bump the current_card to ending_card_of_last_object
a61af66fc99e Initial load
duke
parents:
diff changeset
314 current_card = ending_card_of_last_object;
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318 jbyte* following_clean_card = current_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 if (first_unclean_card < worker_end_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 oop* p = (oop*) start_array->object_start(addr_for(first_unclean_card));
a61af66fc99e Initial load
duke
parents:
diff changeset
322 assert((HeapWord*)p <= addr_for(first_unclean_card), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // "p" should always be >= "last_scanned" because newly GC dirtied
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // cards are no longer scanned again (see comment at end
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // of loop on the increment of "current_card"). Test that
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // hypothesis before removing this code.
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // If this code is removed, deal with the first time through
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // the loop when the last_scanned is the object starting in
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // the previous slice.
a61af66fc99e Initial load
duke
parents:
diff changeset
330 assert((p >= last_scanned) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
331 (last_scanned == first_object_within_slice),
a61af66fc99e Initial load
duke
parents:
diff changeset
332 "Should no longer be possible");
a61af66fc99e Initial load
duke
parents:
diff changeset
333 if (p < last_scanned) {
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // Avoid scanning more than once; this can happen because
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // newgen cards set by GC may a different set than the
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // originally dirty set
a61af66fc99e Initial load
duke
parents:
diff changeset
337 p = last_scanned;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339 oop* to = (oop*)addr_for(following_clean_card);
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Test slice_end first!
a61af66fc99e Initial load
duke
parents:
diff changeset
342 if ((HeapWord*)to > slice_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 to = (oop*)slice_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
344 } else if (to > sp_top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
345 to = sp_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // we know which cards to scan, now clear them
a61af66fc99e Initial load
duke
parents:
diff changeset
349 if (first_unclean_card <= worker_start_card+1)
a61af66fc99e Initial load
duke
parents:
diff changeset
350 first_unclean_card = worker_start_card+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
351 if (following_clean_card >= worker_end_card-1)
a61af66fc99e Initial load
duke
parents:
diff changeset
352 following_clean_card = worker_end_card-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 while (first_unclean_card < following_clean_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 *first_unclean_card++ = clean_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 const int interval = PrefetchScanIntervalInBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // scan all objects in the range
a61af66fc99e Initial load
duke
parents:
diff changeset
360 if (interval != 0) {
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
361 while (p < to) {
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
362 Prefetch::write(p, interval);
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
363 oop m = oop(p);
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
364 assert(m->is_oop_or_null(), "check for header");
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
365 m->push_contents(pm);
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
366 p += m->size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
368 pm->drain_stacks_cond_depth();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
369 } else {
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
370 while (p < to) {
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
371 oop m = oop(p);
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
372 assert(m->is_oop_or_null(), "check for header");
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
373 m->push_contents(pm);
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
374 p += m->size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
1706
9d7a8ab3736b 6962589: remove breadth first scanning code from parallel gc
tonyp
parents: 1612
diff changeset
376 pm->drain_stacks_cond_depth();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378 last_scanned = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // "current_card" is still the "following_clean_card" or
a61af66fc99e Initial load
duke
parents:
diff changeset
381 // the current_card is >= the worker_end_card so the
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // loop will not execute again.
a61af66fc99e Initial load
duke
parents:
diff changeset
383 assert((current_card == following_clean_card) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
384 (current_card >= worker_end_card),
a61af66fc99e Initial load
duke
parents:
diff changeset
385 "current_card should only be incremented if it still equals "
a61af66fc99e Initial load
duke
parents:
diff changeset
386 "following_clean_card");
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // Increment current_card so that it is not processed again.
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // It may now be dirty because a old-to-young pointer was
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // found on it an updated. If it is now dirty, it cannot be
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // be safely cleaned in the next iteration.
a61af66fc99e Initial load
duke
parents:
diff changeset
391 current_card++;
a61af66fc99e Initial load
duke
parents:
diff changeset
392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // This should be called before a scavenge.
a61af66fc99e Initial load
duke
parents:
diff changeset
397 void CardTableExtension::verify_all_young_refs_imprecise() {
a61af66fc99e Initial load
duke
parents:
diff changeset
398 CheckForUnmarkedObjects check;
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
401 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
404 PSPermGen* perm_gen = heap->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 old_gen->object_iterate(&check);
a61af66fc99e Initial load
duke
parents:
diff changeset
407 perm_gen->object_iterate(&check);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // This should be called immediately after a scavenge, before mutators resume.
a61af66fc99e Initial load
duke
parents:
diff changeset
411 void CardTableExtension::verify_all_young_refs_precise() {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
413 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
414
a61af66fc99e Initial load
duke
parents:
diff changeset
415 PSOldGen* old_gen = heap->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
416 PSPermGen* perm_gen = heap->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 CheckForPreciseMarks check(heap->young_gen(), (CardTableExtension*)heap->barrier_set());
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 old_gen->oop_iterate(&check);
a61af66fc99e Initial load
duke
parents:
diff changeset
421 perm_gen->oop_iterate(&check);
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 verify_all_young_refs_precise_helper(old_gen->object_space()->used_region());
a61af66fc99e Initial load
duke
parents:
diff changeset
424 verify_all_young_refs_precise_helper(perm_gen->object_space()->used_region());
a61af66fc99e Initial load
duke
parents:
diff changeset
425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 void CardTableExtension::verify_all_young_refs_precise_helper(MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 CardTableExtension* card_table = (CardTableExtension*)Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // FIX ME ASSERT HERE
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 jbyte* bot = card_table->byte_for(mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
432 jbyte* top = card_table->byte_for(mr.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
433 while(bot <= top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
434 assert(*bot == clean_card || *bot == verify_card, "Found unwanted or unknown card mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
435 if (*bot == verify_card)
a61af66fc99e Initial load
duke
parents:
diff changeset
436 *bot = youngergen_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
437 bot++;
a61af66fc99e Initial load
duke
parents:
diff changeset
438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 bool CardTableExtension::addr_is_marked_imprecise(void *addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
442 jbyte* p = byte_for(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
443 jbyte val = *p;
a61af66fc99e Initial load
duke
parents:
diff changeset
444
a61af66fc99e Initial load
duke
parents:
diff changeset
445 if (card_is_dirty(val))
a61af66fc99e Initial load
duke
parents:
diff changeset
446 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 if (card_is_newgen(val))
a61af66fc99e Initial load
duke
parents:
diff changeset
449 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 if (card_is_clean(val))
a61af66fc99e Initial load
duke
parents:
diff changeset
452 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 assert(false, "Found unhandled card mark type");
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // Also includes verify_card
a61af66fc99e Initial load
duke
parents:
diff changeset
460 bool CardTableExtension::addr_is_marked_precise(void *addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
461 jbyte* p = byte_for(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
462 jbyte val = *p;
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 if (card_is_newgen(val))
a61af66fc99e Initial load
duke
parents:
diff changeset
465 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
466
a61af66fc99e Initial load
duke
parents:
diff changeset
467 if (card_is_verify(val))
a61af66fc99e Initial load
duke
parents:
diff changeset
468 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
469
a61af66fc99e Initial load
duke
parents:
diff changeset
470 if (card_is_clean(val))
a61af66fc99e Initial load
duke
parents:
diff changeset
471 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
472
a61af66fc99e Initial load
duke
parents:
diff changeset
473 if (card_is_dirty(val))
a61af66fc99e Initial load
duke
parents:
diff changeset
474 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
475
a61af66fc99e Initial load
duke
parents:
diff changeset
476 assert(false, "Found unhandled card mark type");
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // Assumes that only the base or the end changes. This allows indentification
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // of the region that is being resized. The
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // CardTableModRefBS::resize_covered_region() is used for the normal case
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // where the covered regions are growing or shrinking at the high end.
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // The method resize_covered_region_by_end() is analogous to
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // CardTableModRefBS::resize_covered_region() but
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // for regions that grow or shrink at the low end.
a61af66fc99e Initial load
duke
parents:
diff changeset
488 void CardTableExtension::resize_covered_region(MemRegion new_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 for (int i = 0; i < _cur_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 if (_covered[i].start() == new_region.start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // Found a covered region with the same start as the
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // new region. The region is growing or shrinking
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // from the start of the region.
a61af66fc99e Initial load
duke
parents:
diff changeset
495 resize_covered_region_by_start(new_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
496 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
498 if (_covered[i].start() > new_region.start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 int changed_region = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
504 for (int j = 0; j < _cur_covered_regions; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
505 if (_covered[j].end() == new_region.end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 changed_region = j;
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // This is a case where the covered region is growing or shrinking
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // at the start of the region.
a61af66fc99e Initial load
duke
parents:
diff changeset
509 assert(changed_region != -1, "Don't expect to add a covered region");
a61af66fc99e Initial load
duke
parents:
diff changeset
510 assert(_covered[changed_region].byte_size() != new_region.byte_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
511 "The sizes should be different here");
a61af66fc99e Initial load
duke
parents:
diff changeset
512 resize_covered_region_by_end(changed_region, new_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
513 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // This should only be a new covered region (where no existing
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // covered region matches at the start or the end).
a61af66fc99e Initial load
duke
parents:
diff changeset
518 assert(_cur_covered_regions < _max_covered_regions,
a61af66fc99e Initial load
duke
parents:
diff changeset
519 "An existing region should have been found");
a61af66fc99e Initial load
duke
parents:
diff changeset
520 resize_covered_region_by_start(new_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 void CardTableExtension::resize_covered_region_by_start(MemRegion new_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
524 CardTableModRefBS::resize_covered_region(new_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
525 debug_only(verify_guard();)
a61af66fc99e Initial load
duke
parents:
diff changeset
526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
527
a61af66fc99e Initial load
duke
parents:
diff changeset
528 void CardTableExtension::resize_covered_region_by_end(int changed_region,
a61af66fc99e Initial load
duke
parents:
diff changeset
529 MemRegion new_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 assert(SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
531 "Only expect an expansion at the low end at a GC");
a61af66fc99e Initial load
duke
parents:
diff changeset
532 debug_only(verify_guard();)
a61af66fc99e Initial load
duke
parents:
diff changeset
533 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
534 for (int k = 0; k < _cur_covered_regions; k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 if (_covered[k].end() == new_region.end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
536 assert(changed_region == k, "Changed region is incorrect");
a61af66fc99e Initial load
duke
parents:
diff changeset
537 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
540 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // Commit new or uncommit old pages, if necessary.
1612
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
543 if (resize_commit_uncommit(changed_region, new_region)) {
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
544 // Set the new start of the committed region
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
545 resize_update_committed_table(changed_region, new_region);
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
546 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // Update card table entries
a61af66fc99e Initial load
duke
parents:
diff changeset
549 resize_update_card_table_entries(changed_region, new_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // Update the covered region
a61af66fc99e Initial load
duke
parents:
diff changeset
552 resize_update_covered_table(changed_region, new_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554 if (TraceCardTableModRefBS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
555 int ind = changed_region;
a61af66fc99e Initial load
duke
parents:
diff changeset
556 gclog_or_tty->print_cr("CardTableModRefBS::resize_covered_region: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
557 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
558 " _covered[%d].start(): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
559 " _covered[%d].last(): " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
560 ind, _covered[ind].start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
561 ind, _covered[ind].last());
a61af66fc99e Initial load
duke
parents:
diff changeset
562 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
563 " _committed[%d].start(): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
564 " _committed[%d].last(): " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
565 ind, _committed[ind].start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
566 ind, _committed[ind].last());
a61af66fc99e Initial load
duke
parents:
diff changeset
567 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
568 " byte_for(start): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
569 " byte_for(last): " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
570 byte_for(_covered[ind].start()),
a61af66fc99e Initial load
duke
parents:
diff changeset
571 byte_for(_covered[ind].last()));
a61af66fc99e Initial load
duke
parents:
diff changeset
572 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
573 " addr_for(start): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
574 " addr_for(last): " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
575 addr_for((jbyte*) _committed[ind].start()),
a61af66fc99e Initial load
duke
parents:
diff changeset
576 addr_for((jbyte*) _committed[ind].last()));
a61af66fc99e Initial load
duke
parents:
diff changeset
577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
578 debug_only(verify_guard();)
a61af66fc99e Initial load
duke
parents:
diff changeset
579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
580
1612
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
581 bool CardTableExtension::resize_commit_uncommit(int changed_region,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
582 MemRegion new_region) {
1612
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
583 bool result = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // Commit new or uncommit old pages, if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
585 MemRegion cur_committed = _committed[changed_region];
a61af66fc99e Initial load
duke
parents:
diff changeset
586 assert(_covered[changed_region].end() == new_region.end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
587 "The ends of the regions are expected to match");
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // Extend the start of this _committed region to
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // to cover the start of any previous _committed region.
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // This forms overlapping regions, but never interior regions.
a61af66fc99e Initial load
duke
parents:
diff changeset
591 HeapWord* min_prev_start = lowest_prev_committed_start(changed_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
592 if (min_prev_start < cur_committed.start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // Only really need to set start of "cur_committed" to
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // the new start (min_prev_start) but assertion checking code
a61af66fc99e Initial load
duke
parents:
diff changeset
595 // below use cur_committed.end() so make it correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
596 MemRegion new_committed =
a61af66fc99e Initial load
duke
parents:
diff changeset
597 MemRegion(min_prev_start, cur_committed.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
598 cur_committed = new_committed;
a61af66fc99e Initial load
duke
parents:
diff changeset
599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
600 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
601 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
602 assert(cur_committed.start() ==
a61af66fc99e Initial load
duke
parents:
diff changeset
603 (HeapWord*) align_size_up((uintptr_t) cur_committed.start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
604 os::vm_page_size()),
a61af66fc99e Initial load
duke
parents:
diff changeset
605 "Starts should have proper alignment");
a61af66fc99e Initial load
duke
parents:
diff changeset
606 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608 jbyte* new_start = byte_for(new_region.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // Round down because this is for the start address
a61af66fc99e Initial load
duke
parents:
diff changeset
610 HeapWord* new_start_aligned =
a61af66fc99e Initial load
duke
parents:
diff changeset
611 (HeapWord*)align_size_down((uintptr_t)new_start, os::vm_page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // The guard page is always committed and should not be committed over.
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // This method is used in cases where the generation is growing toward
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // lower addresses but the guard region is still at the end of the
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // card table. That still makes sense when looking for writes
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // off the end of the card table.
a61af66fc99e Initial load
duke
parents:
diff changeset
617 if (new_start_aligned < cur_committed.start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // Expand the committed region
a61af66fc99e Initial load
duke
parents:
diff changeset
619 //
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // Case A
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // |+ guard +|
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // |+ cur committed +++++++++|
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // |+ new committed +++++++++++++++++|
a61af66fc99e Initial load
duke
parents:
diff changeset
624 //
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // Case B
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // |+ guard +|
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // |+ cur committed +|
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // |+ new committed +++++++|
a61af66fc99e Initial load
duke
parents:
diff changeset
629 //
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // These are not expected because the calculation of the
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // cur committed region and the new committed region
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // share the same end for the covered region.
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // Case C
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // |+ guard +|
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // |+ cur committed +|
a61af66fc99e Initial load
duke
parents:
diff changeset
636 // |+ new committed +++++++++++++++++|
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // Case D
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // |+ guard +|
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // |+ cur committed +++++++++++|
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // |+ new committed +++++++|
a61af66fc99e Initial load
duke
parents:
diff changeset
641
a61af66fc99e Initial load
duke
parents:
diff changeset
642 HeapWord* new_end_for_commit =
a61af66fc99e Initial load
duke
parents:
diff changeset
643 MIN2(cur_committed.end(), _guard_region.start());
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
644 if(new_start_aligned < new_end_for_commit) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
645 MemRegion new_committed =
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
646 MemRegion(new_start_aligned, new_end_for_commit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
647 if (!os::commit_memory((char*)new_committed.start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
648 new_committed.byte_size())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
649 vm_exit_out_of_memory(new_committed.byte_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
650 "card table expansion");
a61af66fc99e Initial load
duke
parents:
diff changeset
651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
652 }
1612
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
653 result = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
654 } else if (new_start_aligned > cur_committed.start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // Shrink the committed region
1612
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
656 #if 0 // uncommitting space is currently unsafe because of the interactions
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
657 // of growing and shrinking regions. One region A can uncommit space
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
658 // that it owns but which is being used by another region B (maybe).
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
659 // Region B has not committed the space because it was already
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
660 // committed by region A.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
661 MemRegion uncommit_region = committed_unique_to_self(changed_region,
a61af66fc99e Initial load
duke
parents:
diff changeset
662 MemRegion(cur_committed.start(), new_start_aligned));
a61af66fc99e Initial load
duke
parents:
diff changeset
663 if (!uncommit_region.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
664 if (!os::uncommit_memory((char*)uncommit_region.start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
665 uncommit_region.byte_size())) {
1612
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
666 // If the uncommit fails, ignore it. Let the
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
667 // committed table resizing go even though the committed
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
668 // table will over state the committed space.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
669 }
a61af66fc99e Initial load
duke
parents:
diff changeset
670 }
1612
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
671 #else
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
672 assert(!result, "Should be false with current workaround");
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
673 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
675 assert(_committed[changed_region].end() == cur_committed.end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
676 "end should not change");
1612
fdde661c8e06 6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
jmasa
parents: 1552
diff changeset
677 return result;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
679
a61af66fc99e Initial load
duke
parents:
diff changeset
680 void CardTableExtension::resize_update_committed_table(int changed_region,
a61af66fc99e Initial load
duke
parents:
diff changeset
681 MemRegion new_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682
a61af66fc99e Initial load
duke
parents:
diff changeset
683 jbyte* new_start = byte_for(new_region.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
684 // Set the new start of the committed region
a61af66fc99e Initial load
duke
parents:
diff changeset
685 HeapWord* new_start_aligned =
a61af66fc99e Initial load
duke
parents:
diff changeset
686 (HeapWord*)align_size_down((uintptr_t)new_start,
a61af66fc99e Initial load
duke
parents:
diff changeset
687 os::vm_page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
688 MemRegion new_committed = MemRegion(new_start_aligned,
a61af66fc99e Initial load
duke
parents:
diff changeset
689 _committed[changed_region].end());
a61af66fc99e Initial load
duke
parents:
diff changeset
690 _committed[changed_region] = new_committed;
a61af66fc99e Initial load
duke
parents:
diff changeset
691 _committed[changed_region].set_start(new_start_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
693
a61af66fc99e Initial load
duke
parents:
diff changeset
694 void CardTableExtension::resize_update_card_table_entries(int changed_region,
a61af66fc99e Initial load
duke
parents:
diff changeset
695 MemRegion new_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
696 debug_only(verify_guard();)
a61af66fc99e Initial load
duke
parents:
diff changeset
697 MemRegion original_covered = _covered[changed_region];
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // Initialize the card entries. Only consider the
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // region covered by the card table (_whole_heap)
a61af66fc99e Initial load
duke
parents:
diff changeset
700 jbyte* entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
701 if (new_region.start() < _whole_heap.start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
702 entry = byte_for(_whole_heap.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
703 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
704 entry = byte_for(new_region.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
706 jbyte* end = byte_for(original_covered.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // If _whole_heap starts at the original covered regions start,
a61af66fc99e Initial load
duke
parents:
diff changeset
708 // this loop will not execute.
a61af66fc99e Initial load
duke
parents:
diff changeset
709 while (entry < end) { *entry++ = clean_card; }
a61af66fc99e Initial load
duke
parents:
diff changeset
710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
711
a61af66fc99e Initial load
duke
parents:
diff changeset
712 void CardTableExtension::resize_update_covered_table(int changed_region,
a61af66fc99e Initial load
duke
parents:
diff changeset
713 MemRegion new_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // Update the covered region
a61af66fc99e Initial load
duke
parents:
diff changeset
715 _covered[changed_region].set_start(new_region.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
716 _covered[changed_region].set_word_size(new_region.word_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // reorder regions. There should only be at most 1 out
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // of order.
a61af66fc99e Initial load
duke
parents:
diff changeset
720 for (int i = _cur_covered_regions-1 ; i > 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
721 if (_covered[i].start() < _covered[i-1].start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
722 MemRegion covered_mr = _covered[i-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
723 _covered[i-1] = _covered[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
724 _covered[i] = covered_mr;
a61af66fc99e Initial load
duke
parents:
diff changeset
725 MemRegion committed_mr = _committed[i-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
726 _committed[i-1] = _committed[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
727 _committed[i] = committed_mr;
a61af66fc99e Initial load
duke
parents:
diff changeset
728 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
731 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
732 for (int m = 0; m < _cur_covered_regions-1; m++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
733 assert(_covered[m].start() <= _covered[m+1].start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
734 "Covered regions out of order");
a61af66fc99e Initial load
duke
parents:
diff changeset
735 assert(_committed[m].start() <= _committed[m+1].start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
736 "Committed regions out of order");
a61af66fc99e Initial load
duke
parents:
diff changeset
737 }
a61af66fc99e Initial load
duke
parents:
diff changeset
738 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // Returns the start of any committed region that is lower than
a61af66fc99e Initial load
duke
parents:
diff changeset
742 // the target committed region (index ind) and that intersects the
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // target region. If none, return start of target region.
a61af66fc99e Initial load
duke
parents:
diff changeset
744 //
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // -------------
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // -------------
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // ------------
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // | target |
a61af66fc99e Initial load
duke
parents:
diff changeset
750 // ------------
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // -------------
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // -------------
a61af66fc99e Initial load
duke
parents:
diff changeset
754 // ^ returns this
a61af66fc99e Initial load
duke
parents:
diff changeset
755 //
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // -------------
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // -------------
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // ------------
a61af66fc99e Initial load
duke
parents:
diff changeset
760 // | target |
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // ------------
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // -------------
a61af66fc99e Initial load
duke
parents:
diff changeset
763 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
764 // -------------
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // ^ returns this
a61af66fc99e Initial load
duke
parents:
diff changeset
766
a61af66fc99e Initial load
duke
parents:
diff changeset
767 HeapWord* CardTableExtension::lowest_prev_committed_start(int ind) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
768 assert(_cur_covered_regions >= 0, "Expecting at least on region");
a61af66fc99e Initial load
duke
parents:
diff changeset
769 HeapWord* min_start = _committed[ind].start();
a61af66fc99e Initial load
duke
parents:
diff changeset
770 for (int j = 0; j < ind; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
771 HeapWord* this_start = _committed[j].start();
a61af66fc99e Initial load
duke
parents:
diff changeset
772 if ((this_start < min_start) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
773 !(_committed[j].intersection(_committed[ind])).is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
774 min_start = this_start;
a61af66fc99e Initial load
duke
parents:
diff changeset
775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
777 return min_start;
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }