comparison src/share/vm/ci/ciInstanceKlass.cpp @ 113:ba764ed4b6f2

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
author coleenp
date Sun, 13 Apr 2008 17:43:42 -0400
parents 52fed2ec0afb
children 437d03ea40b1
comparison
equal deleted inserted replaced
110:a49a647afe9a 113:ba764ed4b6f2
46 _has_subklass = ik->subklass() != NULL; 46 _has_subklass = ik->subklass() != NULL;
47 _is_initialized = ik->is_initialized(); 47 _is_initialized = ik->is_initialized();
48 // Next line must follow and use the result of the previous line: 48 // Next line must follow and use the result of the previous line:
49 _is_linked = _is_initialized || ik->is_linked(); 49 _is_linked = _is_initialized || ik->is_linked();
50 _nonstatic_field_size = ik->nonstatic_field_size(); 50 _nonstatic_field_size = ik->nonstatic_field_size();
51 _has_nonstatic_fields = ik->has_nonstatic_fields();
51 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: 52 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
52 53
53 _nof_implementors = ik->nof_implementors(); 54 _nof_implementors = ik->nof_implementors();
54 for (int i = 0; i < implementors_limit; i++) { 55 for (int i = 0; i < implementors_limit; i++) {
55 _implementors[i] = NULL; // we will fill these lazily 56 _implementors[i] = NULL; // we will fill these lazily
91 { 92 {
92 assert(name->byte_at(0) != '[', "not an instance klass"); 93 assert(name->byte_at(0) != '[', "not an instance klass");
93 _is_initialized = false; 94 _is_initialized = false;
94 _is_linked = false; 95 _is_linked = false;
95 _nonstatic_field_size = -1; 96 _nonstatic_field_size = -1;
97 _has_nonstatic_fields = false;
96 _nonstatic_fields = NULL; 98 _nonstatic_fields = NULL;
97 _nof_implementors = -1; 99 _nof_implementors = -1;
98 _loader = loader; 100 _loader = loader;
99 _protection_domain = protection_domain; 101 _protection_domain = protection_domain;
100 _is_shared = false; 102 _is_shared = false;
199 tty->print_cr(" ***"); 201 tty->print_cr(" ***");
200 }; 202 };
201 assert(offset >= 0 && offset < layout_helper(), "offset must be tame"); 203 assert(offset >= 0 && offset < layout_helper(), "offset must be tame");
202 #endif 204 #endif
203 205
204 if (offset < (instanceOopDesc::header_size() * wordSize)) { 206 if (offset < instanceOopDesc::base_offset_in_bytes()) {
205 // All header offsets belong properly to java/lang/Object. 207 // All header offsets belong properly to java/lang/Object.
206 return CURRENT_ENV->Object_klass(); 208 return CURRENT_ENV->Object_klass();
207 } 209 }
208 210
209 ciInstanceKlass* self = this; 211 ciInstanceKlass* self = this;
210 for (;;) { 212 for (;;) {
211 assert(self->is_loaded(), "must be loaded to have size"); 213 assert(self->is_loaded(), "must be loaded to have size");
212 ciInstanceKlass* super = self->super(); 214 ciInstanceKlass* super = self->super();
213 if (super == NULL || !super->contains_field_offset(offset)) { 215 if (super == NULL || super->nof_nonstatic_fields() == 0 ||
216 !super->contains_field_offset(offset)) {
214 return self; 217 return self;
215 } else { 218 } else {
216 self = super; // return super->get_canonical_holder(offset) 219 self = super; // return super->get_canonical_holder(offset)
217 } 220 }
218 } 221 }
379 assert(is_loaded(), "must be loaded"); 382 assert(is_loaded(), "must be loaded");
380 383
381 if (_nonstatic_fields != NULL) 384 if (_nonstatic_fields != NULL)
382 return _nonstatic_fields->length(); 385 return _nonstatic_fields->length();
383 386
384 // Size in bytes of my fields, including inherited fields. 387 if (!has_nonstatic_fields()) {
385 // About equal to size_helper() - sizeof(oopDesc).
386 int fsize = nonstatic_field_size() * wordSize;
387 if (fsize == 0) { // easy shortcut
388 Arena* arena = CURRENT_ENV->arena(); 388 Arena* arena = CURRENT_ENV->arena();
389 _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL); 389 _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL);
390 return 0; 390 return 0;
391 } 391 }
392 assert(!is_java_lang_Object(), "bootstrap OK"); 392 assert(!is_java_lang_Object(), "bootstrap OK");
393 393
394 // Size in bytes of my fields, including inherited fields.
395 int fsize = nonstatic_field_size() * wordSize;
396
394 ciInstanceKlass* super = this->super(); 397 ciInstanceKlass* super = this->super();
395 int super_fsize = 0;
396 int super_flen = 0;
397 GrowableArray<ciField*>* super_fields = NULL; 398 GrowableArray<ciField*>* super_fields = NULL;
398 if (super != NULL) { 399 if (super != NULL && super->has_nonstatic_fields()) {
399 super_fsize = super->nonstatic_field_size() * wordSize; 400 int super_fsize = super->nonstatic_field_size() * wordSize;
400 super_flen = super->nof_nonstatic_fields(); 401 int super_flen = super->nof_nonstatic_fields();
401 super_fields = super->_nonstatic_fields; 402 super_fields = super->_nonstatic_fields;
402 assert(super_flen == 0 || super_fields != NULL, "first get nof_fields"); 403 assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
403 } 404 // See if I am no larger than my super; if so, I can use his fields.
404 405 if (fsize == super_fsize) {
405 // See if I am no larger than my super; if so, I can use his fields. 406 _nonstatic_fields = super_fields;
406 if (fsize == super_fsize) { 407 return super_fields->length();
407 _nonstatic_fields = super_fields; 408 }
408 return super_fields->length();
409 } 409 }
410 410
411 GrowableArray<ciField*>* fields = NULL; 411 GrowableArray<ciField*>* fields = NULL;
412 GUARDED_VM_ENTRY({ 412 GUARDED_VM_ENTRY({
413 fields = compute_nonstatic_fields_impl(super_fields); 413 fields = compute_nonstatic_fields_impl(super_fields);
423 423
424 // Now sort them by offset, ascending. 424 // Now sort them by offset, ascending.
425 // (In principle, they could mix with superclass fields.) 425 // (In principle, they could mix with superclass fields.)
426 fields->sort(sort_field_by_offset); 426 fields->sort(sort_field_by_offset);
427 #ifdef ASSERT 427 #ifdef ASSERT
428 int last_offset = sizeof(oopDesc); 428 int last_offset = instanceOopDesc::base_offset_in_bytes();
429 for (int i = 0; i < fields->length(); i++) { 429 for (int i = 0; i < fields->length(); i++) {
430 ciField* field = fields->at(i); 430 ciField* field = fields->at(i);
431 int offset = field->offset_in_bytes(); 431 int offset = field->offset_in_bytes();
432 int size = (field->_type == NULL) ? oopSize : field->size_in_bytes(); 432 int size = (field->_type == NULL) ? heapOopSize : field->size_in_bytes();
433 assert(last_offset <= offset, "no field overlap"); 433 assert(last_offset <= offset, "no field overlap");
434 if (last_offset > (int)sizeof(oopDesc)) 434 if (last_offset > (int)sizeof(oopDesc))
435 assert((offset - last_offset) < BytesPerLong, "no big holes"); 435 assert((offset - last_offset) < BytesPerLong, "no big holes");
436 // Note: Two consecutive T_BYTE fields will be separated by wordSize-1 436 // Note: Two consecutive T_BYTE fields will be separated by wordSize-1
437 // padding bytes if one of them is declared by a superclass. 437 // padding bytes if one of them is declared by a superclass.