--- old/src/share/vm/ci/ciField.cpp Mon Feb 21 14:15:20 2011 +++ new/src/share/vm/ci/ciField.cpp Mon Feb 21 14:15:20 2011 @@ -166,7 +166,7 @@ initialize_from(fd); // Either (a) it is marked shared, or else (b) we are done bootstrapping. - assert(is_shared() || ciObjectFactory::is_initialized(), + assert(_holder->is_shared() || ciObjectFactory::is_initialized(), "bootstrap classes must not create & cache unshared fields"); } @@ -285,7 +285,7 @@ ciType* ciField::compute_type_impl() { ciKlass* type = CURRENT_ENV->get_klass_by_name_impl(_holder, _signature, false); - if (!type->is_primitive_type() && is_shared()) { + if (!type->is_primitive_type() && _holder->is_shared()) { // We must not cache a pointer to an unshared type, in a shared field. bool type_is_also_shared = false; if (type->is_type_array_klass()) { @@ -331,7 +331,7 @@ true, false, KILL_COMPILE_ON_FATAL_(false)); // update the hit-cache, unless there is a problem with memory scoping: - if (accessing_klass->is_shared() || !is_shared()) + if (accessing_klass->is_shared() || !_holder->is_shared()) _known_to_link_with = accessing_klass; return true; --- old/src/share/vm/ci/ciField.hpp Mon Feb 21 14:15:21 2011 +++ new/src/share/vm/ci/ciField.hpp Mon Feb 21 14:15:21 2011 @@ -39,7 +39,6 @@ CI_PACKAGE_ACCESS friend class ciEnv; friend class ciInstanceKlass; - friend class NonStaticFieldFiller; private: ciFlags _flags; @@ -123,11 +122,11 @@ return offset(); } - // Is this field shared? - bool is_shared() { - // non-static fields of shared holders are cached - return _holder->is_shared() && !is_static(); - } + // // Is this field shared? + // bool is_shared() { + // // non-static fields of shared holders are cached + // return _holder->is_shared() && !is_static(); + // } // Is this field a constant? // --- 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 @@ -43,7 +43,7 @@ // // 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"); @@ -56,7 +56,7 @@ _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++) { @@ -82,11 +82,12 @@ _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; @@ -207,7 +208,7 @@ 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 { @@ -354,7 +355,7 @@ // 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) @@ -364,63 +365,42 @@ // could do binary search or check bins, but probably not worth it } return NULL; - } - VM_ENTRY_MARK; - instanceKlass* k = get_instanceKlass(); - fieldDescriptor fd; - if (!k->find_field_from_offset(field_offset, is_static, &fd)) { + } 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 + } 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) { + 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; + } + } 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; + } + } + return NULL; } - ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); - return field; } -// ------------------------------------------------------------------ -// ciInstanceKlass::non_static_fields. - -class NonStaticFieldFiller: public FieldClosure { - GrowableArray* _arr; - ciEnv* _curEnv; -public: - NonStaticFieldFiller(ciEnv* curEnv, GrowableArray* arr) : - _curEnv(curEnv), _arr(arr) - {} - void do_field(fieldDescriptor* fd) { - ciField* field = new (_curEnv->arena()) ciField(fd); - _arr->append(field); - } -}; - -GrowableArray* 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(arena, max_n_fields, 0, NULL); - NonStaticFieldFiller filler(curEnv, _non_static_fields); - ik->do_nonstatic_fields(&filler); - } - return _non_static_fields; -} - 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...) @@ -427,8 +407,8 @@ } // ------------------------------------------------------------------ -// 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) @@ -442,13 +422,13 @@ 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* 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. @@ -458,26 +438,18 @@ } } - GrowableArray* 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.) - fields->sort(sort_field_by_offset); + _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 < fields->length(); i++) { - ciField* field = fields->at(i); + 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)); @@ -491,17 +463,17 @@ assert(last_offset <= (int)instanceOopDesc::base_offset_in_bytes() + fsize, "no overflow"); #endif - _nonstatic_fields = fields; - return flen; + return _nonstatic_fields->length(); } -GrowableArray* -ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray* - super_fields) { +void ciInstanceKlass::compute_fields_impl(GrowableArray* super_fields) { ASSERT_IN_VM; Arena* arena = CURRENT_ENV->arena(); - int flen = 0; - GrowableArray* fields = NULL; + int static_len = 0; + int nonstatic_len = 0; + + GrowableArray* static_fields = NULL; + GrowableArray* nonstatic_fields = NULL; instanceKlass* k = get_instanceKlass(); typeArrayOop fields_array = k->fields(); for (int pass = 0; pass <= 1; pass++) { @@ -508,31 +480,38 @@ 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); - fields->append(field); + 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; + } + nonstatic_len += super_fields->length(); } - fields = new (arena) GrowableArray(arena, flen, 0, NULL); + if (nonstatic_fields == NULL) { + nonstatic_fields = new (arena) GrowableArray(arena, nonstatic_len, 0, NULL); + } if (super_fields != NULL) { - fields->appendAll(super_fields); + nonstatic_fields->appendAll(super_fields); } + static_fields = new (arena) GrowableArray(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; } // ------------------------------------------------------------------ --- old/src/share/vm/ci/ciInstanceKlass.hpp Mon Feb 21 14:15:23 2011 +++ new/src/share/vm/ci/ciInstanceKlass.hpp Mon Feb 21 14:15:23 2011 @@ -64,13 +64,12 @@ ciConstantPoolCache* _field_cache; // cached map index->field GrowableArray* _nonstatic_fields; + GrowableArray* _static_fields; enum { implementors_limit = instanceKlass::implementors_limit }; ciInstanceKlass* _implementors[implementors_limit]; jint _nof_implementors; - GrowableArray* _non_static_fields; - protected: ciInstanceKlass(KlassHandle h_k); ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain); @@ -98,8 +97,8 @@ void compute_shared_init_state(); bool compute_shared_has_subklass(); int compute_shared_nof_implementors(); - int compute_nonstatic_fields(); - GrowableArray* compute_nonstatic_fields_impl(GrowableArray* super_fields); + int compute_fields(); + void compute_fields_impl(GrowableArray* super_fields); // Update the init_state for shared klasses void update_if_shared(instanceKlass::ClassState expected) { @@ -148,15 +147,9 @@ return (Klass::layout_helper_size_in_bytes(layout_helper()) >> LogHeapWordSize); } - jint nonstatic_field_size() { - assert(is_loaded(), "must be loaded"); - return _nonstatic_field_size; } jint has_nonstatic_fields() { assert(is_loaded(), "must be loaded"); return _has_nonstatic_fields; } - jint nonstatic_oop_map_size() { - assert(is_loaded(), "must be loaded"); - return _nonstatic_oop_map_size; } ciInstanceKlass* super(); jint nof_implementors() { assert(is_loaded(), "must be loaded"); @@ -168,19 +161,19 @@ ciField* get_field_by_offset(int field_offset, bool is_static); ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static); - GrowableArray* non_static_fields(); - - // total number of nonstatic fields (including inherited): - int nof_nonstatic_fields() { - if (_nonstatic_fields == NULL) - return compute_nonstatic_fields(); - else - return _nonstatic_fields->length(); + // All nonstatic fields, including inherited ones + GrowableArray* nonstatic_fields() { + if (_nonstatic_fields == NULL) { + compute_fields(); + } + return _nonstatic_fields; } - // nth nonstatic field (presented by ascending address) - ciField* nonstatic_field_at(int i) { - assert(_nonstatic_fields != NULL, ""); - return _nonstatic_fields->at(i); + // Static fields declared in this class + GrowableArray* static_fields() { + if (_static_fields == NULL) { + compute_fields(); + } + return _static_fields; } ciInstanceKlass* unique_concrete_subklass(); @@ -187,7 +180,7 @@ bool has_finalizable_subclass(); bool contains_field_offset(int offset) { - return instanceOopDesc::contains_field_offset(offset, nonstatic_field_size()); + return instanceOopDesc::contains_field_offset(offset, _nonstatic_field_size); } // Get the instance of java.lang.Class corresponding to --- old/src/share/vm/ci/ciObjectFactory.cpp Mon Feb 21 14:15:23 2011 +++ new/src/share/vm/ci/ciObjectFactory.cpp Mon Feb 21 14:15:23 2011 @@ -182,7 +182,7 @@ for (int i2 = 0; i2 < len; i2++) { ciObject* obj = _ci_objects->at(i2); if (obj->is_loaded() && obj->is_instance_klass()) { - obj->as_instance_klass()->compute_nonstatic_fields(); + obj->as_instance_klass()->compute_fields(); } } } --- old/src/share/vm/opto/callnode.cpp Mon Feb 21 14:15:24 2011 +++ new/src/share/vm/opto/callnode.cpp Mon Feb 21 14:15:24 2011 @@ -456,7 +456,7 @@ ciField* cifield; if (iklass != NULL) { st->print(" ["); - cifield = iklass->nonstatic_field_at(0); + cifield = iklass->nonstatic_fields()->at(0); cifield->print_name_on(st); format_helper( regalloc, st, fld_node, ":", 0, &scobjs ); } else { @@ -466,7 +466,7 @@ fld_node = mcall->in(first_ind+j); if (iklass != NULL) { st->print(", ["); - cifield = iklass->nonstatic_field_at(j); + cifield = iklass->nonstatic_fields()->at(j); cifield->print_name_on(st); format_helper( regalloc, st, fld_node, ":", j, &scobjs ); } else { --- old/src/share/vm/opto/graphKit.cpp Mon Feb 21 14:15:25 2011 +++ new/src/share/vm/opto/graphKit.cpp Mon Feb 21 14:15:25 2011 @@ -2992,8 +2992,8 @@ hook_memory_on_init(*this, elemidx, minit_in, minit_out); } else if (oop_type->isa_instptr()) { ciInstanceKlass* ik = oop_type->klass()->as_instance_klass(); - for (int i = 0, len = ik->nof_nonstatic_fields(); i < len; i++) { - ciField* field = ik->nonstatic_field_at(i); + for (int i = 0, len = ik->nonstatic_fields()->length(); i < len; i++) { + ciField* field = ik->nonstatic_fields()->at(i); if (field->offset() >= TrackedInitializationLimit * HeapWordSize) continue; // do not bother to track really large numbers of fields // Find (or create) the alias category for this field: --- old/src/share/vm/opto/macro.cpp Mon Feb 21 14:15:26 2011 +++ new/src/share/vm/opto/macro.cpp Mon Feb 21 14:15:26 2011 @@ -693,7 +693,7 @@ // find the fields of the class which will be needed for safepoint debug information assert(klass->is_instance_klass(), "must be an instance klass."); iklass = klass->as_instance_klass(); - nfields = iklass->nof_nonstatic_fields(); + nfields = iklass->nonstatic_fields()->length(); } else { // find the array's elements which will be needed for safepoint debug information nfields = alloc->in(AllocateNode::ALength)->find_int_con(-1); @@ -724,7 +724,7 @@ intptr_t offset; ciField* field = NULL; if (iklass != NULL) { - field = iklass->nonstatic_field_at(j); + field = iklass->nonstatic_fields()->at(j); offset = field->offset(); elem_type = field->type(); basic_elem_type = field->layout_type(); --- old/src/share/vm/opto/memnode.cpp Mon Feb 21 14:15:27 2011 +++ new/src/share/vm/opto/memnode.cpp Mon Feb 21 14:15:27 2011 @@ -1101,10 +1101,10 @@ // Fetch the box object at the base of the array and get its value ciInstance* box = array->obj_at(0)->as_instance(); ciInstanceKlass* ik = box->klass()->as_instance_klass(); - if (ik->nof_nonstatic_fields() == 1) { + if (ik->nonstatic_fields()->length() == 1) { // This should be true nonstatic_field_at requires calling // nof_nonstatic_fields so check it anyway - ciConstant c = box->field_value(ik->nonstatic_field_at(0)); + ciConstant c = box->field_value(ik->nonstatic_fields()->at(0)); cache_offset = c.as_int(); } return true;