--- old/hotspot/src/share/vm/ci/ciInstanceKlass.cpp 2009-08-01 04:09:49.688168590 +0100 +++ new/hotspot/src/share/vm/ci/ciInstanceKlass.cpp 2009-08-01 04:09:49.606608652 +0100 @@ -2,7 +2,7 @@ #pragma ident "@(#)ciInstanceKlass.cpp 1.45 07/09/28 10:23:23 JVM" #endif /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,9 @@ // ciInstanceKlass::ciInstanceKlass // // Loaded instance klass. -ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : ciKlass(h_k) { +ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : + ciKlass(h_k), _non_static_fields(NULL) +{ assert(get_Klass()->oop_is_instance(), "wrong type"); instanceKlass* ik = get_instanceKlass(); @@ -49,6 +51,7 @@ // Next line must follow and use the result of the previous line: _is_linked = _is_initialized || ik->is_linked(); _nonstatic_field_size = ik->nonstatic_field_size(); + _has_nonstatic_fields = ik->has_nonstatic_fields(); _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: _nof_implementors = ik->nof_implementors(); @@ -94,6 +97,7 @@ _is_initialized = false; _is_linked = false; _nonstatic_field_size = -1; + _has_nonstatic_fields = false; _nonstatic_fields = NULL; _nof_implementors = -1; _loader = loader; @@ -202,7 +206,7 @@ assert(offset >= 0 && offset < layout_helper(), "offset must be tame"); #endif - if (offset < (instanceOopDesc::header_size() * wordSize)) { + if (offset < instanceOopDesc::base_offset_in_bytes()) { // All header offsets belong properly to java/lang/Object. return CURRENT_ENV->Object_klass(); } @@ -211,7 +215,8 @@ for (;;) { assert(self->is_loaded(), "must be loaded to have size"); ciInstanceKlass* super = self->super(); - if (super == NULL || !super->contains_field_offset(offset)) { + if (super == NULL || super->nof_nonstatic_fields() == 0 || + !super->contains_field_offset(offset)) { return self; } else { self = super; // return super->get_canonical_holder(offset) @@ -338,6 +343,37 @@ 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; + + _non_static_fields = + new (curEnv->arena()) GrowableArray(max_n_fields); + 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...) @@ -351,31 +387,28 @@ if (_nonstatic_fields != NULL) return _nonstatic_fields->length(); - // Size in bytes of my fields, including inherited fields. - // About equal to size_helper() - sizeof(oopDesc). - int fsize = nonstatic_field_size() * wordSize; - if (fsize == 0) { // easy shortcut + if (!has_nonstatic_fields()) { Arena* arena = CURRENT_ENV->arena(); _nonstatic_fields = new (arena) GrowableArray(arena, 0, 0, NULL); return 0; } assert(!is_java_lang_Object(), "bootstrap OK"); + // Size in bytes of my fields, including inherited fields. + int fsize = nonstatic_field_size() * heapOopSize; + ciInstanceKlass* super = this->super(); - int super_fsize = 0; - int super_flen = 0; GrowableArray* super_fields = NULL; - if (super != NULL) { - super_fsize = super->nonstatic_field_size() * wordSize; - super_flen = super->nof_nonstatic_fields(); + if (super != NULL && super->has_nonstatic_fields()) { + int super_fsize = super->nonstatic_field_size() * heapOopSize; + int super_flen = super->nof_nonstatic_fields(); 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(); + // 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* fields = NULL; @@ -395,11 +428,11 @@ // (In principle, they could mix with superclass fields.) fields->sort(sort_field_by_offset); #ifdef ASSERT - int last_offset = sizeof(oopDesc); + int last_offset = instanceOopDesc::base_offset_in_bytes(); for (int i = 0; i < fields->length(); i++) { ciField* field = fields->at(i); int offset = field->offset_in_bytes(); - int size = (field->_type == NULL) ? oopSize : field->size_in_bytes(); + int size = (field->_type == NULL) ? heapOopSize : field->size_in_bytes(); assert(last_offset <= offset, "no field overlap"); if (last_offset > (int)sizeof(oopDesc)) assert((offset - last_offset) < BytesPerLong, "no big holes"); @@ -408,7 +441,7 @@ // This is a minor inefficiency classFileParser.cpp. last_offset = offset + size; } - assert(last_offset <= (int)sizeof(oopDesc) + fsize, "no overflow"); + assert(last_offset <= (int)instanceOopDesc::base_offset_in_bytes() + fsize, "no overflow"); #endif _nonstatic_fields = fields;