Mercurial > hg > truffle
comparison src/share/vm/ci/ciInstanceKlass.cpp @ 3938:e6b1331a51d2
7086585: make Java field injection more flexible
Reviewed-by: jrose, twisti, kvn, coleenp
author | never |
---|---|
date | Sat, 10 Sep 2011 17:29:02 -0700 |
parents | c7f3d0b4570f |
children | 04b9a2566eec 52b5d32fbfaf |
comparison
equal
deleted
inserted
replaced
3937:c565834fb592 | 3938:e6b1331a51d2 |
---|---|
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 |