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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #12
0
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;
}
Exemple #14
0
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;
}
Exemple #21
0
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;
}
Exemple #24
0
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;
}
Exemple #27
0
void Klass::set_next_sibling(klassOop s) {
  assert(s != as_klassOop(), "sanity check");
  oop_store_without_check((oop*)&_next_sibling, s);
}
Exemple #28
0
void Klass::set_subklass(klassOop s) {
  assert(s != as_klassOop(), "sanity check");
  oop_store_without_check((oop*)&_subklass, s);
}
Exemple #29
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());
  }
}
Exemple #30
0
klassVtable* arrayKlass::vtable() const {
  KlassHandle kh(Thread::current(), as_klassOop());
  return new klassVtable(kh, start_of_vtable(), vtable_length() / vtableEntry::size());
}