END_DECLARE SETUP(IndirectAlienPrimsTests) { rm = new HeapResourceMark(); klassOop byteArrayClass = Universe::byteArrayKlassObj(); PersistentHandle ah(byteArrayClass->klass_part()->allocateObjectSize(8)); PersistentHandle iah(byteArrayClass->klass_part()->allocateObjectSize(8)); PersistentHandle lu(byteArrayClass->klass_part()->allocateObjectSize(8)); PersistentHandle ls(byteArrayClass->klass_part()->allocateObjectSize(8)); doubleValue = doubleOop(Universe::doubleKlassObj()->klass_part()->allocateObject()); doubleValue->set_value(1.625); largeUnsignedInteger = byteArrayOop(lu.as_oop()); largeSignedInteger = byteArrayOop(ls.as_oop()); IntegerOps::unsigned_int_to_Integer((unsigned int)0xFFFFFFFF, byteArrayOop(largeUnsignedInteger)->number()); IntegerOps::int_to_Integer(-1 << 31, byteArrayOop(largeSignedInteger)->number()); alien = byteArrayOop(ah.as_oop()); byteArrayPrimitives::alienSetSize(as_smiOop(-16), alien); byteArrayPrimitives::alienSetAddress(as_smiOop((int)alien_byte_region), alien); memset(alien_byte_region, 0, 16); invalidAlien = byteArrayOop(iah.as_oop()); byteArrayPrimitives::alienSetSize(as_smiOop(-16), invalidAlien); byteArrayPrimitives::alienSetAddress(as_smiOop(0), invalidAlien); }
objArrayOop oopFactory::new_objArray(klassOop klass, int length, TRAPS) { assert(klass->is_klass(), "must be instance class"); if (klass->klass_part()->oop_is_array()) { return ((arrayKlass*)klass->klass_part())->allocate_arrayArray(1, length, THREAD); } else { assert (klass->klass_part()->oop_is_instance(), "new object array with klass not an instanceKlass"); return ((instanceKlass*)klass->klass_part())->allocate_objArray(1, length, THREAD); } }
// Should this header (including its age bits) be preserved in the // case of a scavenge in which CMS is the old generation? inline bool markOopDesc::must_be_preserved_with_bias_for_cms_scavenge(klassOop klass_of_obj_containing_mark) const { assert(UseBiasedLocking, "unexpected"); // CMS scavenges preserve mark words in similar fashion to promotion failures; see above if (has_bias_pattern() || klass_of_obj_containing_mark->klass_part()->prototype_header()->has_bias_pattern()) { return true; } return (this != prototype()); }
void InterpretedIC::trace_inline_cache_miss(InterpretedIC* ic, klassOop klass, LookupResult result) { std->print("InterpretedIC lookup ("); klass->print_value(); std->print(", "); ic->selector()->print_value(); std->print(") --> "); result.print_short_on(std); std->cr(); }
// this function computes the vtable size (including the size needed for miranda // methods) and the number of miranda methods in this class // Note on Miranda methods: Let's say there is a class C that implements // interface I. Let's say there is a method m in I that neither C nor any // of its super classes implement (i.e there is no method of any access, with // the same name and signature as m), then m is a Miranda method which is // entered as a public abstract method in C's vtable. From then on it should // treated as any other public method in C for method over-ride purposes. void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length, int &num_miranda_methods, klassOop super, objArrayOop methods, AccessFlags class_flags, Handle classloader, Symbol* classname, objArrayOop local_interfaces, TRAPS ) { No_Safepoint_Verifier nsv; // set up default result values vtable_length = 0; num_miranda_methods = 0; // start off with super's vtable length instanceKlass* sk = (instanceKlass*)super->klass_part(); vtable_length = super == NULL ? 0 : sk->vtable_length(); // go thru each method in the methods table to see if it needs a new entry int len = methods->length(); for (int i = 0; i < len; i++) { assert(methods->obj_at(i)->is_method(), "must be a methodOop"); methodHandle mh(THREAD, methodOop(methods->obj_at(i))); if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, THREAD)) { vtable_length += vtableEntry::size(); // we need a new entry } } // compute the number of mirandas methods that must be added to the end num_miranda_methods = get_num_mirandas(super, methods, local_interfaces); vtable_length += (num_miranda_methods * vtableEntry::size()); if (Universe::is_bootstrapping() && vtable_length == 0) { // array classes don't have their superclass set correctly during // bootstrapping vtable_length = Universe::base_vtable_size(); } if (super == NULL && !Universe::is_bootstrapping() && vtable_length != Universe::base_vtable_size()) { // Someone is attempting to redefine java.lang.Object incorrectly. The // only way this should happen is from // SystemDictionary::resolve_from_stream(), which will detect this later // and throw a security exception. So don't assert here to let // the exception occur. vtable_length = Universe::base_vtable_size(); } assert(super != NULL || vtable_length == Universe::base_vtable_size(), "bad vtable size for class Object"); assert(vtable_length % vtableEntry::size() == 0, "bad vtable length"); assert(vtable_length >= Universe::base_vtable_size(), "vtable too small"); }
inline void oopDesc::set_klass(klassOop k) { // since klasses are promoted no store check is needed assert(Universe::is_bootstrapping() || k != NULL, "must be a real klassOop"); assert(Universe::is_bootstrapping() || k->is_klass(), "not a klassOop"); if (UseCompressedOops) { oop_store_without_check(compressed_klass_addr(), (oop)k); } else { oop_store_without_check(klass_addr(), (oop) k); } }
bool typeArrayKlass::compute_is_subtype_of(klassOop k) { if (!k->klass_part()->oop_is_typeArray()) { return arrayKlass::compute_is_subtype_of(k); } typeArrayKlass* tak = typeArrayKlass::cast(k); if (dimension() != tak->dimension()) return false; return element_type() == tak->element_type(); }
// ------------------------------------------------------------------ // ciEnv::check_klass_accessiblity // // Note: the logic of this method should mirror the logic of // constantPoolOopDesc::verify_constant_pool_resolve. bool ciEnv::check_klass_accessibility(ciKlass* accessing_klass, klassOop resolved_klass) { if (accessing_klass == NULL || !accessing_klass->is_loaded()) { return true; } if (accessing_klass->is_obj_array()) { accessing_klass = accessing_klass->as_obj_array_klass()->base_element_klass(); } if (!accessing_klass->is_instance_klass()) { return true; } if (resolved_klass->klass_part()->oop_is_objArray()) { // Find the element klass, if this is an array. resolved_klass = objArrayKlass::cast(resolved_klass)->bottom_klass(); } if (resolved_klass->klass_part()->oop_is_instance()) { return Reflection::verify_class_access(accessing_klass->get_klassOop(), resolved_klass, true); } return true; }
// Unevolving classes may point to methods of the evolving class directly // from their constantpool caches and vtables/itables. Fix this. static void adjust_cpool_cache_and_vtable(klassOop k_oop, oop loader) { Klass *k = k_oop->klass_part(); if (k->oop_is_instance()) { instanceKlass *ik = (instanceKlass *) k; bool previous_version; if (java_core_class_name(ik->name()->as_utf8())) return; // By this time we have already replaced the constantpool pointer in the evolving // class itself. However, we need to fix the entries in the old constantpool, which // is still referenced by active old methods of this class. constantPoolCacheOop cp_cache = (k_oop == _evolving_koop) ? _old_constants->cache() : ik->constants()->cache(); do { if (cp_cache != NULL) { cp_cache->adjust_method_entries(_old_methods, _new_methods); } // Fix vtable (this is needed for the evolving class itself and its subclasses). if (ik->vtable_length() > 0 && ik->is_subclass_of(_evolving_koop)) { ik->vtable()->adjust_entries(_old_methods, _new_methods); } // Fix itable, if it exists. if (ik->itable_length() > 0) { ik->itable()->adjust_method_entries(_old_methods, _new_methods); } // Previous version methods could be still on stack so adjust entries // in all previous versions. if (ik->has_previous_version()) { ik = (instanceKlass *)(ik->previous_version())->klass_part(); cp_cache = ik->constants()->cache(); previous_version = true; } else { previous_version = false; } } while (previous_version); } }
// ------------------------------------------------------------------ // ciFieldLayout::fill_in_instance_fields // // Set up the instance fields in this ciFieldLayout. void ciFieldLayout::fill_in_instance_fields(GrowableArray<BasicType>* fieldtypes, GrowableArray<int>* fieldoffsets, GrowableArray<int>* aflags, int& pos, klassOop current) { Klass* k = current->klass_part(); assert(k->oop_is_instance(), "must be instanceKlass"); instanceKlass* ik = (instanceKlass*)k; klassOop super = k->super(); if (super) { fill_in_instance_fields(fieldtypes, fieldoffsets, aflags, pos, super); } // Fill in this klass's instance fields. typeArrayOop field_list = ik->fields(); constantPoolOop cpool = ik->constants(); uint num_fields = field_list->length(); for (uint i = 0; i < num_fields; i += instanceKlass::next_offset) { AccessFlags flags; flags.set_flags(field_list->short_at(i + instanceKlass::access_flags_offset)); if (!flags.is_static()) { // This is an instance field. Add it to our list. int field_offset = ik->offset_from_fields( i ); // Add the type to our list. symbolOop type_sym = cpool->symbol_at(field_list->short_at(i+ instanceKlass::signature_index_offset)); BasicType field_type; field_type = type2field[FieldType::basic_type(type_sym)]; fieldtypes->at_put_grow(pos, field_type, T_VOID); aflags->at_put_grow(pos, flags.as_int(), 0); // The field offset we set here includes the header_size fieldoffsets->at_put_grow(pos, field_offset, 0); pos++; } } }
void AllocationProfiler::add_classes_to_array(klassOop k) { // Iterate over klass and all array klasses for klass k->klass_part()->with_array_klasses_do(&AllocationProfiler::add_class_to_array); }
TESTF(ByteArrayKlassTests, allocateShouldNotFailWhenNotAllowedAndNoSpace) { eden_top = eden_end; ASSERT_TRUE(Universe::new_gen.eden()->free() < 4 * oopSize); ASSERT_TRUE(Universe::new_gen.contains(theClass->klass_part()->allocateObjectSize(100, true))); }
TESTF(ByteArrayKlassTests, allocateShouldAllocateTenuredWhenRequired) { ASSERT_TRUE(Universe::old_gen.contains(theClass->klass_part()->allocateObjectSize(100, false, true))); }
TESTF(ByteArrayKlassTests, allocateShouldFailWhenAllowedAndNoSpace) { eden_top = eden_end; ASSERT_EQUALS((int)NULL, (int)(theClass->klass_part()->allocateObjectSize(100, false))); }
void Klass_vtbl::post_new_init_klass(KlassHandle& klass, klassOop new_klass) const { assert(!new_klass->klass_part()->null_vtbl(), "Not a complete klass"); CollectedHeap::post_allocation_install_obj_klass(klass, new_klass); }
inline void oopDesc::set_klass(klassOop k) { // since klasses are promoted no store check is needed assert(Universe::is_bootstrapping() || k != NULL, "must be a real klassOop"); assert(Universe::is_bootstrapping() || k->is_klass(), "not a klassOop"); oop_store_without_check((oop*) &_klass, (oop) k); }
TESTF(ContextKlassTests, allocateShouldAllocateTenuredWhenRequired) { ASSERT_TRUE(Universe::old_gen.contains(theClass->klass_part()->allocateObject(false, true))); }
TESTF(ContextKlassTests, allocateShouldFailWhenAllowedAndNoSpace) { eden_top = eden_end; ASSERT_EQUALS((int)NULL, (int)(theClass->klass_part()->allocateObject(false))); }
bool Klass::compute_is_subtype_of(klassOop k) { assert(k->is_klass(), "argument must be a class"); return is_subclass_of(k); }
TESTF(ByteArrayKlassTests, shouldBeDoubleByteArray) { eden_top = eden_end; ASSERT_TRUE(theClass->klass_part()->oop_is_byteArray()); }
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()); } }
// Do not expose internal implementation specific classes bool is_visible_klass(klassOop k) { return k->klass_part()->oop_is_instance() || (k->klass_part()->oop_is_array() && k != Universe::systemObjArrayKlassObj()); }