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