0
|
1 /*
|
|
2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
|
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/_constantPoolKlass.cpp.incl"
|
|
27
|
|
28 constantPoolOop constantPoolKlass::allocate(int length, TRAPS) {
|
|
29 int size = constantPoolOopDesc::object_size(length);
|
|
30 KlassHandle klass (THREAD, as_klassOop());
|
|
31 constantPoolOop c =
|
|
32 (constantPoolOop)CollectedHeap::permanent_array_allocate(klass, size, length, CHECK_NULL);
|
|
33
|
|
34 c->set_tags(NULL);
|
|
35 c->set_cache(NULL);
|
|
36 c->set_pool_holder(NULL);
|
|
37 // only set to non-zero if constant pool is merged by RedefineClasses
|
|
38 c->set_orig_length(0);
|
|
39 // all fields are initialized; needed for GC
|
|
40
|
|
41 // initialize tag array
|
|
42 // Note: cannot introduce constant pool handle before since it is not
|
|
43 // completely initialized (no class) -> would cause assertion failure
|
|
44 constantPoolHandle pool (THREAD, c);
|
|
45 typeArrayOop t_oop = oopFactory::new_permanent_byteArray(length, CHECK_NULL);
|
|
46 typeArrayHandle tags (THREAD, t_oop);
|
|
47 for (int index = 0; index < length; index++) {
|
|
48 tags()->byte_at_put(index, JVM_CONSTANT_Invalid);
|
|
49 }
|
|
50 pool->set_tags(tags());
|
|
51
|
|
52 return pool();
|
|
53 }
|
|
54
|
|
55 klassOop constantPoolKlass::create_klass(TRAPS) {
|
|
56 constantPoolKlass o;
|
|
57 KlassHandle klassklass(THREAD, Universe::arrayKlassKlassObj());
|
|
58 arrayKlassHandle k = base_create_array_klass(o.vtbl_value(), header_size(), klassklass, CHECK_NULL);
|
|
59 arrayKlassHandle super (THREAD, k->super());
|
|
60 complete_create_array_klass(k, super, CHECK_NULL);
|
|
61 return k();
|
|
62 }
|
|
63
|
|
64
|
|
65 int constantPoolKlass::oop_size(oop obj) const {
|
|
66 assert(obj->is_constantPool(), "must be constantPool");
|
|
67 return constantPoolOop(obj)->object_size();
|
|
68 }
|
|
69
|
|
70
|
|
71 void constantPoolKlass::oop_follow_contents(oop obj) {
|
|
72 assert (obj->is_constantPool(), "obj must be constant pool");
|
|
73 constantPoolOop cp = (constantPoolOop) obj;
|
|
74 // Performance tweak: We skip iterating over the klass pointer since we
|
|
75 // know that Universe::constantPoolKlassObj never moves.
|
|
76
|
|
77 // If the tags array is null we are in the middle of allocating this constant pool
|
|
78 if (cp->tags() != NULL) {
|
|
79 // gc of constant pool contents
|
|
80 oop* base = (oop*)cp->base();
|
|
81 for (int i = 0; i < cp->length(); i++) {
|
|
82 if (cp->is_pointer_entry(i)) {
|
|
83 if (*base != NULL) MarkSweep::mark_and_push(base);
|
|
84 }
|
|
85 base++;
|
|
86 }
|
|
87 // gc of constant pool instance variables
|
|
88 MarkSweep::mark_and_push(cp->tags_addr());
|
|
89 MarkSweep::mark_and_push(cp->cache_addr());
|
|
90 MarkSweep::mark_and_push(cp->pool_holder_addr());
|
|
91 }
|
|
92 }
|
|
93
|
|
94 #ifndef SERIALGC
|
|
95 void constantPoolKlass::oop_follow_contents(ParCompactionManager* cm,
|
|
96 oop obj) {
|
|
97 assert (obj->is_constantPool(), "obj must be constant pool");
|
|
98 constantPoolOop cp = (constantPoolOop) obj;
|
|
99 // Performance tweak: We skip iterating over the klass pointer since we
|
|
100 // know that Universe::constantPoolKlassObj never moves.
|
|
101
|
|
102 // If the tags array is null we are in the middle of allocating this constant
|
|
103 // pool.
|
|
104 if (cp->tags() != NULL) {
|
|
105 // gc of constant pool contents
|
|
106 oop* base = (oop*)cp->base();
|
|
107 for (int i = 0; i < cp->length(); i++) {
|
|
108 if (cp->is_pointer_entry(i)) {
|
|
109 if (*base != NULL) PSParallelCompact::mark_and_push(cm, base);
|
|
110 }
|
|
111 base++;
|
|
112 }
|
|
113 // gc of constant pool instance variables
|
|
114 PSParallelCompact::mark_and_push(cm, cp->tags_addr());
|
|
115 PSParallelCompact::mark_and_push(cm, cp->cache_addr());
|
|
116 PSParallelCompact::mark_and_push(cm, cp->pool_holder_addr());
|
|
117 }
|
|
118 }
|
|
119 #endif // SERIALGC
|
|
120
|
|
121
|
|
122 int constantPoolKlass::oop_adjust_pointers(oop obj) {
|
|
123 assert (obj->is_constantPool(), "obj must be constant pool");
|
|
124 constantPoolOop cp = (constantPoolOop) obj;
|
|
125 // Get size before changing pointers.
|
|
126 // Don't call size() or oop_size() since that is a virtual call.
|
|
127 int size = cp->object_size();
|
|
128 // Performance tweak: We skip iterating over the klass pointer since we
|
|
129 // know that Universe::constantPoolKlassObj never moves.
|
|
130
|
|
131 // If the tags array is null we are in the middle of allocating this constant
|
|
132 // pool.
|
|
133 if (cp->tags() != NULL) {
|
|
134 oop* base = (oop*)cp->base();
|
|
135 for (int i = 0; i< cp->length(); i++) {
|
|
136 if (cp->is_pointer_entry(i)) {
|
|
137 MarkSweep::adjust_pointer(base);
|
|
138 }
|
|
139 base++;
|
|
140 }
|
|
141 }
|
|
142 MarkSweep::adjust_pointer(cp->tags_addr());
|
|
143 MarkSweep::adjust_pointer(cp->cache_addr());
|
|
144 MarkSweep::adjust_pointer(cp->pool_holder_addr());
|
|
145 return size;
|
|
146 }
|
|
147
|
|
148
|
|
149 int constantPoolKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
|
|
150 assert (obj->is_constantPool(), "obj must be constant pool");
|
|
151 // Performance tweak: We skip iterating over the klass pointer since we
|
|
152 // know that Universe::constantPoolKlassObj never moves.
|
|
153 constantPoolOop cp = (constantPoolOop) obj;
|
|
154 // Get size before changing pointers.
|
|
155 // Don't call size() or oop_size() since that is a virtual call.
|
|
156 int size = cp->object_size();
|
|
157
|
|
158 // If the tags array is null we are in the middle of allocating this constant
|
|
159 // pool.
|
|
160 if (cp->tags() != NULL) {
|
|
161 oop* base = (oop*)cp->base();
|
|
162 for (int i = 0; i < cp->length(); i++) {
|
|
163 if (cp->is_pointer_entry(i)) {
|
|
164 blk->do_oop(base);
|
|
165 }
|
|
166 base++;
|
|
167 }
|
|
168 }
|
|
169 blk->do_oop(cp->tags_addr());
|
|
170 blk->do_oop(cp->cache_addr());
|
|
171 blk->do_oop(cp->pool_holder_addr());
|
|
172 return size;
|
|
173 }
|
|
174
|
|
175
|
|
176 int constantPoolKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
|
|
177 assert (obj->is_constantPool(), "obj must be constant pool");
|
|
178 // Performance tweak: We skip iterating over the klass pointer since we
|
|
179 // know that Universe::constantPoolKlassObj never moves.
|
|
180 constantPoolOop cp = (constantPoolOop) obj;
|
|
181 // Get size before changing pointers.
|
|
182 // Don't call size() or oop_size() since that is a virtual call.
|
|
183 int size = cp->object_size();
|
|
184
|
|
185 // If the tags array is null we are in the middle of allocating this constant
|
|
186 // pool.
|
|
187 if (cp->tags() != NULL) {
|
|
188 oop* base = (oop*)cp->base();
|
|
189 for (int i = 0; i < cp->length(); i++) {
|
|
190 if (mr.contains(base)) {
|
|
191 if (cp->is_pointer_entry(i)) {
|
|
192 blk->do_oop(base);
|
|
193 }
|
|
194 }
|
|
195 base++;
|
|
196 }
|
|
197 }
|
|
198 oop* addr;
|
|
199 addr = cp->tags_addr();
|
|
200 blk->do_oop(addr);
|
|
201 addr = cp->cache_addr();
|
|
202 blk->do_oop(addr);
|
|
203 addr = cp->pool_holder_addr();
|
|
204 blk->do_oop(addr);
|
|
205 return size;
|
|
206 }
|
|
207
|
|
208 #ifndef SERIALGC
|
|
209 int constantPoolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
|
|
210 assert (obj->is_constantPool(), "obj must be constant pool");
|
|
211 constantPoolOop cp = (constantPoolOop) obj;
|
|
212
|
|
213 // If the tags array is null we are in the middle of allocating this constant
|
|
214 // pool.
|
|
215 if (cp->tags() != NULL) {
|
|
216 oop* base = (oop*)cp->base();
|
|
217 for (int i = 0; i < cp->length(); ++i, ++base) {
|
|
218 if (cp->is_pointer_entry(i)) {
|
|
219 PSParallelCompact::adjust_pointer(base);
|
|
220 }
|
|
221 }
|
|
222 }
|
|
223 PSParallelCompact::adjust_pointer(cp->tags_addr());
|
|
224 PSParallelCompact::adjust_pointer(cp->cache_addr());
|
|
225 PSParallelCompact::adjust_pointer(cp->pool_holder_addr());
|
|
226 return cp->object_size();
|
|
227 }
|
|
228
|
|
229 int
|
|
230 constantPoolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
|
|
231 HeapWord* beg_addr, HeapWord* end_addr) {
|
|
232 assert (obj->is_constantPool(), "obj must be constant pool");
|
|
233 constantPoolOop cp = (constantPoolOop) obj;
|
|
234
|
|
235 // If the tags array is null we are in the middle of allocating this constant
|
|
236 // pool.
|
|
237 if (cp->tags() != NULL) {
|
|
238 oop* base = (oop*)cp->base();
|
|
239 oop* const beg_oop = MAX2((oop*)beg_addr, base);
|
|
240 oop* const end_oop = MIN2((oop*)end_addr, base + cp->length());
|
|
241 const size_t beg_idx = pointer_delta(beg_oop, base, sizeof(oop*));
|
|
242 const size_t end_idx = pointer_delta(end_oop, base, sizeof(oop*));
|
|
243 for (size_t cur_idx = beg_idx; cur_idx < end_idx; ++cur_idx, ++base) {
|
|
244 if (cp->is_pointer_entry(int(cur_idx))) {
|
|
245 PSParallelCompact::adjust_pointer(base);
|
|
246 }
|
|
247 }
|
|
248 }
|
|
249
|
|
250 oop* p;
|
|
251 p = cp->tags_addr();
|
|
252 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
|
|
253 p = cp->cache_addr();
|
|
254 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
|
|
255 p = cp->pool_holder_addr();
|
|
256 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
|
|
257
|
|
258 return cp->object_size();
|
|
259 }
|
|
260
|
|
261 void constantPoolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
|
|
262 assert(obj->is_constantPool(), "should be constant pool");
|
|
263 }
|
|
264
|
|
265 void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
|
|
266 assert(obj->is_constantPool(), "should be constant pool");
|
|
267 }
|
|
268 #endif // SERIALGC
|
|
269
|
|
270 #ifndef PRODUCT
|
|
271
|
|
272 // Printing
|
|
273
|
|
274 void constantPoolKlass::oop_print_on(oop obj, outputStream* st) {
|
|
275 EXCEPTION_MARK;
|
|
276 oop anObj;
|
|
277 assert(obj->is_constantPool(), "must be constantPool");
|
|
278 arrayKlass::oop_print_on(obj, st);
|
|
279 constantPoolOop cp = constantPoolOop(obj);
|
|
280
|
|
281 // Temp. remove cache so we can do lookups with original indicies.
|
|
282 constantPoolCacheHandle cache (THREAD, cp->cache());
|
|
283 cp->set_cache(NULL);
|
|
284
|
|
285 for (int index = 1; index < cp->length(); index++) { // Index 0 is unused
|
|
286 st->print(" - %3d : ", index);
|
|
287 cp->tag_at(index).print_on(st);
|
|
288 st->print(" : ");
|
|
289 switch (cp->tag_at(index).value()) {
|
|
290 case JVM_CONSTANT_Class :
|
|
291 { anObj = cp->klass_at(index, CATCH);
|
|
292 anObj->print_value_on(st);
|
|
293 st->print(" {0x%lx}", (address)anObj);
|
|
294 }
|
|
295 break;
|
|
296 case JVM_CONSTANT_Fieldref :
|
|
297 case JVM_CONSTANT_Methodref :
|
|
298 case JVM_CONSTANT_InterfaceMethodref :
|
|
299 st->print("klass_index=%d", cp->klass_ref_index_at(index));
|
|
300 st->print(" name_and_type_index=%d", cp->name_and_type_ref_index_at(index));
|
|
301 break;
|
|
302 case JVM_CONSTANT_UnresolvedString :
|
|
303 case JVM_CONSTANT_String :
|
|
304 anObj = cp->string_at(index, CATCH);
|
|
305 anObj->print_value_on(st);
|
|
306 st->print(" {0x%lx}", (address)anObj);
|
|
307 break;
|
|
308 case JVM_CONSTANT_Integer :
|
|
309 st->print("%d", cp->int_at(index));
|
|
310 break;
|
|
311 case JVM_CONSTANT_Float :
|
|
312 st->print("%f", cp->float_at(index));
|
|
313 break;
|
|
314 case JVM_CONSTANT_Long :
|
|
315 st->print_jlong(cp->long_at(index));
|
|
316 index++; // Skip entry following eigth-byte constant
|
|
317 break;
|
|
318 case JVM_CONSTANT_Double :
|
|
319 st->print("%lf", cp->double_at(index));
|
|
320 index++; // Skip entry following eigth-byte constant
|
|
321 break;
|
|
322 case JVM_CONSTANT_NameAndType :
|
|
323 st->print("name_index=%d", cp->name_ref_index_at(index));
|
|
324 st->print(" signature_index=%d", cp->signature_ref_index_at(index));
|
|
325 break;
|
|
326 case JVM_CONSTANT_Utf8 :
|
|
327 cp->symbol_at(index)->print_value_on(st);
|
|
328 break;
|
|
329 case JVM_CONSTANT_UnresolvedClass : // fall-through
|
|
330 case JVM_CONSTANT_UnresolvedClassInError: {
|
|
331 // unresolved_klass_at requires lock or safe world.
|
|
332 oop entry = *cp->obj_at_addr(index);
|
|
333 entry->print_value_on(st);
|
|
334 }
|
|
335 break;
|
|
336 default:
|
|
337 ShouldNotReachHere();
|
|
338 break;
|
|
339 }
|
|
340 st->cr();
|
|
341 }
|
|
342 st->cr();
|
|
343
|
|
344 // Restore cache
|
|
345 cp->set_cache(cache());
|
|
346 }
|
|
347
|
|
348
|
|
349 #endif
|
|
350
|
|
351 const char* constantPoolKlass::internal_name() const {
|
|
352 return "{constant pool}";
|
|
353 }
|
|
354
|
|
355 // Verification
|
|
356
|
|
357 void constantPoolKlass::oop_verify_on(oop obj, outputStream* st) {
|
|
358 Klass::oop_verify_on(obj, st);
|
|
359 guarantee(obj->is_constantPool(), "object must be constant pool");
|
|
360 constantPoolOop cp = constantPoolOop(obj);
|
|
361 guarantee(cp->is_perm(), "should be in permspace");
|
|
362 if (!cp->partially_loaded()) {
|
|
363 oop* base = (oop*)cp->base();
|
|
364 for (int i = 0; i< cp->length(); i++) {
|
|
365 if (cp->tag_at(i).is_klass()) {
|
|
366 guarantee((*base)->is_perm(), "should be in permspace");
|
|
367 guarantee((*base)->is_klass(), "should be klass");
|
|
368 }
|
|
369 if (cp->tag_at(i).is_unresolved_klass()) {
|
|
370 guarantee((*base)->is_perm(), "should be in permspace");
|
|
371 guarantee((*base)->is_symbol() || (*base)->is_klass(),
|
|
372 "should be symbol or klass");
|
|
373 }
|
|
374 if (cp->tag_at(i).is_symbol()) {
|
|
375 guarantee((*base)->is_perm(), "should be in permspace");
|
|
376 guarantee((*base)->is_symbol(), "should be symbol");
|
|
377 }
|
|
378 if (cp->tag_at(i).is_unresolved_string()) {
|
|
379 guarantee((*base)->is_perm(), "should be in permspace");
|
|
380 guarantee((*base)->is_symbol() || (*base)->is_instance(),
|
|
381 "should be symbol or instance");
|
|
382 }
|
|
383 if (cp->tag_at(i).is_string()) {
|
|
384 guarantee((*base)->is_perm(), "should be in permspace");
|
|
385 guarantee((*base)->is_instance(), "should be instance");
|
|
386 }
|
|
387 base++;
|
|
388 }
|
|
389 guarantee(cp->tags()->is_perm(), "should be in permspace");
|
|
390 guarantee(cp->tags()->is_typeArray(), "should be type array");
|
|
391 if (cp->cache() != NULL) {
|
|
392 // Note: cache() can be NULL before a class is completely setup or
|
|
393 // in temporary constant pools used during constant pool merging
|
|
394 guarantee(cp->cache()->is_perm(), "should be in permspace");
|
|
395 guarantee(cp->cache()->is_constantPoolCache(), "should be constant pool cache");
|
|
396 }
|
|
397 if (cp->pool_holder() != NULL) {
|
|
398 // Note: pool_holder() can be NULL in temporary constant pools
|
|
399 // used during constant pool merging
|
|
400 guarantee(cp->pool_holder()->is_perm(), "should be in permspace");
|
|
401 guarantee(cp->pool_holder()->is_klass(), "should be klass");
|
|
402 }
|
|
403 }
|
|
404 }
|
|
405
|
|
406 bool constantPoolKlass::oop_partially_loaded(oop obj) const {
|
|
407 assert(obj->is_constantPool(), "object must be constant pool");
|
|
408 constantPoolOop cp = constantPoolOop(obj);
|
|
409 return cp->tags() == NULL || cp->pool_holder() == (klassOop) cp; // Check whether pool holder points to self
|
|
410 }
|
|
411
|
|
412
|
|
413 void constantPoolKlass::oop_set_partially_loaded(oop obj) {
|
|
414 assert(obj->is_constantPool(), "object must be constant pool");
|
|
415 constantPoolOop cp = constantPoolOop(obj);
|
|
416 assert(cp->pool_holder() == NULL, "just checking");
|
|
417 cp->set_pool_holder((klassOop) cp); // Temporarily set pool holder to point to self
|
|
418 }
|
|
419
|
|
420 #ifndef PRODUCT
|
|
421 // CompileTheWorld support. Preload all classes loaded references in the passed in constantpool
|
|
422 void constantPoolKlass::preload_and_initialize_all_classes(oop obj, TRAPS) {
|
|
423 guarantee(obj->is_constantPool(), "object must be constant pool");
|
|
424 constantPoolHandle cp(THREAD, (constantPoolOop)obj);
|
|
425 guarantee(!cp->partially_loaded(), "must be fully loaded");
|
|
426
|
|
427 for (int i = 0; i< cp->length(); i++) {
|
|
428 if (cp->tag_at(i).is_unresolved_klass()) {
|
|
429 // This will force loading of the class
|
|
430 klassOop klass = cp->klass_at(i, CHECK);
|
|
431 if (klass->is_instance()) {
|
|
432 // Force initialization of class
|
|
433 instanceKlass::cast(klass)->initialize(CHECK);
|
|
434 }
|
|
435 }
|
|
436 }
|
|
437 }
|
|
438
|
|
439 #endif
|