Mercurial > hg > truffle
annotate src/share/vm/oops/instanceKlassKlass.cpp @ 487:80206b8a9128
6758234: if (k cond (a ? : b: c)) returns reversed answer if k is constant and b and c are longs
Reviewed-by: kvn, jrose
author | never |
---|---|
date | Fri, 12 Dec 2008 19:55:26 -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 } |