src/share/vm/ci/ciInstanceKlass.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/ci/ciInstanceKlass.cpp	Mon Feb 21 14:15:22 2011
--- new/src/share/vm/ci/ciInstanceKlass.cpp	Mon Feb 21 14:15:22 2011

*** 41,51 **** --- 41,51 ---- // ------------------------------------------------------------------ // ciInstanceKlass::ciInstanceKlass // // Loaded instance klass. ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : ! ciKlass(h_k), _non_static_fields(NULL) ! ciKlass(h_k), _nonstatic_fields(NULL) { assert(get_Klass()->oop_is_instance(), "wrong type"); assert(get_instanceKlass()->is_loaded(), "must be at least loaded"); instanceKlass* ik = get_instanceKlass();
*** 54,64 **** --- 54,64 ---- _has_finalizer = access_flags.has_finalizer(); _has_subklass = ik->subklass() != NULL; _init_state = (instanceKlass::ClassState)ik->get_init_state(); _nonstatic_field_size = ik->nonstatic_field_size(); _has_nonstatic_fields = ik->has_nonstatic_fields(); ! _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: ! _nonstatic_fields = NULL; // initialized lazily by compute_fields: _nof_implementors = ik->nof_implementors(); for (int i = 0; i < implementors_limit; i++) { _implementors[i] = NULL; // we will fill these lazily }
*** 80,94 **** --- 80,95 ---- // Lazy fields get filled in only upon request. _super = NULL; _java_mirror = NULL; if (is_shared()) { + assert(is_initialized() || is_interface(), "shared classes should be fully initialized"); if (h_k() != SystemDictionary::Object_klass()) { super(); } java_mirror(); ! //compute_nonstatic_fields(); // done outside of constructor ! //compute_fields(); // done outside of constructor } _field_cache = NULL; }
*** 205,215 **** --- 206,216 ---- ciInstanceKlass* self = this; for (;;) { assert(self->is_loaded(), "must be loaded to have size"); ciInstanceKlass* super = self->super(); ! if (super == NULL || super->nof_nonstatic_fields() == 0 || ! if (super == NULL || super->nonstatic_fields()->length() == 0 || !super->contains_field_offset(offset)) { return self; } else { self = super; // return super->get_canonical_holder(offset) }
*** 352,436 **** --- 353,416 ---- // ------------------------------------------------------------------ // ciInstanceKlass::get_field_by_offset ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) { if (!is_static) { ! for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) { ! for (int i = 0, len = nonstatic_fields()->length(); i < len; i++) { ciField* field = _nonstatic_fields->at(i); int field_off = field->offset_in_bytes(); if (field_off == field_offset) return field; if (field_off > field_offset) break; // could do binary search or check bins, but probably not worth it } return NULL; + } else { + for (int i = 0, len = static_fields()->length(); i < len; i++) { + ciField* field = _static_fields->at(i); + int field_off = field->offset_in_bytes(); + if (field_off == field_offset) + return field; + if (field_off > field_offset) + break; + // could do binary search or check bins, but probably not worth it } VM_ENTRY_MARK; instanceKlass* k = get_instanceKlass(); fieldDescriptor fd; if (!k->find_field_from_offset(field_offset, is_static, &fd)) { return NULL; } ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); return field; } // ------------------------------------------------------------------ // ciInstanceKlass::get_field_by_name ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) { VM_ENTRY_MARK; instanceKlass* k = get_instanceKlass(); ! fieldDescriptor fd; klassOop def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd); if (def == NULL) { return NULL; + if (!is_static) { + for (int i = 0, len = nonstatic_fields()->length(); i < len; i++) { ! ciField* field = _nonstatic_fields->at(i); + if (field->name() == name && field->signature() == signature) { + return field; } ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); + } + return NULL; + } else { + for (int i = 0, len = static_fields()->length(); i < len; i++) { + ciField* field = _static_fields->at(i); + if (field->name() == name && field->signature() == signature) { return field; } // ------------------------------------------------------------------ // ciInstanceKlass::non_static_fields. class NonStaticFieldFiller: public FieldClosure { GrowableArray<ciField*>* _arr; ciEnv* _curEnv; public: NonStaticFieldFiller(ciEnv* curEnv, GrowableArray<ciField*>* arr) : _curEnv(curEnv), _arr(arr) {} void do_field(fieldDescriptor* fd) { ciField* field = new (_curEnv->arena()) ciField(fd); _arr->append(field); } }; GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() { if (_non_static_fields == NULL) { VM_ENTRY_MARK; ciEnv* curEnv = ciEnv::current(); instanceKlass* ik = get_instanceKlass(); int max_n_fields = ik->fields()->length()/instanceKlass::next_offset; Arena* arena = curEnv->arena(); _non_static_fields = new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL); NonStaticFieldFiller filler(curEnv, _non_static_fields); ik->do_nonstatic_fields(&filler); } ! return _non_static_fields; ! return NULL; + } } static int sort_field_by_offset(ciField** a, ciField** b) { return (*a)->offset_in_bytes() - (*b)->offset_in_bytes(); // (no worries about 32-bit overflow...) } // ------------------------------------------------------------------ ! // ciInstanceKlass::compute_nonstatic_fields ! int ciInstanceKlass::compute_nonstatic_fields() { ! // ciInstanceKlass::compute_fields ! int ciInstanceKlass::compute_fields() { assert(is_loaded(), "must be loaded"); if (_nonstatic_fields != NULL) return _nonstatic_fields->length();
*** 440,485 **** --- 420,457 ---- return 0; } assert(!is_java_lang_Object(), "bootstrap OK"); // Size in bytes of my fields, including inherited fields. ! int fsize = nonstatic_field_size() * heapOopSize; ! int fsize = _nonstatic_field_size * heapOopSize; ciInstanceKlass* super = this->super(); GrowableArray<ciField*>* super_fields = NULL; if (super != NULL && super->has_nonstatic_fields()) { ! int super_fsize = super->nonstatic_field_size() * heapOopSize; ! int super_flen = super->nof_nonstatic_fields(); ! int super_fsize = super->_nonstatic_field_size * heapOopSize; ! int super_flen = super->nonstatic_fields()->length(); super_fields = super->_nonstatic_fields; assert(super_flen == 0 || super_fields != NULL, "first get nof_fields"); // See if I am no larger than my super; if so, I can use his fields. if (fsize == super_fsize) { _nonstatic_fields = super_fields; return super_fields->length(); } } GrowableArray<ciField*>* fields = NULL; GUARDED_VM_ENTRY({ ! fields = compute_nonstatic_fields_impl(super_fields); ! compute_fields_impl(super_fields); }); if (fields == NULL) { // This can happen if this class (java.lang.Class) has invisible fields. _nonstatic_fields = super_fields; return super_fields->length(); } int flen = fields->length(); // Now sort them by offset, ascending. // (In principle, they could mix with superclass fields.) ! _static_fields->sort(sort_field_by_offset); + _nonstatic_fields->sort(sort_field_by_offset); #ifdef ASSERT int last_offset = instanceOopDesc::base_offset_in_bytes(); ! for (int i = 0; i < _nonstatic_fields->length(); i++) { ! ciField* field = _nonstatic_fields->at(i); int offset = field->offset_in_bytes(); int size = (field->_type == NULL) ? heapOopSize : field->size_in_bytes(); assert(last_offset <= offset, err_msg("no field overlap: %d <= %d", last_offset, offset)); if (last_offset > (int)sizeof(oopDesc)) assert((offset - last_offset) < BytesPerLong, "no big holes");
*** 489,540 **** --- 461,519 ---- last_offset = offset + size; } assert(last_offset <= (int)instanceOopDesc::base_offset_in_bytes() + fsize, "no overflow"); #endif ! _nonstatic_fields = fields; return flen; ! return _nonstatic_fields->length(); } GrowableArray<ciField*>* ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>* super_fields) { + void ciInstanceKlass::compute_fields_impl(GrowableArray<ciField*>* super_fields) { ASSERT_IN_VM; Arena* arena = CURRENT_ENV->arena(); ! int flen = 0; ! GrowableArray<ciField*>* fields = NULL; ! int static_len = 0; ! int nonstatic_len = 0; + + GrowableArray<ciField*>* static_fields = NULL; + GrowableArray<ciField*>* nonstatic_fields = NULL; instanceKlass* k = get_instanceKlass(); typeArrayOop fields_array = k->fields(); for (int pass = 0; pass <= 1; pass++) { for (int i = 0, alen = fields_array->length(); i < alen; i += instanceKlass::next_offset) { fieldDescriptor fd; fd.initialize(k->as_klassOop(), i); if (fd.is_static()) continue; if (pass == 0) { ! flen += 1; ! if (fd.is_static()) static_len++; + else nonstatic_len++; } else { ciField* field = new (arena) ciField(&fd); ! if (fd.is_static()) static_fields->append(field); + else nonstatic_fields->append(field); } } // Between passes, allocate the array: if (pass == 0) { if (flen == 0) { return NULL; // return nothing if none are locally declared } if (super_fields != NULL) { flen += super_fields->length(); + if (nonstatic_len == 0) { + nonstatic_fields = super_fields; } ! fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL); ! nonstatic_len += super_fields->length(); + } + if (nonstatic_fields == NULL) { + nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, nonstatic_len, 0, NULL); + } if (super_fields != NULL) { ! nonstatic_fields->appendAll(super_fields); } + static_fields = new (arena) GrowableArray<ciField*>(arena, nonstatic_len, 0, NULL); } } ! assert(fields->length() == flen, "sanity"); ! return fields; ! assert(nonstatic_fields->length() == nonstatic_len, "sanity"); ! assert(static_fields->length() == static_len, "sanity"); + + _nonstatic_fields = nonstatic_fields; + _static_fields = static_fields; } // ------------------------------------------------------------------ // ciInstanceKlass::find_method //

src/share/vm/ci/ciInstanceKlass.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File