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

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