klassOop objArrayKlass::create_subclass(mixinOop mixin, Format format) { if (format == weakArray_klass) return weakArrayKlass::create_class(as_klassOop(), mixin); if (format == mem_klass || format == objArray_klass) { return objArrayKlass::create_class(as_klassOop(), mixin); } return NULL; }
constMethodOop constMethodKlass::allocate(int byte_code_size, int compressed_line_number_size, int localvariable_table_length, int checked_exceptions_length, bool is_conc_safe, TRAPS) { int size = constMethodOopDesc::object_size(byte_code_size, compressed_line_number_size, localvariable_table_length, checked_exceptions_length); KlassHandle h_k(THREAD, as_klassOop()); constMethodOop cm = (constMethodOop) CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); assert(!cm->is_parsable(), "Not yet safely parsable"); No_Safepoint_Verifier no_safepoint; cm->set_interpreter_kind(Interpreter::invalid); cm->init_fingerprint(); cm->set_method(NULL); cm->set_stackmap_data(NULL); cm->set_exception_table(NULL); cm->set_code_size(byte_code_size); cm->set_constMethod_size(size); cm->set_inlined_tables_length(checked_exceptions_length, compressed_line_number_size, localvariable_table_length); assert(cm->size() == size, "wrong size for object"); cm->set_is_conc_safe(is_conc_safe); cm->set_partially_loaded(); assert(cm->is_parsable(), "Is safely parsable by gc"); return cm; }
constantPoolOop constantPoolKlass::allocate(int length, bool is_conc_safe, TRAPS) { int size = constantPoolOopDesc::object_size(length); KlassHandle klass (THREAD, as_klassOop()); constantPoolOop c = (constantPoolOop)CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL); c->set_length(length); c->set_tags(NULL); c->set_cache(NULL); c->set_pool_holder(NULL); c->set_flags(0); // only set to non-zero if constant pool is merged by RedefineClasses c->set_orig_length(0); // if constant pool may change during RedefineClasses, it is created // unsafe for GC concurrent processing. c->set_is_conc_safe(is_conc_safe); // all fields are initialized; needed for GC // initialize tag array // Note: cannot introduce constant pool handle before since it is not // completely initialized (no class) -> would cause assertion failure constantPoolHandle pool (THREAD, c); typeArrayOop t_oop = oopFactory::new_permanent_byteArray(length, CHECK_NULL); typeArrayHandle tags (THREAD, t_oop); for (int index = 0; index < length; index++) { tags()->byte_at_put(index, JVM_CONSTANT_Invalid); } pool->set_tags(tags()); return pool(); }
oop doubleByteArrayKlass::allocateObjectSize(int size, bool permit_scavenge, bool tenured) { klassOop k = as_klassOop(); int ni_size = non_indexable_size(); int obj_size = ni_size + 1 + roundTo(size * 2, oopSize) / oopSize; // allocate oop* result = tenured ? Universe::allocate_tenured(obj_size, permit_scavenge) : Universe::allocate(obj_size, (memOop*)&k, permit_scavenge); if (result == NULL) return NULL; doubleByteArrayOop obj = as_doubleByteArrayOop(result); // header memOop(obj)->initialize_header(true, k); // instance variables memOop(obj)->initialize_body(memOopDesc::header_size(), ni_size); // indexables oop* base = (oop*) obj->addr(); oop* end = base + obj_size; // %optimized 'obj->set_length(size)' base[ni_size] = as_smiOop(size); // %optimized 'for (int index = 1; index <= size; index++) // obj->doubleByte_at_put(index, 0)' base = &base[ni_size+1]; while (base < end) *base++ = (oop) 0; return obj; }
constantPoolCacheOop constantPoolCacheKlass::allocate(int length, TRAPS) { // allocate memory int size = constantPoolCacheOopDesc::object_size(length); KlassHandle klass (THREAD, as_klassOop()); // Commented out below is the original code. The code from // permanent_obj_allocate() was in-lined so that we could // set the _length field, necessary to correctly compute its // size(), before setting its klass word further below. // constantPoolCacheOop cache = (constantPoolCacheOop) // CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL); oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL); #ifndef PRODUCT const size_t hs = oopDesc::header_size(); Universe::heap()->check_for_bad_heap_word_value(((HeapWord*) obj)+hs, size-hs); #endif constantPoolCacheOop cache = (constantPoolCacheOop) obj; assert(!UseConcMarkSweepGC || obj->klass_or_null() == NULL, "klass should be NULL here when using CMS"); cache->set_length(length); // should become visible before klass is set below. cache->set_constant_pool(NULL); OrderAccess::storestore(); obj->set_klass(klass()); assert(cache->size() == size, "Incorrect cache->size()"); return cache; }
/** * 为某一类型对应的java.lang.Class实例分配存储空间 */ instanceOop instanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) { // Query before forming handle. int size = instance_size(k); KlassHandle h_k(THREAD, as_klassOop()); instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL); return i; }
bool symbolKlass::allocate_symbols(int names_count, const char** names, int* lengths, symbolOop* sym_oops, TRAPS) { if (UseConcMarkSweepGC || UseParallelGC) { // Concurrent GC needs to mark all the allocated symbol oops after // the remark phase which isn't done below (except the first symbol oop). // So return false which will let the symbols be allocated one by one. // The parallel collector uses an object start array to find the // start of objects on a dirty card. The object start array is not // updated for the start of each symbol so is not precise. During // object array verification this causes a verification failure. // In a product build this causes extra searching for the start of // a symbol. As with the concurrent collector a return of false will // cause each symbol to be allocated separately and in the case // of the parallel collector will cause the object // start array to be updated. return false; } assert(names_count > 0, "can't allocate 0 symbols"); int total_size = 0; int i, sizes[SymbolTable::symbol_alloc_batch_size]; for (i=0; i<names_count; i++) { int len = lengths[i]; if (len > symbolOopDesc::max_length()) { return false; } int sz = symbolOopDesc::object_size(len); sizes[i] = sz * HeapWordSize; total_size += sz; } symbolKlassHandle h_k(THREAD, as_klassOop()); HeapWord* base = Universe::heap()->permanent_mem_allocate(total_size); if (base == NULL) { return false; } // CAN'T take any safepoint during the initialization of the symbol oops ! No_Safepoint_Verifier nosafepoint; klassOop sk = h_k(); int pos = 0; for (i=0; i<names_count; i++) { symbolOop s = (symbolOop) (((char*)base) + pos); s->set_mark(markOopDesc::prototype()); s->set_klass(sk); s->set_utf8_length(lengths[i]); const char* name = names[i]; for (int j=0; j<lengths[i]; j++) { s->byte_at_put(j, name[j]); } assert(s->is_parsable(), "should be parsable here."); sym_oops[i] = s; pos += sizes[i]; } return true; }
void arrayKlass::array_klasses_do(void f(klassOop k)) { klassOop k = as_klassOop(); // Iterate over this array klass and all higher dimensions while (k != NULL) { f(k); k = arrayKlass::cast(k)->higher_dimension(); } }
typeArrayOop typeArrayKlass::allocate_permanent(int length, TRAPS) { if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); int size = typeArrayOopDesc::object_size(layout_helper(), length); KlassHandle h_k(THREAD, as_klassOop()); typeArrayOop t = (typeArrayOop) CollectedHeap::permanent_array_allocate(h_k, size, length, CHECK_NULL); assert(t->is_parsable(), "Can't publish until parsable"); return t; }
constantPoolCacheOop constantPoolCacheKlass::allocate(int length, TRAPS) { // allocate memory int size = constantPoolCacheOopDesc::object_size(length); KlassHandle klass (THREAD, as_klassOop()); constantPoolCacheOop cache = (constantPoolCacheOop) CollectedHeap::permanent_array_allocate(klass, size, length, CHECK_0); cache->set_constant_pool(NULL); return cache; }
compiledICHolderOop compiledICHolderKlass::allocate(TRAPS) { KlassHandle h_k(THREAD, as_klassOop()); int size = compiledICHolderOopDesc::object_size(); compiledICHolderOop c = (compiledICHolderOop) CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); c->set_holder_method(NULL); c->set_holder_klass(NULL); return c; }
oop memOopKlass::allocateObject() { klassOop k = as_klassOop(); int size = non_indexable_size(); // allocate memOop obj = as_memOop(Universe::allocate(size, (memOop*)&k)); // header obj->initialize_header(has_untagged_contents(), k); // instance variables obj->initialize_body(memOopDesc::header_size(), size); return obj; }
methodDataOop methodDataKlass::allocate(methodHandle method, TRAPS) { int size = methodDataOopDesc::compute_allocation_size_in_words(method()); KlassHandle h_k(THREAD, as_klassOop()); methodDataOop mdo = (methodDataOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_0); assert(!mdo->is_parsable(), "not expecting parsability yet."); No_GC_Verifier nogc; // the init function should not GC mdo->initialize(method()); assert(mdo->is_parsable(), "should be parsable here."); assert(size == mdo->object_size(), "wrong size for methodDataOop"); return mdo; }
bool Klass::is_subclass_of(klassOop k) const { // Run up the super chain and check klassOop t = as_klassOop(); if (t == k) return true; t = Klass::cast(t)->super(); while (t != NULL) { if (t == k) return true; t = Klass::cast(t)->super(); } return false; }
oop memOopKlass::allocateObject(bool permit_scavenge, bool tenured) { klassOop k = as_klassOop(); int size = non_indexable_size(); oop* result = basicAllocate(size, &k, permit_scavenge, tenured); if (!result) return NULL; // allocate memOop obj = as_memOop(result); // header obj->initialize_header(has_untagged_contents(), k); // instance variables obj->initialize_body(memOopDesc::header_size(), size); return obj; }
oop associationKlass::allocateObject(bool permit_scavenge, bool tenured) { klassOop k = as_klassOop(); int size = non_indexable_size(); // allocate oop* result = Universe::allocate_tenured(size, permit_scavenge); if (result == NULL && !permit_scavenge) return NULL; associationOop obj = as_associationOop(result); // header memOop(obj)->initialize_header(has_untagged_contents(), k); obj->set_key(symbolOop(nilObj)); obj->set_value(nilObj); obj->set_is_constant(false); // instance variables obj->initialize_body(associationOopDesc::header_size(), size); return obj; }
klassOop memOopKlass::create_subclass(mixinOop mixin, Format format) { assert(can_be_subclassed(), "must be able to subclass this"); if (format == mem_klass) return memOopKlass::create_class(as_klassOop(), mixin); if (format == objArray_klass) return objArrayKlass::create_class(as_klassOop(), mixin); if (format == byteArray_klass) return byteArrayKlass::create_class(as_klassOop(), mixin); if (format == doubleByteArray_klass) return doubleByteArrayKlass::create_class(as_klassOop(), mixin); if (format == weakArray_klass) return weakArrayKlass::create_class(as_klassOop(), mixin); if (number_of_instance_variables() > 0) { warning("super class has instance variables when mixing in special mixin"); return NULL; } if (format == mixin_klass) return mixinKlass::create_class(as_klassOop(), mixin); if (format == proxy_klass) return proxyKlass::create_class(as_klassOop(), mixin); if (format == process_klass) return processKlass::create_class(as_klassOop(), mixin); return NULL; }
oop objArrayKlass::allocateObjectSize(int size) { klassOop k = as_klassOop(); int ni_size = non_indexable_size(); int obj_size = ni_size + 1 + size; // allocate objArrayOop obj = as_objArrayOop(Universe::allocate(obj_size, (memOop*)&k)); // header memOop(obj)->initialize_header(has_untagged_contents(), k); // instance variables memOop(obj)->initialize_body(memOopDesc::header_size(), ni_size); // indexables oop* base = (oop*) obj->addr(); oop* end = base + obj_size; // %optimized 'obj->set_length(size)' base[ni_size] = as_smiOop(size); memOop(obj)->initialize_body(ni_size+1, obj_size); return obj; }
oop mixinKlass::allocateObject(bool permit_scavenge, bool tenured) { klassOop k = as_klassOop(); int size = non_indexable_size(); // allocate oop* result = basicAllocate(size, &k, permit_scavenge, tenured); if (result == NULL) return NULL; mixinOop obj = as_mixinOop(result); // header + instance variables memOop(obj)->initialize_header(true, k); memOop(obj)->initialize_body(memOopDesc::header_size(), size); objArrayOop filler = oopFactory::new_objArray(0); obj->set_methods(filler); obj->set_instVars(filler); obj->set_classVars(filler); obj->set_installed(falseObj); return obj; }
oop byteArrayKlass::allocateObjectSize(int size) { klassOop k = as_klassOop(); int ni_size = non_indexable_size(); int obj_size = ni_size + 1 + roundTo(size, oopSize) / oopSize; // allocate byteArrayOop obj = as_byteArrayOop(Universe::allocate(obj_size, (memOop*)&k)); // header memOop(obj)->initialize_header(true, k); // instance variables memOop(obj)->initialize_body(memOopDesc::header_size(), ni_size); // indexables oop* base = (oop*) obj->addr(); oop* end = base + obj_size; // %optimized 'obj->set_length(size)' base[ni_size] = as_smiOop(size); // %optimized 'for (int index = 1; index <= size; index++) // obj->byte_at_put(index, '\000')' base = &base[ni_size+1]; while (base < end) *base++ = (oop) 0; return obj; }
constantPoolCacheOop constantPoolCacheKlass::allocate(int length, bool is_conc_safe, TRAPS) { // allocate memory int size = constantPoolCacheOopDesc::object_size(length); KlassHandle klass (THREAD, as_klassOop()); // This is the original code. The code from permanent_obj_allocate() // was in-lined to allow the setting of is_conc_safe before the klass // is installed. // constantPoolCacheOop cache = (constantPoolCacheOop) // CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL); oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL); constantPoolCacheOop cache = (constantPoolCacheOop) obj; cache->set_is_conc_safe(is_conc_safe); // The store to is_conc_safe must be visible before the klass // is set. This should be done safely because _is_conc_safe has // been declared volatile. If there are any problems, consider adding // OrderAccess::storestore(); CollectedHeap::post_allocation_install_obj_klass(klass, obj, size); NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj, size)); // The length field affects the size of the object. The allocation // above allocates the correct size (see calculation of "size") but // the size() method of the constant pool cache oop will not reflect // that size until the correct length is set. cache->set_length(length); // The store of the length must be visible before is_conc_safe is // set to a safe state. // This should be done safely because _is_conc_safe has // been declared volatile. If there are any problems, consider adding // OrderAccess::storestore(); cache->set_is_conc_safe(methodOopDesc::IsSafeConc); cache->set_constant_pool(NULL); return cache; }
typeArrayOop typeArrayKlass::allocate(int length, TRAPS) { assert(log2_element_size() >= 0, "bad scale"); if (length >= 0) { if (length <= max_length()) { size_t size = typeArrayOopDesc::object_size(layout_helper(), length); KlassHandle h_k(THREAD, as_klassOop()); typeArrayOop t; CollectedHeap* ch = Universe::heap(); if (size < ch->large_typearray_limit()) { t = (typeArrayOop)CollectedHeap::array_allocate(h_k, (int)size, length, CHECK_NULL); } else { t = (typeArrayOop)CollectedHeap::large_typearray_allocate(h_k, (int)size, length, CHECK_NULL); } assert(t->is_parsable(), "Don't publish unless parsable"); return t; } else { THROW_OOP_0(Universe::out_of_memory_error_array_size()); } } else { THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); } }
symbolOop symbolKlass::allocate_symbol(u1* name, int len, TRAPS) { // Don't allow symbol oops to be created which cannot fit in a symbolOop. if (len > symbolOopDesc::max_length()) { THROW_MSG_0(vmSymbols::java_lang_InternalError(), "name is too long to represent"); } int size = symbolOopDesc::object_size(len); symbolKlassHandle h_k(THREAD, as_klassOop()); symbolOop sym = (symbolOop) CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_0); assert(!sym->is_parsable(), "not expecting parsability yet."); sym->set_next(NULL); sym->set_utf8_length(len); for (int i = 0; i < len; i++) { sym->byte_at_put(i, name[i]); } // Let the first emptySymbol be created and // ensure only one is ever created. assert(sym->is_parsable() || Universe::emptySymbol() == NULL, "should be parsable here."); return sym; }
methodOop methodKlass::allocate(constMethodHandle xconst, AccessFlags access_flags, TRAPS) { int size = methodOopDesc::object_size(access_flags.is_native()); KlassHandle h_k(THREAD, as_klassOop()); assert(xconst()->is_parsable(), "possible publication protocol violation"); methodOop m = (methodOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); assert(!m->is_parsable(), "not expecting parsability yet."); No_Safepoint_Verifier no_safepoint; // until m becomes parsable below m->set_constMethod(xconst()); m->set_access_flags(access_flags); m->set_method_size(size); m->set_name_index(0); m->set_signature_index(0); #ifdef CC_INTERP m->set_result_index(T_VOID); #endif m->set_constants(NULL); m->set_max_stack(0); m->set_max_locals(0); m->set_intrinsic_id(vmIntrinsics::_none); m->set_method_data(NULL); m->set_interpreter_throwout_count(0); m->set_vtable_index(methodOopDesc::garbage_vtable_index); // Fix and bury in methodOop m->set_interpreter_entry(NULL); // sets i2i entry and from_int m->set_highest_tier_compile(CompLevel_none); m->set_adapter_entry(NULL); m->clear_code(); // from_c/from_i get set to c2i/i2i if (access_flags.is_native()) { m->clear_native_function(); m->set_signature_handler(NULL); } NOT_PRODUCT(m->set_compiled_invocation_count(0);)
typeArrayOop typeArrayKlass::allocate_common(int length, bool do_zero, TRAPS) { assert(log2_element_size() >= 0, "bad scale"); if (length >= 0) { if (length <= max_length()) { size_t size = typeArrayOopDesc::object_size(layout_helper(), length); KlassHandle h_k(THREAD, as_klassOop()); typeArrayOop t; CollectedHeap* ch = Universe::heap(); if (do_zero) { t = (typeArrayOop)CollectedHeap::array_allocate(h_k, (int)size, length, CHECK_NULL); } else { t = (typeArrayOop)CollectedHeap::array_allocate_nozero(h_k, (int)size, length, CHECK_NULL); } assert(t->is_parsable(), "Don't publish unless parsable"); return t; } else { report_java_out_of_memory("Requested array size exceeds VM limit"); JvmtiExport::post_array_size_exhausted(); THROW_OOP_0(Universe::out_of_memory_error_array_size()); } } else { THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); } }
klassOop associationKlass::create_subclass(mixinOop mixin, Format format) { if (format == mem_klass || format == association_klass) { return associationKlass::create_class(as_klassOop(), mixin); } return NULL; }
void Klass::set_next_sibling(klassOop s) { assert(s != as_klassOop(), "sanity check"); oop_store_without_check((oop*)&_next_sibling, s); }
void Klass::set_subklass(klassOop s) { assert(s != as_klassOop(), "sanity check"); oop_store_without_check((oop*)&_subklass, s); }
void Klass::initialize_supers(klassOop k, TRAPS) { if (FastSuperclassLimit == 0) { // None of the other machinery matters. set_super(k); return; } if (k == NULL) { set_super(NULL); oop_store_without_check((oop*) &_primary_supers[0], (oop) this->as_klassOop()); assert(super_depth() == 0, "Object must already be initialized properly"); } else if (k != super() || k == SystemDictionary::Object_klass()) { assert(super() == NULL || super() == SystemDictionary::Object_klass(), "initialize this only once to a non-trivial value"); set_super(k); Klass* sup = k->klass_part(); int sup_depth = sup->super_depth(); juint my_depth = MIN2(sup_depth + 1, (int)primary_super_limit()); if (!can_be_primary_super_slow()) my_depth = primary_super_limit(); for (juint i = 0; i < my_depth; i++) { oop_store_without_check((oop*) &_primary_supers[i], (oop) sup->_primary_supers[i]); } klassOop *super_check_cell; if (my_depth < primary_super_limit()) { oop_store_without_check((oop*) &_primary_supers[my_depth], (oop) this->as_klassOop()); super_check_cell = &_primary_supers[my_depth]; } else { // Overflow of the primary_supers array forces me to be secondary. super_check_cell = &_secondary_super_cache; } set_super_check_offset((address)super_check_cell - (address) this->as_klassOop()); #ifdef ASSERT { juint j = super_depth(); assert(j == my_depth, "computed accessor gets right answer"); klassOop t = as_klassOop(); while (!Klass::cast(t)->can_be_primary_super()) { t = Klass::cast(t)->super(); j = Klass::cast(t)->super_depth(); } for (juint j1 = j+1; j1 < primary_super_limit(); j1++) { assert(primary_super_of_depth(j1) == NULL, "super list padding"); } while (t != NULL) { assert(primary_super_of_depth(j) == t, "super list initialization"); t = Klass::cast(t)->super(); --j; } assert(j == (juint)-1, "correct depth count"); } #endif } if (secondary_supers() == NULL) { KlassHandle this_kh (THREAD, this); // Now compute the list of secondary supertypes. // Secondaries can occasionally be on the super chain, // if the inline "_primary_supers" array overflows. int extras = 0; klassOop p; for (p = super(); !(p == NULL || p->klass_part()->can_be_primary_super()); p = p->klass_part()->super()) { ++extras; } // Compute the "real" non-extra secondaries. objArrayOop secondary_oops = compute_secondary_supers(extras, CHECK); objArrayHandle secondaries (THREAD, secondary_oops); // Store the extra secondaries in the first array positions: int fillp = extras; for (p = this_kh->super(); !(p == NULL || p->klass_part()->can_be_primary_super()); p = p->klass_part()->super()) { int i; // Scan for overflow primaries being duplicates of 2nd'arys // This happens frequently for very deeply nested arrays: the // primary superclass chain overflows into the secondary. The // secondary list contains the element_klass's secondaries with // an extra array dimension added. If the element_klass's // secondary list already contains some primary overflows, they // (with the extra level of array-ness) will collide with the // normal primary superclass overflows. for( i = extras; i < secondaries->length(); i++ ) if( secondaries->obj_at(i) == p ) break; if( i < secondaries->length() ) continue; // It's a dup, don't put it in secondaries->obj_at_put(--fillp, p); } // See if we had some dup's, so the array has holes in it. if( fillp > 0 ) { // Pack the array. Drop the old secondaries array on the floor // and let GC reclaim it. objArrayOop s2 = oopFactory::new_system_objArray(secondaries->length() - fillp, CHECK); for( int i = 0; i < s2->length(); i++ ) s2->obj_at_put( i, secondaries->obj_at(i+fillp) ); secondaries = objArrayHandle(THREAD, s2); } #ifdef ASSERT if (secondaries() != Universe::the_array_interfaces_array()) { // We must not copy any NULL placeholders left over from bootstrap. for (int j = 0; j < secondaries->length(); j++) { assert(secondaries->obj_at(j) != NULL, "correct bootstrapping order"); } } #endif this_kh->set_secondary_supers(secondaries()); } }
klassVtable* arrayKlass::vtable() const { KlassHandle kh(Thread::current(), as_klassOop()); return new klassVtable(kh, start_of_vtable(), vtable_length() / vtableEntry::size()); }