annotate src/hotspot/share/ci/ciInstanceKlass.cpp @ 53410:9c18c9d839d3

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