167 assert(layout_helper_log2_element_size(lh) == esize, "correct decode"); 168 assert((1 << esize) < BytesPerLong || is_aligned(hsize, HeapWordsPerLong), "unaligned base"); 169 170 return lh; 171 } 172 173 int ValueArrayKlass::oop_size(oop obj) const { 174 assert(obj->is_valueArray(),"must be a value array"); 175 valueArrayOop array = valueArrayOop(obj); 176 return array->object_size(); 177 } 178 179 jint ValueArrayKlass::max_elements() const { 180 return arrayOopDesc::max_array_length(arrayOopDesc::header_size(T_VALUETYPE), element_byte_size()); 181 } 182 183 oop ValueArrayKlass::protection_domain() const { 184 return element_klass()->protection_domain(); 185 } 186 187 void ValueArrayKlass::copy_array(arrayOop s, int src_pos, 188 arrayOop d, int dst_pos, int length, TRAPS) { 189 190 assert(s->is_objArray() || s->is_valueArray(), "must be obj or value array"); 191 192 // Check destination 193 if ((!d->is_valueArray()) && (!d->is_objArray())) { 194 THROW(vmSymbols::java_lang_ArrayStoreException()); 195 } 196 197 // Check if all offsets and lengths are non negative 198 if (src_pos < 0 || dst_pos < 0 || length < 0) { 199 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 200 } 201 // Check if the ranges are valid 202 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) 203 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) { 204 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 205 } 206 // Check zero copy 219 if (!s_elem_klass->is_subtype_of(d_elem_klass)) { 220 THROW(vmSymbols::java_lang_ArrayStoreException()); 221 } 222 223 valueArrayOop sa = valueArrayOop(s); 224 ValueKlass* s_elem_vklass = element_klass(); 225 226 // valueArray-to-valueArray 227 if (dk->is_valueArray_klass()) { 228 // element types MUST be exact, subtype check would be dangerous 229 if (dk != this) { 230 THROW(vmSymbols::java_lang_ArrayStoreException()); 231 } 232 233 valueArrayOop da = valueArrayOop(d); 234 address dst = (address) da->value_at_addr(dst_pos, layout_helper()); 235 address src = (address) sa->value_at_addr(src_pos, layout_helper()); 236 if (contains_oops()) { 237 int elem_incr = 1 << log2_element_size(); 238 address src_end = src + (length << log2_element_size()); 239 while (src < src_end) { 240 s_elem_vklass->value_store(src, dst, element_byte_size(), true, false); 241 src += elem_incr; 242 dst += elem_incr; 243 } 244 } else { 245 // we are basically a type array...don't bother limiting element copy 246 // it would have to be a lot wasted space to be worth value_store() calls, need a setting here ? 247 Copy::conjoint_memory_atomic(src, dst, (size_t)length << log2_element_size()); 248 } 249 } 250 else { // valueArray-to-objArray 251 assert(dk->is_objArray_klass(), "Expected objArray here"); 252 // Need to allocate each new src elem payload -> dst oop 253 objArrayHandle dh(THREAD, (objArrayOop)d); 254 valueArrayHandle sh(THREAD, sa); 255 int dst_end = dst_pos + length; 256 while (dst_pos < dst_end) { 257 oop o = s_elem_vklass->allocate_instance(CHECK); 258 s_elem_vklass->value_store(sh->value_at_addr(src_pos, layout_helper()), 259 s_elem_vklass->data_for_oop(o), true, true); 260 dh->obj_at_put(dst_pos, o); 261 dst_pos++; 262 src_pos++; | 167 assert(layout_helper_log2_element_size(lh) == esize, "correct decode"); 168 assert((1 << esize) < BytesPerLong || is_aligned(hsize, HeapWordsPerLong), "unaligned base"); 169 170 return lh; 171 } 172 173 int ValueArrayKlass::oop_size(oop obj) const { 174 assert(obj->is_valueArray(),"must be a value array"); 175 valueArrayOop array = valueArrayOop(obj); 176 return array->object_size(); 177 } 178 179 jint ValueArrayKlass::max_elements() const { 180 return arrayOopDesc::max_array_length(arrayOopDesc::header_size(T_VALUETYPE), element_byte_size()); 181 } 182 183 oop ValueArrayKlass::protection_domain() const { 184 return element_klass()->protection_domain(); 185 } 186 187 // Temp hack having this here: need to move towards Access API 188 static bool needs_backwards_copy(arrayOop s, int src_pos, 189 arrayOop d, int dst_pos, int length) { 190 return oopDesc::equals(s, d) && (dst_pos > src_pos) && (dst_pos - src_pos) < length; 191 } 192 193 void ValueArrayKlass::copy_array(arrayOop s, int src_pos, 194 arrayOop d, int dst_pos, int length, TRAPS) { 195 196 assert(s->is_objArray() || s->is_valueArray(), "must be obj or value array"); 197 198 // Check destination 199 if ((!d->is_valueArray()) && (!d->is_objArray())) { 200 THROW(vmSymbols::java_lang_ArrayStoreException()); 201 } 202 203 // Check if all offsets and lengths are non negative 204 if (src_pos < 0 || dst_pos < 0 || length < 0) { 205 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 206 } 207 // Check if the ranges are valid 208 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) 209 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) { 210 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); 211 } 212 // Check zero copy 225 if (!s_elem_klass->is_subtype_of(d_elem_klass)) { 226 THROW(vmSymbols::java_lang_ArrayStoreException()); 227 } 228 229 valueArrayOop sa = valueArrayOop(s); 230 ValueKlass* s_elem_vklass = element_klass(); 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++; |