ciObjectFactory.cpp revision 5776:de6a9e811145
1254721Semaste/* 2254721Semaste * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 3353358Sdim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4353358Sdim * 5353358Sdim * This code is free software; you can redistribute it and/or modify it 6254721Semaste * under the terms of the GNU General Public License version 2 only, as 7254721Semaste * published by the Free Software Foundation. 8254721Semaste * 9254721Semaste * This code is distributed in the hope that it will be useful, but WITHOUT 10254721Semaste * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11254721Semaste * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12296417Sdim * version 2 for more details (a copy is included in the LICENSE file that 13296417Sdim * accompanied this code). 14280031Sdim * 15296417Sdim * You should have received a copy of the GNU General Public License version 16280031Sdim * 2 along with this work; if not, write to the Free Software Foundation, 17280031Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18314564Sdim * 19254721Semaste * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20327952Sdim * or visit www.oracle.com if you need additional information or have any 21254721Semaste * questions. 22254721Semaste * 23254721Semaste */ 24344779Sdim 25321369Sdim#include "precompiled.hpp" 26321369Sdim#include "ci/ciCallSite.hpp" 27254721Semaste#include "ci/ciInstance.hpp" 28254721Semaste#include "ci/ciInstanceKlass.hpp" 29254721Semaste#include "ci/ciMemberName.hpp" 30353358Sdim#include "ci/ciMethod.hpp" 31341825Sdim#include "ci/ciMethodData.hpp" 32254721Semaste#include "ci/ciMethodHandle.hpp" 33254721Semaste#include "ci/ciMethodType.hpp" 34314564Sdim#include "ci/ciNullObject.hpp" 35314564Sdim#include "ci/ciObjArray.hpp" 36314564Sdim#include "ci/ciObjArrayKlass.hpp" 37341825Sdim#include "ci/ciObject.hpp" 38254721Semaste#include "ci/ciObjectFactory.hpp" 39254721Semaste#include "ci/ciSymbol.hpp" 40341825Sdim#include "ci/ciTypeArray.hpp" 41341825Sdim#include "ci/ciTypeArrayKlass.hpp" 42341825Sdim#include "ci/ciUtilities.hpp" 43341825Sdim#include "classfile/systemDictionary.hpp" 44254721Semaste#include "gc_interface/collectedHeap.inline.hpp" 45254721Semaste#include "memory/allocation.inline.hpp" 46341825Sdim#include "oops/oop.inline.hpp" 47341825Sdim#include "oops/oop.inline2.hpp" 48254721Semaste#include "runtime/fieldType.hpp" 49254721Semaste 50314564Sdim// ciObjectFactory 51341825Sdim// 52254721Semaste// This class handles requests for the creation of new instances 53254721Semaste// of ciObject and its subclasses. It contains a caching mechanism 54341825Sdim// which ensures that for each oop, at most one ciObject is created. 55341825Sdim// This invariant allows more efficient implementation of ciObject. 56341825Sdim// 57341825Sdim// Implementation note: the oop->ciObject mapping is represented as 58341825Sdim// a table stored in an array. Even though objects are moved 59254721Semaste// by the garbage collector, the compactor preserves their relative 60254721Semaste// order; address comparison of oops (in perm space) is safe so long 61254721Semaste// as we prohibit GC during our comparisons. We currently use binary 62254721Semaste// search to find the oop in the table, and inserting a new oop 63254721Semaste// into the table may be costly. If this cost ends up being 64254721Semaste// problematic the underlying data structure can be switched to some 65254721Semaste// sort of balanced binary tree. 66314564Sdim 67341825SdimGrowableArray<ciMetadata*>* ciObjectFactory::_shared_ci_metadata = NULL; 68341825SdimciSymbol* ciObjectFactory::_shared_ci_symbols[vmSymbols::SID_LIMIT]; 69341825Sdimint ciObjectFactory::_shared_ident_limit = 0; 70341825Sdimvolatile bool ciObjectFactory::_initialized = false; 71341825Sdim 72314564Sdim 73341825Sdim// ------------------------------------------------------------------ 74341825Sdim// ciObjectFactory::ciObjectFactory 75341825SdimciObjectFactory::ciObjectFactory(Arena* arena, 76341825Sdim int expected_size) { 77341825Sdim 78314564Sdim for (int i = 0; i < NON_PERM_BUCKETS; i++) { 79314564Sdim _non_perm_bucket[i] = NULL; 80254721Semaste } 81353358Sdim _non_perm_count = 0; 82254721Semaste 83341825Sdim _next_ident = _shared_ident_limit; 84341825Sdim _arena = arena; 85353358Sdim _ci_metadata = new (arena) GrowableArray<ciMetadata*>(arena, expected_size, 0, NULL); 86254721Semaste 87314564Sdim // If the shared ci objects exist append them to this factory's objects 88314564Sdim 89254721Semaste if (_shared_ci_metadata != NULL) { 90314564Sdim _ci_metadata->appendAll(_shared_ci_metadata); 91314564Sdim } 92296417Sdim 93314564Sdim _unloaded_methods = new (arena) GrowableArray<ciMethod*>(arena, 4, 0, NULL); 94314564Sdim _unloaded_klasses = new (arena) GrowableArray<ciKlass*>(arena, 8, 0, NULL); 95314564Sdim _unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL); 96254721Semaste _return_addresses = 97314564Sdim new (arena) GrowableArray<ciReturnAddress*>(arena, 8, 0, NULL); 98314564Sdim 99314564Sdim _symbols = new (arena) GrowableArray<ciSymbol*>(arena, 100, 0, NULL); 100314564Sdim} 101314564Sdim 102254721Semaste// ------------------------------------------------------------------ 103314564Sdim// ciObjectFactory::ciObjectFactory 104254721Semastevoid ciObjectFactory::initialize() { 105353358Sdim ASSERT_IN_VM; 106254721Semaste JavaThread* thread = JavaThread::current(); 107353358Sdim HandleMark handle_mark(thread); 108254721Semaste 109314564Sdim // This Arena is long lived and exists in the resource mark of the 110254721Semaste // compiler thread that initializes the initial ciObjectFactory which 111314564Sdim // creates the shared ciObjects that all later ciObjectFactories use. 112254721Semaste Arena* arena = new (mtCompiler) Arena(); 113314564Sdim ciEnv initial(arena); 114314564Sdim ciEnv* env = ciEnv::current(); 115314564Sdim env->_factory->init_shared_objects(); 116254721Semaste 117314564Sdim _initialized = true; 118254721Semaste 119314564Sdim} 120314564Sdim 121254721Semastevoid ciObjectFactory::init_shared_objects() { 122314564Sdim 123314564Sdim _next_ident = 1; // start numbering CI objects at 1 124254721Semaste 125314564Sdim { 126314564Sdim // Create the shared symbols, but not in _shared_ci_metadata. 127314564Sdim int i; 128288943Sdim for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { 129314564Sdim Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i); 130314564Sdim assert(vmSymbols::find_sid(vmsym) == i, "1-1 mapping"); 131288943Sdim ciSymbol* sym = new (_arena) ciSymbol(vmsym, (vmSymbols::SID) i); 132314564Sdim init_ident_of(sym); 133314564Sdim _shared_ci_symbols[i] = sym; 134288943Sdim } 135314564Sdim#ifdef ASSERT 136314564Sdim for (i = vmSymbols::FIRST_SID; i < vmSymbols::SID_LIMIT; i++) { 137314564Sdim Symbol* vmsym = vmSymbols::symbol_at((vmSymbols::SID) i); 138314564Sdim ciSymbol* sym = vm_symbol_at((vmSymbols::SID) i); 139288943Sdim assert(sym->get_symbol() == vmsym, "oop must match"); 140314564Sdim } 141314564Sdim assert(ciSymbol::void_class_signature()->get_symbol() == vmSymbols::void_class_signature(), "spot check"); 142288943Sdim#endif 143314564Sdim } 144314564Sdim 145321369Sdim _ci_metadata = new (_arena) GrowableArray<ciMetadata*>(_arena, 64, 0, NULL); 146254721Semaste 147314564Sdim for (int i = T_BOOLEAN; i <= T_CONFLICT; i++) { 148314564Sdim BasicType t = (BasicType)i; 149314564Sdim if (type2name(t) != NULL && t != T_OBJECT && t != T_ARRAY && t != T_NARROWOOP && t != T_NARROWKLASS) { 150254721Semaste ciType::_basic_types[t] = new (_arena) ciType(t); 151314564Sdim init_ident_of(ciType::_basic_types[t]); 152254721Semaste } 153314564Sdim } 154314564Sdim 155314564Sdim ciEnv::_null_object_instance = new (_arena) ciNullObject(); 156341825Sdim init_ident_of(ciEnv::_null_object_instance); 157341825Sdim 158341825Sdim#define WK_KLASS_DEFN(name, ignore_s, opt) \ 159314564Sdim if (SystemDictionary::name() != NULL) \ 160254721Semaste ciEnv::_##name = get_metadata(SystemDictionary::name())->as_instance_klass(); 161314564Sdim 162254721Semaste WK_KLASSES_DO(WK_KLASS_DEFN) 163353358Sdim#undef WK_KLASS_DEFN 164314564Sdim 165314564Sdim for (int len = -1; len != _ci_metadata->length(); ) { 166254721Semaste len = _ci_metadata->length(); 167314564Sdim for (int i2 = 0; i2 < len; i2++) { 168314564Sdim ciMetadata* obj = _ci_metadata->at(i2); 169254721Semaste assert (obj->is_metadata(), "what else would it be?"); 170341825Sdim if (obj->is_loaded() && obj->is_instance_klass()) { 171341825Sdim obj->as_instance_klass()->compute_nonstatic_fields(); 172254721Semaste } 173341825Sdim } 174341825Sdim } 175314564Sdim 176254721Semaste ciEnv::_unloaded_cisymbol = ciObjectFactory::get_symbol(vmSymbols::dummy_symbol()); 177314564Sdim // Create dummy InstanceKlass and ObjArrayKlass object and assign them idents 178314564Sdim ciEnv::_unloaded_ciinstance_klass = new (_arena) ciInstanceKlass(ciEnv::_unloaded_cisymbol, NULL, NULL); 179314564Sdim init_ident_of(ciEnv::_unloaded_ciinstance_klass); 180254721Semaste ciEnv::_unloaded_ciobjarrayklass = new (_arena) ciObjArrayKlass(ciEnv::_unloaded_cisymbol, ciEnv::_unloaded_ciinstance_klass, 1); 181341825Sdim init_ident_of(ciEnv::_unloaded_ciobjarrayklass); 182341825Sdim assert(ciEnv::_unloaded_ciobjarrayklass->is_obj_array_klass(), "just checking"); 183314564Sdim 184353358Sdim get_metadata(Universe::boolArrayKlassObj()); 185314564Sdim get_metadata(Universe::charArrayKlassObj()); 186314564Sdim get_metadata(Universe::singleArrayKlassObj()); 187353358Sdim get_metadata(Universe::doubleArrayKlassObj()); 188314564Sdim get_metadata(Universe::byteArrayKlassObj()); 189314564Sdim get_metadata(Universe::shortArrayKlassObj()); 190314564Sdim get_metadata(Universe::intArrayKlassObj()); 191314564Sdim get_metadata(Universe::longArrayKlassObj()); 192254721Semaste 193341825Sdim 194341825Sdim 195314564Sdim assert(_non_perm_count == 0, "no shared non-perm objects"); 196360784Sdim 197314564Sdim // The shared_ident_limit is the first ident number that will 198314564Sdim // be used for non-shared objects. That is, numbers less than 199353358Sdim // this limit are permanently assigned to shared CI objects, 200314564Sdim // while the higher numbers are recycled afresh by each new ciEnv. 201314564Sdim 202314564Sdim _shared_ident_limit = _next_ident; 203254721Semaste _shared_ci_metadata = _ci_metadata; 204314564Sdim} 205314564Sdim 206314564Sdim 207314564SdimciSymbol* ciObjectFactory::get_symbol(Symbol* key) { 208360784Sdim vmSymbols::SID sid = vmSymbols::find_sid(key); 209314564Sdim if (sid != vmSymbols::NO_SID) { 210353358Sdim // do not pollute the main cache with it 211314564Sdim return vm_symbol_at(sid); 212353358Sdim } 213314564Sdim 214314564Sdim assert(vmSymbols::find_sid(key) == vmSymbols::NO_SID, ""); 215314564Sdim ciSymbol* s = new (arena()) ciSymbol(key, vmSymbols::NO_SID); 216314564Sdim _symbols->push(s); 217254721Semaste return s; 218341825Sdim} 219341825Sdim 220341825Sdim// Decrement the refcount when done on symbols referenced by this compilation. 221314564Sdimvoid ciObjectFactory::remove_symbols() { 222353358Sdim for (int i = 0; i < _symbols->length(); i++) { 223314564Sdim ciSymbol* s = _symbols->at(i); 224353358Sdim s->get_symbol()->decrement_refcount(); 225314564Sdim } 226314564Sdim // Since _symbols is resource allocated we're not allowed to delete it 227314564Sdim // but it'll go away just the same. 228254721Semaste} 229341825Sdim 230341825Sdim// ------------------------------------------------------------------ 231254721Semaste// ciObjectFactory::get 232341825Sdim// 233341825Sdim// Get the ciObject corresponding to some oop. If the ciObject has 234314564Sdim// already been created, it is returned. Otherwise, a new ciObject 235353358Sdim// is created. 236314564SdimciObject* ciObjectFactory::get(oop key) { 237353358Sdim ASSERT_IN_VM; 238314564Sdim 239314564Sdim assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be"); 240353358Sdim 241314564Sdim NonPermObject* &bucket = find_non_perm(key); 242314564Sdim if (bucket != NULL) { 243314564Sdim return bucket->object(); 244254721Semaste } 245314564Sdim 246314564Sdim // The ciObject does not yet exist. Create it and insert it 247353358Sdim // into the cache. 248314564Sdim Handle keyHandle(key); 249353358Sdim ciObject* new_object = create_new_object(keyHandle()); 250314564Sdim assert(keyHandle() == new_object->get_oop(), "must be properly recorded"); 251314564Sdim init_ident_of(new_object); 252314564Sdim assert(Universe::heap()->is_in_reserved(new_object->get_oop()), "must be"); 253314564Sdim 254254721Semaste // Not a perm-space object. 255314564Sdim insert_non_perm(bucket, keyHandle(), new_object); 256314564Sdim return new_object; 257353358Sdim} 258314564Sdim 259353358Sdim// ------------------------------------------------------------------ 260314564Sdim// ciObjectFactory::get 261314564Sdim// 262314564Sdim// Get the ciObject corresponding to some oop. If the ciObject has 263254721Semaste// already been created, it is returned. Otherwise, a new ciObject 264314564Sdim// is created. 265314564SdimciMetadata* ciObjectFactory::get_metadata(Metadata* key) { 266353358Sdim ASSERT_IN_VM; 267314564Sdim 268353358Sdim#ifdef ASSERT 269314564Sdim if (CIObjectFactoryVerify) { 270314564Sdim Metadata* last = NULL; 271314564Sdim for (int j = 0; j< _ci_metadata->length(); j++) { 272314564Sdim Metadata* o = _ci_metadata->at(j)->constant_encoding(); 273314564Sdim assert(last < o, "out of order"); 274254721Semaste last = o; 275314564Sdim } 276314564Sdim } 277353358Sdim#endif // ASSERT 278314564Sdim int len = _ci_metadata->length(); 279314564Sdim int index = find(key, _ci_metadata); 280353358Sdim#ifdef ASSERT 281314564Sdim if (CIObjectFactoryVerify) { 282314564Sdim for (int i=0; i<_ci_metadata->length(); i++) { 283314564Sdim if (_ci_metadata->at(i)->constant_encoding() == key) { 284314564Sdim assert(index == i, " bad lookup"); 285254721Semaste } 286314564Sdim } 287314564Sdim } 288314564Sdim#endif 289341825Sdim if (!is_found_at(index, key, _ci_metadata)) { 290341825Sdim // The ciObject does not yet exist. Create it and insert it 291341825Sdim // into the cache. 292314564Sdim ciMetadata* new_object = create_new_object(key); 293341825Sdim init_ident_of(new_object); 294341825Sdim assert(new_object->is_metadata(), "must be"); 295314564Sdim 296353358Sdim if (len != _ci_metadata->length()) { 297314564Sdim // creating the new object has recursively entered new objects 298314564Sdim // into the table. We need to recompute our index. 299314564Sdim index = find(key, _ci_metadata); 300254721Semaste } 301314564Sdim assert(!is_found_at(index, key, _ci_metadata), "no double insert"); 302254721Semaste insert(index, new_object, _ci_metadata); 303314564Sdim return new_object; 304314564Sdim } 305254721Semaste return _ci_metadata->at(index)->as_metadata(); 306314564Sdim} 307353358Sdim 308314564Sdim// ------------------------------------------------------------------ 309314564Sdim// ciObjectFactory::create_new_object 310254721Semaste// 311314564Sdim// Create a new ciObject from an oop. 312353358Sdim// 313314564Sdim// Implementation note: this functionality could be virtual behavior 314314564Sdim// of the oop itself. For now, we explicitly marshal the object. 315254721SemasteciObject* ciObjectFactory::create_new_object(oop o) { 316314564Sdim EXCEPTION_CONTEXT; 317353358Sdim 318314564Sdim if (o->is_instance()) { 319314564Sdim instanceHandle h_i(THREAD, (instanceOop)o); 320254721Semaste if (java_lang_invoke_CallSite::is_instance(o)) 321353358Sdim return new (arena()) ciCallSite(h_i); 322314564Sdim else if (java_lang_invoke_MemberName::is_instance(o)) 323314564Sdim return new (arena()) ciMemberName(h_i); 324254721Semaste else if (java_lang_invoke_MethodHandle::is_instance(o)) 325314564Sdim return new (arena()) ciMethodHandle(h_i); 326314564Sdim else if (java_lang_invoke_MethodType::is_instance(o)) 327254721Semaste return new (arena()) ciMethodType(h_i); 328314564Sdim else 329353358Sdim return new (arena()) ciInstance(h_i); 330314564Sdim } else if (o->is_objArray()) { 331314564Sdim objArrayHandle h_oa(THREAD, (objArrayOop)o); 332254721Semaste return new (arena()) ciObjArray(h_oa); 333341825Sdim } else if (o->is_typeArray()) { 334341825Sdim typeArrayHandle h_ta(THREAD, (typeArrayOop)o); 335327952Sdim return new (arena()) ciTypeArray(h_ta); 336327952Sdim } 337327952Sdim 338353358Sdim // The oop is of some type not supported by the compiler interface. 339327952Sdim ShouldNotReachHere(); 340327952Sdim return NULL; 341327952Sdim} 342314564Sdim 343353358Sdim// ------------------------------------------------------------------ 344314564Sdim// ciObjectFactory::create_new_object 345314564Sdim// 346254721Semaste// Create a new ciObject from a Metadata*. 347314564Sdim// 348353358Sdim// Implementation note: this functionality could be virtual behavior 349314564Sdim// of the oop itself. For now, we explicitly marshal the object. 350314564SdimciMetadata* ciObjectFactory::create_new_object(Metadata* o) { 351314564Sdim EXCEPTION_CONTEXT; 352254721Semaste 353314564Sdim if (o->is_klass()) { 354280031Sdim KlassHandle h_k(THREAD, (Klass*)o); 355314564Sdim Klass* k = (Klass*)o; 356254721Semaste if (k->oop_is_instance()) { 357314564Sdim return new (arena()) ciInstanceKlass(h_k); 358254721Semaste } else if (k->oop_is_objArray()) { 359314564Sdim return new (arena()) ciObjArrayKlass(h_k); 360254721Semaste } else if (k->oop_is_typeArray()) { 361314564Sdim return new (arena()) ciTypeArrayKlass(h_k); 362254721Semaste } 363314564Sdim } else if (o->is_method()) { 364254721Semaste methodHandle h_m(THREAD, (Method*)o); 365314564Sdim return new (arena()) ciMethod(h_m); 366314564Sdim } else if (o->is_methodData()) { 367353358Sdim // Hold methodHandle alive - might not be necessary ??? 368314564Sdim methodHandle h_m(THREAD, ((MethodData*)o)->method()); 369353358Sdim return new (arena()) ciMethodData((MethodData*)o); 370314564Sdim } 371353358Sdim 372314564Sdim // The oop is of some type not supported by the compiler interface. 373314564Sdim ShouldNotReachHere(); 374314564Sdim return NULL; 375314564Sdim} 376314564Sdim 377258054Semaste//------------------------------------------------------------------ 378314564Sdim// ciObjectFactory::get_unloaded_method 379314564Sdim// 380314564Sdim// Get the ciMethod representing an unloaded/unfound method. 381280031Sdim// 382314564Sdim// Implementation note: unloaded methods are currently stored in 383280031Sdim// an unordered array, requiring a linear-time lookup for each 384314564Sdim// unloaded method. This may need to change. 385314564SdimciMethod* ciObjectFactory::get_unloaded_method(ciInstanceKlass* holder, 386353358Sdim ciSymbol* name, 387314564Sdim ciSymbol* signature, 388314564Sdim ciInstanceKlass* accessor) { 389314564Sdim ciSignature* that = NULL; 390280031Sdim for (int i = 0; i < _unloaded_methods->length(); i++) { 391314564Sdim ciMethod* entry = _unloaded_methods->at(i); 392314564Sdim if (entry->holder()->equals(holder) && 393353358Sdim entry->name()->equals(name) && 394314564Sdim entry->signature()->as_symbol()->equals(signature)) { 395314564Sdim // Short-circuit slow resolve. 396314564Sdim if (entry->signature()->accessing_klass() == accessor) { 397280031Sdim // We've found a match. 398314564Sdim return entry; 399280031Sdim } else { 400341825Sdim // Lazily create ciSignature 401341825Sdim if (that == NULL) that = new (arena()) ciSignature(accessor, constantPoolHandle(), signature); 402314564Sdim if (entry->signature()->equals(that)) { 403353358Sdim // We've found a match. 404314564Sdim return entry; 405314564Sdim } 406280031Sdim } 407344779Sdim } 408344779Sdim } 409353358Sdim 410344779Sdim // This is a new unloaded method. Create it and stick it in 411344779Sdim // the cache. 412344779Sdim ciMethod* new_method = new (arena()) ciMethod(holder, name, signature, accessor); 413314564Sdim 414314564Sdim init_ident_of(new_method); 415353358Sdim _unloaded_methods->append(new_method); 416314564Sdim 417314564Sdim return new_method; 418288943Sdim} 419314564Sdim 420314564Sdim//------------------------------------------------------------------ 421353358Sdim// ciObjectFactory::get_unloaded_klass 422314564Sdim// 423314564Sdim// Get a ciKlass representing an unloaded klass. 424353358Sdim// 425314564Sdim// Implementation note: unloaded klasses are currently stored in 426314564Sdim// an unordered array, requiring a linear-time lookup for each 427314564Sdim// unloaded klass. This may need to change. 428353358SdimciKlass* ciObjectFactory::get_unloaded_klass(ciKlass* accessing_klass, 429314564Sdim ciSymbol* name, 430314564Sdim bool create_if_not_found) { 431288943Sdim EXCEPTION_CONTEXT; 432314564Sdim oop loader = NULL; 433341825Sdim oop domain = NULL; 434341825Sdim if (accessing_klass != NULL) { 435341825Sdim loader = accessing_klass->loader(); 436314564Sdim domain = accessing_klass->protection_domain(); 437353358Sdim } 438314564Sdim for (int i=0; i<_unloaded_klasses->length(); i++) { 439314564Sdim ciKlass* entry = _unloaded_klasses->at(i); 440314564Sdim if (entry->name()->equals(name) && 441314564Sdim entry->loader() == loader && 442314564Sdim entry->protection_domain() == domain) { 443353358Sdim // We've found a match. 444314564Sdim return entry; 445314564Sdim } 446314564Sdim } 447314564Sdim 448353358Sdim if (!create_if_not_found) 449314564Sdim return NULL; 450314564Sdim 451314564Sdim // This is a new unloaded klass. Create it and stick it in 452314564Sdim // the cache. 453314564Sdim ciKlass* new_klass = NULL; 454314564Sdim 455314564Sdim // Two cases: this is an unloaded ObjArrayKlass or an 456314564Sdim // unloaded InstanceKlass. Deal with both. 457314564Sdim if (name->byte_at(0) == '[') { 458314564Sdim // Decompose the name.' 459341825Sdim FieldArrayInfo fd; 460341825Sdim BasicType element_type = FieldType::get_array_info(name->get_symbol(), 461341825Sdim fd, THREAD); 462314564Sdim if (HAS_PENDING_EXCEPTION) { 463353358Sdim CLEAR_PENDING_EXCEPTION; 464314564Sdim CURRENT_THREAD_ENV->record_out_of_memory_failure(); 465314564Sdim return ciEnv::_unloaded_ciobjarrayklass; 466314564Sdim } 467314564Sdim int dimension = fd.dimension(); 468314564Sdim assert(element_type != T_ARRAY, "unsuccessful decomposition"); 469314564Sdim ciKlass* element_klass = NULL; 470314564Sdim if (element_type == T_OBJECT) { 471353358Sdim ciEnv *env = CURRENT_THREAD_ENV; 472314564Sdim ciSymbol* ci_name = env->get_symbol(fd.object_key()); 473314564Sdim element_klass = 474314564Sdim env->get_klass_by_name(accessing_klass, ci_name, false)->as_instance_klass(); 475314564Sdim } else { 476314564Sdim assert(dimension > 1, "one dimensional type arrays are always loaded."); 477314564Sdim 478314564Sdim // The type array itself takes care of one of the dimensions. 479314564Sdim dimension--; 480353358Sdim 481314564Sdim // The element klass is a TypeArrayKlass. 482314564Sdim element_klass = ciTypeArrayKlass::make(element_type); 483314564Sdim } 484327952Sdim new_klass = new (arena()) ciObjArrayKlass(name, element_klass, dimension); 485327952Sdim } else { 486327952Sdim jobject loader_handle = NULL; 487327952Sdim jobject domain_handle = NULL; 488353358Sdim if (accessing_klass != NULL) { 489327952Sdim loader_handle = accessing_klass->loader_handle(); 490327952Sdim domain_handle = accessing_klass->protection_domain_handle(); 491327952Sdim } 492314564Sdim new_klass = new (arena()) ciInstanceKlass(name, loader_handle, domain_handle); 493314564Sdim } 494314564Sdim init_ident_of(new_klass); 495314564Sdim _unloaded_klasses->append(new_klass); 496353358Sdim 497314564Sdim return new_klass; 498314564Sdim} 499353358Sdim 500314564Sdim 501314564Sdim//------------------------------------------------------------------ 502353358Sdim// ciObjectFactory::get_unloaded_instance 503314564Sdim// 504314564Sdim// Get a ciInstance representing an as-yet undetermined instance of a given class. 505314564Sdim// 506314564SdimciInstance* ciObjectFactory::get_unloaded_instance(ciInstanceKlass* instance_klass) { 507314564Sdim for (int i=0; i<_unloaded_instances->length(); i++) { 508314564Sdim ciInstance* entry = _unloaded_instances->at(i); 509314564Sdim if (entry->klass()->equals(instance_klass)) { 510314564Sdim // We've found a match. 511314564Sdim return entry; 512314564Sdim } 513327952Sdim } 514327952Sdim 515327952Sdim // This is a new unloaded instance. Create it and stick it in 516314564Sdim // the cache. 517314564Sdim ciInstance* new_instance = new (arena()) ciInstance(instance_klass); 518314564Sdim 519314564Sdim init_ident_of(new_instance); 520314564Sdim _unloaded_instances->append(new_instance); 521360784Sdim 522327952Sdim // make sure it looks the way we want: 523314564Sdim assert(!new_instance->is_loaded(), ""); 524314564Sdim assert(new_instance->klass() == instance_klass, ""); 525314564Sdim 526314564Sdim return new_instance; 527314564Sdim} 528314564Sdim 529314564Sdim 530314564Sdim//------------------------------------------------------------------ 531288943Sdim// ciObjectFactory::get_unloaded_klass_mirror 532314564Sdim// 533288943Sdim// Get a ciInstance representing an unresolved klass mirror. 534314564Sdim// 535314564Sdim// Currently, this ignores the parameters and returns a unique unloaded instance. 536314564SdimciInstance* ciObjectFactory::get_unloaded_klass_mirror(ciKlass* type) { 537341825Sdim assert(ciEnv::_Class_klass != NULL, ""); 538341825Sdim return get_unloaded_instance(ciEnv::_Class_klass->as_instance_klass()); 539341825Sdim} 540314564Sdim 541341825Sdim//------------------------------------------------------------------ 542341825Sdim// ciObjectFactory::get_unloaded_method_handle_constant 543314564Sdim// 544353358Sdim// Get a ciInstance representing an unresolved method handle constant. 545314564Sdim// 546314564Sdim// Currently, this ignores the parameters and returns a unique unloaded instance. 547314564SdimciInstance* ciObjectFactory::get_unloaded_method_handle_constant(ciKlass* holder, 548314564Sdim ciSymbol* name, 549314564Sdim ciSymbol* signature, 550353358Sdim int ref_kind) { 551353358Sdim if (ciEnv::_MethodHandle_klass == NULL) return NULL; 552327952Sdim return get_unloaded_instance(ciEnv::_MethodHandle_klass->as_instance_klass()); 553360784Sdim} 554360784Sdim 555327952Sdim//------------------------------------------------------------------ 556314564Sdim// ciObjectFactory::get_unloaded_method_type_constant 557360784Sdim// 558360784Sdim// Get a ciInstance representing an unresolved method type constant. 559327952Sdim// 560360784Sdim// Currently, this ignores the parameters and returns a unique unloaded instance. 561327952SdimciInstance* ciObjectFactory::get_unloaded_method_type_constant(ciSymbol* signature) { 562327952Sdim if (ciEnv::_MethodType_klass == NULL) return NULL; 563327952Sdim return get_unloaded_instance(ciEnv::_MethodType_klass->as_instance_klass()); 564327952Sdim} 565327952Sdim 566327952SdimciInstance* ciObjectFactory::get_unloaded_object_constant() { 567327952Sdim if (ciEnv::_Object_klass == NULL) return NULL; 568327952Sdim return get_unloaded_instance(ciEnv::_Object_klass->as_instance_klass()); 569327952Sdim} 570327952Sdim 571254721Semaste//------------------------------------------------------------------ 572314564Sdim// ciObjectFactory::get_empty_methodData 573314564Sdim// 574254721Semaste// Get the ciMethodData representing the methodData for a method with 575314564Sdim// none. 576314564SdimciMethodData* ciObjectFactory::get_empty_methodData() { 577341825Sdim ciMethodData* new_methodData = new (arena()) ciMethodData(); 578341825Sdim init_ident_of(new_methodData); 579341825Sdim return new_methodData; 580314564Sdim} 581353358Sdim 582314564Sdim//------------------------------------------------------------------ 583314564Sdim// ciObjectFactory::get_return_address 584353358Sdim// 585314564Sdim// Get a ciReturnAddress for a specified bci. 586314564SdimciReturnAddress* ciObjectFactory::get_return_address(int bci) { 587314564Sdim for (int i=0; i<_return_addresses->length(); i++) { 588353358Sdim ciReturnAddress* entry = _return_addresses->at(i); 589314564Sdim if (entry->bci() == bci) { 590314564Sdim // We've found a match. 591314564Sdim return entry; 592353358Sdim } 593314564Sdim } 594314564Sdim 595314564Sdim ciReturnAddress* new_ret_addr = new (arena()) ciReturnAddress(bci); 596353358Sdim init_ident_of(new_ret_addr); 597314564Sdim _return_addresses->append(new_ret_addr); 598314564Sdim return new_ret_addr; 599314564Sdim} 600314564Sdim 601314564Sdim// ------------------------------------------------------------------ 602314564Sdim// ciObjectFactory::init_ident_of 603314564Sdimvoid ciObjectFactory::init_ident_of(ciBaseObject* obj) { 604314564Sdim obj->set_ident(_next_ident++); 605314564Sdim} 606254721Semaste 607314564Sdim// ------------------------------------------------------------------ 608314564Sdim// ciObjectFactory::find 609254721Semaste// 610314564Sdim// Use binary search to find the position of this oop in the cache. 611254721Semaste// If there is no entry in the cache corresponding to this oop, return 612314564Sdim// the position at which the oop should be inserted. 613341825Sdimint ciObjectFactory::find(Metadata* key, GrowableArray<ciMetadata*>* objects) { 614341825Sdim int min = 0; 615341825Sdim int max = objects->length()-1; 616341825Sdim 617288943Sdim // print_contents(); 618314564Sdim 619288943Sdim while (max >= min) { 620314564Sdim int mid = (max + min) / 2; 621314564Sdim Metadata* value = objects->at(mid)->constant_encoding(); 622314564Sdim if (value < key) { 623314564Sdim min = mid + 1; 624314564Sdim } else if (value > key) { 625314564Sdim max = mid - 1; 626314564Sdim } else { 627254721Semaste return mid; 628314564Sdim } 629341825Sdim } 630314564Sdim return min; 631280031Sdim} 632314564Sdim 633314564Sdim// ------------------------------------------------------------------ 634314564Sdim// ciObjectFactory::is_found_at 635314564Sdim// 636314564Sdim// Verify that the binary seach found the given key. 637314564Sdimbool ciObjectFactory::is_found_at(int index, Metadata* key, GrowableArray<ciMetadata*>* objects) { 638314564Sdim return (index < objects->length() && 639314564Sdim objects->at(index)->constant_encoding() == key); 640314564Sdim} 641314564Sdim 642314564Sdim 643314564Sdim// ------------------------------------------------------------------ 644314564Sdim// ciObjectFactory::insert 645353358Sdim// 646353358Sdim// Insert a ciObject into the table at some index. 647353358Sdimvoid ciObjectFactory::insert(int index, ciMetadata* obj, GrowableArray<ciMetadata*>* objects) { 648341825Sdim int len = objects->length(); 649341825Sdim if (len == index) { 650341825Sdim objects->append(obj); 651314564Sdim } else { 652314564Sdim objects->append(objects->at(len-1)); 653314564Sdim int pos; 654314564Sdim for (pos = len-2; pos >= index; pos--) { 655314564Sdim objects->at_put(pos+1,objects->at(pos)); 656314564Sdim } 657314564Sdim objects->at_put(index, obj); 658314564Sdim } 659314564Sdim} 660314564Sdim 661327952Sdimstatic ciObjectFactory::NonPermObject* emptyBucket = NULL; 662288943Sdim 663314564Sdim// ------------------------------------------------------------------ 664254721Semaste// ciObjectFactory::find_non_perm 665314564Sdim// 666314564Sdim// Use a small hash table, hashed on the klass of the key. 667314564Sdim// If there is no entry in the cache corresponding to this oop, return 668254721Semaste// the null tail of the bucket into which the oop should be inserted. 669254721SemasteciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) { 670254721Semaste assert(Universe::heap()->is_in_reserved_or_null(key), "must be"); 671254721Semaste ciMetadata* klass = get_metadata(key->klass()); 672296417Sdim NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS]; 673 for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) { 674 if (is_equal(p, key)) break; 675 } 676 return (*bp); 677} 678 679 680 681// ------------------------------------------------------------------ 682// Code for for NonPermObject 683// 684inline ciObjectFactory::NonPermObject::NonPermObject(ciObjectFactory::NonPermObject* &bucket, oop key, ciObject* object) { 685 assert(ciObjectFactory::is_initialized(), ""); 686 _object = object; 687 _next = bucket; 688 bucket = this; 689} 690 691 692 693// ------------------------------------------------------------------ 694// ciObjectFactory::insert_non_perm 695// 696// Insert a ciObject into the non-perm table. 697void ciObjectFactory::insert_non_perm(ciObjectFactory::NonPermObject* &where, oop key, ciObject* obj) { 698 assert(Universe::heap()->is_in_reserved_or_null(key), "must be"); 699 assert(&where != &emptyBucket, "must not try to fill empty bucket"); 700 NonPermObject* p = new (arena()) NonPermObject(where, key, obj); 701 assert(where == p && is_equal(p, key) && p->object() == obj, "entry must match"); 702 assert(find_non_perm(key) == p, "must find the same spot"); 703 ++_non_perm_count; 704} 705 706// ------------------------------------------------------------------ 707// ciObjectFactory::vm_symbol_at 708// Get the ciSymbol corresponding to some index in vmSymbols. 709ciSymbol* ciObjectFactory::vm_symbol_at(int index) { 710 assert(index >= vmSymbols::FIRST_SID && index < vmSymbols::SID_LIMIT, "oob"); 711 return _shared_ci_symbols[index]; 712} 713 714// ------------------------------------------------------------------ 715// ciObjectFactory::metadata_do 716void ciObjectFactory::metadata_do(void f(Metadata*)) { 717 if (_ci_metadata == NULL) return; 718 for (int j = 0; j< _ci_metadata->length(); j++) { 719 Metadata* o = _ci_metadata->at(j)->constant_encoding(); 720 f(o); 721 } 722} 723 724// ------------------------------------------------------------------ 725// ciObjectFactory::print_contents_impl 726void ciObjectFactory::print_contents_impl() { 727 int len = _ci_metadata->length(); 728 tty->print_cr("ciObjectFactory (%d) meta data contents:", len); 729 for (int i=0; i<len; i++) { 730 _ci_metadata->at(i)->print(); 731 tty->cr(); 732 } 733} 734 735// ------------------------------------------------------------------ 736// ciObjectFactory::print_contents 737void ciObjectFactory::print_contents() { 738 print(); 739 tty->cr(); 740 GUARDED_VM_ENTRY(print_contents_impl();) 741} 742 743// ------------------------------------------------------------------ 744// ciObjectFactory::print 745// 746// Print debugging information about the object factory 747void ciObjectFactory::print() { 748 tty->print("<ciObjectFactory oops=%d metadata=%d unloaded_methods=%d unloaded_instances=%d unloaded_klasses=%d>", 749 _non_perm_count, _ci_metadata->length(), _unloaded_methods->length(), 750 _unloaded_instances->length(), 751 _unloaded_klasses->length()); 752} 753