Mercurial > hg > truffle
annotate src/share/vm/oops/instanceKlassKlass.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 | a45484ea312d |
children | c89f86385056 |
rev | line source |
---|---|
0 | 1 /* |
196 | 2 * Copyright 1997-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/_instanceKlassKlass.cpp.incl" | |
27 | |
28 klassOop instanceKlassKlass::create_klass(TRAPS) { | |
29 instanceKlassKlass o; | |
30 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); | |
31 KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL); | |
32 // Make sure size calculation is right | |
33 assert(k()->size() == align_object_size(header_size()), "wrong size for object"); | |
34 java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror | |
35 return k(); | |
36 } | |
37 | |
38 int instanceKlassKlass::oop_size(oop obj) const { | |
39 assert(obj->is_klass(), "must be klass"); | |
40 return instanceKlass::cast(klassOop(obj))->object_size(); | |
41 } | |
42 | |
43 bool instanceKlassKlass::oop_is_parsable(oop obj) const { | |
44 assert(obj->is_klass(), "must be klass"); | |
45 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
46 return (!ik->null_vtbl()) && ik->object_is_parsable(); | |
47 } | |
48 | |
49 void instanceKlassKlass::iterate_c_heap_oops(instanceKlass* ik, | |
50 OopClosure* closure) { | |
51 if (ik->oop_map_cache() != NULL) { | |
52 ik->oop_map_cache()->oop_iterate(closure); | |
53 } | |
54 | |
55 if (ik->jni_ids() != NULL) { | |
56 ik->jni_ids()->oops_do(closure); | |
57 } | |
58 } | |
59 | |
60 void instanceKlassKlass::oop_follow_contents(oop obj) { | |
61 assert(obj->is_klass(),"must be a klass"); | |
62 assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); | |
63 | |
64 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
65 ik->follow_static_fields(); | |
66 { | |
67 HandleMark hm; | |
68 ik->vtable()->oop_follow_contents(); | |
69 ik->itable()->oop_follow_contents(); | |
70 } | |
71 | |
72 MarkSweep::mark_and_push(ik->adr_array_klasses()); | |
73 MarkSweep::mark_and_push(ik->adr_methods()); | |
74 MarkSweep::mark_and_push(ik->adr_method_ordering()); | |
75 MarkSweep::mark_and_push(ik->adr_local_interfaces()); | |
76 MarkSweep::mark_and_push(ik->adr_transitive_interfaces()); | |
77 MarkSweep::mark_and_push(ik->adr_fields()); | |
78 MarkSweep::mark_and_push(ik->adr_constants()); | |
79 MarkSweep::mark_and_push(ik->adr_class_loader()); | |
80 MarkSweep::mark_and_push(ik->adr_source_file_name()); | |
81 MarkSweep::mark_and_push(ik->adr_source_debug_extension()); | |
82 MarkSweep::mark_and_push(ik->adr_inner_classes()); | |
83 MarkSweep::mark_and_push(ik->adr_protection_domain()); | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
84 MarkSweep::mark_and_push(ik->adr_host_klass()); |
0 | 85 MarkSweep::mark_and_push(ik->adr_signers()); |
86 MarkSweep::mark_and_push(ik->adr_generic_signature()); | |
87 MarkSweep::mark_and_push(ik->adr_class_annotations()); | |
88 MarkSweep::mark_and_push(ik->adr_fields_annotations()); | |
89 MarkSweep::mark_and_push(ik->adr_methods_annotations()); | |
90 MarkSweep::mark_and_push(ik->adr_methods_parameter_annotations()); | |
91 MarkSweep::mark_and_push(ik->adr_methods_default_annotations()); | |
92 | |
93 // We do not follow adr_implementors() here. It is followed later | |
94 // in instanceKlass::follow_weak_klass_links() | |
95 | |
96 klassKlass::oop_follow_contents(obj); | |
97 | |
98 iterate_c_heap_oops(ik, &MarkSweep::mark_and_push_closure); | |
99 } | |
100 | |
101 #ifndef SERIALGC | |
102 void instanceKlassKlass::oop_follow_contents(ParCompactionManager* cm, | |
103 oop obj) { | |
104 assert(obj->is_klass(),"must be a klass"); | |
105 assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); | |
106 | |
107 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
108 ik->follow_static_fields(cm); | |
109 ik->vtable()->oop_follow_contents(cm); | |
110 ik->itable()->oop_follow_contents(cm); | |
111 | |
112 PSParallelCompact::mark_and_push(cm, ik->adr_array_klasses()); | |
113 PSParallelCompact::mark_and_push(cm, ik->adr_methods()); | |
114 PSParallelCompact::mark_and_push(cm, ik->adr_method_ordering()); | |
115 PSParallelCompact::mark_and_push(cm, ik->adr_local_interfaces()); | |
116 PSParallelCompact::mark_and_push(cm, ik->adr_transitive_interfaces()); | |
117 PSParallelCompact::mark_and_push(cm, ik->adr_fields()); | |
118 PSParallelCompact::mark_and_push(cm, ik->adr_constants()); | |
119 PSParallelCompact::mark_and_push(cm, ik->adr_class_loader()); | |
120 PSParallelCompact::mark_and_push(cm, ik->adr_source_file_name()); | |
121 PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension()); | |
122 PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes()); | |
123 PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain()); | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
124 PSParallelCompact::mark_and_push(cm, ik->adr_host_klass()); |
0 | 125 PSParallelCompact::mark_and_push(cm, ik->adr_signers()); |
126 PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature()); | |
127 PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations()); | |
128 PSParallelCompact::mark_and_push(cm, ik->adr_fields_annotations()); | |
129 PSParallelCompact::mark_and_push(cm, ik->adr_methods_annotations()); | |
130 PSParallelCompact::mark_and_push(cm, ik->adr_methods_parameter_annotations()); | |
131 PSParallelCompact::mark_and_push(cm, ik->adr_methods_default_annotations()); | |
132 | |
133 // We do not follow adr_implementor() here. It is followed later | |
134 // in instanceKlass::follow_weak_klass_links() | |
135 | |
136 klassKlass::oop_follow_contents(cm, obj); | |
137 | |
138 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); | |
139 iterate_c_heap_oops(ik, &mark_and_push_closure); | |
140 } | |
141 #endif // SERIALGC | |
142 | |
143 int instanceKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) { | |
144 assert(obj->is_klass(),"must be a klass"); | |
145 assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); | |
146 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
147 // Get size before changing pointers. | |
148 // Don't call size() or oop_size() since that is a virtual call. | |
149 int size = ik->object_size(); | |
150 | |
151 ik->iterate_static_fields(blk); | |
152 ik->vtable()->oop_oop_iterate(blk); | |
153 ik->itable()->oop_oop_iterate(blk); | |
154 | |
155 blk->do_oop(ik->adr_array_klasses()); | |
156 blk->do_oop(ik->adr_methods()); | |
157 blk->do_oop(ik->adr_method_ordering()); | |
158 blk->do_oop(ik->adr_local_interfaces()); | |
159 blk->do_oop(ik->adr_transitive_interfaces()); | |
160 blk->do_oop(ik->adr_fields()); | |
161 blk->do_oop(ik->adr_constants()); | |
162 blk->do_oop(ik->adr_class_loader()); | |
163 blk->do_oop(ik->adr_protection_domain()); | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
164 blk->do_oop(ik->adr_host_klass()); |
0 | 165 blk->do_oop(ik->adr_signers()); |
166 blk->do_oop(ik->adr_source_file_name()); | |
167 blk->do_oop(ik->adr_source_debug_extension()); | |
168 blk->do_oop(ik->adr_inner_classes()); | |
169 for (int i = 0; i < instanceKlass::implementors_limit; i++) { | |
170 blk->do_oop(&ik->adr_implementors()[i]); | |
171 } | |
172 blk->do_oop(ik->adr_generic_signature()); | |
173 blk->do_oop(ik->adr_class_annotations()); | |
174 blk->do_oop(ik->adr_fields_annotations()); | |
175 blk->do_oop(ik->adr_methods_annotations()); | |
176 blk->do_oop(ik->adr_methods_parameter_annotations()); | |
177 blk->do_oop(ik->adr_methods_default_annotations()); | |
178 | |
179 klassKlass::oop_oop_iterate(obj, blk); | |
180 | |
181 if(ik->oop_map_cache() != NULL) ik->oop_map_cache()->oop_iterate(blk); | |
182 return size; | |
183 } | |
184 | |
185 int instanceKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, | |
186 MemRegion mr) { | |
187 assert(obj->is_klass(),"must be a klass"); | |
188 assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); | |
189 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
190 // Get size before changing pointers. | |
191 // Don't call size() or oop_size() since that is a virtual call. | |
192 int size = ik->object_size(); | |
193 | |
194 ik->iterate_static_fields(blk, mr); | |
195 ik->vtable()->oop_oop_iterate_m(blk, mr); | |
196 ik->itable()->oop_oop_iterate_m(blk, mr); | |
197 | |
198 oop* adr; | |
199 adr = ik->adr_array_klasses(); | |
200 if (mr.contains(adr)) blk->do_oop(adr); | |
201 adr = ik->adr_methods(); | |
202 if (mr.contains(adr)) blk->do_oop(adr); | |
203 adr = ik->adr_method_ordering(); | |
204 if (mr.contains(adr)) blk->do_oop(adr); | |
205 adr = ik->adr_local_interfaces(); | |
206 if (mr.contains(adr)) blk->do_oop(adr); | |
207 adr = ik->adr_transitive_interfaces(); | |
208 if (mr.contains(adr)) blk->do_oop(adr); | |
209 adr = ik->adr_fields(); | |
210 if (mr.contains(adr)) blk->do_oop(adr); | |
211 adr = ik->adr_constants(); | |
212 if (mr.contains(adr)) blk->do_oop(adr); | |
213 adr = ik->adr_class_loader(); | |
214 if (mr.contains(adr)) blk->do_oop(adr); | |
215 adr = ik->adr_protection_domain(); | |
216 if (mr.contains(adr)) blk->do_oop(adr); | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
217 adr = ik->adr_host_klass(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
218 if (mr.contains(adr)) blk->do_oop(adr); |
0 | 219 adr = ik->adr_signers(); |
220 if (mr.contains(adr)) blk->do_oop(adr); | |
221 adr = ik->adr_source_file_name(); | |
222 if (mr.contains(adr)) blk->do_oop(adr); | |
223 adr = ik->adr_source_debug_extension(); | |
224 if (mr.contains(adr)) blk->do_oop(adr); | |
225 adr = ik->adr_inner_classes(); | |
226 if (mr.contains(adr)) blk->do_oop(adr); | |
227 adr = ik->adr_implementors(); | |
228 for (int i = 0; i < instanceKlass::implementors_limit; i++) { | |
229 if (mr.contains(&adr[i])) blk->do_oop(&adr[i]); | |
230 } | |
231 adr = ik->adr_generic_signature(); | |
232 if (mr.contains(adr)) blk->do_oop(adr); | |
233 adr = ik->adr_class_annotations(); | |
234 if (mr.contains(adr)) blk->do_oop(adr); | |
235 adr = ik->adr_fields_annotations(); | |
236 if (mr.contains(adr)) blk->do_oop(adr); | |
237 adr = ik->adr_methods_annotations(); | |
238 if (mr.contains(adr)) blk->do_oop(adr); | |
239 adr = ik->adr_methods_parameter_annotations(); | |
240 if (mr.contains(adr)) blk->do_oop(adr); | |
241 adr = ik->adr_methods_default_annotations(); | |
242 if (mr.contains(adr)) blk->do_oop(adr); | |
243 | |
244 klassKlass::oop_oop_iterate_m(obj, blk, mr); | |
245 | |
246 if(ik->oop_map_cache() != NULL) ik->oop_map_cache()->oop_iterate(blk, mr); | |
247 return size; | |
248 } | |
249 | |
250 int instanceKlassKlass::oop_adjust_pointers(oop obj) { | |
251 assert(obj->is_klass(),"must be a klass"); | |
252 assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); | |
253 | |
254 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
255 ik->adjust_static_fields(); | |
256 ik->vtable()->oop_adjust_pointers(); | |
257 ik->itable()->oop_adjust_pointers(); | |
258 | |
259 MarkSweep::adjust_pointer(ik->adr_array_klasses()); | |
260 MarkSweep::adjust_pointer(ik->adr_methods()); | |
261 MarkSweep::adjust_pointer(ik->adr_method_ordering()); | |
262 MarkSweep::adjust_pointer(ik->adr_local_interfaces()); | |
263 MarkSweep::adjust_pointer(ik->adr_transitive_interfaces()); | |
264 MarkSweep::adjust_pointer(ik->adr_fields()); | |
265 MarkSweep::adjust_pointer(ik->adr_constants()); | |
266 MarkSweep::adjust_pointer(ik->adr_class_loader()); | |
267 MarkSweep::adjust_pointer(ik->adr_protection_domain()); | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
268 MarkSweep::adjust_pointer(ik->adr_host_klass()); |
0 | 269 MarkSweep::adjust_pointer(ik->adr_signers()); |
270 MarkSweep::adjust_pointer(ik->adr_source_file_name()); | |
271 MarkSweep::adjust_pointer(ik->adr_source_debug_extension()); | |
272 MarkSweep::adjust_pointer(ik->adr_inner_classes()); | |
273 for (int i = 0; i < instanceKlass::implementors_limit; i++) { | |
274 MarkSweep::adjust_pointer(&ik->adr_implementors()[i]); | |
275 } | |
276 MarkSweep::adjust_pointer(ik->adr_generic_signature()); | |
277 MarkSweep::adjust_pointer(ik->adr_class_annotations()); | |
278 MarkSweep::adjust_pointer(ik->adr_fields_annotations()); | |
279 MarkSweep::adjust_pointer(ik->adr_methods_annotations()); | |
280 MarkSweep::adjust_pointer(ik->adr_methods_parameter_annotations()); | |
281 MarkSweep::adjust_pointer(ik->adr_methods_default_annotations()); | |
282 | |
283 iterate_c_heap_oops(ik, &MarkSweep::adjust_root_pointer_closure); | |
284 | |
285 return klassKlass::oop_adjust_pointers(obj); | |
286 } | |
287 | |
288 #ifndef SERIALGC | |
289 void instanceKlassKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) { | |
290 assert(!pm->depth_first(), "invariant"); | |
291 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
292 ik->copy_static_fields(pm); | |
293 | |
294 oop* loader_addr = ik->adr_class_loader(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
295 if (PSScavenge::should_scavenge(loader_addr)) { |
0 | 296 pm->claim_or_forward_breadth(loader_addr); |
297 } | |
298 | |
299 oop* pd_addr = ik->adr_protection_domain(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
300 if (PSScavenge::should_scavenge(pd_addr)) { |
0 | 301 pm->claim_or_forward_breadth(pd_addr); |
302 } | |
303 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
304 oop* hk_addr = ik->adr_host_klass(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
305 if (PSScavenge::should_scavenge(hk_addr)) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
306 pm->claim_or_forward_breadth(hk_addr); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
307 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
308 |
0 | 309 oop* sg_addr = ik->adr_signers(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
310 if (PSScavenge::should_scavenge(sg_addr)) { |
0 | 311 pm->claim_or_forward_breadth(sg_addr); |
312 } | |
313 | |
314 klassKlass::oop_copy_contents(pm, obj); | |
315 } | |
316 | |
317 void instanceKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { | |
318 assert(pm->depth_first(), "invariant"); | |
319 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
320 ik->push_static_fields(pm); | |
321 | |
322 oop* loader_addr = ik->adr_class_loader(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
323 if (PSScavenge::should_scavenge(loader_addr)) { |
0 | 324 pm->claim_or_forward_depth(loader_addr); |
325 } | |
326 | |
327 oop* pd_addr = ik->adr_protection_domain(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
328 if (PSScavenge::should_scavenge(pd_addr)) { |
0 | 329 pm->claim_or_forward_depth(pd_addr); |
330 } | |
331 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
332 oop* hk_addr = ik->adr_host_klass(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
333 if (PSScavenge::should_scavenge(hk_addr)) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
334 pm->claim_or_forward_depth(hk_addr); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
335 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
336 |
0 | 337 oop* sg_addr = ik->adr_signers(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
338 if (PSScavenge::should_scavenge(sg_addr)) { |
0 | 339 pm->claim_or_forward_depth(sg_addr); |
340 } | |
341 | |
342 klassKlass::oop_copy_contents(pm, obj); | |
343 } | |
344 | |
345 int instanceKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { | |
346 assert(obj->is_klass(),"must be a klass"); | |
347 assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), | |
348 "must be instance klass"); | |
349 | |
350 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
351 ik->update_static_fields(); | |
352 ik->vtable()->oop_update_pointers(cm); | |
353 ik->itable()->oop_update_pointers(cm); | |
354 | |
355 oop* const beg_oop = ik->oop_block_beg(); | |
356 oop* const end_oop = ik->oop_block_end(); | |
357 for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) { | |
358 PSParallelCompact::adjust_pointer(cur_oop); | |
359 } | |
360 | |
361 OopClosure* closure = PSParallelCompact::adjust_root_pointer_closure(); | |
362 iterate_c_heap_oops(ik, closure); | |
363 | |
364 klassKlass::oop_update_pointers(cm, obj); | |
365 return ik->object_size(); | |
366 } | |
367 | |
368 int instanceKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj, | |
369 HeapWord* beg_addr, | |
370 HeapWord* end_addr) { | |
371 assert(obj->is_klass(),"must be a klass"); | |
372 assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), | |
373 "must be instance klass"); | |
374 | |
375 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
376 ik->update_static_fields(beg_addr, end_addr); | |
377 ik->vtable()->oop_update_pointers(cm, beg_addr, end_addr); | |
378 ik->itable()->oop_update_pointers(cm, beg_addr, end_addr); | |
379 | |
380 oop* const beg_oop = MAX2((oop*)beg_addr, ik->oop_block_beg()); | |
381 oop* const end_oop = MIN2((oop*)end_addr, ik->oop_block_end()); | |
382 for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) { | |
383 PSParallelCompact::adjust_pointer(cur_oop); | |
384 } | |
385 | |
386 // The oop_map_cache, jni_ids and jni_id_map are allocated from the C heap, | |
387 // and so don't lie within any 'Chunk' boundaries. Update them when the | |
388 // lowest addressed oop in the instanceKlass 'oop_block' is updated. | |
389 if (beg_oop == ik->oop_block_beg()) { | |
390 OopClosure* closure = PSParallelCompact::adjust_root_pointer_closure(); | |
391 iterate_c_heap_oops(ik, closure); | |
392 } | |
393 | |
394 klassKlass::oop_update_pointers(cm, obj, beg_addr, end_addr); | |
395 return ik->object_size(); | |
396 } | |
397 #endif // SERIALGC | |
398 | |
399 klassOop instanceKlassKlass::allocate_instance_klass(int vtable_len, int itable_len, int static_field_size, | |
400 int nonstatic_oop_map_size, ReferenceType rt, TRAPS) { | |
401 | |
402 int size = instanceKlass::object_size(align_object_offset(vtable_len) + align_object_offset(itable_len) + static_field_size + nonstatic_oop_map_size); | |
403 | |
404 // Allocation | |
405 KlassHandle h_this_klass(THREAD, as_klassOop()); | |
406 KlassHandle k; | |
407 if (rt == REF_NONE) { | |
408 // regular klass | |
409 instanceKlass o; | |
410 k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL); | |
411 } else { | |
412 // reference klass | |
413 instanceRefKlass o; | |
414 k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL); | |
415 } | |
416 { | |
417 No_Safepoint_Verifier no_safepoint; // until k becomes parsable | |
418 instanceKlass* ik = (instanceKlass*) k()->klass_part(); | |
419 assert(!k()->is_parsable(), "not expecting parsability yet."); | |
420 | |
421 // The sizes of these these three variables are used for determining the | |
422 // size of the instanceKlassOop. It is critical that these are set to the right | |
423 // sizes before the first GC, i.e., when we allocate the mirror. | |
424 ik->set_vtable_length(vtable_len); | |
425 ik->set_itable_length(itable_len); | |
426 ik->set_static_field_size(static_field_size); | |
427 ik->set_nonstatic_oop_map_size(nonstatic_oop_map_size); | |
428 assert(k()->size() == size, "wrong size for object"); | |
429 | |
430 ik->set_array_klasses(NULL); | |
431 ik->set_methods(NULL); | |
432 ik->set_method_ordering(NULL); | |
433 ik->set_local_interfaces(NULL); | |
434 ik->set_transitive_interfaces(NULL); | |
435 ik->init_implementor(); | |
436 ik->set_fields(NULL); | |
437 ik->set_constants(NULL); | |
438 ik->set_class_loader(NULL); | |
439 ik->set_protection_domain(NULL); | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
440 ik->set_host_klass(NULL); |
0 | 441 ik->set_signers(NULL); |
442 ik->set_source_file_name(NULL); | |
443 ik->set_source_debug_extension(NULL); | |
444 ik->set_inner_classes(NULL); | |
445 ik->set_static_oop_field_size(0); | |
446 ik->set_nonstatic_field_size(0); | |
447 ik->set_is_marked_dependent(false); | |
448 ik->set_init_state(instanceKlass::allocated); | |
449 ik->set_init_thread(NULL); | |
450 ik->set_reference_type(rt); | |
451 ik->set_oop_map_cache(NULL); | |
452 ik->set_jni_ids(NULL); | |
453 ik->set_osr_nmethods_head(NULL); | |
454 ik->set_breakpoints(NULL); | |
455 ik->init_previous_versions(); | |
456 ik->set_generic_signature(NULL); | |
457 ik->release_set_methods_jmethod_ids(NULL); | |
458 ik->release_set_methods_cached_itable_indices(NULL); | |
459 ik->set_class_annotations(NULL); | |
460 ik->set_fields_annotations(NULL); | |
461 ik->set_methods_annotations(NULL); | |
462 ik->set_methods_parameter_annotations(NULL); | |
463 ik->set_methods_default_annotations(NULL); | |
464 ik->set_enclosing_method_indices(0, 0); | |
465 ik->set_jvmti_cached_class_field_map(NULL); | |
466 ik->set_initial_method_idnum(0); | |
467 assert(k()->is_parsable(), "should be parsable here."); | |
468 | |
469 // initialize the non-header words to zero | |
470 intptr_t* p = (intptr_t*)k(); | |
471 for (int index = instanceKlass::header_size(); index < size; index++) { | |
472 p[index] = NULL_WORD; | |
473 } | |
474 | |
475 // To get verify to work - must be set to partial loaded before first GC point. | |
476 k()->set_partially_loaded(); | |
477 } | |
478 | |
479 // GC can happen here | |
480 java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror | |
481 return k(); | |
482 } | |
483 | |
484 | |
485 | |
486 #ifndef PRODUCT | |
487 | |
488 // Printing | |
489 | |
490 static const char* state_names[] = { | |
491 "unparseable_by_gc", "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error" | |
492 }; | |
493 | |
494 | |
495 void instanceKlassKlass::oop_print_on(oop obj, outputStream* st) { | |
496 assert(obj->is_klass(), "must be klass"); | |
497 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
498 klassKlass::oop_print_on(obj, st); | |
499 | |
500 st->print(" - instance size: %d", ik->size_helper()); st->cr(); | |
501 st->print(" - klass size: %d", ik->object_size()); st->cr(); | |
502 st->print(" - access: "); ik->access_flags().print_on(st); st->cr(); | |
503 st->print(" - state: "); st->print_cr(state_names[ik->_init_state]); | |
504 st->print(" - name: "); ik->name()->print_value_on(st); st->cr(); | |
505 st->print(" - super: "); ik->super()->print_value_on(st); st->cr(); | |
506 st->print(" - sub: "); | |
507 Klass* sub = ik->subklass(); | |
508 int n; | |
509 for (n = 0; sub != NULL; n++, sub = sub->next_sibling()) { | |
510 if (n < MaxSubklassPrintSize) { | |
511 sub->as_klassOop()->print_value_on(st); | |
512 st->print(" "); | |
513 } | |
514 } | |
515 if (n >= MaxSubklassPrintSize) st->print("(%d more klasses...)", n - MaxSubklassPrintSize); | |
516 st->cr(); | |
517 | |
518 if (ik->is_interface()) { | |
519 st->print_cr(" - nof implementors: %d", ik->nof_implementors()); | |
520 int print_impl = 0; | |
521 for (int i = 0; i < instanceKlass::implementors_limit; i++) { | |
522 if (ik->implementor(i) != NULL) { | |
523 if (++print_impl == 1) | |
524 st->print_cr(" - implementor: "); | |
525 st->print(" "); | |
526 ik->implementor(i)->print_value_on(st); | |
527 } | |
528 } | |
529 if (print_impl > 0) st->cr(); | |
530 } | |
531 | |
532 st->print(" - arrays: "); ik->array_klasses()->print_value_on(st); st->cr(); | |
533 st->print(" - methods: "); ik->methods()->print_value_on(st); st->cr(); | |
534 if (Verbose) { | |
535 objArrayOop methods = ik->methods(); | |
536 for(int i = 0; i < methods->length(); i++) { | |
537 tty->print("%d : ", i); methods->obj_at(i)->print_value(); tty->cr(); | |
538 } | |
539 } | |
540 st->print(" - method ordering: "); ik->method_ordering()->print_value_on(st); st->cr(); | |
541 st->print(" - local interfaces: "); ik->local_interfaces()->print_value_on(st); st->cr(); | |
542 st->print(" - trans. interfaces: "); ik->transitive_interfaces()->print_value_on(st); st->cr(); | |
543 st->print(" - constants: "); ik->constants()->print_value_on(st); st->cr(); | |
544 st->print(" - class loader: "); ik->class_loader()->print_value_on(st); st->cr(); | |
545 st->print(" - protection domain: "); ik->protection_domain()->print_value_on(st); st->cr(); | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
546 st->print(" - host class: "); ik->host_klass()->print_value_on(st); st->cr(); |
0 | 547 st->print(" - signers: "); ik->signers()->print_value_on(st); st->cr(); |
548 if (ik->source_file_name() != NULL) { | |
549 st->print(" - source file: "); | |
550 ik->source_file_name()->print_value_on(st); | |
551 st->cr(); | |
552 } | |
553 if (ik->source_debug_extension() != NULL) { | |
554 st->print(" - source debug extension: "); | |
555 ik->source_debug_extension()->print_value_on(st); | |
556 st->cr(); | |
557 } | |
558 | |
559 st->print_cr(" - previous version: "); | |
560 { | |
561 ResourceMark rm; | |
562 // PreviousVersionInfo objects returned via PreviousVersionWalker | |
563 // contain a GrowableArray of handles. We have to clean up the | |
564 // GrowableArray _after_ the PreviousVersionWalker destructor | |
565 // has destroyed the handles. | |
566 { | |
567 PreviousVersionWalker pvw(ik); | |
568 for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); | |
569 pv_info != NULL; pv_info = pvw.next_previous_version()) { | |
570 pv_info->prev_constant_pool_handle()()->print_value_on(st); | |
571 } | |
572 st->cr(); | |
573 } // pvw is cleaned up | |
574 } // rm is cleaned up | |
575 | |
576 if (ik->generic_signature() != NULL) { | |
577 st->print(" - generic signature: "); | |
578 ik->generic_signature()->print_value_on(st); | |
579 } | |
580 st->print(" - inner classes: "); ik->inner_classes()->print_value_on(st); st->cr(); | |
581 st->print(" - java mirror: "); ik->java_mirror()->print_value_on(st); st->cr(); | |
582 st->print(" - vtable length %d (start addr: " INTPTR_FORMAT ")", ik->vtable_length(), ik->start_of_vtable()); st->cr(); | |
583 st->print(" - itable length %d (start addr: " INTPTR_FORMAT ")", ik->itable_length(), ik->start_of_itable()); st->cr(); | |
584 st->print_cr(" - static fields:"); | |
585 FieldPrinter print_static_field(st); | |
586 ik->do_local_static_fields(&print_static_field); | |
587 st->print_cr(" - non-static fields:"); | |
588 FieldPrinter print_nonstatic_field(st, obj); | |
589 ik->do_nonstatic_fields(&print_nonstatic_field); | |
590 | |
591 st->print(" - static oop maps: "); | |
592 if (ik->static_oop_field_size() > 0) { | |
593 int first_offset = ik->offset_of_static_fields(); | |
594 st->print("%d-%d", first_offset, first_offset + ik->static_oop_field_size() - 1); | |
595 } | |
596 st->cr(); | |
597 | |
598 st->print(" - non-static oop maps: "); | |
599 OopMapBlock* map = ik->start_of_nonstatic_oop_maps(); | |
600 OopMapBlock* end_map = map + ik->nonstatic_oop_map_size(); | |
601 while (map < end_map) { | |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
113
diff
changeset
|
602 st->print("%d-%d ", map->offset(), map->offset() + heapOopSize*(map->length() - 1)); |
0 | 603 map++; |
604 } | |
605 st->cr(); | |
606 } | |
607 | |
608 | |
609 void instanceKlassKlass::oop_print_value_on(oop obj, outputStream* st) { | |
610 assert(obj->is_klass(), "must be klass"); | |
611 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
612 ik->name()->print_value_on(st); | |
613 } | |
614 | |
615 #endif // PRODUCT | |
616 | |
617 const char* instanceKlassKlass::internal_name() const { | |
618 return "{instance class}"; | |
619 } | |
620 | |
621 // Verification | |
622 | |
623 class VerifyFieldClosure: public OopClosure { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
624 protected: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
625 template <class T> void do_oop_work(T* p) { |
0 | 626 guarantee(Universe::heap()->is_in(p), "should be in heap"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
627 oop obj = oopDesc::load_decode_heap_oop(p); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
628 guarantee(obj->is_oop_or_null(), "should be in heap"); |
0 | 629 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
630 public: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
631 virtual void do_oop(oop* p) { VerifyFieldClosure::do_oop_work(p); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
632 virtual void do_oop(narrowOop* p) { VerifyFieldClosure::do_oop_work(p); } |
0 | 633 }; |
634 | |
635 void instanceKlassKlass::oop_verify_on(oop obj, outputStream* st) { | |
636 klassKlass::oop_verify_on(obj, st); | |
637 if (!obj->partially_loaded()) { | |
638 Thread *thread = Thread::current(); | |
639 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
640 | |
641 #ifndef PRODUCT | |
642 // Avoid redundant verifies | |
643 if (ik->_verify_count == Universe::verify_count()) return; | |
644 ik->_verify_count = Universe::verify_count(); | |
645 #endif | |
646 // Verify that klass is present in SystemDictionary | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
647 if (ik->is_loaded() && !ik->is_anonymous()) { |
0 | 648 symbolHandle h_name (thread, ik->name()); |
649 Handle h_loader (thread, ik->class_loader()); | |
650 Handle h_obj(thread, obj); | |
651 SystemDictionary::verify_obj_klass_present(h_obj, h_name, h_loader); | |
652 } | |
653 | |
654 // Verify static fields | |
655 VerifyFieldClosure blk; | |
656 ik->iterate_static_fields(&blk); | |
657 | |
658 // Verify vtables | |
659 if (ik->is_linked()) { | |
660 ResourceMark rm(thread); | |
661 // $$$ This used to be done only for m/s collections. Doing it | |
662 // always seemed a valid generalization. (DLD -- 6/00) | |
663 ik->vtable()->verify(st); | |
664 } | |
665 | |
666 // Verify oop map cache | |
667 if (ik->oop_map_cache() != NULL) { | |
668 ik->oop_map_cache()->verify(); | |
669 } | |
670 | |
671 // Verify first subklass | |
672 if (ik->subklass_oop() != NULL) { | |
673 guarantee(ik->subklass_oop()->is_perm(), "should be in permspace"); | |
674 guarantee(ik->subklass_oop()->is_klass(), "should be klass"); | |
675 } | |
676 | |
677 // Verify siblings | |
678 klassOop super = ik->super(); | |
679 Klass* sib = ik->next_sibling(); | |
680 int sib_count = 0; | |
681 while (sib != NULL) { | |
682 if (sib == ik) { | |
683 fatal1("subclass cycle of length %d", sib_count); | |
684 } | |
685 if (sib_count >= 100000) { | |
686 fatal1("suspiciously long subclass list %d", sib_count); | |
687 } | |
688 guarantee(sib->as_klassOop()->is_klass(), "should be klass"); | |
689 guarantee(sib->as_klassOop()->is_perm(), "should be in permspace"); | |
690 guarantee(sib->super() == super, "siblings should have same superklass"); | |
691 sib = sib->next_sibling(); | |
692 } | |
693 | |
694 // Verify implementor fields | |
695 bool saw_null_impl = false; | |
696 for (int i = 0; i < instanceKlass::implementors_limit; i++) { | |
697 klassOop im = ik->implementor(i); | |
698 if (im == NULL) { saw_null_impl = true; continue; } | |
699 guarantee(!saw_null_impl, "non-nulls must preceded all nulls"); | |
700 guarantee(ik->is_interface(), "only interfaces should have implementor set"); | |
701 guarantee(i < ik->nof_implementors(), "should only have one implementor"); | |
702 guarantee(im->is_perm(), "should be in permspace"); | |
703 guarantee(im->is_klass(), "should be klass"); | |
704 guarantee(!Klass::cast(klassOop(im))->is_interface(), "implementors cannot be interfaces"); | |
705 } | |
706 | |
707 // Verify local interfaces | |
708 objArrayOop local_interfaces = ik->local_interfaces(); | |
709 guarantee(local_interfaces->is_perm(), "should be in permspace"); | |
710 guarantee(local_interfaces->is_objArray(), "should be obj array"); | |
711 int j; | |
712 for (j = 0; j < local_interfaces->length(); j++) { | |
713 oop e = local_interfaces->obj_at(j); | |
714 guarantee(e->is_klass() && Klass::cast(klassOop(e))->is_interface(), "invalid local interface"); | |
715 } | |
716 | |
717 // Verify transitive interfaces | |
718 objArrayOop transitive_interfaces = ik->transitive_interfaces(); | |
719 guarantee(transitive_interfaces->is_perm(), "should be in permspace"); | |
720 guarantee(transitive_interfaces->is_objArray(), "should be obj array"); | |
721 for (j = 0; j < transitive_interfaces->length(); j++) { | |
722 oop e = transitive_interfaces->obj_at(j); | |
723 guarantee(e->is_klass() && Klass::cast(klassOop(e))->is_interface(), "invalid transitive interface"); | |
724 } | |
725 | |
726 // Verify methods | |
727 objArrayOop methods = ik->methods(); | |
728 guarantee(methods->is_perm(), "should be in permspace"); | |
729 guarantee(methods->is_objArray(), "should be obj array"); | |
730 for (j = 0; j < methods->length(); j++) { | |
731 guarantee(methods->obj_at(j)->is_method(), "non-method in methods array"); | |
732 } | |
733 for (j = 0; j < methods->length() - 1; j++) { | |
734 methodOop m1 = methodOop(methods->obj_at(j)); | |
735 methodOop m2 = methodOop(methods->obj_at(j + 1)); | |
736 guarantee(m1->name()->fast_compare(m2->name()) <= 0, "methods not sorted correctly"); | |
737 } | |
738 | |
739 // Verify method ordering | |
740 typeArrayOop method_ordering = ik->method_ordering(); | |
741 guarantee(method_ordering->is_perm(), "should be in permspace"); | |
742 guarantee(method_ordering->is_typeArray(), "should be type array"); | |
743 int length = method_ordering->length(); | |
744 if (JvmtiExport::can_maintain_original_method_order()) { | |
745 guarantee(length == methods->length(), "invalid method ordering length"); | |
746 jlong sum = 0; | |
747 for (j = 0; j < length; j++) { | |
748 int original_index = method_ordering->int_at(j); | |
749 guarantee(original_index >= 0 && original_index < length, "invalid method ordering index"); | |
750 sum += original_index; | |
751 } | |
752 // Verify sum of indices 0,1,...,length-1 | |
753 guarantee(sum == ((jlong)length*(length-1))/2, "invalid method ordering sum"); | |
754 } else { | |
755 guarantee(length == 0, "invalid method ordering length"); | |
756 } | |
757 | |
758 // Verify JNI static field identifiers | |
759 if (ik->jni_ids() != NULL) { | |
760 ik->jni_ids()->verify(ik->as_klassOop()); | |
761 } | |
762 | |
763 // Verify other fields | |
764 if (ik->array_klasses() != NULL) { | |
765 guarantee(ik->array_klasses()->is_perm(), "should be in permspace"); | |
766 guarantee(ik->array_klasses()->is_klass(), "should be klass"); | |
767 } | |
768 guarantee(ik->fields()->is_perm(), "should be in permspace"); | |
769 guarantee(ik->fields()->is_typeArray(), "should be type array"); | |
770 guarantee(ik->constants()->is_perm(), "should be in permspace"); | |
771 guarantee(ik->constants()->is_constantPool(), "should be constant pool"); | |
772 guarantee(ik->inner_classes()->is_perm(), "should be in permspace"); | |
773 guarantee(ik->inner_classes()->is_typeArray(), "should be type array"); | |
774 if (ik->source_file_name() != NULL) { | |
775 guarantee(ik->source_file_name()->is_perm(), "should be in permspace"); | |
776 guarantee(ik->source_file_name()->is_symbol(), "should be symbol"); | |
777 } | |
778 if (ik->source_debug_extension() != NULL) { | |
779 guarantee(ik->source_debug_extension()->is_perm(), "should be in permspace"); | |
780 guarantee(ik->source_debug_extension()->is_symbol(), "should be symbol"); | |
781 } | |
782 if (ik->protection_domain() != NULL) { | |
783 guarantee(ik->protection_domain()->is_oop(), "should be oop"); | |
784 } | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
785 if (ik->host_klass() != NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
786 guarantee(ik->host_klass()->is_oop(), "should be oop"); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
787 } |
0 | 788 if (ik->signers() != NULL) { |
789 guarantee(ik->signers()->is_objArray(), "should be obj array"); | |
790 } | |
791 if (ik->generic_signature() != NULL) { | |
792 guarantee(ik->generic_signature()->is_perm(), "should be in permspace"); | |
793 guarantee(ik->generic_signature()->is_symbol(), "should be symbol"); | |
794 } | |
795 if (ik->class_annotations() != NULL) { | |
796 guarantee(ik->class_annotations()->is_typeArray(), "should be type array"); | |
797 } | |
798 if (ik->fields_annotations() != NULL) { | |
799 guarantee(ik->fields_annotations()->is_objArray(), "should be obj array"); | |
800 } | |
801 if (ik->methods_annotations() != NULL) { | |
802 guarantee(ik->methods_annotations()->is_objArray(), "should be obj array"); | |
803 } | |
804 if (ik->methods_parameter_annotations() != NULL) { | |
805 guarantee(ik->methods_parameter_annotations()->is_objArray(), "should be obj array"); | |
806 } | |
807 if (ik->methods_default_annotations() != NULL) { | |
808 guarantee(ik->methods_default_annotations()->is_objArray(), "should be obj array"); | |
809 } | |
810 } | |
811 } | |
812 | |
813 | |
814 bool instanceKlassKlass::oop_partially_loaded(oop obj) const { | |
815 assert(obj->is_klass(), "object must be klass"); | |
816 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
817 assert(ik->oop_is_instance(), "object must be instanceKlass"); | |
818 return ik->transitive_interfaces() == (objArrayOop) obj; // Check whether transitive_interfaces points to self | |
819 } | |
820 | |
821 | |
822 // The transitive_interfaces is the last field set when loading an object. | |
823 void instanceKlassKlass::oop_set_partially_loaded(oop obj) { | |
824 assert(obj->is_klass(), "object must be klass"); | |
825 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); | |
826 // Set the layout helper to a place-holder value, until fuller initialization. | |
827 // (This allows asserts in oop_is_instance to succeed.) | |
828 ik->set_layout_helper(Klass::instance_layout_helper(0, true)); | |
829 assert(ik->oop_is_instance(), "object must be instanceKlass"); | |
830 assert(ik->transitive_interfaces() == NULL, "just checking"); | |
831 ik->set_transitive_interfaces((objArrayOop) obj); // Temporarily set transitive_interfaces to point to self | |
832 } |