--- old/src/hotspot/share/oops/objArrayKlass.cpp 2019-03-11 14:26:23.558354915 +0100 +++ new/src/hotspot/share/oops/objArrayKlass.cpp 2019-03-11 14:26:23.346354918 +0100 @@ -32,6 +32,7 @@ #include "memory/iterator.inline.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" +#include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/arrayKlass.inline.hpp" @@ -97,31 +98,7 @@ } // 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); - int idx = 0; - new_str[idx++] = '['; - if (element_klass->is_instance_klass()) { // it could be an array or simple type - new_str[idx++] = 'L'; - } - memcpy(&new_str[idx], name_str, len * sizeof(char)); - idx += len; - if (element_klass->is_instance_klass()) { - 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); - } - } + Symbol* name = ArrayKlass::create_element_klass_array_name(element_klass, CHECK_NULL); // Initialize instance variables ObjArrayKlass* oak = ObjArrayKlass::allocate(loader_data, n, element_klass, name, CHECK_0); @@ -151,10 +128,13 @@ Klass* bk; if (element_klass->is_objArray_klass()) { bk = ObjArrayKlass::cast(element_klass)->bottom_klass(); + } else if (element_klass->is_valueArray_klass()) { + bk = ValueArrayKlass::cast(element_klass)->element_klass(); } else { bk = element_klass; } - assert(bk != NULL && (bk->is_instance_klass() || bk->is_typeArray_klass()), "invalid bottom 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()); @@ -179,28 +159,30 @@ oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) { int length = *sizes; + if (rank == 1) { // last dim may be valueArray + return oopFactory::new_array(element_klass(), length, CHECK_NULL); + } + guarantee(rank > 1, "Rank below 1"); // 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 - // allocated, however the lower dimension values must be checked - // for illegal values. - for (int i = 0; i < rank - 1; ++i) { - sizes += 1; - if (*sizes < 0) { - THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", *sizes)); - } + 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 + // allocated, however the lower dimension values must be checked + // for illegal values. + for (int i = 0; i < rank - 1; ++i) { + sizes += 1; + if (*sizes < 0) { + THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", *sizes)); } } } @@ -247,6 +229,13 @@ int dst_pos, int length, TRAPS) { assert(s->is_objArray(), "must be obj array"); + if (EnableValhalla) { + if (d->is_valueArray()) { + ValueArrayKlass::cast(d->klass())->copy_array(s, src_pos, d, dst_pos, length, THREAD); + return; + } + } + if (!d->is_objArray()) { ResourceMark rm(THREAD); stringStream ss; @@ -298,7 +287,26 @@ if (length==0) { return; } - if (UseCompressedOops) { + if (EnableValhalla && ArrayKlass::cast(d->klass())->element_klass()->is_value()) { + assert(d->is_objArray(), "Expected objArray"); + ValueKlass* d_elem_vklass = ValueKlass::cast(ArrayKlass::cast(d->klass())->element_klass()); + objArrayOop da = objArrayOop(d); + objArrayOop sa = objArrayOop(s); + int src_end = src_pos + length; + while (src_pos < src_end) { + oop se = sa->obj_at(src_pos); + if (se == NULL) { + THROW(vmSymbols::java_lang_NullPointerException()); + } + // Check exact type per element + if (se->klass() != d_elem_vklass) { + THROW(vmSymbols::java_lang_ArrayStoreException()); + } + da->obj_at_put(dst_pos, se); // TODO: review with ValueArrayKlass::copy_array and Access API + dst_pos++; + src_pos++; + } + } else if (UseCompressedOops) { size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset(src_pos); size_t dst_offset = (size_t) objArrayOopDesc::obj_at_offset(dst_pos); assert(arrayOopDesc::obj_offset_to_raw(s, src_offset, NULL) == @@ -436,7 +444,7 @@ void ObjArrayKlass::print_on(outputStream* st) const { #ifndef PRODUCT Klass::print_on(st); - st->print(" - instance klass: "); + st->print(" - element klass: "); element_klass()->print_value_on(st); st->cr(); #endif //PRODUCT @@ -498,7 +506,8 @@ guarantee(element_klass()->is_klass(), "should be klass"); guarantee(bottom_klass()->is_klass(), "should be klass"); Klass* bk = bottom_klass(); - guarantee(bk->is_instance_klass() || bk->is_typeArray_klass(), "invalid bottom klass"); + guarantee(bk->is_instance_klass() || bk->is_typeArray_klass() || bk->is_valueArray_klass(), + "invalid bottom klass"); } void ObjArrayKlass::oop_verify_on(oop obj, outputStream* st) {