Klass::Klass() { Klass* k = this; { // Preinitialize supertype information. // A later call to initialize_supers() may update these settings: set_super(NULL); for (juint i = 0; i < Klass::primary_super_limit(); i++) { _primary_supers[i] = NULL; } set_secondary_supers(NULL); _primary_supers[0] = k; set_super_check_offset(in_bytes(primary_supers_offset())); } set_java_mirror(NULL); set_modifier_flags(0); set_layout_helper(Klass::_lh_neutral_value); set_name(NULL); AccessFlags af; af.set_flags(0); set_access_flags(af); set_subklass(NULL); set_next_sibling(NULL); set_next_link(NULL); set_alloc_count(0); TRACE_SET_KLASS_TRACE_ID(this, 0); set_prototype_header(markOopDesc::prototype()); set_biased_lock_revocation_count(0); set_last_biased_lock_bulk_revocation_time(0); // The klass doesn't have any references at this point. clear_modified_oops(); clear_accumulated_modified_oops(); }
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()); } }
void Klass::initialize_supers(Klass* k, TRAPS) { if (FastSuperclassLimit == 0) { // None of the other machinery matters. set_super(k); return; } if (k == NULL) { set_super(NULL); _primary_supers[0] = this; 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; 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++) { _primary_supers[i] = sup->_primary_supers[i]; } Klass* *super_check_cell; if (my_depth < primary_super_limit()) { _primary_supers[my_depth] = this; 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); #ifdef ASSERT { juint j = super_depth(); assert(j == my_depth, "computed accessor gets right answer"); Klass* t = this; while (!t->can_be_primary_super()) { t = t->super(); j = 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 = 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; Klass* p; for (p = super(); !(p == NULL || p->can_be_primary_super()); p = p->super()) { ++extras; } ResourceMark rm(THREAD); // need to reclaim GrowableArrays allocated below // Compute the "real" non-extra secondaries. GrowableArray<Klass*>* secondaries = compute_secondary_supers(extras); if (secondaries == NULL) { // secondary_supers set by compute_secondary_supers return; } GrowableArray<Klass*>* primaries = new GrowableArray<Klass*>(extras); for (p = this_kh->super(); !(p == NULL || p->can_be_primary_super()); p = p->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 = 0; i < secondaries->length(); i++ ) { if( secondaries->at(i) == p ) break; } if( i < secondaries->length() ) continue; // It's a dup, don't put it in primaries->push(p); } // Combine the two arrays into a metadata object to pack the array. // The primaries are added in the reverse order, then the secondaries. int new_length = primaries->length() + secondaries->length(); Array<Klass*>* s2 = MetadataFactory::new_array<Klass*>( class_loader_data(), new_length, CHECK); int fill_p = primaries->length(); for (int j = 0; j < fill_p; j++) { s2->at_put(j, primaries->pop()); // add primaries in reverse order. } for( int j = 0; j < secondaries->length(); j++ ) { s2->at_put(j+fill_p, secondaries->at(j)); // add secondaries on the end. } #ifdef ASSERT // We must not copy any NULL placeholders left over from bootstrap. for (int j = 0; j < s2->length(); j++) { assert(s2->at(j) != NULL, "correct bootstrapping order"); } #endif this_kh->set_secondary_supers(s2); } }