< prev index next >
src/share/vm/oops/objArrayKlass.cpp
Print this page
*** 44,73 ****
#include "runtime/handles.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/copy.hpp"
#include "utilities/macros.hpp"
! ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, KlassHandle klass_handle, Symbol* name, TRAPS) {
assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(),
"array klasses must be same size as InstanceKlass");
int size = ArrayKlass::static_size(ObjArrayKlass::header_size());
! return new (loader_data, size, THREAD) ObjArrayKlass(n, klass_handle, name);
}
Klass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data,
! int n, KlassHandle element_klass, TRAPS) {
// Eagerly allocate the direct array supertype.
! KlassHandle super_klass = KlassHandle();
if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) {
! KlassHandle element_super (THREAD, element_klass->super());
! if (element_super.not_null()) {
// The element type has a direct super. E.g., String[] has direct super of Object[].
! super_klass = KlassHandle(THREAD, element_super->array_klass_or_null());
! bool supers_exist = super_klass.not_null();
// Also, see if the element has secondary supertypes.
// We need an array type for each.
Array<Klass*>* element_supers = element_klass->secondary_supers();
for( int i = element_supers->length()-1; i >= 0; i-- ) {
Klass* elem_super = element_supers->at(i);
--- 44,73 ----
#include "runtime/handles.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/copy.hpp"
#include "utilities/macros.hpp"
! ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS) {
assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(),
"array klasses must be same size as InstanceKlass");
int size = ArrayKlass::static_size(ObjArrayKlass::header_size());
! return new (loader_data, size, THREAD) ObjArrayKlass(n, k, name);
}
Klass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data,
! int n, Klass* element_klass, TRAPS) {
// Eagerly allocate the direct array supertype.
! Klass* super_klass = NULL;
if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) {
! Klass* element_super = element_klass->super();
! if (element_super != NULL) {
// The element type has a direct super. E.g., String[] has direct super of Object[].
! super_klass = element_super->array_klass_or_null();
! bool supers_exist = super_klass != NULL;
// Also, see if the element has secondary supertypes.
// We need an array type for each.
Array<Klass*>* element_supers = element_klass->secondary_supers();
for( int i = element_supers->length()-1; i >= 0; i-- ) {
Klass* elem_super = element_supers->at(i);
*** 76,113 ****
break;
}
}
if (!supers_exist) {
// Oops. Not allocated yet. Back out, allocate it, and retry.
! KlassHandle ek;
{
MutexUnlocker mu(MultiArray_lock);
MutexUnlocker mc(Compile_lock); // for vtables
! Klass* sk = element_super->array_klass(CHECK_0);
! super_klass = KlassHandle(THREAD, sk);
for( int i = element_supers->length()-1; i >= 0; i-- ) {
! KlassHandle elem_super (THREAD, element_supers->at(i));
elem_super->array_klass(CHECK_0);
}
// Now retry from the beginning
! Klass* klass_oop = element_klass->array_klass(n, CHECK_0);
! // Create a handle because the enclosing brace, when locking
! // can cause a gc. Better to have this function return a Handle.
! ek = KlassHandle(THREAD, klass_oop);
} // re-lock
! return ek();
}
} else {
// The element type is already Object. Object[] has direct super of Object.
! super_klass = KlassHandle(THREAD, SystemDictionary::Object_klass());
}
}
// Create type name for klass.
Symbol* name = NULL;
if (!element_klass->is_instance_klass() ||
! (name = InstanceKlass::cast(element_klass())->array_name()) == NULL) {
ResourceMark rm(THREAD);
char *name_str = element_klass->name()->as_C_string();
int len = element_klass->name()->utf8_length();
char *new_str = NEW_RESOURCE_ARRAY(char, len + 4);
--- 76,109 ----
break;
}
}
if (!supers_exist) {
// Oops. Not allocated yet. Back out, allocate it, and retry.
! Klass* ek = NULL;
{
MutexUnlocker mu(MultiArray_lock);
MutexUnlocker mc(Compile_lock); // for vtables
! super_klass = element_super->array_klass(CHECK_0);
for( int i = element_supers->length()-1; i >= 0; i-- ) {
! Klass* elem_super = element_supers->at(i);
elem_super->array_klass(CHECK_0);
}
// Now retry from the beginning
! ek = element_klass->array_klass(n, CHECK_0);
} // re-lock
! return ek;
}
} else {
// The element type is already Object. Object[] has direct super of Object.
! super_klass = SystemDictionary::Object_klass();
}
}
// Create type name for klass.
Symbol* name = NULL;
if (!element_klass->is_instance_klass() ||
! (name = InstanceKlass::cast(element_klass)->array_name()) == NULL) {
ResourceMark rm(THREAD);
char *name_str = element_klass->name()->as_C_string();
int len = element_klass->name()->utf8_length();
char *new_str = NEW_RESOURCE_ARRAY(char, len + 4);
*** 122,132 ****
new_str[idx++] = ';';
}
new_str[idx++] = '\0';
name = SymbolTable::new_permanent_symbol(new_str, CHECK_0);
if (element_klass->is_instance_klass()) {
! InstanceKlass* ik = InstanceKlass::cast(element_klass());
ik->set_array_name(name);
}
}
// Initialize instance variables
--- 118,128 ----
new_str[idx++] = ';';
}
new_str[idx++] = '\0';
name = SymbolTable::new_permanent_symbol(new_str, CHECK_0);
if (element_klass->is_instance_klass()) {
! InstanceKlass* ik = InstanceKlass::cast(element_klass);
ik->set_array_name(name);
}
}
// Initialize instance variables
*** 144,166 ****
ArrayKlass::complete_create_array_klass(oak, super_klass, module, CHECK_0);
return oak;
}
! ObjArrayKlass::ObjArrayKlass(int n, KlassHandle element_klass, Symbol* name) : ArrayKlass(name) {
this->set_dimension(n);
! this->set_element_klass(element_klass());
// decrement refcount because object arrays are not explicitly freed. The
// InstanceKlass array_name() keeps the name counted while the klass is
// loaded.
name->decrement_refcount();
Klass* bk;
if (element_klass->is_objArray_klass()) {
! bk = ObjArrayKlass::cast(element_klass())->bottom_klass();
} else {
! bk = element_klass();
}
assert(bk != NULL && (bk->is_instance_klass() || bk->is_typeArray_klass()), "invalid bottom klass");
this->set_bottom_klass(bk);
this->set_class_loader_data(bk->class_loader_data());
--- 140,162 ----
ArrayKlass::complete_create_array_klass(oak, super_klass, module, CHECK_0);
return oak;
}
! ObjArrayKlass::ObjArrayKlass(int n, Klass* element_klass, Symbol* name) : ArrayKlass(name) {
this->set_dimension(n);
! this->set_element_klass(element_klass);
// decrement refcount because object arrays are not explicitly freed. The
// InstanceKlass array_name() keeps the name counted while the klass is
// loaded.
name->decrement_refcount();
Klass* bk;
if (element_klass->is_objArray_klass()) {
! bk = ObjArrayKlass::cast(element_klass)->bottom_klass();
} else {
! bk = element_klass;
}
assert(bk != NULL && (bk->is_instance_klass() || bk->is_typeArray_klass()), "invalid bottom klass");
this->set_bottom_klass(bk);
this->set_class_loader_data(bk->class_loader_data());
*** 176,187 ****
objArrayOop ObjArrayKlass::allocate(int length, TRAPS) {
if (length >= 0) {
if (length <= arrayOopDesc::max_array_length(T_OBJECT)) {
int size = objArrayOopDesc::object_size(length);
! KlassHandle h_k(THREAD, this);
! return (objArrayOop)CollectedHeap::array_allocate(h_k, size, length, THREAD);
} 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());
}
--- 172,182 ----
objArrayOop ObjArrayKlass::allocate(int length, TRAPS) {
if (length >= 0) {
if (length <= arrayOopDesc::max_array_length(T_OBJECT)) {
int size = objArrayOopDesc::object_size(length);
! return (objArrayOop)CollectedHeap::array_allocate(this, size, length, THREAD);
} 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());
}
*** 194,211 ****
oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) {
int length = *sizes;
// Call to lower_dimension uses this pointer, so most be called before a
// possible GC
! KlassHandle h_lower_dimension(THREAD, lower_dimension());
// If length < 0 allocate will throw an exception.
objArrayOop array = allocate(length, CHECK_NULL);
objArrayHandle h_array (THREAD, array);
if (rank > 1) {
if (length != 0) {
for (int index = 0; index < length; index++) {
! ArrayKlass* ak = ArrayKlass::cast(h_lower_dimension());
oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL);
h_array->obj_at_put(index, sub_array);
}
} else {
// Since this array dimension has zero length, nothing will be
--- 189,206 ----
oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) {
int length = *sizes;
// Call to lower_dimension uses this pointer, so most be called before a
// possible GC
! Klass* ld_klass = lower_dimension();
// If length < 0 allocate will throw an exception.
objArrayOop array = allocate(length, CHECK_NULL);
objArrayHandle h_array (THREAD, array);
if (rank > 1) {
if (length != 0) {
for (int index = 0; index < length; index++) {
! ArrayKlass* ak = ArrayKlass::cast(ld_klass);
oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL);
h_array->obj_at_put(index, sub_array);
}
} else {
// Since this array dimension has zero length, nothing will be
< prev index next >