// Unevolving classes may point to methods of the evolving class directly
// from their constantpool caches and vtables/itables. Fix this. 
void VM_RedefineClasses::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; 

    // 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);
  }
}
Exemplo n.º 2
0
// ------------------------------------------------------------------
// 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++;
    }
  }
}
Exemplo n.º 3
0
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());
  }
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
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)));
}
TESTF(ByteArrayKlassTests, shouldBeDoubleByteArray) {
  eden_top = eden_end;
  ASSERT_TRUE(theClass->klass_part()->oop_is_byteArray());
}
Exemplo n.º 10
0
TESTF(ContextKlassTests, allocateShouldAllocateTenuredWhenRequired) {
  ASSERT_TRUE(Universe::old_gen.contains(theClass->klass_part()->allocateObject(false, true)));
}
Exemplo n.º 11
0
TESTF(ContextKlassTests, allocateShouldFailWhenAllowedAndNoSpace) {
  eden_top = eden_end;
  ASSERT_EQUALS((int)NULL, (int)(theClass->klass_part()->allocateObject(false)));
}
Exemplo n.º 12
0
 // 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());
 }