src/share/vm/ci/ciInstanceKlass.cpp

Mon, 12 Nov 2012 14:03:53 -0800

author
minqi
date
Mon, 12 Nov 2012 14:03:53 -0800
changeset 4267
bd7a7ce2e264
parent 4037
da91efe96a93
child 4531
fcc9e7681d63
permissions
-rw-r--r--

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

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

mercurial