29 #include "ci/ciUtilities.hpp" |
29 #include "ci/ciUtilities.hpp" |
30 #include "classfile/systemDictionary.hpp" |
30 #include "classfile/systemDictionary.hpp" |
31 #include "memory/allocation.hpp" |
31 #include "memory/allocation.hpp" |
32 #include "memory/allocation.inline.hpp" |
32 #include "memory/allocation.inline.hpp" |
33 #include "oops/oop.inline.hpp" |
33 #include "oops/oop.inline.hpp" |
|
34 #include "oops/fieldStreams.hpp" |
34 #include "runtime/fieldDescriptor.hpp" |
35 #include "runtime/fieldDescriptor.hpp" |
35 |
36 |
36 // ciInstanceKlass |
37 // ciInstanceKlass |
37 // |
38 // |
38 // This class represents a klassOop in the HotSpot virtual machine |
39 // This class represents a klassOop in the HotSpot virtual machine |
410 GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() { |
411 GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() { |
411 if (_non_static_fields == NULL) { |
412 if (_non_static_fields == NULL) { |
412 VM_ENTRY_MARK; |
413 VM_ENTRY_MARK; |
413 ciEnv* curEnv = ciEnv::current(); |
414 ciEnv* curEnv = ciEnv::current(); |
414 instanceKlass* ik = get_instanceKlass(); |
415 instanceKlass* ik = get_instanceKlass(); |
415 int max_n_fields = ik->fields()->length()/instanceKlass::next_offset; |
416 int max_n_fields = ik->java_fields_count(); |
416 |
417 |
417 Arena* arena = curEnv->arena(); |
418 Arena* arena = curEnv->arena(); |
418 _non_static_fields = |
419 _non_static_fields = |
419 new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL); |
420 new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL); |
420 NonStaticFieldFiller filler(curEnv, _non_static_fields); |
421 NonStaticFieldFiller filler(curEnv, _non_static_fields); |
474 int flen = fields->length(); |
475 int flen = fields->length(); |
475 |
476 |
476 // Now sort them by offset, ascending. |
477 // Now sort them by offset, ascending. |
477 // (In principle, they could mix with superclass fields.) |
478 // (In principle, they could mix with superclass fields.) |
478 fields->sort(sort_field_by_offset); |
479 fields->sort(sort_field_by_offset); |
479 #ifdef ASSERT |
|
480 int last_offset = instanceOopDesc::base_offset_in_bytes(); |
|
481 for (int i = 0; i < fields->length(); i++) { |
|
482 ciField* field = fields->at(i); |
|
483 int offset = field->offset_in_bytes(); |
|
484 int size = (field->_type == NULL) ? heapOopSize : field->size_in_bytes(); |
|
485 assert(last_offset <= offset, err_msg("no field overlap: %d <= %d", last_offset, offset)); |
|
486 if (last_offset > (int)sizeof(oopDesc)) |
|
487 assert((offset - last_offset) < BytesPerLong, "no big holes"); |
|
488 // Note: Two consecutive T_BYTE fields will be separated by wordSize-1 |
|
489 // padding bytes if one of them is declared by a superclass. |
|
490 // This is a minor inefficiency classFileParser.cpp. |
|
491 last_offset = offset + size; |
|
492 } |
|
493 assert(last_offset <= (int)instanceOopDesc::base_offset_in_bytes() + fsize, "no overflow"); |
|
494 #endif |
|
495 |
|
496 _nonstatic_fields = fields; |
480 _nonstatic_fields = fields; |
497 return flen; |
481 return flen; |
498 } |
482 } |
499 |
483 |
500 GrowableArray<ciField*>* |
484 GrowableArray<ciField*>* |
503 ASSERT_IN_VM; |
487 ASSERT_IN_VM; |
504 Arena* arena = CURRENT_ENV->arena(); |
488 Arena* arena = CURRENT_ENV->arena(); |
505 int flen = 0; |
489 int flen = 0; |
506 GrowableArray<ciField*>* fields = NULL; |
490 GrowableArray<ciField*>* fields = NULL; |
507 instanceKlass* k = get_instanceKlass(); |
491 instanceKlass* k = get_instanceKlass(); |
508 typeArrayOop fields_array = k->fields(); |
492 for (JavaFieldStream fs(k); !fs.done(); fs.next()) { |
509 for (int pass = 0; pass <= 1; pass++) { |
493 if (fs.access_flags().is_static()) continue; |
510 for (int i = 0, alen = fields_array->length(); i < alen; i += instanceKlass::next_offset) { |
494 flen += 1; |
511 fieldDescriptor fd; |
495 } |
512 fd.initialize(k->as_klassOop(), i); |
496 |
513 if (fd.is_static()) continue; |
497 // allocate the array: |
514 if (pass == 0) { |
498 if (flen == 0) { |
515 flen += 1; |
499 return NULL; // return nothing if none are locally declared |
516 } else { |
500 } |
517 ciField* field = new (arena) ciField(&fd); |
501 if (super_fields != NULL) { |
518 fields->append(field); |
502 flen += super_fields->length(); |
519 } |
503 } |
520 } |
504 fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL); |
521 |
505 if (super_fields != NULL) { |
522 // Between passes, allocate the array: |
506 fields->appendAll(super_fields); |
523 if (pass == 0) { |
507 } |
524 if (flen == 0) { |
508 |
525 return NULL; // return nothing if none are locally declared |
509 for (JavaFieldStream fs(k); !fs.done(); fs.next()) { |
526 } |
510 if (fs.access_flags().is_static()) continue; |
527 if (super_fields != NULL) { |
511 fieldDescriptor fd; |
528 flen += super_fields->length(); |
512 fd.initialize(k->as_klassOop(), fs.index()); |
529 } |
513 ciField* field = new (arena) ciField(&fd); |
530 fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL); |
514 fields->append(field); |
531 if (super_fields != NULL) { |
|
532 fields->appendAll(super_fields); |
|
533 } |
|
534 } |
|
535 } |
515 } |
536 assert(fields->length() == flen, "sanity"); |
516 assert(fields->length() == flen, "sanity"); |
537 return fields; |
517 return fields; |
538 } |
518 } |
539 |
519 |