231 232 // valueArray-to-valueArray 233 if (dk->is_valueArray_klass()) { 234 // element types MUST be exact, subtype check would be dangerous 235 if (dk != this) { 236 THROW(vmSymbols::java_lang_ArrayStoreException()); 237 } 238 239 valueArrayOop da = valueArrayOop(d); 240 address dst = (address) da->value_at_addr(dst_pos, layout_helper()); 241 address src = (address) sa->value_at_addr(src_pos, layout_helper()); 242 if (contains_oops()) { 243 int elem_incr = 1 << log2_element_size(); 244 address src_end = src + (length << log2_element_size()); 245 if (needs_backwards_copy(s, src_pos, d, dst_pos, length)) { 246 swap(src, src_end); 247 dst = dst + (length << log2_element_size()); 248 do { 249 src -= elem_incr; 250 dst -= elem_incr; 251 s_elem_vklass->value_store(src, dst, element_byte_size(), true, false); 252 } while (src > src_end); 253 } else { 254 address src_end = src + (length << log2_element_size()); 255 while (src < src_end) { 256 s_elem_vklass->value_store(src, dst, element_byte_size(), true, false); 257 src += elem_incr; 258 dst += elem_incr; 259 } 260 } 261 } else { 262 // we are basically a type array...don't bother limiting element copy 263 // it would have to be a lot wasted space to be worth value_store() calls, need a setting here ? 264 Copy::conjoint_memory_atomic(src, dst, (size_t)length << log2_element_size()); 265 } 266 } 267 else { // valueArray-to-objArray 268 assert(dk->is_objArray_klass(), "Expected objArray here"); 269 // Need to allocate each new src elem payload -> dst oop 270 objArrayHandle dh(THREAD, (objArrayOop)d); 271 valueArrayHandle sh(THREAD, sa); 272 int dst_end = dst_pos + length; 273 while (dst_pos < dst_end) { 274 oop o = s_elem_vklass->allocate_instance(CHECK); 275 s_elem_vklass->value_store(sh->value_at_addr(src_pos, layout_helper()), 276 s_elem_vklass->data_for_oop(o), true, true); 277 dh->obj_at_put(dst_pos, o); 278 dst_pos++; 279 src_pos++; 280 } 281 } 282 } else { 283 assert(s->is_objArray(), "Expected objArray"); 284 objArrayOop sa = objArrayOop(s); 285 assert(d->is_valueArray(), "Excepted valueArray"); // objArray-to-valueArray 286 ValueKlass* d_elem_vklass = ValueKlass::cast(d_elem_klass); 287 valueArrayOop da = valueArrayOop(d); 288 289 int src_end = src_pos + length; 290 int delem_incr = 1 << dk->log2_element_size(); 291 address dst = (address) da->value_at_addr(dst_pos, layout_helper()); 292 while (src_pos < src_end) { 293 oop se = sa->obj_at(src_pos); 294 if (se == NULL) { 295 THROW(vmSymbols::java_lang_NullPointerException()); 296 } 297 // Check exact type per element 298 if (se->klass() != d_elem_klass) { 299 THROW(vmSymbols::java_lang_ArrayStoreException()); 300 } 301 d_elem_vklass->value_store(d_elem_vklass->data_for_oop(se), dst, true, false); 302 dst += delem_incr; 303 src_pos++; 304 } 305 } 306 } 307 308 309 Klass* ValueArrayKlass::array_klass_impl(ArrayStorageProperties storage_props, bool or_null, int n, TRAPS) { 310 assert(storage_props.is_flattened() || n > 1, "Expected flat storage"); 311 assert(dimension() <= n, "check order of chain"); 312 int dim = dimension(); 313 if (dim == n) return this; 314 315 if (higher_dimension_acquire() == NULL) { 316 if (or_null) return NULL; 317 318 ResourceMark rm; 319 { 320 // Ensure atomic creation of higher dimensions 321 MutexLocker mu(MultiArray_lock, THREAD); | 231 232 // valueArray-to-valueArray 233 if (dk->is_valueArray_klass()) { 234 // element types MUST be exact, subtype check would be dangerous 235 if (dk != this) { 236 THROW(vmSymbols::java_lang_ArrayStoreException()); 237 } 238 239 valueArrayOop da = valueArrayOop(d); 240 address dst = (address) da->value_at_addr(dst_pos, layout_helper()); 241 address src = (address) sa->value_at_addr(src_pos, layout_helper()); 242 if (contains_oops()) { 243 int elem_incr = 1 << log2_element_size(); 244 address src_end = src + (length << log2_element_size()); 245 if (needs_backwards_copy(s, src_pos, d, dst_pos, length)) { 246 swap(src, src_end); 247 dst = dst + (length << log2_element_size()); 248 do { 249 src -= elem_incr; 250 dst -= elem_incr; 251 HeapAccess<>::value_copy(src, dst, s_elem_vklass); 252 } while (src > src_end); 253 } else { 254 address src_end = src + (length << log2_element_size()); 255 while (src < src_end) { 256 HeapAccess<>::value_copy(src, dst, s_elem_vklass); 257 src += elem_incr; 258 dst += elem_incr; 259 } 260 } 261 } else { 262 // we are basically a type array...don't bother limiting element copy 263 // it would have to be a lot wasted space to be worth value_store() calls, need a setting here ? 264 Copy::conjoint_memory_atomic(src, dst, (size_t)length << log2_element_size()); 265 } 266 } 267 else { // valueArray-to-objArray 268 assert(dk->is_objArray_klass(), "Expected objArray here"); 269 // Need to allocate each new src elem payload -> dst oop 270 objArrayHandle dh(THREAD, (objArrayOop)d); 271 valueArrayHandle sh(THREAD, sa); 272 int dst_end = dst_pos + length; 273 while (dst_pos < dst_end) { 274 oop o = valueArrayOopDesc::value_copy_from_index(sh, src_pos, CHECK); 275 dh->obj_at_put(dst_pos, o); 276 dst_pos++; 277 src_pos++; 278 } 279 } 280 } else { 281 assert(s->is_objArray(), "Expected objArray"); 282 objArrayOop sa = objArrayOop(s); 283 assert(d->is_valueArray(), "Excepted valueArray"); // objArray-to-valueArray 284 ValueKlass* d_elem_vklass = ValueKlass::cast(d_elem_klass); 285 valueArrayOop da = valueArrayOop(d); 286 287 int src_end = src_pos + length; 288 int delem_incr = 1 << dk->log2_element_size(); 289 address dst = (address) da->value_at_addr(dst_pos, layout_helper()); 290 while (src_pos < src_end) { 291 oop se = sa->obj_at(src_pos); 292 if (se == NULL) { 293 THROW(vmSymbols::java_lang_NullPointerException()); 294 } 295 // Check exact type per element 296 if (se->klass() != d_elem_klass) { 297 THROW(vmSymbols::java_lang_ArrayStoreException()); 298 } 299 d_elem_vklass->value_copy_oop_to_payload(se, dst); 300 dst += delem_incr; 301 src_pos++; 302 } 303 } 304 } 305 306 307 Klass* ValueArrayKlass::array_klass_impl(ArrayStorageProperties storage_props, bool or_null, int n, TRAPS) { 308 assert(storage_props.is_flattened() || n > 1, "Expected flat storage"); 309 assert(dimension() <= n, "check order of chain"); 310 int dim = dimension(); 311 if (dim == n) return this; 312 313 if (higher_dimension_acquire() == NULL) { 314 if (or_null) return NULL; 315 316 ResourceMark rm; 317 { 318 // Ensure atomic creation of higher dimensions 319 MutexLocker mu(MultiArray_lock, THREAD); |