Mercurial > hg > graal-compiler
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. |