Mercurial > hg > truffle
annotate src/share/vm/oops/methodDataKlass.cpp @ 452:00b023ae2d78
6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery.
Reviewed-by: apetrusenko, jcoomes
author | ysr |
---|---|
date | Thu, 20 Nov 2008 12:27:41 -0800 |
parents | d1605aabd0a1 |
children | 4e6abf09f540 |
rev | line source |
---|---|
0 | 1 /* |
196 | 2 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_methodDataKlass.cpp.incl" | |
27 | |
28 klassOop methodDataKlass::create_klass(TRAPS) { | |
29 methodDataKlass o; | |
30 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); | |
31 KlassHandle k = base_create_klass(h_this_klass, header_size(), | |
32 o.vtbl_value(), CHECK_NULL); | |
33 // Make sure size calculation is right | |
34 assert(k()->size() == align_object_size(header_size()), | |
35 "wrong size for object"); | |
36 return k(); | |
37 } | |
38 | |
39 | |
40 int methodDataKlass::oop_size(oop obj) const { | |
41 assert(obj->is_methodData(), "must be method data oop"); | |
42 return methodDataOop(obj)->object_size(); | |
43 } | |
44 | |
45 | |
46 bool methodDataKlass::oop_is_parsable(oop obj) const { | |
47 assert(obj->is_methodData(), "must be method data oop"); | |
48 return methodDataOop(obj)->object_is_parsable(); | |
49 } | |
50 | |
51 | |
52 methodDataOop methodDataKlass::allocate(methodHandle method, TRAPS) { | |
53 int size = methodDataOopDesc::compute_allocation_size_in_words(method); | |
54 KlassHandle h_k(THREAD, as_klassOop()); | |
55 methodDataOop mdo = | |
56 (methodDataOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); | |
57 assert(!mdo->is_parsable(), "not expecting parsability yet."); | |
58 No_Safepoint_Verifier no_safepoint; // init function atomic wrt GC | |
59 mdo->initialize(method); | |
60 | |
61 assert(mdo->is_parsable(), "should be parsable here."); | |
62 assert(size == mdo->object_size(), "wrong size for methodDataOop"); | |
63 return mdo; | |
64 } | |
65 | |
66 | |
67 void methodDataKlass::oop_follow_contents(oop obj) { | |
68 assert (obj->is_methodData(), "object must be method data"); | |
69 methodDataOop m = methodDataOop(obj); | |
70 | |
71 obj->follow_header(); | |
72 MarkSweep::mark_and_push(m->adr_method()); | |
73 ResourceMark rm; | |
74 for (ProfileData* data = m->first_data(); | |
75 m->is_valid(data); | |
76 data = m->next_data(data)) { | |
77 data->follow_contents(); | |
78 } | |
79 } | |
80 | |
81 #ifndef SERIALGC | |
82 void methodDataKlass::oop_follow_contents(ParCompactionManager* cm, | |
83 oop obj) { | |
84 assert (obj->is_methodData(), "object must be method data"); | |
85 methodDataOop m = methodDataOop(obj); | |
86 | |
87 obj->follow_header(cm); | |
88 PSParallelCompact::mark_and_push(cm, m->adr_method()); | |
89 ResourceMark rm; | |
90 for (ProfileData* data = m->first_data(); | |
91 m->is_valid(data); | |
92 data = m->next_data(data)) { | |
93 data->follow_contents(cm); | |
94 } | |
95 } | |
96 #endif // SERIALGC | |
97 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
98 |
0 | 99 int methodDataKlass::oop_oop_iterate(oop obj, OopClosure* blk) { |
100 assert (obj->is_methodData(), "object must be method data"); | |
101 methodDataOop m = methodDataOop(obj); | |
102 // Get size before changing pointers | |
103 // Don't call size() or oop_size() since that is a virtual call. | |
104 int size = m->object_size(); | |
105 | |
106 obj->oop_iterate_header(blk); | |
107 blk->do_oop(m->adr_method()); | |
108 ResourceMark rm; | |
109 for (ProfileData* data = m->first_data(); | |
110 m->is_valid(data); | |
111 data = m->next_data(data)) { | |
112 data->oop_iterate(blk); | |
113 } | |
114 return size; | |
115 } | |
116 | |
117 int methodDataKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { | |
118 assert (obj->is_methodData(), "object must be method data"); | |
119 methodDataOop m = methodDataOop(obj); | |
120 // Get size before changing pointers | |
121 // Don't call size() or oop_size() since that is a virtual call. | |
122 int size = m->object_size(); | |
123 | |
124 obj->oop_iterate_header(blk, mr); | |
125 oop* adr = m->adr_method(); | |
126 if (mr.contains(adr)) { | |
127 blk->do_oop(m->adr_method()); | |
128 } | |
129 ResourceMark rm; | |
130 for (ProfileData* data = m->first_data(); | |
131 m->is_valid(data); | |
132 data = m->next_data(data)) { | |
133 data->oop_iterate_m(blk, mr); | |
134 } | |
135 return size; | |
136 } | |
137 | |
138 int methodDataKlass::oop_adjust_pointers(oop obj) { | |
139 assert(obj->is_methodData(), "should be method data"); | |
140 methodDataOop m = methodDataOop(obj); | |
141 // Get size before changing pointers | |
142 // Don't call size() or oop_size() since that is a virtual call. | |
143 int size = m->object_size(); | |
144 | |
145 obj->adjust_header(); | |
146 MarkSweep::adjust_pointer(m->adr_method()); | |
147 ResourceMark rm; | |
148 ProfileData* data; | |
149 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) { | |
150 data->adjust_pointers(); | |
151 } | |
152 return size; | |
153 } | |
154 | |
155 | |
156 #ifndef SERIALGC | |
157 void methodDataKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) { | |
158 assert (obj->is_methodData(), "object must be method data"); | |
159 methodDataOop m = methodDataOop(obj); | |
160 // This should never point into the young gen. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
161 assert(!PSScavenge::should_scavenge(m->adr_method()), "Sanity"); |
0 | 162 } |
163 | |
164 void methodDataKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { | |
165 assert (obj->is_methodData(), "object must be method data"); | |
166 methodDataOop m = methodDataOop(obj); | |
167 // This should never point into the young gen. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
168 assert(!PSScavenge::should_scavenge(m->adr_method()), "Sanity"); |
0 | 169 } |
170 | |
171 int methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { | |
172 assert(obj->is_methodData(), "should be method data"); | |
173 methodDataOop m = methodDataOop(obj); | |
174 | |
175 PSParallelCompact::adjust_pointer(m->adr_method()); | |
176 | |
177 ResourceMark rm; | |
178 ProfileData* data; | |
179 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) { | |
180 data->update_pointers(); | |
181 } | |
182 return m->object_size(); | |
183 } | |
184 | |
185 int | |
186 methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj, | |
187 HeapWord* beg_addr, HeapWord* end_addr) { | |
188 assert(obj->is_methodData(), "should be method data"); | |
189 | |
190 oop* p; | |
191 methodDataOop m = methodDataOop(obj); | |
192 | |
193 p = m->adr_method(); | |
194 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr); | |
195 | |
196 ResourceMark rm; | |
197 ProfileData* data; | |
198 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) { | |
199 data->update_pointers(beg_addr, end_addr); | |
200 } | |
201 return m->object_size(); | |
202 } | |
203 #endif // SERIALGC | |
204 | |
205 #ifndef PRODUCT | |
206 | |
207 // Printing | |
208 void methodDataKlass::oop_print_on(oop obj, outputStream* st) { | |
209 assert(obj->is_methodData(), "should be method data"); | |
210 methodDataOop m = methodDataOop(obj); | |
211 st->print("method data for "); | |
212 m->method()->print_value_on(st); | |
213 st->cr(); | |
214 m->print_data_on(st); | |
215 } | |
216 | |
217 void methodDataKlass::oop_print_value_on(oop obj, outputStream* st) { | |
218 assert(obj->is_methodData(), "should be method data"); | |
219 methodDataOop m = methodDataOop(obj); | |
220 st->print("method data for "); | |
221 m->method()->print_value_on(st); | |
222 } | |
223 | |
224 #endif // !PRODUCT | |
225 | |
226 const char* methodDataKlass::internal_name() const { | |
227 return "{method data}"; | |
228 } | |
229 | |
230 | |
231 // Verification | |
232 void methodDataKlass::oop_verify_on(oop obj, outputStream* st) { | |
233 Klass::oop_verify_on(obj, st); | |
234 guarantee(obj->is_methodData(), "object must be method data"); | |
235 methodDataOop m = methodDataOop(obj); | |
236 guarantee(m->is_perm(), "should be in permspace"); | |
237 m->verify_data_on(st); | |
238 } |