annotate src/hotspot/share/ci/ciInstanceKlass.cpp @ 52848:448c8cd077c9

8214303: [lworld] Value types consistency checks should have been removed with 8214138
author fparain
date Mon, 26 Nov 2018 11:38:13 -0500
parents d02b39679f11
children 128ccaa6d2e3
rev   line source
duke@1 1 /*
kbarrett@49371 2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation.
duke@1 8 *
duke@1 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 13 * accompanied this code).
duke@1 14 *
duke@1 15 * You should have received a copy of the GNU General Public License version
duke@1 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 18 *
trims@5547 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@5547 20 * or visit www.oracle.com if you need additional information or have any
trims@5547 21 * questions.
duke@1 22 *
duke@1 23 */
duke@1 24
stefank@7397 25 #include "precompiled.hpp"
stefank@7397 26 #include "ci/ciField.hpp"
stefank@7397 27 #include "ci/ciInstance.hpp"
stefank@7397 28 #include "ci/ciInstanceKlass.hpp"
coleenp@49661 29 #include "ci/ciUtilities.inline.hpp"
dsimms@47254 30 #include "ci/ciValueKlass.hpp"
stefank@7397 31 #include "classfile/systemDictionary.hpp"
stefank@7397 32 #include "memory/allocation.hpp"
stefank@7397 33 #include "memory/allocation.inline.hpp"
jprovino@37248 34 #include "memory/resourceArea.hpp"
stefank@7397 35 #include "oops/oop.inline.hpp"
never@10546 36 #include "oops/fieldStreams.hpp"
dsimms@47254 37 #include "oops/valueKlass.hpp"
iklam@51822 38 #include "runtime/fieldDescriptor.inline.hpp"
coleenp@49661 39 #include "runtime/handles.inline.hpp"
kbarrett@49371 40 #include "runtime/jniHandles.inline.hpp"
duke@1 41
duke@1 42 // ciInstanceKlass
duke@1 43 //
coleenp@13728 44 // This class represents a Klass* in the HotSpot virtual machine
coleenp@13728 45 // whose Klass part in an InstanceKlass.
duke@1 46
coleenp@47949 47
coleenp@47949 48 // ------------------------------------------------------------------
duke@1 49 // ciInstanceKlass::ciInstanceKlass
duke@1 50 //
duke@1 51 // Loaded instance klass.
coleenp@46329 52 ciInstanceKlass::ciInstanceKlass(Klass* k) :
coleenp@46329 53 ciKlass(k)
kvn@217 54 {
coleenp@33611 55 assert(get_Klass()->is_instance_klass(), "wrong type");
never@8314 56 assert(get_instanceKlass()->is_loaded(), "must be at least loaded");
coleenp@13728 57 InstanceKlass* ik = get_instanceKlass();
duke@1 58
duke@1 59 AccessFlags access_flags = ik->access_flags();
duke@1 60 _flags = ciFlags(access_flags);
duke@1 61 _has_finalizer = access_flags.has_finalizer();
duke@1 62 _has_subklass = ik->subklass() != NULL;
coleenp@11407 63 _init_state = ik->init_state();
duke@1 64 _nonstatic_field_size = ik->nonstatic_field_size();
coleenp@360 65 _has_nonstatic_fields = ik->has_nonstatic_fields();
dholmes@41669 66 _has_nonstatic_concrete_methods = ik->has_nonstatic_concrete_methods();
lfoltan@51799 67 _is_unsafe_anonymous = ik->is_unsafe_anonymous();
dsimms@47254 68 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields
roland@28396 69 _has_injected_fields = -1;
dsimms@47254 70 _vcc_klass = NULL;
jiangli@12369 71 _implementor = NULL; // we will fill these lazily
duke@1 72
eosterlund@48715 73 // Ensure that the metadata wrapped by the ciMetadata is kept alive by GC.
eosterlund@48715 74 // This is primarily useful for metadata which is considered as weak roots
eosterlund@48715 75 // by the GC but need to be strong roots if reachable from a current compilation.
eosterlund@48715 76 // InstanceKlass are created for both weak and strong metadata. Ensuring this metadata
eosterlund@48715 77 // alive covers the cases where there are weak roots without performance cost.
coleenp@49950 78 oop holder = ik->holder_phantom();
lfoltan@51799 79 if (ik->is_unsafe_anonymous()) {
coleenp@47949 80 // Though ciInstanceKlass records class loader oop, it's not enough to keep
lfoltan@51799 81 // VM unsafe anonymous classes alive (loader == NULL). Klass holder should
lfoltan@51799 82 // be used instead. It is enough to record a ciObject, since cached elements are never removed
coleenp@47949 83 // during ciObjectFactory lifetime. ciObjectFactory itself is created for
coleenp@47949 84 // every compilation and lives for the whole duration of the compilation.
lfoltan@51799 85 assert(holder != NULL, "holder of unsafe anonymous class is the mirror which is never null");
coleenp@47949 86 (void)CURRENT_ENV->get_object(holder);
coleenp@47949 87 }
coleenp@47949 88
duke@1 89 Thread *thread = Thread::current();
duke@1 90 if (ciObjectFactory::is_initialized()) {
duke@1 91 _loader = JNIHandles::make_local(thread, ik->class_loader());
duke@1 92 _protection_domain = JNIHandles::make_local(thread,
duke@1 93 ik->protection_domain());
duke@1 94 _is_shared = false;
duke@1 95 } else {
duke@1 96 Handle h_loader(thread, ik->class_loader());
duke@1 97 Handle h_protection_domain(thread, ik->protection_domain());
duke@1 98 _loader = JNIHandles::make_global(h_loader);
duke@1 99 _protection_domain = JNIHandles::make_global(h_protection_domain);
duke@1 100 _is_shared = true;
duke@1 101 }
duke@1 102
duke@1 103 // Lazy fields get filled in only upon request.
duke@1 104 _super = NULL;
duke@1 105 _java_mirror = NULL;
duke@1 106
duke@1 107 if (is_shared()) {
coleenp@46329 108 if (k != SystemDictionary::Object_klass()) {
duke@1 109 super();
duke@1 110 }
duke@1 111 //compute_nonstatic_fields(); // done outside of constructor
duke@1 112 }
duke@1 113
duke@1 114 _field_cache = NULL;
duke@1 115 }
duke@1 116
duke@1 117 // Version for unloaded classes:
duke@1 118 ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
duke@1 119 jobject loader, jobject protection_domain)
coleenp@13728 120 : ciKlass(name, T_OBJECT)
duke@1 121 {
duke@1 122 assert(name->byte_at(0) != '[', "not an instance klass");
coleenp@13728 123 _init_state = (InstanceKlass::ClassState)0;
duke@1 124 _nonstatic_field_size = -1;
coleenp@360 125 _has_nonstatic_fields = false;
dsimms@47254 126 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields
roland@28396 127 _has_injected_fields = -1;
dsimms@47254 128 _vcc_klass = NULL;
lfoltan@51799 129 _is_unsafe_anonymous = false;
duke@1 130 _loader = loader;
duke@1 131 _protection_domain = protection_domain;
duke@1 132 _is_shared = false;
duke@1 133 _super = NULL;
duke@1 134 _java_mirror = NULL;
duke@1 135 _field_cache = NULL;
duke@1 136 }
duke@1 137
duke@1 138
duke@1 139
duke@1 140 // ------------------------------------------------------------------
duke@1 141 // ciInstanceKlass::compute_shared_is_initialized
never@5925 142 void ciInstanceKlass::compute_shared_init_state() {
duke@1 143 GUARDED_VM_ENTRY(
coleenp@13728 144 InstanceKlass* ik = get_instanceKlass();
coleenp@11407 145 _init_state = ik->init_state();
duke@1 146 )
duke@1 147 }
duke@1 148
duke@1 149 // ------------------------------------------------------------------
duke@1 150 // ciInstanceKlass::compute_shared_has_subklass
duke@1 151 bool ciInstanceKlass::compute_shared_has_subklass() {
duke@1 152 GUARDED_VM_ENTRY(
coleenp@13728 153 InstanceKlass* ik = get_instanceKlass();
duke@1 154 _has_subklass = ik->subklass() != NULL;
duke@1 155 return _has_subklass;
duke@1 156 )
duke@1 157 }
duke@1 158
duke@1 159 // ------------------------------------------------------------------
duke@1 160 // ciInstanceKlass::loader
duke@1 161 oop ciInstanceKlass::loader() {
duke@1 162 ASSERT_IN_VM;
duke@1 163 return JNIHandles::resolve(_loader);
duke@1 164 }
duke@1 165
duke@1 166 // ------------------------------------------------------------------
duke@1 167 // ciInstanceKlass::loader_handle
duke@1 168 jobject ciInstanceKlass::loader_handle() {
duke@1 169 return _loader;
duke@1 170 }
duke@1 171
duke@1 172 // ------------------------------------------------------------------
duke@1 173 // ciInstanceKlass::protection_domain
duke@1 174 oop ciInstanceKlass::protection_domain() {
duke@1 175 ASSERT_IN_VM;
duke@1 176 return JNIHandles::resolve(_protection_domain);
duke@1 177 }
duke@1 178
duke@1 179 // ------------------------------------------------------------------
duke@1 180 // ciInstanceKlass::protection_domain_handle
duke@1 181 jobject ciInstanceKlass::protection_domain_handle() {
duke@1 182 return _protection_domain;
duke@1 183 }
duke@1 184
duke@1 185 // ------------------------------------------------------------------
duke@1 186 // ciInstanceKlass::field_cache
duke@1 187 //
duke@1 188 // Get the field cache associated with this klass.
duke@1 189 ciConstantPoolCache* ciInstanceKlass::field_cache() {
duke@1 190 if (is_shared()) {
duke@1 191 return NULL;
duke@1 192 }
duke@1 193 if (_field_cache == NULL) {
duke@1 194 assert(!is_java_lang_Object(), "Object has no fields");
duke@1 195 Arena* arena = CURRENT_ENV->arena();
duke@1 196 _field_cache = new (arena) ciConstantPoolCache(arena, 5);
duke@1 197 }
duke@1 198 return _field_cache;
duke@1 199 }
duke@1 200
duke@1 201 // ------------------------------------------------------------------
duke@1 202 // ciInstanceKlass::get_canonical_holder
duke@1 203 //
duke@1 204 ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) {
duke@1 205 #ifdef ASSERT
duke@1 206 if (!(offset >= 0 && offset < layout_helper())) {
duke@1 207 tty->print("*** get_canonical_holder(%d) on ", offset);
duke@1 208 this->print();
duke@1 209 tty->print_cr(" ***");
duke@1 210 };
duke@1 211 assert(offset >= 0 && offset < layout_helper(), "offset must be tame");
duke@1 212 #endif
duke@1 213
coleenp@360 214 if (offset < instanceOopDesc::base_offset_in_bytes()) {
duke@1 215 // All header offsets belong properly to java/lang/Object.
duke@1 216 return CURRENT_ENV->Object_klass();
duke@1 217 }
duke@1 218
duke@1 219 ciInstanceKlass* self = this;
duke@1 220 for (;;) {
duke@1 221 assert(self->is_loaded(), "must be loaded to have size");
duke@1 222 ciInstanceKlass* super = self->super();
coleenp@360 223 if (super == NULL || super->nof_nonstatic_fields() == 0 ||
coleenp@360 224 !super->contains_field_offset(offset)) {
duke@1 225 return self;
duke@1 226 } else {
duke@1 227 self = super; // return super->get_canonical_holder(offset)
duke@1 228 }
duke@1 229 }
duke@1 230 }
duke@1 231
duke@1 232 // ------------------------------------------------------------------
duke@1 233 // ciInstanceKlass::is_java_lang_Object
duke@1 234 //
duke@1 235 // Is this klass java.lang.Object?
coleenp@13728 236 bool ciInstanceKlass::is_java_lang_Object() const {
duke@1 237 return equals(CURRENT_ENV->Object_klass());
duke@1 238 }
duke@1 239
duke@1 240 // ------------------------------------------------------------------
duke@1 241 // ciInstanceKlass::uses_default_loader
kvn@17383 242 bool ciInstanceKlass::uses_default_loader() const {
twisti@4567 243 // Note: We do not need to resolve the handle or enter the VM
twisti@4567 244 // in order to test null-ness.
twisti@4567 245 return _loader == NULL;
twisti@4567 246 }
twisti@4567 247
twisti@4567 248 // ------------------------------------------------------------------
kvn@17383 249
kvn@17383 250 /**
kvn@17383 251 * Return basic type of boxed value for box klass or T_OBJECT if not.
kvn@17383 252 */
kvn@17383 253 BasicType ciInstanceKlass::box_klass_type() const {
kvn@17383 254 if (uses_default_loader() && is_loaded()) {
kvn@17383 255 return SystemDictionary::box_klass_type(get_Klass());
kvn@17383 256 } else {
kvn@17383 257 return T_OBJECT;
kvn@17383 258 }
kvn@17383 259 }
kvn@17383 260
kvn@17383 261 /**
kvn@17383 262 * Is this boxing klass?
kvn@17383 263 */
kvn@17383 264 bool ciInstanceKlass::is_box_klass() const {
kvn@17383 265 return is_java_primitive(box_klass_type());
kvn@17383 266 }
kvn@17383 267
kvn@17383 268 /**
kvn@17383 269 * Is this boxed value offset?
kvn@17383 270 */
kvn@17383 271 bool ciInstanceKlass::is_boxed_value_offset(int offset) const {
kvn@17383 272 BasicType bt = box_klass_type();
kvn@17383 273 return is_java_primitive(bt) &&
kvn@17383 274 (offset == java_lang_boxing_object::value_offset_in_bytes(bt));
kvn@17383 275 }
kvn@17383 276
kvn@17383 277 // ------------------------------------------------------------------
twisti@4567 278 // ciInstanceKlass::is_in_package
twisti@4567 279 //
twisti@4567 280 // Is this klass in the given package?
twisti@4567 281 bool ciInstanceKlass::is_in_package(const char* packagename, int len) {
twisti@4567 282 // To avoid class loader mischief, this test always rejects application classes.
twisti@4567 283 if (!uses_default_loader())
twisti@4567 284 return false;
twisti@4567 285 GUARDED_VM_ENTRY(
twisti@4567 286 return is_in_package_impl(packagename, len);
twisti@4567 287 )
twisti@4567 288 }
twisti@4567 289
twisti@4567 290 bool ciInstanceKlass::is_in_package_impl(const char* packagename, int len) {
twisti@4567 291 ASSERT_IN_VM;
twisti@4567 292
twisti@4567 293 // If packagename contains trailing '/' exclude it from the
twisti@4567 294 // prefix-test since we test for it explicitly.
twisti@4567 295 if (packagename[len - 1] == '/')
twisti@4567 296 len--;
twisti@4567 297
twisti@4567 298 if (!name()->starts_with(packagename, len))
twisti@4567 299 return false;
twisti@4567 300
twisti@4567 301 // Test if the class name is something like "java/lang".
twisti@4567 302 if ((len + 1) > name()->utf8_length())
twisti@4567 303 return false;
twisti@4567 304
twisti@4567 305 // Test for trailing '/'
twisti@4567 306 if ((char) name()->byte_at(len) != '/')
twisti@4567 307 return false;
twisti@4567 308
twisti@4567 309 // Make sure it's not actually in a subpackage:
twisti@4567 310 if (name()->index_of_at(len+1, "/", 1) >= 0)
twisti@4567 311 return false;
twisti@4567 312
twisti@4567 313 return true;
duke@1 314 }
duke@1 315
duke@1 316 // ------------------------------------------------------------------
duke@1 317 // ciInstanceKlass::print_impl
duke@1 318 //
duke@1 319 // Implementation of the print method.
duke@1 320 void ciInstanceKlass::print_impl(outputStream* st) {
duke@1 321 ciKlass::print_impl(st);
drchase@24424 322 GUARDED_VM_ENTRY(st->print(" loader=" INTPTR_FORMAT, p2i((address)loader()));)
duke@1 323 if (is_loaded()) {
duke@1 324 st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=",
duke@1 325 bool_to_str(is_initialized()),
duke@1 326 bool_to_str(has_finalizer()),
duke@1 327 bool_to_str(has_subklass()),
duke@1 328 layout_helper());
duke@1 329
duke@1 330 _flags.print_klass_flags();
duke@1 331
duke@1 332 if (_super) {
duke@1 333 st->print(" super=");
duke@1 334 _super->print_name();
duke@1 335 }
duke@1 336 if (_java_mirror) {
duke@1 337 st->print(" mirror=PRESENT");
duke@1 338 }
duke@1 339 } else {
duke@1 340 st->print(" loaded=false");
duke@1 341 }
duke@1 342 }
duke@1 343
duke@1 344 // ------------------------------------------------------------------
duke@1 345 // ciInstanceKlass::super
duke@1 346 //
duke@1 347 // Get the superklass of this klass.
duke@1 348 ciInstanceKlass* ciInstanceKlass::super() {
duke@1 349 assert(is_loaded(), "must be loaded");
duke@1 350 if (_super == NULL && !is_java_lang_Object()) {
duke@1 351 GUARDED_VM_ENTRY(
coleenp@13728 352 Klass* super_klass = get_instanceKlass()->super();
coleenp@13728 353 _super = CURRENT_ENV->get_instance_klass(super_klass);
duke@1 354 )
duke@1 355 }
duke@1 356 return _super;
duke@1 357 }
duke@1 358
duke@1 359 // ------------------------------------------------------------------
duke@1 360 // ciInstanceKlass::java_mirror
duke@1 361 //
duke@1 362 // Get the instance of java.lang.Class corresponding to this klass.
jrose@5884 363 // Cache it on this->_java_mirror.
duke@1 364 ciInstance* ciInstanceKlass::java_mirror() {
never@8725 365 if (is_shared()) {
never@8725 366 return ciKlass::java_mirror();
never@8725 367 }
duke@1 368 if (_java_mirror == NULL) {
jrose@5884 369 _java_mirror = ciKlass::java_mirror();
duke@1 370 }
duke@1 371 return _java_mirror;
duke@1 372 }
duke@1 373
duke@1 374 // ------------------------------------------------------------------
duke@1 375 // ciInstanceKlass::unique_concrete_subklass
duke@1 376 ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() {
duke@1 377 if (!is_loaded()) return NULL; // No change if class is not loaded
duke@1 378 if (!is_abstract()) return NULL; // Only applies to abstract classes.
duke@1 379 if (!has_subklass()) return NULL; // Must have at least one subklass.
duke@1 380 VM_ENTRY_MARK;
coleenp@13728 381 InstanceKlass* ik = get_instanceKlass();
duke@1 382 Klass* up = ik->up_cast_abstract();
coleenp@33611 383 assert(up->is_instance_klass(), "must be InstanceKlass");
duke@1 384 if (ik == up) {
duke@1 385 return NULL;
duke@1 386 }
coleenp@13728 387 return CURRENT_THREAD_ENV->get_instance_klass(up);
duke@1 388 }
duke@1 389
duke@1 390 // ------------------------------------------------------------------
duke@1 391 // ciInstanceKlass::has_finalizable_subclass
duke@1 392 bool ciInstanceKlass::has_finalizable_subclass() {
duke@1 393 if (!is_loaded()) return true;
duke@1 394 VM_ENTRY_MARK;
duke@1 395 return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL;
duke@1 396 }
duke@1 397
duke@1 398 // ------------------------------------------------------------------
duke@1 399 // ciInstanceKlass::get_field_by_offset
duke@1 400 ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) {
duke@1 401 if (!is_static) {
duke@1 402 for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) {
duke@1 403 ciField* field = _nonstatic_fields->at(i);
duke@1 404 int field_off = field->offset_in_bytes();
duke@1 405 if (field_off == field_offset)
duke@1 406 return field;
duke@1 407 if (field_off > field_offset)
duke@1 408 break;
duke@1 409 // could do binary search or check bins, but probably not worth it
duke@1 410 }
duke@1 411 return NULL;
duke@1 412 }
duke@1 413 VM_ENTRY_MARK;
coleenp@13728 414 InstanceKlass* k = get_instanceKlass();
duke@1 415 fieldDescriptor fd;
duke@1 416 if (!k->find_field_from_offset(field_offset, is_static, &fd)) {
duke@1 417 return NULL;
duke@1 418 }
duke@1 419 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
duke@1 420 return field;
duke@1 421 }
duke@1 422
kvn@217 423 // ------------------------------------------------------------------
never@4450 424 // ciInstanceKlass::get_field_by_name
never@4450 425 ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) {
never@4450 426 VM_ENTRY_MARK;
coleenp@13728 427 InstanceKlass* k = get_instanceKlass();
never@4450 428 fieldDescriptor fd;
coleenp@13728 429 Klass* def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd);
never@4450 430 if (def == NULL) {
never@4450 431 return NULL;
never@4450 432 }
never@4450 433 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
never@4450 434 return field;
never@4450 435 }
never@4450 436
kvn@217 437
duke@1 438 static int sort_field_by_offset(ciField** a, ciField** b) {
duke@1 439 return (*a)->offset_in_bytes() - (*b)->offset_in_bytes();
duke@1 440 // (no worries about 32-bit overflow...)
duke@1 441 }
duke@1 442
duke@1 443 // ------------------------------------------------------------------
duke@1 444 // ciInstanceKlass::compute_nonstatic_fields
duke@1 445 int ciInstanceKlass::compute_nonstatic_fields() {
duke@1 446 assert(is_loaded(), "must be loaded");
duke@1 447
duke@1 448 if (_nonstatic_fields != NULL)
duke@1 449 return _nonstatic_fields->length();
duke@1 450
coleenp@360 451 if (!has_nonstatic_fields()) {
duke@1 452 Arena* arena = CURRENT_ENV->arena();
duke@1 453 _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL);
duke@1 454 return 0;
duke@1 455 }
duke@1 456 assert(!is_java_lang_Object(), "bootstrap OK");
duke@1 457
coleenp@360 458 // Size in bytes of my fields, including inherited fields.
kvn@591 459 int fsize = nonstatic_field_size() * heapOopSize;
coleenp@360 460
duke@1 461 ciInstanceKlass* super = this->super();
duke@1 462 GrowableArray<ciField*>* super_fields = NULL;
coleenp@360 463 if (super != NULL && super->has_nonstatic_fields()) {
kvn@591 464 int super_fsize = super->nonstatic_field_size() * heapOopSize;
coleenp@360 465 int super_flen = super->nof_nonstatic_fields();
duke@1 466 super_fields = super->_nonstatic_fields;
duke@1 467 assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
coleenp@360 468 // See if I am no larger than my super; if so, I can use his fields.
coleenp@360 469 if (fsize == super_fsize) {
coleenp@360 470 _nonstatic_fields = super_fields;
coleenp@360 471 return super_fields->length();
coleenp@360 472 }
duke@1 473 }
duke@1 474
duke@1 475 GrowableArray<ciField*>* fields = NULL;
duke@1 476 GUARDED_VM_ENTRY({
duke@1 477 fields = compute_nonstatic_fields_impl(super_fields);
duke@1 478 });
duke@1 479
duke@1 480 if (fields == NULL) {
duke@1 481 // This can happen if this class (java.lang.Class) has invisible fields.
vlivanov@31037 482 if (super_fields != NULL) {
vlivanov@31037 483 _nonstatic_fields = super_fields;
vlivanov@31037 484 return super_fields->length();
vlivanov@31037 485 } else {
vlivanov@31037 486 return 0;
vlivanov@31037 487 }
duke@1 488 }
duke@1 489
duke@1 490 _nonstatic_fields = fields;
thartmann@47260 491 return fields->length();
duke@1 492 }
duke@1 493
thartmann@47260 494 GrowableArray<ciField*>* ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>* super_fields, bool flatten) {
duke@1 495 ASSERT_IN_VM;
duke@1 496 Arena* arena = CURRENT_ENV->arena();
duke@1 497 int flen = 0;
duke@1 498 GrowableArray<ciField*>* fields = NULL;
coleenp@13728 499 InstanceKlass* k = get_instanceKlass();
never@10546 500 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
never@10546 501 if (fs.access_flags().is_static()) continue;
never@10546 502 flen += 1;
never@10546 503 }
duke@1 504
never@10546 505 // allocate the array:
never@10546 506 if (flen == 0) {
never@10546 507 return NULL; // return nothing if none are locally declared
never@10546 508 }
never@10546 509 if (super_fields != NULL) {
never@10546 510 flen += super_fields->length();
never@10546 511 }
dsimms@47254 512
never@10546 513 fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL);
never@10546 514 if (super_fields != NULL) {
never@10546 515 fields->appendAll(super_fields);
never@10546 516 }
never@10546 517
never@10546 518 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
never@10546 519 if (fs.access_flags().is_static()) continue;
drchase@20017 520 fieldDescriptor& fd = fs.field_descriptor();
fparain@49045 521 if (fd.is_flattened() && flatten) {
dsimms@47254 522 // Value type fields are embedded
dsimms@47254 523 int field_offset = fd.offset();
dsimms@47254 524 // Get ValueKlass and adjust number of fields
thartmann@52225 525 Klass* k = get_instanceKlass()->get_value_field_klass(fd.index());
thartmann@52225 526 ciValueKlass* vk = CURRENT_ENV->get_klass(k)->as_value_klass();
thartmann@47260 527 flen += vk->nof_nonstatic_fields() - 1;
dsimms@47254 528 // Iterate over fields of the flattened value type and copy them to 'this'
dsimms@47254 529 for (int i = 0; i < vk->nof_nonstatic_fields(); ++i) {
dsimms@47254 530 ciField* flattened_field = vk->nonstatic_field_at(i);
dsimms@47254 531 // Adjust offset to account for missing oop header
dsimms@47254 532 int offset = field_offset + (flattened_field->offset() - vk->first_field_offset());
dsimms@47254 533 // A flattened field can be treated as final if the non-flattened
dsimms@47254 534 // field is declared final or the holder klass is a value type itself.
dsimms@47254 535 bool is_final = fd.is_final() || is_valuetype();
dsimms@47254 536 ciField* field = new (arena) ciField(flattened_field, this, offset, is_final);
dsimms@47254 537 fields->append(field);
dsimms@47254 538 }
dsimms@47254 539 } else {
dsimms@47254 540 ciField* field = new (arena) ciField(&fd);
dsimms@47254 541 fields->append(field);
dsimms@47254 542 }
duke@1 543 }
duke@1 544 assert(fields->length() == flen, "sanity");
thartmann@47260 545 // Now sort them by offset, ascending.
thartmann@47260 546 // (In principle, they could mix with superclass fields.)
thartmann@47260 547 fields->sort(sort_field_by_offset);
duke@1 548 return fields;
duke@1 549 }
duke@1 550
roland@28933 551 bool ciInstanceKlass::compute_injected_fields_helper() {
roland@28396 552 ASSERT_IN_VM;
roland@28396 553 InstanceKlass* k = get_instanceKlass();
roland@28396 554
roland@28396 555 for (InternalFieldStream fs(k); !fs.done(); fs.next()) {
roland@28396 556 if (fs.access_flags().is_static()) continue;
roland@28933 557 return true;
roland@28396 558 }
roland@28933 559 return false;
roland@28396 560 }
roland@28396 561
roland@28933 562 void ciInstanceKlass::compute_injected_fields() {
roland@28396 563 assert(is_loaded(), "must be loaded");
roland@28396 564
roland@28933 565 int has_injected_fields = 0;
roland@28396 566 if (super() != NULL && super()->has_injected_fields()) {
roland@28933 567 has_injected_fields = 1;
roland@28933 568 } else {
roland@28933 569 GUARDED_VM_ENTRY({
roland@28933 570 has_injected_fields = compute_injected_fields_helper() ? 1 : 0;
roland@28933 571 });
roland@28396 572 }
roland@28933 573 // may be concurrently initialized for shared ciInstanceKlass objects
roland@28933 574 assert(_has_injected_fields == -1 || _has_injected_fields == has_injected_fields, "broken concurrent initialization");
roland@28933 575 _has_injected_fields = has_injected_fields;
roland@28396 576 }
roland@28396 577
duke@1 578 // ------------------------------------------------------------------
duke@1 579 // ciInstanceKlass::find_method
duke@1 580 //
duke@1 581 // Find a method in this klass.
duke@1 582 ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) {
duke@1 583 VM_ENTRY_MARK;
coleenp@13728 584 InstanceKlass* k = get_instanceKlass();
coleenp@8076 585 Symbol* name_sym = name->get_symbol();
coleenp@8076 586 Symbol* sig_sym= signature->get_symbol();
duke@1 587
coleenp@13728 588 Method* m = k->find_method(name_sym, sig_sym);
duke@1 589 if (m == NULL) return NULL;
duke@1 590
coleenp@13728 591 return CURRENT_THREAD_ENV->get_method(m);
duke@1 592 }
duke@1 593
duke@1 594 // ------------------------------------------------------------------
duke@1 595 // ciInstanceKlass::is_leaf_type
duke@1 596 bool ciInstanceKlass::is_leaf_type() {
duke@1 597 assert(is_loaded(), "must be loaded");
duke@1 598 if (is_shared()) {
duke@1 599 return is_final(); // approximately correct
duke@1 600 } else {
jiangli@12369 601 return !_has_subklass && (nof_implementors() == 0);
duke@1 602 }
duke@1 603 }
duke@1 604
duke@1 605 // ------------------------------------------------------------------
duke@1 606 // ciInstanceKlass::implementor
duke@1 607 //
duke@1 608 // Report an implementor of this interface.
duke@1 609 // Note that there are various races here, since my copy
duke@1 610 // of _nof_implementors might be out of date with respect
coleenp@13728 611 // to results returned by InstanceKlass::implementor.
duke@1 612 // This is OK, since any dependencies we decide to assert
duke@1 613 // will be checked later under the Compile_lock.
jiangli@12369 614 ciInstanceKlass* ciInstanceKlass::implementor() {
jiangli@12369 615 ciInstanceKlass* impl = _implementor;
duke@1 616 if (impl == NULL) {
duke@1 617 // Go into the VM to fetch the implementor.
duke@1 618 {
duke@1 619 VM_ENTRY_MARK;
coleenp@51715 620 MutexLocker ml(Compile_lock);
coleenp@13728 621 Klass* k = get_instanceKlass()->implementor();
duke@1 622 if (k != NULL) {
coleenp@13728 623 if (k == get_instanceKlass()) {
jiangli@12369 624 // More than one implementors. Use 'this' in this case.
jiangli@12369 625 impl = this;
jiangli@12369 626 } else {
coleenp@13728 627 impl = CURRENT_THREAD_ENV->get_instance_klass(k);
jiangli@12369 628 }
duke@1 629 }
duke@1 630 }
duke@1 631 // Memoize this result.
duke@1 632 if (!is_shared()) {
jiangli@12369 633 _implementor = impl;
duke@1 634 }
duke@1 635 }
duke@1 636 return impl;
duke@1 637 }
minqi@14477 638
lfoltan@51799 639 ciInstanceKlass* ciInstanceKlass::unsafe_anonymous_host() {
coleenp@44738 640 assert(is_loaded(), "must be loaded");
lfoltan@51799 641 if (is_unsafe_anonymous()) {
coleenp@44738 642 VM_ENTRY_MARK
lfoltan@51799 643 Klass* unsafe_anonymous_host = get_instanceKlass()->unsafe_anonymous_host();
lfoltan@51799 644 return CURRENT_ENV->get_instance_klass(unsafe_anonymous_host);
coleenp@44738 645 }
coleenp@44738 646 return NULL;
coleenp@44738 647 }
coleenp@44738 648
dsimms@47254 649 ciInstanceKlass* ciInstanceKlass::vcc_klass() {
fparain@49029 650 return NULL;
dsimms@47254 651 }
dsimms@47254 652
minqi@14477 653 // Utility class for printing of the contents of the static fields for
minqi@14477 654 // use by compilation replay. It only prints out the information that
minqi@14477 655 // could be consumed by the compiler, so for primitive types it prints
minqi@14477 656 // out the actual value. For Strings it's the actual string value.
minqi@14477 657 // For array types it it's first level array size since that's the
minqi@14477 658 // only value which statically unchangeable. For all other reference
minqi@14477 659 // types it simply prints out the dynamic type.
minqi@14477 660
dsimms@47254 661 class StaticFieldPrinter : public FieldClosure {
dsimms@47254 662 protected:
minqi@14477 663 outputStream* _out;
dsimms@47254 664 public:
dsimms@47254 665 StaticFieldPrinter(outputStream* out) :
dsimms@47254 666 _out(out) {
dsimms@47254 667 }
dsimms@47254 668 void do_field_helper(fieldDescriptor* fd, oop obj, bool flattened);
dsimms@47254 669 };
dsimms@47254 670
dsimms@47254 671 class StaticFinalFieldPrinter : public StaticFieldPrinter {
minqi@14477 672 const char* _holder;
minqi@14477 673 public:
minqi@14477 674 StaticFinalFieldPrinter(outputStream* out, const char* holder) :
dsimms@47254 675 StaticFieldPrinter(out), _holder(holder) {
minqi@14477 676 }
minqi@14477 677 void do_field(fieldDescriptor* fd) {
minqi@14477 678 if (fd->is_final() && !fd->has_initial_value()) {
vlivanov@15471 679 ResourceMark rm;
dsimms@47254 680 InstanceKlass* holder = fd->field_holder();
dsimms@47254 681 oop mirror = holder->java_mirror();
dsimms@47254 682 _out->print("staticfield %s %s ", _holder, fd->name()->as_quoted_ascii());
dsimms@47254 683 BasicType bt = fd->field_type();
dsimms@47254 684 if (bt != T_OBJECT && bt != T_ARRAY) {
dsimms@47254 685 _out->print("%s ", fd->signature()->as_quoted_ascii());
dsimms@47254 686 }
dsimms@47254 687 do_field_helper(fd, mirror, false);
dsimms@47254 688 _out->cr();
minqi@14477 689 }
minqi@14477 690 }
minqi@14477 691 };
minqi@14477 692
dsimms@47254 693 class ValueTypeFieldPrinter : public StaticFieldPrinter {
dsimms@47254 694 oop _obj;
dsimms@47254 695 public:
dsimms@47254 696 ValueTypeFieldPrinter(outputStream* out, oop obj) :
dsimms@47254 697 StaticFieldPrinter(out), _obj(obj) {
dsimms@47254 698 }
dsimms@47254 699 void do_field(fieldDescriptor* fd) {
dsimms@47254 700 do_field_helper(fd, _obj, true);
dsimms@47254 701 _out->print(" ");
dsimms@47254 702 }
dsimms@47254 703 };
dsimms@47254 704
dsimms@47254 705 void StaticFieldPrinter::do_field_helper(fieldDescriptor* fd, oop mirror, bool flattened) {
dsimms@47254 706 BasicType bt = fd->field_type();
dsimms@47254 707 switch (bt) {
dsimms@47254 708 case T_BYTE: _out->print("%d", mirror->byte_field(fd->offset())); break;
dsimms@47254 709 case T_BOOLEAN: _out->print("%d", mirror->bool_field(fd->offset())); break;
dsimms@47254 710 case T_SHORT: _out->print("%d", mirror->short_field(fd->offset())); break;
dsimms@47254 711 case T_CHAR: _out->print("%d", mirror->char_field(fd->offset())); break;
dsimms@47254 712 case T_INT: _out->print("%d", mirror->int_field(fd->offset())); break;
dsimms@47254 713 case T_LONG: _out->print(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break;
dsimms@47254 714 case T_FLOAT: {
dsimms@47254 715 float f = mirror->float_field(fd->offset());
dsimms@47254 716 _out->print("%d", *(int*)&f);
dsimms@47254 717 break;
dsimms@47254 718 }
dsimms@47254 719 case T_DOUBLE: {
dsimms@47254 720 double d = mirror->double_field(fd->offset());
dsimms@47254 721 _out->print(INT64_FORMAT, *(int64_t*)&d);
dsimms@47254 722 break;
dsimms@47254 723 }
dsimms@47254 724 case T_ARRAY:
dsimms@47254 725 case T_OBJECT: {
dsimms@47254 726 oop value = mirror->obj_field_acquire(fd->offset());
dsimms@47254 727 if (value == NULL) {
dsimms@47254 728 _out->print("null");
dsimms@47254 729 } else {
dsimms@47254 730 _out->print("%s", value->klass()->signature_name());
dsimms@47254 731 if (value->is_array()) {
dsimms@47254 732 _out->print(" %d", ((arrayOop)value)->length());
dsimms@47254 733 } else {
dsimms@47254 734 assert(value->is_instance() && bt == T_OBJECT, "what else?");
dsimms@47254 735 if (value->is_a(SystemDictionary::String_klass())) {
roland@48430 736 const char* ascii_value = java_lang_String::as_quoted_ascii(value);
roland@48430 737 _out->print("\"%s\"", (ascii_value != NULL) ? ascii_value : "");
thartmann@47260 738 }
dsimms@47254 739 }
dsimms@47254 740 }
dsimms@47254 741 break;
dsimms@47254 742 }
dsimms@47254 743 case T_VALUETYPE: {
dsimms@47254 744 ResetNoHandleMark rnhm;
dsimms@47254 745 Thread* THREAD = Thread::current();
dsimms@47254 746 SignatureStream ss(fd->signature(), false);
dsimms@47254 747 Symbol* name = ss.as_symbol(THREAD);
dsimms@47254 748 assert(!HAS_PENDING_EXCEPTION, "can resolve klass?");
dsimms@47254 749 InstanceKlass* holder = fd->field_holder();
dsimms@47254 750 Klass* k = SystemDictionary::find(name, Handle(THREAD, holder->class_loader()),
dsimms@47254 751 Handle(THREAD, holder->protection_domain()), THREAD);
dsimms@47254 752 assert(k != NULL && !HAS_PENDING_EXCEPTION, "can resolve klass?");
dsimms@47254 753 ValueKlass* vk = ValueKlass::cast(k);
dsimms@47254 754 oop obj;
dsimms@47254 755 if (flattened) {
dsimms@47254 756 int field_offset = fd->offset() - vk->first_field_offset();
dsimms@47254 757 obj = (oop)((address)mirror + field_offset);
dsimms@47254 758 } else {
dsimms@47254 759 obj = mirror->obj_field_acquire(fd->offset());
dsimms@47254 760 }
dsimms@47254 761 ValueTypeFieldPrinter print_field(_out, obj);
dsimms@47254 762 vk->do_nonstatic_fields(&print_field);
dsimms@47254 763 break;
dsimms@47254 764 }
dsimms@47254 765 default:
dsimms@47254 766 ShouldNotReachHere();
dsimms@47254 767 }
dsimms@47254 768 }
dsimms@47254 769
minqi@14477 770
minqi@14477 771 void ciInstanceKlass::dump_replay_data(outputStream* out) {
vlivanov@15471 772 ResourceMark rm;
vlivanov@15471 773
minqi@14477 774 InstanceKlass* ik = get_instanceKlass();
minqi@14477 775 ConstantPool* cp = ik->constants();
minqi@14477 776
minqi@14477 777 // Try to record related loaded classes
minqi@14477 778 Klass* sub = ik->subklass();
minqi@14477 779 while (sub != NULL) {
coleenp@33611 780 if (sub->is_instance_klass()) {
minqi@14477 781 out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());
minqi@14477 782 }
minqi@14477 783 sub = sub->next_sibling();
minqi@14477 784 }
minqi@14477 785
minqi@14477 786 // Dump out the state of the constant pool tags. During replay the
minqi@14477 787 // tags will be validated for things which shouldn't change and
minqi@14477 788 // classes will be resolved if the tags indicate that they were
minqi@14477 789 // resolved at compile time.
minqi@14477 790 out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(),
minqi@14477 791 is_linked(), is_initialized(), cp->length());
minqi@14477 792 for (int index = 1; index < cp->length(); index++) {
minqi@14477 793 out->print(" %d", cp->tags()->at(index));
minqi@14477 794 }
minqi@14477 795 out->cr();
minqi@14477 796 if (is_initialized()) {
minqi@14477 797 // Dump out the static final fields in case the compilation relies
minqi@14477 798 // on their value for correct replay.
minqi@14477 799 StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii());
minqi@14477 800 ik->do_local_static_fields(&sffp);
minqi@14477 801 }
minqi@14477 802 }