1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,517 @@ 1.4 +/* 1.5 + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "incls/_precompiled.incl" 1.29 +#include "incls/_ciInstanceKlass.cpp.incl" 1.30 + 1.31 +// ciInstanceKlass 1.32 +// 1.33 +// This class represents a klassOop in the HotSpot virtual machine 1.34 +// whose Klass part in an instanceKlass. 1.35 + 1.36 +// ------------------------------------------------------------------ 1.37 +// ciInstanceKlass::ciInstanceKlass 1.38 +// 1.39 +// Loaded instance klass. 1.40 +ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : ciKlass(h_k) { 1.41 + assert(get_Klass()->oop_is_instance(), "wrong type"); 1.42 + instanceKlass* ik = get_instanceKlass(); 1.43 + 1.44 + AccessFlags access_flags = ik->access_flags(); 1.45 + _flags = ciFlags(access_flags); 1.46 + _has_finalizer = access_flags.has_finalizer(); 1.47 + _has_subklass = ik->subklass() != NULL; 1.48 + _is_initialized = ik->is_initialized(); 1.49 + // Next line must follow and use the result of the previous line: 1.50 + _is_linked = _is_initialized || ik->is_linked(); 1.51 + _nonstatic_field_size = ik->nonstatic_field_size(); 1.52 + _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: 1.53 + 1.54 + _nof_implementors = ik->nof_implementors(); 1.55 + for (int i = 0; i < implementors_limit; i++) { 1.56 + _implementors[i] = NULL; // we will fill these lazily 1.57 + } 1.58 + 1.59 + Thread *thread = Thread::current(); 1.60 + if (ciObjectFactory::is_initialized()) { 1.61 + _loader = JNIHandles::make_local(thread, ik->class_loader()); 1.62 + _protection_domain = JNIHandles::make_local(thread, 1.63 + ik->protection_domain()); 1.64 + _is_shared = false; 1.65 + } else { 1.66 + Handle h_loader(thread, ik->class_loader()); 1.67 + Handle h_protection_domain(thread, ik->protection_domain()); 1.68 + _loader = JNIHandles::make_global(h_loader); 1.69 + _protection_domain = JNIHandles::make_global(h_protection_domain); 1.70 + _is_shared = true; 1.71 + } 1.72 + 1.73 + // Lazy fields get filled in only upon request. 1.74 + _super = NULL; 1.75 + _java_mirror = NULL; 1.76 + 1.77 + if (is_shared()) { 1.78 + if (h_k() != SystemDictionary::object_klass()) { 1.79 + super(); 1.80 + } 1.81 + java_mirror(); 1.82 + //compute_nonstatic_fields(); // done outside of constructor 1.83 + } 1.84 + 1.85 + _field_cache = NULL; 1.86 +} 1.87 + 1.88 +// Version for unloaded classes: 1.89 +ciInstanceKlass::ciInstanceKlass(ciSymbol* name, 1.90 + jobject loader, jobject protection_domain) 1.91 + : ciKlass(name, ciInstanceKlassKlass::make()) 1.92 +{ 1.93 + assert(name->byte_at(0) != '[', "not an instance klass"); 1.94 + _is_initialized = false; 1.95 + _is_linked = false; 1.96 + _nonstatic_field_size = -1; 1.97 + _nonstatic_fields = NULL; 1.98 + _nof_implementors = -1; 1.99 + _loader = loader; 1.100 + _protection_domain = protection_domain; 1.101 + _is_shared = false; 1.102 + _super = NULL; 1.103 + _java_mirror = NULL; 1.104 + _field_cache = NULL; 1.105 +} 1.106 + 1.107 + 1.108 + 1.109 +// ------------------------------------------------------------------ 1.110 +// ciInstanceKlass::compute_shared_is_initialized 1.111 +bool ciInstanceKlass::compute_shared_is_initialized() { 1.112 + GUARDED_VM_ENTRY( 1.113 + instanceKlass* ik = get_instanceKlass(); 1.114 + _is_initialized = ik->is_initialized(); 1.115 + return _is_initialized; 1.116 + ) 1.117 +} 1.118 + 1.119 +// ------------------------------------------------------------------ 1.120 +// ciInstanceKlass::compute_shared_is_linked 1.121 +bool ciInstanceKlass::compute_shared_is_linked() { 1.122 + GUARDED_VM_ENTRY( 1.123 + instanceKlass* ik = get_instanceKlass(); 1.124 + _is_linked = ik->is_linked(); 1.125 + return _is_linked; 1.126 + ) 1.127 +} 1.128 + 1.129 +// ------------------------------------------------------------------ 1.130 +// ciInstanceKlass::compute_shared_has_subklass 1.131 +bool ciInstanceKlass::compute_shared_has_subklass() { 1.132 + GUARDED_VM_ENTRY( 1.133 + instanceKlass* ik = get_instanceKlass(); 1.134 + _has_subklass = ik->subklass() != NULL; 1.135 + return _has_subklass; 1.136 + ) 1.137 +} 1.138 + 1.139 +// ------------------------------------------------------------------ 1.140 +// ciInstanceKlass::compute_shared_nof_implementors 1.141 +int ciInstanceKlass::compute_shared_nof_implementors() { 1.142 + // We requery this property, since it is a very old ciObject. 1.143 + GUARDED_VM_ENTRY( 1.144 + instanceKlass* ik = get_instanceKlass(); 1.145 + _nof_implementors = ik->nof_implementors(); 1.146 + return _nof_implementors; 1.147 + ) 1.148 +} 1.149 + 1.150 +// ------------------------------------------------------------------ 1.151 +// ciInstanceKlass::loader 1.152 +oop ciInstanceKlass::loader() { 1.153 + ASSERT_IN_VM; 1.154 + return JNIHandles::resolve(_loader); 1.155 +} 1.156 + 1.157 +// ------------------------------------------------------------------ 1.158 +// ciInstanceKlass::loader_handle 1.159 +jobject ciInstanceKlass::loader_handle() { 1.160 + return _loader; 1.161 +} 1.162 + 1.163 +// ------------------------------------------------------------------ 1.164 +// ciInstanceKlass::protection_domain 1.165 +oop ciInstanceKlass::protection_domain() { 1.166 + ASSERT_IN_VM; 1.167 + return JNIHandles::resolve(_protection_domain); 1.168 +} 1.169 + 1.170 +// ------------------------------------------------------------------ 1.171 +// ciInstanceKlass::protection_domain_handle 1.172 +jobject ciInstanceKlass::protection_domain_handle() { 1.173 + return _protection_domain; 1.174 +} 1.175 + 1.176 +// ------------------------------------------------------------------ 1.177 +// ciInstanceKlass::field_cache 1.178 +// 1.179 +// Get the field cache associated with this klass. 1.180 +ciConstantPoolCache* ciInstanceKlass::field_cache() { 1.181 + if (is_shared()) { 1.182 + return NULL; 1.183 + } 1.184 + if (_field_cache == NULL) { 1.185 + assert(!is_java_lang_Object(), "Object has no fields"); 1.186 + Arena* arena = CURRENT_ENV->arena(); 1.187 + _field_cache = new (arena) ciConstantPoolCache(arena, 5); 1.188 + } 1.189 + return _field_cache; 1.190 +} 1.191 + 1.192 +// ------------------------------------------------------------------ 1.193 +// ciInstanceKlass::get_canonical_holder 1.194 +// 1.195 +ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) { 1.196 + #ifdef ASSERT 1.197 + if (!(offset >= 0 && offset < layout_helper())) { 1.198 + tty->print("*** get_canonical_holder(%d) on ", offset); 1.199 + this->print(); 1.200 + tty->print_cr(" ***"); 1.201 + }; 1.202 + assert(offset >= 0 && offset < layout_helper(), "offset must be tame"); 1.203 + #endif 1.204 + 1.205 + if (offset < (instanceOopDesc::header_size() * wordSize)) { 1.206 + // All header offsets belong properly to java/lang/Object. 1.207 + return CURRENT_ENV->Object_klass(); 1.208 + } 1.209 + 1.210 + ciInstanceKlass* self = this; 1.211 + for (;;) { 1.212 + assert(self->is_loaded(), "must be loaded to have size"); 1.213 + ciInstanceKlass* super = self->super(); 1.214 + if (super == NULL || !super->contains_field_offset(offset)) { 1.215 + return self; 1.216 + } else { 1.217 + self = super; // return super->get_canonical_holder(offset) 1.218 + } 1.219 + } 1.220 +} 1.221 + 1.222 +// ------------------------------------------------------------------ 1.223 +// ciInstanceKlass::is_java_lang_Object 1.224 +// 1.225 +// Is this klass java.lang.Object? 1.226 +bool ciInstanceKlass::is_java_lang_Object() { 1.227 + return equals(CURRENT_ENV->Object_klass()); 1.228 +} 1.229 + 1.230 +// ------------------------------------------------------------------ 1.231 +// ciInstanceKlass::uses_default_loader 1.232 +bool ciInstanceKlass::uses_default_loader() { 1.233 + VM_ENTRY_MARK; 1.234 + return loader() == NULL; 1.235 +} 1.236 + 1.237 +// ------------------------------------------------------------------ 1.238 +// ciInstanceKlass::print_impl 1.239 +// 1.240 +// Implementation of the print method. 1.241 +void ciInstanceKlass::print_impl(outputStream* st) { 1.242 + ciKlass::print_impl(st); 1.243 + GUARDED_VM_ENTRY(st->print(" loader=0x%x", (address)loader());) 1.244 + if (is_loaded()) { 1.245 + st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=", 1.246 + bool_to_str(is_initialized()), 1.247 + bool_to_str(has_finalizer()), 1.248 + bool_to_str(has_subklass()), 1.249 + layout_helper()); 1.250 + 1.251 + _flags.print_klass_flags(); 1.252 + 1.253 + if (_super) { 1.254 + st->print(" super="); 1.255 + _super->print_name(); 1.256 + } 1.257 + if (_java_mirror) { 1.258 + st->print(" mirror=PRESENT"); 1.259 + } 1.260 + } else { 1.261 + st->print(" loaded=false"); 1.262 + } 1.263 +} 1.264 + 1.265 +// ------------------------------------------------------------------ 1.266 +// ciInstanceKlass::super 1.267 +// 1.268 +// Get the superklass of this klass. 1.269 +ciInstanceKlass* ciInstanceKlass::super() { 1.270 + assert(is_loaded(), "must be loaded"); 1.271 + if (_super == NULL && !is_java_lang_Object()) { 1.272 + GUARDED_VM_ENTRY( 1.273 + klassOop super_klass = get_instanceKlass()->super(); 1.274 + _super = CURRENT_ENV->get_object(super_klass)->as_instance_klass(); 1.275 + ) 1.276 + } 1.277 + return _super; 1.278 +} 1.279 + 1.280 +// ------------------------------------------------------------------ 1.281 +// ciInstanceKlass::java_mirror 1.282 +// 1.283 +// Get the instance of java.lang.Class corresponding to this klass. 1.284 +ciInstance* ciInstanceKlass::java_mirror() { 1.285 + assert(is_loaded(), "must be loaded"); 1.286 + if (_java_mirror == NULL) { 1.287 + _java_mirror = ciKlass::java_mirror(); 1.288 + } 1.289 + return _java_mirror; 1.290 +} 1.291 + 1.292 +// ------------------------------------------------------------------ 1.293 +// ciInstanceKlass::unique_concrete_subklass 1.294 +ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() { 1.295 + if (!is_loaded()) return NULL; // No change if class is not loaded 1.296 + if (!is_abstract()) return NULL; // Only applies to abstract classes. 1.297 + if (!has_subklass()) return NULL; // Must have at least one subklass. 1.298 + VM_ENTRY_MARK; 1.299 + instanceKlass* ik = get_instanceKlass(); 1.300 + Klass* up = ik->up_cast_abstract(); 1.301 + assert(up->oop_is_instance(), "must be instanceKlass"); 1.302 + if (ik == up) { 1.303 + return NULL; 1.304 + } 1.305 + return CURRENT_THREAD_ENV->get_object(up->as_klassOop())->as_instance_klass(); 1.306 +} 1.307 + 1.308 +// ------------------------------------------------------------------ 1.309 +// ciInstanceKlass::has_finalizable_subclass 1.310 +bool ciInstanceKlass::has_finalizable_subclass() { 1.311 + if (!is_loaded()) return true; 1.312 + VM_ENTRY_MARK; 1.313 + return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL; 1.314 +} 1.315 + 1.316 +// ------------------------------------------------------------------ 1.317 +// ciInstanceKlass::get_field_by_offset 1.318 +ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) { 1.319 + if (!is_static) { 1.320 + for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) { 1.321 + ciField* field = _nonstatic_fields->at(i); 1.322 + int field_off = field->offset_in_bytes(); 1.323 + if (field_off == field_offset) 1.324 + return field; 1.325 + if (field_off > field_offset) 1.326 + break; 1.327 + // could do binary search or check bins, but probably not worth it 1.328 + } 1.329 + return NULL; 1.330 + } 1.331 + VM_ENTRY_MARK; 1.332 + instanceKlass* k = get_instanceKlass(); 1.333 + fieldDescriptor fd; 1.334 + if (!k->find_field_from_offset(field_offset, is_static, &fd)) { 1.335 + return NULL; 1.336 + } 1.337 + ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); 1.338 + return field; 1.339 +} 1.340 + 1.341 +static int sort_field_by_offset(ciField** a, ciField** b) { 1.342 + return (*a)->offset_in_bytes() - (*b)->offset_in_bytes(); 1.343 + // (no worries about 32-bit overflow...) 1.344 +} 1.345 + 1.346 +// ------------------------------------------------------------------ 1.347 +// ciInstanceKlass::compute_nonstatic_fields 1.348 +int ciInstanceKlass::compute_nonstatic_fields() { 1.349 + assert(is_loaded(), "must be loaded"); 1.350 + 1.351 + if (_nonstatic_fields != NULL) 1.352 + return _nonstatic_fields->length(); 1.353 + 1.354 + // Size in bytes of my fields, including inherited fields. 1.355 + // About equal to size_helper() - sizeof(oopDesc). 1.356 + int fsize = nonstatic_field_size() * wordSize; 1.357 + if (fsize == 0) { // easy shortcut 1.358 + Arena* arena = CURRENT_ENV->arena(); 1.359 + _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL); 1.360 + return 0; 1.361 + } 1.362 + assert(!is_java_lang_Object(), "bootstrap OK"); 1.363 + 1.364 + ciInstanceKlass* super = this->super(); 1.365 + int super_fsize = 0; 1.366 + int super_flen = 0; 1.367 + GrowableArray<ciField*>* super_fields = NULL; 1.368 + if (super != NULL) { 1.369 + super_fsize = super->nonstatic_field_size() * wordSize; 1.370 + super_flen = super->nof_nonstatic_fields(); 1.371 + super_fields = super->_nonstatic_fields; 1.372 + assert(super_flen == 0 || super_fields != NULL, "first get nof_fields"); 1.373 + } 1.374 + 1.375 + // See if I am no larger than my super; if so, I can use his fields. 1.376 + if (fsize == super_fsize) { 1.377 + _nonstatic_fields = super_fields; 1.378 + return super_fields->length(); 1.379 + } 1.380 + 1.381 + GrowableArray<ciField*>* fields = NULL; 1.382 + GUARDED_VM_ENTRY({ 1.383 + fields = compute_nonstatic_fields_impl(super_fields); 1.384 + }); 1.385 + 1.386 + if (fields == NULL) { 1.387 + // This can happen if this class (java.lang.Class) has invisible fields. 1.388 + _nonstatic_fields = super_fields; 1.389 + return super_fields->length(); 1.390 + } 1.391 + 1.392 + int flen = fields->length(); 1.393 + 1.394 + // Now sort them by offset, ascending. 1.395 + // (In principle, they could mix with superclass fields.) 1.396 + fields->sort(sort_field_by_offset); 1.397 +#ifdef ASSERT 1.398 + int last_offset = sizeof(oopDesc); 1.399 + for (int i = 0; i < fields->length(); i++) { 1.400 + ciField* field = fields->at(i); 1.401 + int offset = field->offset_in_bytes(); 1.402 + int size = (field->_type == NULL) ? oopSize : field->size_in_bytes(); 1.403 + assert(last_offset <= offset, "no field overlap"); 1.404 + if (last_offset > (int)sizeof(oopDesc)) 1.405 + assert((offset - last_offset) < BytesPerLong, "no big holes"); 1.406 + // Note: Two consecutive T_BYTE fields will be separated by wordSize-1 1.407 + // padding bytes if one of them is declared by a superclass. 1.408 + // This is a minor inefficiency classFileParser.cpp. 1.409 + last_offset = offset + size; 1.410 + } 1.411 + assert(last_offset <= (int)sizeof(oopDesc) + fsize, "no overflow"); 1.412 +#endif 1.413 + 1.414 + _nonstatic_fields = fields; 1.415 + return flen; 1.416 +} 1.417 + 1.418 +GrowableArray<ciField*>* 1.419 +ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>* 1.420 + super_fields) { 1.421 + ASSERT_IN_VM; 1.422 + Arena* arena = CURRENT_ENV->arena(); 1.423 + int flen = 0; 1.424 + GrowableArray<ciField*>* fields = NULL; 1.425 + instanceKlass* k = get_instanceKlass(); 1.426 + typeArrayOop fields_array = k->fields(); 1.427 + for (int pass = 0; pass <= 1; pass++) { 1.428 + for (int i = 0, alen = fields_array->length(); i < alen; i += instanceKlass::next_offset) { 1.429 + fieldDescriptor fd; 1.430 + fd.initialize(k->as_klassOop(), i); 1.431 + if (fd.is_static()) continue; 1.432 + if (pass == 0) { 1.433 + flen += 1; 1.434 + } else { 1.435 + ciField* field = new (arena) ciField(&fd); 1.436 + fields->append(field); 1.437 + } 1.438 + } 1.439 + 1.440 + // Between passes, allocate the array: 1.441 + if (pass == 0) { 1.442 + if (flen == 0) { 1.443 + return NULL; // return nothing if none are locally declared 1.444 + } 1.445 + if (super_fields != NULL) { 1.446 + flen += super_fields->length(); 1.447 + } 1.448 + fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL); 1.449 + if (super_fields != NULL) { 1.450 + fields->appendAll(super_fields); 1.451 + } 1.452 + } 1.453 + } 1.454 + assert(fields->length() == flen, "sanity"); 1.455 + return fields; 1.456 +} 1.457 + 1.458 +// ------------------------------------------------------------------ 1.459 +// ciInstanceKlass::find_method 1.460 +// 1.461 +// Find a method in this klass. 1.462 +ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) { 1.463 + VM_ENTRY_MARK; 1.464 + instanceKlass* k = get_instanceKlass(); 1.465 + symbolOop name_sym = name->get_symbolOop(); 1.466 + symbolOop sig_sym= signature->get_symbolOop(); 1.467 + 1.468 + methodOop m = k->find_method(name_sym, sig_sym); 1.469 + if (m == NULL) return NULL; 1.470 + 1.471 + return CURRENT_THREAD_ENV->get_object(m)->as_method(); 1.472 +} 1.473 + 1.474 +// ------------------------------------------------------------------ 1.475 +// ciInstanceKlass::is_leaf_type 1.476 +bool ciInstanceKlass::is_leaf_type() { 1.477 + assert(is_loaded(), "must be loaded"); 1.478 + if (is_shared()) { 1.479 + return is_final(); // approximately correct 1.480 + } else { 1.481 + return !_has_subklass && (_nof_implementors == 0); 1.482 + } 1.483 +} 1.484 + 1.485 +// ------------------------------------------------------------------ 1.486 +// ciInstanceKlass::implementor 1.487 +// 1.488 +// Report an implementor of this interface. 1.489 +// Returns NULL if exact information is not available. 1.490 +// Note that there are various races here, since my copy 1.491 +// of _nof_implementors might be out of date with respect 1.492 +// to results returned by instanceKlass::implementor. 1.493 +// This is OK, since any dependencies we decide to assert 1.494 +// will be checked later under the Compile_lock. 1.495 +ciInstanceKlass* ciInstanceKlass::implementor(int n) { 1.496 + if (n > implementors_limit) { 1.497 + return NULL; 1.498 + } 1.499 + ciInstanceKlass* impl = _implementors[n]; 1.500 + if (impl == NULL) { 1.501 + if (_nof_implementors > implementors_limit) { 1.502 + return NULL; 1.503 + } 1.504 + // Go into the VM to fetch the implementor. 1.505 + { 1.506 + VM_ENTRY_MARK; 1.507 + klassOop k = get_instanceKlass()->implementor(n); 1.508 + if (k != NULL) { 1.509 + impl = CURRENT_THREAD_ENV->get_object(k)->as_instance_klass(); 1.510 + } 1.511 + } 1.512 + // Memoize this result. 1.513 + if (!is_shared()) { 1.514 + _implementors[n] = (impl == NULL)? this: impl; 1.515 + } 1.516 + } else if (impl == this) { 1.517 + impl = NULL; // memoized null result from a VM query 1.518 + } 1.519 + return impl; 1.520 +}