1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,705 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "ci/ciField.hpp" 1.30 +#include "ci/ciInstance.hpp" 1.31 +#include "ci/ciInstanceKlass.hpp" 1.32 +#include "ci/ciUtilities.hpp" 1.33 +#include "classfile/systemDictionary.hpp" 1.34 +#include "memory/allocation.hpp" 1.35 +#include "memory/allocation.inline.hpp" 1.36 +#include "oops/oop.inline.hpp" 1.37 +#include "oops/fieldStreams.hpp" 1.38 +#include "runtime/fieldDescriptor.hpp" 1.39 + 1.40 +// ciInstanceKlass 1.41 +// 1.42 +// This class represents a Klass* in the HotSpot virtual machine 1.43 +// whose Klass part in an InstanceKlass. 1.44 + 1.45 +// ------------------------------------------------------------------ 1.46 +// ciInstanceKlass::ciInstanceKlass 1.47 +// 1.48 +// Loaded instance klass. 1.49 +ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : 1.50 + ciKlass(h_k), _non_static_fields(NULL) 1.51 +{ 1.52 + assert(get_Klass()->oop_is_instance(), "wrong type"); 1.53 + assert(get_instanceKlass()->is_loaded(), "must be at least loaded"); 1.54 + InstanceKlass* ik = get_instanceKlass(); 1.55 + 1.56 + AccessFlags access_flags = ik->access_flags(); 1.57 + _flags = ciFlags(access_flags); 1.58 + _has_finalizer = access_flags.has_finalizer(); 1.59 + _has_subklass = ik->subklass() != NULL; 1.60 + _init_state = ik->init_state(); 1.61 + _nonstatic_field_size = ik->nonstatic_field_size(); 1.62 + _has_nonstatic_fields = ik->has_nonstatic_fields(); 1.63 + _has_default_methods = ik->has_default_methods(); 1.64 + _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: 1.65 + 1.66 + _implementor = NULL; // we will fill these lazily 1.67 + 1.68 + Thread *thread = Thread::current(); 1.69 + if (ciObjectFactory::is_initialized()) { 1.70 + _loader = JNIHandles::make_local(thread, ik->class_loader()); 1.71 + _protection_domain = JNIHandles::make_local(thread, 1.72 + ik->protection_domain()); 1.73 + _is_shared = false; 1.74 + } else { 1.75 + Handle h_loader(thread, ik->class_loader()); 1.76 + Handle h_protection_domain(thread, ik->protection_domain()); 1.77 + _loader = JNIHandles::make_global(h_loader); 1.78 + _protection_domain = JNIHandles::make_global(h_protection_domain); 1.79 + _is_shared = true; 1.80 + } 1.81 + 1.82 + // Lazy fields get filled in only upon request. 1.83 + _super = NULL; 1.84 + _java_mirror = NULL; 1.85 + 1.86 + if (is_shared()) { 1.87 + if (h_k() != SystemDictionary::Object_klass()) { 1.88 + super(); 1.89 + } 1.90 + //compute_nonstatic_fields(); // done outside of constructor 1.91 + } 1.92 + 1.93 + _field_cache = NULL; 1.94 +} 1.95 + 1.96 +// Version for unloaded classes: 1.97 +ciInstanceKlass::ciInstanceKlass(ciSymbol* name, 1.98 + jobject loader, jobject protection_domain) 1.99 + : ciKlass(name, T_OBJECT) 1.100 +{ 1.101 + assert(name->byte_at(0) != '[', "not an instance klass"); 1.102 + _init_state = (InstanceKlass::ClassState)0; 1.103 + _nonstatic_field_size = -1; 1.104 + _has_nonstatic_fields = false; 1.105 + _nonstatic_fields = NULL; 1.106 + _loader = loader; 1.107 + _protection_domain = protection_domain; 1.108 + _is_shared = false; 1.109 + _super = NULL; 1.110 + _java_mirror = NULL; 1.111 + _field_cache = NULL; 1.112 +} 1.113 + 1.114 + 1.115 + 1.116 +// ------------------------------------------------------------------ 1.117 +// ciInstanceKlass::compute_shared_is_initialized 1.118 +void ciInstanceKlass::compute_shared_init_state() { 1.119 + GUARDED_VM_ENTRY( 1.120 + InstanceKlass* ik = get_instanceKlass(); 1.121 + _init_state = ik->init_state(); 1.122 + ) 1.123 +} 1.124 + 1.125 +// ------------------------------------------------------------------ 1.126 +// ciInstanceKlass::compute_shared_has_subklass 1.127 +bool ciInstanceKlass::compute_shared_has_subklass() { 1.128 + GUARDED_VM_ENTRY( 1.129 + InstanceKlass* ik = get_instanceKlass(); 1.130 + _has_subklass = ik->subklass() != NULL; 1.131 + return _has_subklass; 1.132 + ) 1.133 +} 1.134 + 1.135 +// ------------------------------------------------------------------ 1.136 +// ciInstanceKlass::loader 1.137 +oop ciInstanceKlass::loader() { 1.138 + ASSERT_IN_VM; 1.139 + return JNIHandles::resolve(_loader); 1.140 +} 1.141 + 1.142 +// ------------------------------------------------------------------ 1.143 +// ciInstanceKlass::loader_handle 1.144 +jobject ciInstanceKlass::loader_handle() { 1.145 + return _loader; 1.146 +} 1.147 + 1.148 +// ------------------------------------------------------------------ 1.149 +// ciInstanceKlass::protection_domain 1.150 +oop ciInstanceKlass::protection_domain() { 1.151 + ASSERT_IN_VM; 1.152 + return JNIHandles::resolve(_protection_domain); 1.153 +} 1.154 + 1.155 +// ------------------------------------------------------------------ 1.156 +// ciInstanceKlass::protection_domain_handle 1.157 +jobject ciInstanceKlass::protection_domain_handle() { 1.158 + return _protection_domain; 1.159 +} 1.160 + 1.161 +// ------------------------------------------------------------------ 1.162 +// ciInstanceKlass::field_cache 1.163 +// 1.164 +// Get the field cache associated with this klass. 1.165 +ciConstantPoolCache* ciInstanceKlass::field_cache() { 1.166 + if (is_shared()) { 1.167 + return NULL; 1.168 + } 1.169 + if (_field_cache == NULL) { 1.170 + assert(!is_java_lang_Object(), "Object has no fields"); 1.171 + Arena* arena = CURRENT_ENV->arena(); 1.172 + _field_cache = new (arena) ciConstantPoolCache(arena, 5); 1.173 + } 1.174 + return _field_cache; 1.175 +} 1.176 + 1.177 +// ------------------------------------------------------------------ 1.178 +// ciInstanceKlass::get_canonical_holder 1.179 +// 1.180 +ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) { 1.181 + #ifdef ASSERT 1.182 + if (!(offset >= 0 && offset < layout_helper())) { 1.183 + tty->print("*** get_canonical_holder(%d) on ", offset); 1.184 + this->print(); 1.185 + tty->print_cr(" ***"); 1.186 + }; 1.187 + assert(offset >= 0 && offset < layout_helper(), "offset must be tame"); 1.188 + #endif 1.189 + 1.190 + if (offset < instanceOopDesc::base_offset_in_bytes()) { 1.191 + // All header offsets belong properly to java/lang/Object. 1.192 + return CURRENT_ENV->Object_klass(); 1.193 + } 1.194 + 1.195 + ciInstanceKlass* self = this; 1.196 + for (;;) { 1.197 + assert(self->is_loaded(), "must be loaded to have size"); 1.198 + ciInstanceKlass* super = self->super(); 1.199 + if (super == NULL || super->nof_nonstatic_fields() == 0 || 1.200 + !super->contains_field_offset(offset)) { 1.201 + return self; 1.202 + } else { 1.203 + self = super; // return super->get_canonical_holder(offset) 1.204 + } 1.205 + } 1.206 +} 1.207 + 1.208 +// ------------------------------------------------------------------ 1.209 +// ciInstanceKlass::is_java_lang_Object 1.210 +// 1.211 +// Is this klass java.lang.Object? 1.212 +bool ciInstanceKlass::is_java_lang_Object() const { 1.213 + return equals(CURRENT_ENV->Object_klass()); 1.214 +} 1.215 + 1.216 +// ------------------------------------------------------------------ 1.217 +// ciInstanceKlass::uses_default_loader 1.218 +bool ciInstanceKlass::uses_default_loader() const { 1.219 + // Note: We do not need to resolve the handle or enter the VM 1.220 + // in order to test null-ness. 1.221 + return _loader == NULL; 1.222 +} 1.223 + 1.224 +// ------------------------------------------------------------------ 1.225 + 1.226 +/** 1.227 + * Return basic type of boxed value for box klass or T_OBJECT if not. 1.228 + */ 1.229 +BasicType ciInstanceKlass::box_klass_type() const { 1.230 + if (uses_default_loader() && is_loaded()) { 1.231 + return SystemDictionary::box_klass_type(get_Klass()); 1.232 + } else { 1.233 + return T_OBJECT; 1.234 + } 1.235 +} 1.236 + 1.237 +/** 1.238 + * Is this boxing klass? 1.239 + */ 1.240 +bool ciInstanceKlass::is_box_klass() const { 1.241 + return is_java_primitive(box_klass_type()); 1.242 +} 1.243 + 1.244 +/** 1.245 + * Is this boxed value offset? 1.246 + */ 1.247 +bool ciInstanceKlass::is_boxed_value_offset(int offset) const { 1.248 + BasicType bt = box_klass_type(); 1.249 + return is_java_primitive(bt) && 1.250 + (offset == java_lang_boxing_object::value_offset_in_bytes(bt)); 1.251 +} 1.252 + 1.253 +// ------------------------------------------------------------------ 1.254 +// ciInstanceKlass::is_in_package 1.255 +// 1.256 +// Is this klass in the given package? 1.257 +bool ciInstanceKlass::is_in_package(const char* packagename, int len) { 1.258 + // To avoid class loader mischief, this test always rejects application classes. 1.259 + if (!uses_default_loader()) 1.260 + return false; 1.261 + GUARDED_VM_ENTRY( 1.262 + return is_in_package_impl(packagename, len); 1.263 + ) 1.264 +} 1.265 + 1.266 +bool ciInstanceKlass::is_in_package_impl(const char* packagename, int len) { 1.267 + ASSERT_IN_VM; 1.268 + 1.269 + // If packagename contains trailing '/' exclude it from the 1.270 + // prefix-test since we test for it explicitly. 1.271 + if (packagename[len - 1] == '/') 1.272 + len--; 1.273 + 1.274 + if (!name()->starts_with(packagename, len)) 1.275 + return false; 1.276 + 1.277 + // Test if the class name is something like "java/lang". 1.278 + if ((len + 1) > name()->utf8_length()) 1.279 + return false; 1.280 + 1.281 + // Test for trailing '/' 1.282 + if ((char) name()->byte_at(len) != '/') 1.283 + return false; 1.284 + 1.285 + // Make sure it's not actually in a subpackage: 1.286 + if (name()->index_of_at(len+1, "/", 1) >= 0) 1.287 + return false; 1.288 + 1.289 + return true; 1.290 +} 1.291 + 1.292 +// ------------------------------------------------------------------ 1.293 +// ciInstanceKlass::print_impl 1.294 +// 1.295 +// Implementation of the print method. 1.296 +void ciInstanceKlass::print_impl(outputStream* st) { 1.297 + ciKlass::print_impl(st); 1.298 + GUARDED_VM_ENTRY(st->print(" loader=" INTPTR_FORMAT, p2i((address)loader()));) 1.299 + if (is_loaded()) { 1.300 + st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=", 1.301 + bool_to_str(is_initialized()), 1.302 + bool_to_str(has_finalizer()), 1.303 + bool_to_str(has_subklass()), 1.304 + layout_helper()); 1.305 + 1.306 + _flags.print_klass_flags(); 1.307 + 1.308 + if (_super) { 1.309 + st->print(" super="); 1.310 + _super->print_name(); 1.311 + } 1.312 + if (_java_mirror) { 1.313 + st->print(" mirror=PRESENT"); 1.314 + } 1.315 + } else { 1.316 + st->print(" loaded=false"); 1.317 + } 1.318 +} 1.319 + 1.320 +// ------------------------------------------------------------------ 1.321 +// ciInstanceKlass::super 1.322 +// 1.323 +// Get the superklass of this klass. 1.324 +ciInstanceKlass* ciInstanceKlass::super() { 1.325 + assert(is_loaded(), "must be loaded"); 1.326 + if (_super == NULL && !is_java_lang_Object()) { 1.327 + GUARDED_VM_ENTRY( 1.328 + Klass* super_klass = get_instanceKlass()->super(); 1.329 + _super = CURRENT_ENV->get_instance_klass(super_klass); 1.330 + ) 1.331 + } 1.332 + return _super; 1.333 +} 1.334 + 1.335 +// ------------------------------------------------------------------ 1.336 +// ciInstanceKlass::java_mirror 1.337 +// 1.338 +// Get the instance of java.lang.Class corresponding to this klass. 1.339 +// Cache it on this->_java_mirror. 1.340 +ciInstance* ciInstanceKlass::java_mirror() { 1.341 + if (is_shared()) { 1.342 + return ciKlass::java_mirror(); 1.343 + } 1.344 + if (_java_mirror == NULL) { 1.345 + _java_mirror = ciKlass::java_mirror(); 1.346 + } 1.347 + return _java_mirror; 1.348 +} 1.349 + 1.350 +// ------------------------------------------------------------------ 1.351 +// ciInstanceKlass::unique_concrete_subklass 1.352 +ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() { 1.353 + if (!is_loaded()) return NULL; // No change if class is not loaded 1.354 + if (!is_abstract()) return NULL; // Only applies to abstract classes. 1.355 + if (!has_subklass()) return NULL; // Must have at least one subklass. 1.356 + VM_ENTRY_MARK; 1.357 + InstanceKlass* ik = get_instanceKlass(); 1.358 + Klass* up = ik->up_cast_abstract(); 1.359 + assert(up->oop_is_instance(), "must be InstanceKlass"); 1.360 + if (ik == up) { 1.361 + return NULL; 1.362 + } 1.363 + return CURRENT_THREAD_ENV->get_instance_klass(up); 1.364 +} 1.365 + 1.366 +// ------------------------------------------------------------------ 1.367 +// ciInstanceKlass::has_finalizable_subclass 1.368 +bool ciInstanceKlass::has_finalizable_subclass() { 1.369 + if (!is_loaded()) return true; 1.370 + VM_ENTRY_MARK; 1.371 + return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL; 1.372 +} 1.373 + 1.374 +// ------------------------------------------------------------------ 1.375 +// ciInstanceKlass::get_field_by_offset 1.376 +ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) { 1.377 + if (!is_static) { 1.378 + for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) { 1.379 + ciField* field = _nonstatic_fields->at(i); 1.380 + int field_off = field->offset_in_bytes(); 1.381 + if (field_off == field_offset) 1.382 + return field; 1.383 + if (field_off > field_offset) 1.384 + break; 1.385 + // could do binary search or check bins, but probably not worth it 1.386 + } 1.387 + return NULL; 1.388 + } 1.389 + VM_ENTRY_MARK; 1.390 + InstanceKlass* k = get_instanceKlass(); 1.391 + fieldDescriptor fd; 1.392 + if (!k->find_field_from_offset(field_offset, is_static, &fd)) { 1.393 + return NULL; 1.394 + } 1.395 + ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); 1.396 + return field; 1.397 +} 1.398 + 1.399 +// ------------------------------------------------------------------ 1.400 +// ciInstanceKlass::get_field_by_name 1.401 +ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) { 1.402 + VM_ENTRY_MARK; 1.403 + InstanceKlass* k = get_instanceKlass(); 1.404 + fieldDescriptor fd; 1.405 + Klass* def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd); 1.406 + if (def == NULL) { 1.407 + return NULL; 1.408 + } 1.409 + ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); 1.410 + return field; 1.411 +} 1.412 + 1.413 +// ------------------------------------------------------------------ 1.414 +// ciInstanceKlass::non_static_fields. 1.415 + 1.416 +class NonStaticFieldFiller: public FieldClosure { 1.417 + GrowableArray<ciField*>* _arr; 1.418 + ciEnv* _curEnv; 1.419 +public: 1.420 + NonStaticFieldFiller(ciEnv* curEnv, GrowableArray<ciField*>* arr) : 1.421 + _curEnv(curEnv), _arr(arr) 1.422 + {} 1.423 + void do_field(fieldDescriptor* fd) { 1.424 + ciField* field = new (_curEnv->arena()) ciField(fd); 1.425 + _arr->append(field); 1.426 + } 1.427 +}; 1.428 + 1.429 +GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() { 1.430 + if (_non_static_fields == NULL) { 1.431 + VM_ENTRY_MARK; 1.432 + ciEnv* curEnv = ciEnv::current(); 1.433 + InstanceKlass* ik = get_instanceKlass(); 1.434 + int max_n_fields = ik->java_fields_count(); 1.435 + 1.436 + Arena* arena = curEnv->arena(); 1.437 + _non_static_fields = 1.438 + new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL); 1.439 + NonStaticFieldFiller filler(curEnv, _non_static_fields); 1.440 + ik->do_nonstatic_fields(&filler); 1.441 + } 1.442 + return _non_static_fields; 1.443 +} 1.444 + 1.445 +static int sort_field_by_offset(ciField** a, ciField** b) { 1.446 + return (*a)->offset_in_bytes() - (*b)->offset_in_bytes(); 1.447 + // (no worries about 32-bit overflow...) 1.448 +} 1.449 + 1.450 +// ------------------------------------------------------------------ 1.451 +// ciInstanceKlass::compute_nonstatic_fields 1.452 +int ciInstanceKlass::compute_nonstatic_fields() { 1.453 + assert(is_loaded(), "must be loaded"); 1.454 + 1.455 + if (_nonstatic_fields != NULL) 1.456 + return _nonstatic_fields->length(); 1.457 + 1.458 + if (!has_nonstatic_fields()) { 1.459 + Arena* arena = CURRENT_ENV->arena(); 1.460 + _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL); 1.461 + return 0; 1.462 + } 1.463 + assert(!is_java_lang_Object(), "bootstrap OK"); 1.464 + 1.465 + // Size in bytes of my fields, including inherited fields. 1.466 + int fsize = nonstatic_field_size() * heapOopSize; 1.467 + 1.468 + ciInstanceKlass* super = this->super(); 1.469 + GrowableArray<ciField*>* super_fields = NULL; 1.470 + if (super != NULL && super->has_nonstatic_fields()) { 1.471 + int super_fsize = super->nonstatic_field_size() * heapOopSize; 1.472 + int super_flen = super->nof_nonstatic_fields(); 1.473 + super_fields = super->_nonstatic_fields; 1.474 + assert(super_flen == 0 || super_fields != NULL, "first get nof_fields"); 1.475 + // See if I am no larger than my super; if so, I can use his fields. 1.476 + if (fsize == super_fsize) { 1.477 + _nonstatic_fields = super_fields; 1.478 + return super_fields->length(); 1.479 + } 1.480 + } 1.481 + 1.482 + GrowableArray<ciField*>* fields = NULL; 1.483 + GUARDED_VM_ENTRY({ 1.484 + fields = compute_nonstatic_fields_impl(super_fields); 1.485 + }); 1.486 + 1.487 + if (fields == NULL) { 1.488 + // This can happen if this class (java.lang.Class) has invisible fields. 1.489 + _nonstatic_fields = super_fields; 1.490 + return super_fields->length(); 1.491 + } 1.492 + 1.493 + int flen = fields->length(); 1.494 + 1.495 + // Now sort them by offset, ascending. 1.496 + // (In principle, they could mix with superclass fields.) 1.497 + fields->sort(sort_field_by_offset); 1.498 + _nonstatic_fields = fields; 1.499 + return flen; 1.500 +} 1.501 + 1.502 +GrowableArray<ciField*>* 1.503 +ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>* 1.504 + super_fields) { 1.505 + ASSERT_IN_VM; 1.506 + Arena* arena = CURRENT_ENV->arena(); 1.507 + int flen = 0; 1.508 + GrowableArray<ciField*>* fields = NULL; 1.509 + InstanceKlass* k = get_instanceKlass(); 1.510 + for (JavaFieldStream fs(k); !fs.done(); fs.next()) { 1.511 + if (fs.access_flags().is_static()) continue; 1.512 + flen += 1; 1.513 + } 1.514 + 1.515 + // allocate the array: 1.516 + if (flen == 0) { 1.517 + return NULL; // return nothing if none are locally declared 1.518 + } 1.519 + if (super_fields != NULL) { 1.520 + flen += super_fields->length(); 1.521 + } 1.522 + fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL); 1.523 + if (super_fields != NULL) { 1.524 + fields->appendAll(super_fields); 1.525 + } 1.526 + 1.527 + for (JavaFieldStream fs(k); !fs.done(); fs.next()) { 1.528 + if (fs.access_flags().is_static()) continue; 1.529 + fieldDescriptor& fd = fs.field_descriptor(); 1.530 + ciField* field = new (arena) ciField(&fd); 1.531 + fields->append(field); 1.532 + } 1.533 + assert(fields->length() == flen, "sanity"); 1.534 + return fields; 1.535 +} 1.536 + 1.537 +// ------------------------------------------------------------------ 1.538 +// ciInstanceKlass::find_method 1.539 +// 1.540 +// Find a method in this klass. 1.541 +ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) { 1.542 + VM_ENTRY_MARK; 1.543 + InstanceKlass* k = get_instanceKlass(); 1.544 + Symbol* name_sym = name->get_symbol(); 1.545 + Symbol* sig_sym= signature->get_symbol(); 1.546 + 1.547 + Method* m = k->find_method(name_sym, sig_sym); 1.548 + if (m == NULL) return NULL; 1.549 + 1.550 + return CURRENT_THREAD_ENV->get_method(m); 1.551 +} 1.552 + 1.553 +// ------------------------------------------------------------------ 1.554 +// ciInstanceKlass::is_leaf_type 1.555 +bool ciInstanceKlass::is_leaf_type() { 1.556 + assert(is_loaded(), "must be loaded"); 1.557 + if (is_shared()) { 1.558 + return is_final(); // approximately correct 1.559 + } else { 1.560 + return !_has_subklass && (nof_implementors() == 0); 1.561 + } 1.562 +} 1.563 + 1.564 +// ------------------------------------------------------------------ 1.565 +// ciInstanceKlass::implementor 1.566 +// 1.567 +// Report an implementor of this interface. 1.568 +// Note that there are various races here, since my copy 1.569 +// of _nof_implementors might be out of date with respect 1.570 +// to results returned by InstanceKlass::implementor. 1.571 +// This is OK, since any dependencies we decide to assert 1.572 +// will be checked later under the Compile_lock. 1.573 +ciInstanceKlass* ciInstanceKlass::implementor() { 1.574 + ciInstanceKlass* impl = _implementor; 1.575 + if (impl == NULL) { 1.576 + // Go into the VM to fetch the implementor. 1.577 + { 1.578 + VM_ENTRY_MARK; 1.579 + Klass* k = get_instanceKlass()->implementor(); 1.580 + if (k != NULL) { 1.581 + if (k == get_instanceKlass()) { 1.582 + // More than one implementors. Use 'this' in this case. 1.583 + impl = this; 1.584 + } else { 1.585 + impl = CURRENT_THREAD_ENV->get_instance_klass(k); 1.586 + } 1.587 + } 1.588 + } 1.589 + // Memoize this result. 1.590 + if (!is_shared()) { 1.591 + _implementor = impl; 1.592 + } 1.593 + } 1.594 + return impl; 1.595 +} 1.596 + 1.597 +// Utility class for printing of the contents of the static fields for 1.598 +// use by compilation replay. It only prints out the information that 1.599 +// could be consumed by the compiler, so for primitive types it prints 1.600 +// out the actual value. For Strings it's the actual string value. 1.601 +// For array types it it's first level array size since that's the 1.602 +// only value which statically unchangeable. For all other reference 1.603 +// types it simply prints out the dynamic type. 1.604 + 1.605 +class StaticFinalFieldPrinter : public FieldClosure { 1.606 + outputStream* _out; 1.607 + const char* _holder; 1.608 + public: 1.609 + StaticFinalFieldPrinter(outputStream* out, const char* holder) : 1.610 + _out(out), 1.611 + _holder(holder) { 1.612 + } 1.613 + void do_field(fieldDescriptor* fd) { 1.614 + if (fd->is_final() && !fd->has_initial_value()) { 1.615 + ResourceMark rm; 1.616 + oop mirror = fd->field_holder()->java_mirror(); 1.617 + _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii()); 1.618 + switch (fd->field_type()) { 1.619 + case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break; 1.620 + case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break; 1.621 + case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break; 1.622 + case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break; 1.623 + case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break; 1.624 + case T_LONG: _out->print_cr(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break; 1.625 + case T_FLOAT: { 1.626 + float f = mirror->float_field(fd->offset()); 1.627 + _out->print_cr("%d", *(int*)&f); 1.628 + break; 1.629 + } 1.630 + case T_DOUBLE: { 1.631 + double d = mirror->double_field(fd->offset()); 1.632 + _out->print_cr(INT64_FORMAT, *(int64_t*)&d); 1.633 + break; 1.634 + } 1.635 + case T_ARRAY: { 1.636 + oop value = mirror->obj_field_acquire(fd->offset()); 1.637 + if (value == NULL) { 1.638 + _out->print_cr("null"); 1.639 + } else { 1.640 + typeArrayOop ta = (typeArrayOop)value; 1.641 + _out->print("%d", ta->length()); 1.642 + if (value->is_objArray()) { 1.643 + objArrayOop oa = (objArrayOop)value; 1.644 + const char* klass_name = value->klass()->name()->as_quoted_ascii(); 1.645 + _out->print(" %s", klass_name); 1.646 + } 1.647 + _out->cr(); 1.648 + } 1.649 + break; 1.650 + } 1.651 + case T_OBJECT: { 1.652 + oop value = mirror->obj_field_acquire(fd->offset()); 1.653 + if (value == NULL) { 1.654 + _out->print_cr("null"); 1.655 + } else if (value->is_instance()) { 1.656 + if (value->is_a(SystemDictionary::String_klass())) { 1.657 + _out->print("\""); 1.658 + _out->print_raw(java_lang_String::as_quoted_ascii(value)); 1.659 + _out->print_cr("\""); 1.660 + } else { 1.661 + const char* klass_name = value->klass()->name()->as_quoted_ascii(); 1.662 + _out->print_cr("%s", klass_name); 1.663 + } 1.664 + } else { 1.665 + ShouldNotReachHere(); 1.666 + } 1.667 + break; 1.668 + } 1.669 + default: 1.670 + ShouldNotReachHere(); 1.671 + } 1.672 + } 1.673 + } 1.674 +}; 1.675 + 1.676 + 1.677 +void ciInstanceKlass::dump_replay_data(outputStream* out) { 1.678 + ResourceMark rm; 1.679 + 1.680 + InstanceKlass* ik = get_instanceKlass(); 1.681 + ConstantPool* cp = ik->constants(); 1.682 + 1.683 + // Try to record related loaded classes 1.684 + Klass* sub = ik->subklass(); 1.685 + while (sub != NULL) { 1.686 + if (sub->oop_is_instance()) { 1.687 + out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii()); 1.688 + } 1.689 + sub = sub->next_sibling(); 1.690 + } 1.691 + 1.692 + // Dump out the state of the constant pool tags. During replay the 1.693 + // tags will be validated for things which shouldn't change and 1.694 + // classes will be resolved if the tags indicate that they were 1.695 + // resolved at compile time. 1.696 + out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(), 1.697 + is_linked(), is_initialized(), cp->length()); 1.698 + for (int index = 1; index < cp->length(); index++) { 1.699 + out->print(" %d", cp->tags()->at(index)); 1.700 + } 1.701 + out->cr(); 1.702 + if (is_initialized()) { 1.703 + // Dump out the static final fields in case the compilation relies 1.704 + // on their value for correct replay. 1.705 + StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii()); 1.706 + ik->do_local_static_fields(&sffp); 1.707 + } 1.708 +}