annotate hotspot/src/share/vm/ci/ciInstanceKlass.cpp @ 14477:95e66ea71f71

6830717: replay of compilations would help with debugging Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method. Reviewed-by: kvn, twisti, sspitsyn Contributed-by: yumin.qi@oracle.com
author minqi
date Mon, 12 Nov 2012 14:03:53 -0800
parents 882756847a04
children 41f75023e6a6
rev   line source
duke@1 1 /*
jiangli@12369 2 * Copyright (c) 1999, 2012, 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"
stefank@7397 29 #include "ci/ciUtilities.hpp"
stefank@7397 30 #include "classfile/systemDictionary.hpp"
stefank@7397 31 #include "memory/allocation.hpp"
stefank@7397 32 #include "memory/allocation.inline.hpp"
stefank@7397 33 #include "oops/oop.inline.hpp"
never@10546 34 #include "oops/fieldStreams.hpp"
stefank@7397 35 #include "runtime/fieldDescriptor.hpp"
duke@1 36
duke@1 37 // ciInstanceKlass
duke@1 38 //
coleenp@13728 39 // This class represents a Klass* in the HotSpot virtual machine
coleenp@13728 40 // whose Klass part in an InstanceKlass.
duke@1 41
duke@1 42 // ------------------------------------------------------------------
duke@1 43 // ciInstanceKlass::ciInstanceKlass
duke@1 44 //
duke@1 45 // Loaded instance klass.
kvn@217 46 ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
kvn@217 47 ciKlass(h_k), _non_static_fields(NULL)
kvn@217 48 {
duke@1 49 assert(get_Klass()->oop_is_instance(), "wrong type");
never@8314 50 assert(get_instanceKlass()->is_loaded(), "must be at least loaded");
coleenp@13728 51 InstanceKlass* ik = get_instanceKlass();
duke@1 52
duke@1 53 AccessFlags access_flags = ik->access_flags();
duke@1 54 _flags = ciFlags(access_flags);
duke@1 55 _has_finalizer = access_flags.has_finalizer();
duke@1 56 _has_subklass = ik->subklass() != NULL;
coleenp@11407 57 _init_state = ik->init_state();
duke@1 58 _nonstatic_field_size = ik->nonstatic_field_size();
coleenp@360 59 _has_nonstatic_fields = ik->has_nonstatic_fields();
duke@1 60 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
duke@1 61
jiangli@12369 62 _implementor = NULL; // we will fill these lazily
duke@1 63
duke@1 64 Thread *thread = Thread::current();
duke@1 65 if (ciObjectFactory::is_initialized()) {
duke@1 66 _loader = JNIHandles::make_local(thread, ik->class_loader());
duke@1 67 _protection_domain = JNIHandles::make_local(thread,
duke@1 68 ik->protection_domain());
duke@1 69 _is_shared = false;
duke@1 70 } else {
duke@1 71 Handle h_loader(thread, ik->class_loader());
duke@1 72 Handle h_protection_domain(thread, ik->protection_domain());
duke@1 73 _loader = JNIHandles::make_global(h_loader);
duke@1 74 _protection_domain = JNIHandles::make_global(h_protection_domain);
duke@1 75 _is_shared = true;
duke@1 76 }
duke@1 77
duke@1 78 // Lazy fields get filled in only upon request.
duke@1 79 _super = NULL;
duke@1 80 _java_mirror = NULL;
duke@1 81
duke@1 82 if (is_shared()) {
never@4571 83 if (h_k() != SystemDictionary::Object_klass()) {
duke@1 84 super();
duke@1 85 }
duke@1 86 //compute_nonstatic_fields(); // done outside of constructor
duke@1 87 }
duke@1 88
duke@1 89 _field_cache = NULL;
duke@1 90 }
duke@1 91
duke@1 92 // Version for unloaded classes:
duke@1 93 ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
duke@1 94 jobject loader, jobject protection_domain)
coleenp@13728 95 : ciKlass(name, T_OBJECT)
duke@1 96 {
duke@1 97 assert(name->byte_at(0) != '[', "not an instance klass");
coleenp@13728 98 _init_state = (InstanceKlass::ClassState)0;
duke@1 99 _nonstatic_field_size = -1;
coleenp@360 100 _has_nonstatic_fields = false;
duke@1 101 _nonstatic_fields = NULL;
duke@1 102 _loader = loader;
duke@1 103 _protection_domain = protection_domain;
duke@1 104 _is_shared = false;
duke@1 105 _super = NULL;
duke@1 106 _java_mirror = NULL;
duke@1 107 _field_cache = NULL;
duke@1 108 }
duke@1 109
duke@1 110
duke@1 111
duke@1 112 // ------------------------------------------------------------------
duke@1 113 // ciInstanceKlass::compute_shared_is_initialized
never@5925 114 void ciInstanceKlass::compute_shared_init_state() {
duke@1 115 GUARDED_VM_ENTRY(
coleenp@13728 116 InstanceKlass* ik = get_instanceKlass();
coleenp@11407 117 _init_state = ik->init_state();
duke@1 118 )
duke@1 119 }
duke@1 120
duke@1 121 // ------------------------------------------------------------------
duke@1 122 // ciInstanceKlass::compute_shared_has_subklass
duke@1 123 bool ciInstanceKlass::compute_shared_has_subklass() {
duke@1 124 GUARDED_VM_ENTRY(
coleenp@13728 125 InstanceKlass* ik = get_instanceKlass();
duke@1 126 _has_subklass = ik->subklass() != NULL;
duke@1 127 return _has_subklass;
duke@1 128 )
duke@1 129 }
duke@1 130
duke@1 131 // ------------------------------------------------------------------
duke@1 132 // ciInstanceKlass::loader
duke@1 133 oop ciInstanceKlass::loader() {
duke@1 134 ASSERT_IN_VM;
duke@1 135 return JNIHandles::resolve(_loader);
duke@1 136 }
duke@1 137
duke@1 138 // ------------------------------------------------------------------
duke@1 139 // ciInstanceKlass::loader_handle
duke@1 140 jobject ciInstanceKlass::loader_handle() {
duke@1 141 return _loader;
duke@1 142 }
duke@1 143
duke@1 144 // ------------------------------------------------------------------
duke@1 145 // ciInstanceKlass::protection_domain
duke@1 146 oop ciInstanceKlass::protection_domain() {
duke@1 147 ASSERT_IN_VM;
duke@1 148 return JNIHandles::resolve(_protection_domain);
duke@1 149 }
duke@1 150
duke@1 151 // ------------------------------------------------------------------
duke@1 152 // ciInstanceKlass::protection_domain_handle
duke@1 153 jobject ciInstanceKlass::protection_domain_handle() {
duke@1 154 return _protection_domain;
duke@1 155 }
duke@1 156
duke@1 157 // ------------------------------------------------------------------
duke@1 158 // ciInstanceKlass::field_cache
duke@1 159 //
duke@1 160 // Get the field cache associated with this klass.
duke@1 161 ciConstantPoolCache* ciInstanceKlass::field_cache() {
duke@1 162 if (is_shared()) {
duke@1 163 return NULL;
duke@1 164 }
duke@1 165 if (_field_cache == NULL) {
duke@1 166 assert(!is_java_lang_Object(), "Object has no fields");
duke@1 167 Arena* arena = CURRENT_ENV->arena();
duke@1 168 _field_cache = new (arena) ciConstantPoolCache(arena, 5);
duke@1 169 }
duke@1 170 return _field_cache;
duke@1 171 }
duke@1 172
duke@1 173 // ------------------------------------------------------------------
duke@1 174 // ciInstanceKlass::get_canonical_holder
duke@1 175 //
duke@1 176 ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) {
duke@1 177 #ifdef ASSERT
duke@1 178 if (!(offset >= 0 && offset < layout_helper())) {
duke@1 179 tty->print("*** get_canonical_holder(%d) on ", offset);
duke@1 180 this->print();
duke@1 181 tty->print_cr(" ***");
duke@1 182 };
duke@1 183 assert(offset >= 0 && offset < layout_helper(), "offset must be tame");
duke@1 184 #endif
duke@1 185
coleenp@360 186 if (offset < instanceOopDesc::base_offset_in_bytes()) {
duke@1 187 // All header offsets belong properly to java/lang/Object.
duke@1 188 return CURRENT_ENV->Object_klass();
duke@1 189 }
duke@1 190
duke@1 191 ciInstanceKlass* self = this;
duke@1 192 for (;;) {
duke@1 193 assert(self->is_loaded(), "must be loaded to have size");
duke@1 194 ciInstanceKlass* super = self->super();
coleenp@360 195 if (super == NULL || super->nof_nonstatic_fields() == 0 ||
coleenp@360 196 !super->contains_field_offset(offset)) {
duke@1 197 return self;
duke@1 198 } else {
duke@1 199 self = super; // return super->get_canonical_holder(offset)
duke@1 200 }
duke@1 201 }
duke@1 202 }
duke@1 203
duke@1 204 // ------------------------------------------------------------------
duke@1 205 // ciInstanceKlass::is_java_lang_Object
duke@1 206 //
duke@1 207 // Is this klass java.lang.Object?
coleenp@13728 208 bool ciInstanceKlass::is_java_lang_Object() const {
duke@1 209 return equals(CURRENT_ENV->Object_klass());
duke@1 210 }
duke@1 211
duke@1 212 // ------------------------------------------------------------------
duke@1 213 // ciInstanceKlass::uses_default_loader
duke@1 214 bool ciInstanceKlass::uses_default_loader() {
twisti@4567 215 // Note: We do not need to resolve the handle or enter the VM
twisti@4567 216 // in order to test null-ness.
twisti@4567 217 return _loader == NULL;
twisti@4567 218 }
twisti@4567 219
twisti@4567 220 // ------------------------------------------------------------------
twisti@4567 221 // ciInstanceKlass::is_in_package
twisti@4567 222 //
twisti@4567 223 // Is this klass in the given package?
twisti@4567 224 bool ciInstanceKlass::is_in_package(const char* packagename, int len) {
twisti@4567 225 // To avoid class loader mischief, this test always rejects application classes.
twisti@4567 226 if (!uses_default_loader())
twisti@4567 227 return false;
twisti@4567 228 GUARDED_VM_ENTRY(
twisti@4567 229 return is_in_package_impl(packagename, len);
twisti@4567 230 )
twisti@4567 231 }
twisti@4567 232
twisti@4567 233 bool ciInstanceKlass::is_in_package_impl(const char* packagename, int len) {
twisti@4567 234 ASSERT_IN_VM;
twisti@4567 235
twisti@4567 236 // If packagename contains trailing '/' exclude it from the
twisti@4567 237 // prefix-test since we test for it explicitly.
twisti@4567 238 if (packagename[len - 1] == '/')
twisti@4567 239 len--;
twisti@4567 240
twisti@4567 241 if (!name()->starts_with(packagename, len))
twisti@4567 242 return false;
twisti@4567 243
twisti@4567 244 // Test if the class name is something like "java/lang".
twisti@4567 245 if ((len + 1) > name()->utf8_length())
twisti@4567 246 return false;
twisti@4567 247
twisti@4567 248 // Test for trailing '/'
twisti@4567 249 if ((char) name()->byte_at(len) != '/')
twisti@4567 250 return false;
twisti@4567 251
twisti@4567 252 // Make sure it's not actually in a subpackage:
twisti@4567 253 if (name()->index_of_at(len+1, "/", 1) >= 0)
twisti@4567 254 return false;
twisti@4567 255
twisti@4567 256 return true;
duke@1 257 }
duke@1 258
duke@1 259 // ------------------------------------------------------------------
duke@1 260 // ciInstanceKlass::print_impl
duke@1 261 //
duke@1 262 // Implementation of the print method.
duke@1 263 void ciInstanceKlass::print_impl(outputStream* st) {
duke@1 264 ciKlass::print_impl(st);
duke@1 265 GUARDED_VM_ENTRY(st->print(" loader=0x%x", (address)loader());)
duke@1 266 if (is_loaded()) {
duke@1 267 st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=",
duke@1 268 bool_to_str(is_initialized()),
duke@1 269 bool_to_str(has_finalizer()),
duke@1 270 bool_to_str(has_subklass()),
duke@1 271 layout_helper());
duke@1 272
duke@1 273 _flags.print_klass_flags();
duke@1 274
duke@1 275 if (_super) {
duke@1 276 st->print(" super=");
duke@1 277 _super->print_name();
duke@1 278 }
duke@1 279 if (_java_mirror) {
duke@1 280 st->print(" mirror=PRESENT");
duke@1 281 }
duke@1 282 } else {
duke@1 283 st->print(" loaded=false");
duke@1 284 }
duke@1 285 }
duke@1 286
duke@1 287 // ------------------------------------------------------------------
duke@1 288 // ciInstanceKlass::super
duke@1 289 //
duke@1 290 // Get the superklass of this klass.
duke@1 291 ciInstanceKlass* ciInstanceKlass::super() {
duke@1 292 assert(is_loaded(), "must be loaded");
duke@1 293 if (_super == NULL && !is_java_lang_Object()) {
duke@1 294 GUARDED_VM_ENTRY(
coleenp@13728 295 Klass* super_klass = get_instanceKlass()->super();
coleenp@13728 296 _super = CURRENT_ENV->get_instance_klass(super_klass);
duke@1 297 )
duke@1 298 }
duke@1 299 return _super;
duke@1 300 }
duke@1 301
duke@1 302 // ------------------------------------------------------------------
duke@1 303 // ciInstanceKlass::java_mirror
duke@1 304 //
duke@1 305 // Get the instance of java.lang.Class corresponding to this klass.
jrose@5884 306 // Cache it on this->_java_mirror.
duke@1 307 ciInstance* ciInstanceKlass::java_mirror() {
never@8725 308 if (is_shared()) {
never@8725 309 return ciKlass::java_mirror();
never@8725 310 }
duke@1 311 if (_java_mirror == NULL) {
jrose@5884 312 _java_mirror = ciKlass::java_mirror();
duke@1 313 }
duke@1 314 return _java_mirror;
duke@1 315 }
duke@1 316
duke@1 317 // ------------------------------------------------------------------
duke@1 318 // ciInstanceKlass::unique_concrete_subklass
duke@1 319 ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() {
duke@1 320 if (!is_loaded()) return NULL; // No change if class is not loaded
duke@1 321 if (!is_abstract()) return NULL; // Only applies to abstract classes.
duke@1 322 if (!has_subklass()) return NULL; // Must have at least one subklass.
duke@1 323 VM_ENTRY_MARK;
coleenp@13728 324 InstanceKlass* ik = get_instanceKlass();
duke@1 325 Klass* up = ik->up_cast_abstract();
coleenp@13728 326 assert(up->oop_is_instance(), "must be InstanceKlass");
duke@1 327 if (ik == up) {
duke@1 328 return NULL;
duke@1 329 }
coleenp@13728 330 return CURRENT_THREAD_ENV->get_instance_klass(up);
duke@1 331 }
duke@1 332
duke@1 333 // ------------------------------------------------------------------
duke@1 334 // ciInstanceKlass::has_finalizable_subclass
duke@1 335 bool ciInstanceKlass::has_finalizable_subclass() {
duke@1 336 if (!is_loaded()) return true;
duke@1 337 VM_ENTRY_MARK;
duke@1 338 return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL;
duke@1 339 }
duke@1 340
duke@1 341 // ------------------------------------------------------------------
duke@1 342 // ciInstanceKlass::get_field_by_offset
duke@1 343 ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) {
duke@1 344 if (!is_static) {
duke@1 345 for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) {
duke@1 346 ciField* field = _nonstatic_fields->at(i);
duke@1 347 int field_off = field->offset_in_bytes();
duke@1 348 if (field_off == field_offset)
duke@1 349 return field;
duke@1 350 if (field_off > field_offset)
duke@1 351 break;
duke@1 352 // could do binary search or check bins, but probably not worth it
duke@1 353 }
duke@1 354 return NULL;
duke@1 355 }
duke@1 356 VM_ENTRY_MARK;
coleenp@13728 357 InstanceKlass* k = get_instanceKlass();
duke@1 358 fieldDescriptor fd;
duke@1 359 if (!k->find_field_from_offset(field_offset, is_static, &fd)) {
duke@1 360 return NULL;
duke@1 361 }
duke@1 362 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
duke@1 363 return field;
duke@1 364 }
duke@1 365
kvn@217 366 // ------------------------------------------------------------------
never@4450 367 // ciInstanceKlass::get_field_by_name
never@4450 368 ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) {
never@4450 369 VM_ENTRY_MARK;
coleenp@13728 370 InstanceKlass* k = get_instanceKlass();
never@4450 371 fieldDescriptor fd;
coleenp@13728 372 Klass* def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd);
never@4450 373 if (def == NULL) {
never@4450 374 return NULL;
never@4450 375 }
never@4450 376 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd);
never@4450 377 return field;
never@4450 378 }
never@4450 379
never@4450 380 // ------------------------------------------------------------------
kvn@217 381 // ciInstanceKlass::non_static_fields.
kvn@217 382
kvn@217 383 class NonStaticFieldFiller: public FieldClosure {
kvn@217 384 GrowableArray<ciField*>* _arr;
kvn@217 385 ciEnv* _curEnv;
kvn@217 386 public:
kvn@217 387 NonStaticFieldFiller(ciEnv* curEnv, GrowableArray<ciField*>* arr) :
kvn@217 388 _curEnv(curEnv), _arr(arr)
kvn@217 389 {}
kvn@217 390 void do_field(fieldDescriptor* fd) {
kvn@217 391 ciField* field = new (_curEnv->arena()) ciField(fd);
kvn@217 392 _arr->append(field);
kvn@217 393 }
kvn@217 394 };
kvn@217 395
kvn@217 396 GrowableArray<ciField*>* ciInstanceKlass::non_static_fields() {
kvn@217 397 if (_non_static_fields == NULL) {
kvn@217 398 VM_ENTRY_MARK;
kvn@217 399 ciEnv* curEnv = ciEnv::current();
coleenp@13728 400 InstanceKlass* ik = get_instanceKlass();
never@10546 401 int max_n_fields = ik->java_fields_count();
kvn@217 402
kvn@6180 403 Arena* arena = curEnv->arena();
kvn@217 404 _non_static_fields =
kvn@6180 405 new (arena) GrowableArray<ciField*>(arena, max_n_fields, 0, NULL);
kvn@217 406 NonStaticFieldFiller filler(curEnv, _non_static_fields);
kvn@217 407 ik->do_nonstatic_fields(&filler);
kvn@217 408 }
kvn@217 409 return _non_static_fields;
kvn@217 410 }
kvn@217 411
duke@1 412 static int sort_field_by_offset(ciField** a, ciField** b) {
duke@1 413 return (*a)->offset_in_bytes() - (*b)->offset_in_bytes();
duke@1 414 // (no worries about 32-bit overflow...)
duke@1 415 }
duke@1 416
duke@1 417 // ------------------------------------------------------------------
duke@1 418 // ciInstanceKlass::compute_nonstatic_fields
duke@1 419 int ciInstanceKlass::compute_nonstatic_fields() {
duke@1 420 assert(is_loaded(), "must be loaded");
duke@1 421
duke@1 422 if (_nonstatic_fields != NULL)
duke@1 423 return _nonstatic_fields->length();
duke@1 424
coleenp@360 425 if (!has_nonstatic_fields()) {
duke@1 426 Arena* arena = CURRENT_ENV->arena();
duke@1 427 _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, NULL);
duke@1 428 return 0;
duke@1 429 }
duke@1 430 assert(!is_java_lang_Object(), "bootstrap OK");
duke@1 431
coleenp@360 432 // Size in bytes of my fields, including inherited fields.
kvn@591 433 int fsize = nonstatic_field_size() * heapOopSize;
coleenp@360 434
duke@1 435 ciInstanceKlass* super = this->super();
duke@1 436 GrowableArray<ciField*>* super_fields = NULL;
coleenp@360 437 if (super != NULL && super->has_nonstatic_fields()) {
kvn@591 438 int super_fsize = super->nonstatic_field_size() * heapOopSize;
coleenp@360 439 int super_flen = super->nof_nonstatic_fields();
duke@1 440 super_fields = super->_nonstatic_fields;
duke@1 441 assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
coleenp@360 442 // See if I am no larger than my super; if so, I can use his fields.
coleenp@360 443 if (fsize == super_fsize) {
coleenp@360 444 _nonstatic_fields = super_fields;
coleenp@360 445 return super_fields->length();
coleenp@360 446 }
duke@1 447 }
duke@1 448
duke@1 449 GrowableArray<ciField*>* fields = NULL;
duke@1 450 GUARDED_VM_ENTRY({
duke@1 451 fields = compute_nonstatic_fields_impl(super_fields);
duke@1 452 });
duke@1 453
duke@1 454 if (fields == NULL) {
duke@1 455 // This can happen if this class (java.lang.Class) has invisible fields.
duke@1 456 _nonstatic_fields = super_fields;
duke@1 457 return super_fields->length();
duke@1 458 }
duke@1 459
duke@1 460 int flen = fields->length();
duke@1 461
duke@1 462 // Now sort them by offset, ascending.
duke@1 463 // (In principle, they could mix with superclass fields.)
duke@1 464 fields->sort(sort_field_by_offset);
duke@1 465 _nonstatic_fields = fields;
duke@1 466 return flen;
duke@1 467 }
duke@1 468
duke@1 469 GrowableArray<ciField*>*
duke@1 470 ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>*
duke@1 471 super_fields) {
duke@1 472 ASSERT_IN_VM;
duke@1 473 Arena* arena = CURRENT_ENV->arena();
duke@1 474 int flen = 0;
duke@1 475 GrowableArray<ciField*>* fields = NULL;
coleenp@13728 476 InstanceKlass* k = get_instanceKlass();
never@10546 477 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
never@10546 478 if (fs.access_flags().is_static()) continue;
never@10546 479 flen += 1;
never@10546 480 }
duke@1 481
never@10546 482 // allocate the array:
never@10546 483 if (flen == 0) {
never@10546 484 return NULL; // return nothing if none are locally declared
never@10546 485 }
never@10546 486 if (super_fields != NULL) {
never@10546 487 flen += super_fields->length();
never@10546 488 }
never@10546 489 fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, NULL);
never@10546 490 if (super_fields != NULL) {
never@10546 491 fields->appendAll(super_fields);
never@10546 492 }
never@10546 493
never@10546 494 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
never@10546 495 if (fs.access_flags().is_static()) continue;
never@10546 496 fieldDescriptor fd;
coleenp@13728 497 fd.initialize(k, fs.index());
never@10546 498 ciField* field = new (arena) ciField(&fd);
never@10546 499 fields->append(field);
duke@1 500 }
duke@1 501 assert(fields->length() == flen, "sanity");
duke@1 502 return fields;
duke@1 503 }
duke@1 504
duke@1 505 // ------------------------------------------------------------------
duke@1 506 // ciInstanceKlass::find_method
duke@1 507 //
duke@1 508 // Find a method in this klass.
duke@1 509 ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) {
duke@1 510 VM_ENTRY_MARK;
coleenp@13728 511 InstanceKlass* k = get_instanceKlass();
coleenp@8076 512 Symbol* name_sym = name->get_symbol();
coleenp@8076 513 Symbol* sig_sym= signature->get_symbol();
duke@1 514
coleenp@13728 515 Method* m = k->find_method(name_sym, sig_sym);
duke@1 516 if (m == NULL) return NULL;
duke@1 517
coleenp@13728 518 return CURRENT_THREAD_ENV->get_method(m);
duke@1 519 }
duke@1 520
duke@1 521 // ------------------------------------------------------------------
duke@1 522 // ciInstanceKlass::is_leaf_type
duke@1 523 bool ciInstanceKlass::is_leaf_type() {
duke@1 524 assert(is_loaded(), "must be loaded");
duke@1 525 if (is_shared()) {
duke@1 526 return is_final(); // approximately correct
duke@1 527 } else {
jiangli@12369 528 return !_has_subklass && (nof_implementors() == 0);
duke@1 529 }
duke@1 530 }
duke@1 531
duke@1 532 // ------------------------------------------------------------------
duke@1 533 // ciInstanceKlass::implementor
duke@1 534 //
duke@1 535 // Report an implementor of this interface.
duke@1 536 // Note that there are various races here, since my copy
duke@1 537 // of _nof_implementors might be out of date with respect
coleenp@13728 538 // to results returned by InstanceKlass::implementor.
duke@1 539 // This is OK, since any dependencies we decide to assert
duke@1 540 // will be checked later under the Compile_lock.
jiangli@12369 541 ciInstanceKlass* ciInstanceKlass::implementor() {
jiangli@12369 542 ciInstanceKlass* impl = _implementor;
duke@1 543 if (impl == NULL) {
duke@1 544 // Go into the VM to fetch the implementor.
duke@1 545 {
duke@1 546 VM_ENTRY_MARK;
coleenp@13728 547 Klass* k = get_instanceKlass()->implementor();
duke@1 548 if (k != NULL) {
coleenp@13728 549 if (k == get_instanceKlass()) {
jiangli@12369 550 // More than one implementors. Use 'this' in this case.
jiangli@12369 551 impl = this;
jiangli@12369 552 } else {
coleenp@13728 553 impl = CURRENT_THREAD_ENV->get_instance_klass(k);
jiangli@12369 554 }
duke@1 555 }
duke@1 556 }
duke@1 557 // Memoize this result.
duke@1 558 if (!is_shared()) {
jiangli@12369 559 _implementor = impl;
duke@1 560 }
duke@1 561 }
duke@1 562 return impl;
duke@1 563 }
minqi@14477 564
minqi@14477 565 // Utility class for printing of the contents of the static fields for
minqi@14477 566 // use by compilation replay. It only prints out the information that
minqi@14477 567 // could be consumed by the compiler, so for primitive types it prints
minqi@14477 568 // out the actual value. For Strings it's the actual string value.
minqi@14477 569 // For array types it it's first level array size since that's the
minqi@14477 570 // only value which statically unchangeable. For all other reference
minqi@14477 571 // types it simply prints out the dynamic type.
minqi@14477 572
minqi@14477 573 class StaticFinalFieldPrinter : public FieldClosure {
minqi@14477 574 outputStream* _out;
minqi@14477 575 const char* _holder;
minqi@14477 576 public:
minqi@14477 577 StaticFinalFieldPrinter(outputStream* out, const char* holder) :
minqi@14477 578 _out(out),
minqi@14477 579 _holder(holder) {
minqi@14477 580 }
minqi@14477 581 void do_field(fieldDescriptor* fd) {
minqi@14477 582 if (fd->is_final() && !fd->has_initial_value()) {
minqi@14477 583 oop mirror = fd->field_holder()->java_mirror();
minqi@14477 584 _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
minqi@14477 585 switch (fd->field_type()) {
minqi@14477 586 case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break;
minqi@14477 587 case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break;
minqi@14477 588 case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break;
minqi@14477 589 case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break;
minqi@14477 590 case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break;
minqi@14477 591 case T_LONG: _out->print_cr(INT64_FORMAT, mirror->long_field(fd->offset())); break;
minqi@14477 592 case T_FLOAT: {
minqi@14477 593 float f = mirror->float_field(fd->offset());
minqi@14477 594 _out->print_cr("%d", *(int*)&f);
minqi@14477 595 break;
minqi@14477 596 }
minqi@14477 597 case T_DOUBLE: {
minqi@14477 598 double d = mirror->double_field(fd->offset());
minqi@14477 599 _out->print_cr(INT64_FORMAT, *(jlong*)&d);
minqi@14477 600 break;
minqi@14477 601 }
minqi@14477 602 case T_ARRAY: {
minqi@14477 603 oop value = mirror->obj_field_acquire(fd->offset());
minqi@14477 604 if (value == NULL) {
minqi@14477 605 _out->print_cr("null");
minqi@14477 606 } else {
minqi@14477 607 typeArrayOop ta = (typeArrayOop)value;
minqi@14477 608 _out->print("%d", ta->length());
minqi@14477 609 if (value->is_objArray()) {
minqi@14477 610 objArrayOop oa = (objArrayOop)value;
minqi@14477 611 const char* klass_name = value->klass()->name()->as_quoted_ascii();
minqi@14477 612 _out->print(" %s", klass_name);
minqi@14477 613 }
minqi@14477 614 _out->cr();
minqi@14477 615 }
minqi@14477 616 break;
minqi@14477 617 }
minqi@14477 618 case T_OBJECT: {
minqi@14477 619 oop value = mirror->obj_field_acquire(fd->offset());
minqi@14477 620 if (value == NULL) {
minqi@14477 621 _out->print_cr("null");
minqi@14477 622 } else if (value->is_instance()) {
minqi@14477 623 if (value->is_a(SystemDictionary::String_klass())) {
minqi@14477 624 _out->print("\"");
minqi@14477 625 _out->print_raw(java_lang_String::as_quoted_ascii(value));
minqi@14477 626 _out->print_cr("\"");
minqi@14477 627 } else {
minqi@14477 628 const char* klass_name = value->klass()->name()->as_quoted_ascii();
minqi@14477 629 _out->print_cr(klass_name);
minqi@14477 630 }
minqi@14477 631 } else {
minqi@14477 632 ShouldNotReachHere();
minqi@14477 633 }
minqi@14477 634 break;
minqi@14477 635 }
minqi@14477 636 default:
minqi@14477 637 ShouldNotReachHere();
minqi@14477 638 }
minqi@14477 639 }
minqi@14477 640 }
minqi@14477 641 };
minqi@14477 642
minqi@14477 643
minqi@14477 644 void ciInstanceKlass::dump_replay_data(outputStream* out) {
minqi@14477 645 ASSERT_IN_VM;
minqi@14477 646 InstanceKlass* ik = get_instanceKlass();
minqi@14477 647 ConstantPool* cp = ik->constants();
minqi@14477 648
minqi@14477 649 // Try to record related loaded classes
minqi@14477 650 Klass* sub = ik->subklass();
minqi@14477 651 while (sub != NULL) {
minqi@14477 652 if (sub->oop_is_instance()) {
minqi@14477 653 out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());
minqi@14477 654 }
minqi@14477 655 sub = sub->next_sibling();
minqi@14477 656 }
minqi@14477 657
minqi@14477 658 // Dump out the state of the constant pool tags. During replay the
minqi@14477 659 // tags will be validated for things which shouldn't change and
minqi@14477 660 // classes will be resolved if the tags indicate that they were
minqi@14477 661 // resolved at compile time.
minqi@14477 662 out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(),
minqi@14477 663 is_linked(), is_initialized(), cp->length());
minqi@14477 664 for (int index = 1; index < cp->length(); index++) {
minqi@14477 665 out->print(" %d", cp->tags()->at(index));
minqi@14477 666 }
minqi@14477 667 out->cr();
minqi@14477 668 if (is_initialized()) {
minqi@14477 669 // Dump out the static final fields in case the compilation relies
minqi@14477 670 // on their value for correct replay.
minqi@14477 671 StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii());
minqi@14477 672 ik->do_local_static_fields(&sffp);
minqi@14477 673 }
minqi@14477 674 }