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