src/share/vm/oops/constantPoolKlass.cpp

Sun, 13 Apr 2008 17:43:42 -0400

author
coleenp
date
Sun, 13 Apr 2008 17:43:42 -0400
changeset 548
ba764ed4b6f2
parent 435
a61af66fc99e
child 631
d1605aabd0a1
permissions
-rw-r--r--

6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv
Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold

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

mercurial