Mercurial > hg > truffle
diff src/share/vm/oops/typeArrayKlass.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | fc9d8850ab8b |
children | 86af3dacab81 d8ce2825b193 |
line wrap: on
line diff
--- a/src/share/vm/oops/typeArrayKlass.cpp Fri Aug 31 16:39:35 2012 -0700 +++ b/src/share/vm/oops/typeArrayKlass.cpp Sat Sep 01 13:25:18 2012 -0400 @@ -23,23 +23,25 @@ */ #include "precompiled.hpp" +#include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "gc_interface/collectedHeap.hpp" #include "gc_interface/collectedHeap.inline.hpp" +#include "memory/metadataFactory.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "memory/universe.inline.hpp" #include "oops/instanceKlass.hpp" -#include "oops/klassOop.hpp" -#include "oops/objArrayKlassKlass.hpp" +#include "oops/klass.inline.hpp" +#include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" #include "oops/typeArrayKlass.hpp" #include "oops/typeArrayOop.hpp" #include "runtime/handles.inline.hpp" -bool typeArrayKlass::compute_is_subtype_of(klassOop k) { - if (!k->klass_part()->oop_is_typeArray()) { +bool typeArrayKlass::compute_is_subtype_of(Klass* k) { + if (!k->oop_is_typeArray()) { return arrayKlass::compute_is_subtype_of(k); } @@ -49,31 +51,46 @@ return element_type() == tak->element_type(); } -klassOop typeArrayKlass::create_klass(BasicType type, int scale, +typeArrayKlass* typeArrayKlass::create_klass(BasicType type, const char* name_str, TRAPS) { - typeArrayKlass o; - Symbol* sym = NULL; if (name_str != NULL) { sym = SymbolTable::new_permanent_symbol(name_str, CHECK_NULL); } - KlassHandle klassklass (THREAD, Universe::typeArrayKlassKlassObj()); + + ClassLoaderData* null_loader_data = ClassLoaderData::the_null_class_loader_data(); + + typeArrayKlass* ak = typeArrayKlass::allocate(null_loader_data, type, sym, CHECK_NULL); - arrayKlassHandle k = base_create_array_klass(o.vtbl_value(), header_size(), klassklass, CHECK_NULL); - typeArrayKlass* ak = typeArrayKlass::cast(k()); - ak->set_name(sym); - ak->set_layout_helper(array_layout_helper(type)); - assert(scale == (1 << ak->log2_element_size()), "scale must check out"); - assert(ak->oop_is_javaArray(), "sanity"); - assert(ak->oop_is_typeArray(), "sanity"); - ak->set_max_length(arrayOopDesc::max_array_length(type)); - assert(k()->size() > header_size(), "bad size"); + // Add all classes to our internal class loader list here, + // including classes in the bootstrap (NULL) class loader. + // GC walks these as strong roots. + null_loader_data->add_class(ak); // Call complete_create_array_klass after all instance variables have been initialized. - KlassHandle super (THREAD, k->super()); - complete_create_array_klass(k, super, CHECK_NULL); + complete_create_array_klass(ak, ak->super(), CHECK_NULL); + + return ak; +} + +typeArrayKlass* typeArrayKlass::allocate(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS) { + assert(typeArrayKlass::header_size() <= InstanceKlass::header_size(), + "array klasses must be same size as InstanceKlass"); + + int size = arrayKlass::static_size(typeArrayKlass::header_size()); - return k(); + return new (loader_data, size, THREAD) typeArrayKlass(type, name); +} + +typeArrayKlass::typeArrayKlass(BasicType type, Symbol* name) : arrayKlass(name) { + set_layout_helper(array_layout_helper(type)); + assert(oop_is_array(), "sanity"); + assert(oop_is_typeArray(), "sanity"); + + set_max_length(arrayOopDesc::max_array_length(type)); + assert(size() >= typeArrayKlass::header_size(), "bad size"); + + set_class_loader_data(ClassLoaderData::the_null_class_loader_data()); } typeArrayOop typeArrayKlass::allocate_common(int length, bool do_zero, TRAPS) { @@ -81,7 +98,7 @@ if (length >= 0) { if (length <= max_length()) { size_t size = typeArrayOopDesc::object_size(layout_helper(), length); - KlassHandle h_k(THREAD, as_klassOop()); + KlassHandle h_k(THREAD, this); typeArrayOop t; CollectedHeap* ch = Universe::heap(); if (do_zero) { @@ -89,7 +106,6 @@ } 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"); @@ -101,16 +117,6 @@ } } -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; -} - oop typeArrayKlass::multi_allocate(int rank, jint* last_size, TRAPS) { // For typeArrays this is only called for the last dimension assert(rank == 1, "just checking"); @@ -150,19 +156,13 @@ // create a klass of array holding typeArrays -klassOop typeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) { - typeArrayKlassHandle h_this(THREAD, as_klassOop()); - return array_klass_impl(h_this, or_null, n, THREAD); -} +Klass* typeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) { + int dim = dimension(); + assert(dim <= n, "check order of chain"); + if (dim == n) + return this; -klassOop typeArrayKlass::array_klass_impl(typeArrayKlassHandle h_this, bool or_null, int n, TRAPS) { - int dimension = h_this->dimension(); - assert(dimension <= n, "check order of chain"); - if (dimension == n) - return h_this(); - - objArrayKlassHandle h_ak(THREAD, h_this->higher_dimension()); - if (h_ak.is_null()) { + if (higher_dimension() == NULL) { if (or_null) return NULL; ResourceMark rm; @@ -172,28 +172,27 @@ // Atomic create higher dimension and link into list MutexLocker mu(MultiArray_lock, THREAD); - h_ak = objArrayKlassHandle(THREAD, h_this->higher_dimension()); - if (h_ak.is_null()) { - klassOop oak = objArrayKlassKlass::cast( - Universe::objArrayKlassKlassObj())->allocate_objArray_klass( - dimension + 1, h_this, CHECK_NULL); - h_ak = objArrayKlassHandle(THREAD, oak); - h_ak->set_lower_dimension(h_this()); + if (higher_dimension() == NULL) { + Klass* oak = objArrayKlass::allocate_objArray_klass( + class_loader_data(), dim + 1, this, CHECK_NULL); + objArrayKlass* h_ak = objArrayKlass::cast(oak); + h_ak->set_lower_dimension(this); OrderAccess::storestore(); - h_this->set_higher_dimension(h_ak()); + set_higher_dimension(h_ak); assert(h_ak->oop_is_objArray(), "incorrect initialization of objArrayKlass"); } } } else { CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); } + objArrayKlass* h_ak = objArrayKlass::cast(higher_dimension()); if (or_null) { return h_ak->array_klass_or_null(n); } return h_ak->array_klass(n, CHECK_NULL); } -klassOop typeArrayKlass::array_klass_impl(bool or_null, TRAPS) { +Klass* typeArrayKlass::array_klass_impl(bool or_null, TRAPS) { return array_klass_impl(or_null, dimension() + 1, THREAD); } @@ -225,7 +224,7 @@ return t->object_size(); } -int typeArrayKlass::oop_oop_iterate(oop obj, OopClosure* blk) { +int typeArrayKlass::oop_oop_iterate(oop obj, ExtendedOopClosure* blk) { assert(obj->is_typeArray(),"must be a type array"); typeArrayOop t = typeArrayOop(obj); // Performance tweak: We skip iterating over the klass pointer since we @@ -233,7 +232,7 @@ return t->object_size(); } -int typeArrayKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { +int typeArrayKlass::oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) { assert(obj->is_typeArray(),"must be a type array"); typeArrayOop t = typeArrayOop(obj); // Performance tweak: We skip iterating over the klass pointer since we @@ -243,6 +242,7 @@ #ifndef SERIALGC void typeArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { + ShouldNotReachHere(); assert(obj->is_typeArray(),"must be a type array"); } @@ -273,8 +273,35 @@ return NULL; } + +// Printing + +void typeArrayKlass::print_on(outputStream* st) const { #ifndef PRODUCT -// Printing + assert(is_klass(), "must be klass"); + print_value_on(st); + Klass::print_on(st); +#endif //PRODUCT +} + +void typeArrayKlass::print_value_on(outputStream* st) const { + assert(is_klass(), "must be klass"); + st->print("{type array "); + switch (element_type()) { + case T_BOOLEAN: st->print("bool"); break; + case T_CHAR: st->print("char"); break; + case T_FLOAT: st->print("float"); break; + case T_DOUBLE: st->print("double"); break; + case T_BYTE: st->print("byte"); break; + case T_SHORT: st->print("short"); break; + case T_INT: st->print("int"); break; + case T_LONG: st->print("long"); break; + default: ShouldNotReachHere(); + } + st->print("}"); +} + +#ifndef PRODUCT static void print_boolean_array(typeArrayOop ta, int print_len, outputStream* st) { for (int index = 0; index < print_len; index++) {