54 ValueArrayKlass::ValueArrayKlass(Klass* element_klass, Symbol* name) : ArrayKlass(name) {
55 assert(element_klass->is_value(), "Expected Value");
56
57 set_element_klass(ValueKlass::cast(element_klass));
58 set_class_loader_data(element_klass->class_loader_data());
59 set_layout_helper(array_layout_helper(ValueKlass::cast(element_klass)));
60
61 assert((1 << Klass::layout_helper_log2_element_size(layout_helper())) >=
62 element_value_store_size(), "sanity");
63 assert(is_array_klass(), "sanity");
64 assert(is_valueArray_klass(), "sanity");
65
66 CMH("tweak name symbol refcnt ?")
67 #ifndef PRODUCT
68 if (PrintValueArrayLayout) {
69 print();
70 }
71 #endif
72 }
73
74 void ValueArrayKlass::set_element_klass(ValueKlass* k) {
75 _element_klass = k;
76 _element_value_store_size = k->raw_value_byte_size();
77 }
78
79 ValueArrayKlass* ValueArrayKlass::allocate_klass(Klass* element_klass,
80 Symbol* name,
81 TRAPS) {
82 assert(ValueArrayFlatten, "Flatten array not allowed");
83 assert(ValueKlass::cast(element_klass)->is_atomic() || (!ValueArrayAtomicAccess), "Atomic by-default");
84
85 ClassLoaderData* loader_data = element_klass->class_loader_data();
86 int size = ArrayKlass::static_size(ValueArrayKlass::header_size());
87 ValueArrayKlass* vak = new (loader_data, size, THREAD) ValueArrayKlass(element_klass, name);
88 if (vak == NULL) {
89 return NULL;
90 }
91 loader_data->add_class(vak);
92 complete_create_array_klass(vak, vak->super(), vak->module(), CHECK_NULL);
93 return vak;
94 }
95
96 ValueArrayKlass* ValueArrayKlass::allocate_klass(Klass* element_klass, TRAPS) {
97 Symbol* name = ArrayKlass::create_element_klass_array_name(element_klass, CHECK_NULL);
98 return allocate_klass(element_klass, name, THREAD);
99 }
100
101 void ValueArrayKlass::initialize(TRAPS) {
102 element_klass()->initialize(THREAD);
180 if (src_pos < 0 || dst_pos < 0 || length < 0) {
181 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
182 }
183 // Check if the ranges are valid
184 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
185 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
186 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
187 }
188 // Check zero copy
189 if (length == 0)
190 return;
191
192 valueArrayOop sa = valueArrayOop(s);
193 valueArrayOop da = valueArrayOop(d);
194 address src = (address) sa->value_at_addr(src_pos, layout_helper());
195 address dst = (address) da->value_at_addr(dst_pos, layout_helper());
196 if (contains_oops()) {
197 int elem_incr = 1 << log2_element_size();
198 address src_end = src + (length << log2_element_size());
199 while (src < src_end) {
200 element_klass()->value_store(src, dst, element_value_store_size(), true, false);
201 src += elem_incr;
202 dst += elem_incr;
203 }
204 } else {
205 // we are basically a type array...don't bother limiting element copy
206 // it would have to be a lot wasted space to be worth value_store() calls, need a setting here ?
207 Copy::conjoint_memory_atomic(src, dst, (size_t)length << log2_element_size());
208 }
209 }
210
211
212 Klass* ValueArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
213
214 assert(dimension() <= n, "check order of chain");
215 int dim = dimension();
216 if (dim == n) return this;
217
218 if (higher_dimension() == NULL) {
219 if (or_null) return NULL;
220
277
278 int elem_size = element_byte_size();
279 st->print(" - element size %i ", elem_size);
280 st->print("aligned layout size %i", 1 << layout_helper_log2_element_size(layout_helper()));
281 st->cr();
282 #endif //PRODUCT
283 }
284
285 void ValueArrayKlass::print_value_on(outputStream* st) const {
286 assert(is_klass(), "must be klass");
287
288 element_klass()->print_value_on(st);
289 st->print("[]");
290 }
291
292
293 #ifndef PRODUCT
294 void ValueArrayKlass::oop_print_on(oop obj, outputStream* st) {
295 ArrayKlass::oop_print_on(obj, st);
296 valueArrayOop va = valueArrayOop(obj);
297 ValueKlass* vk = element_klass();
298 int print_len = MIN2((intx) va->length(), MaxElementPrintSize);
299 for(int index = 0; index < print_len; index++) {
300 int off = (address) va->value_at_addr(index, layout_helper()) - (address) obj;
301 st->print_cr(" - Index %3d offset %3d: ", index, off);
302 oop obj = (oop) ((address)va->value_at_addr(index, layout_helper()) - vk->first_field_offset());
303 FieldPrinter print_field(st, obj);
304 vk->do_nonstatic_fields(&print_field);
305 st->cr();
306 }
307 int remaining = va->length() - print_len;
308 if (remaining > 0) {
309 st->print_cr(" - <%d more elements, increase MaxElementPrintSize to print>", remaining);
310 }
311 }
312 #endif //PRODUCT
313
314 void ValueArrayKlass::oop_print_value_on(oop obj, outputStream* st) {
315 assert(obj->is_valueArray(), "must be valueArray");
316 st->print("a ");
317 element_klass()->print_value_on(st);
320 obj->print_address_on(st);
321 if (PrintMiscellaneous && (WizardMode || Verbose)) {
322 int lh = layout_helper();
323 st->print("{");
324 for (int i = 0; i < len; i++) {
325 if (i > 4) {
326 st->print("..."); break;
327 }
328 st->print(" " INTPTR_FORMAT, (intptr_t)(void*)valueArrayOop(obj)->value_at_addr(i , lh));
329 }
330 st->print(" }");
331 }
332 }
333
334 // Verification
335
336 void ValueArrayKlass::oop_verify_on(oop obj, outputStream* st) {
337 ArrayKlass::oop_verify_on(obj, st);
338 guarantee(obj->is_valueArray(), "must be valueArray");
339
340 if (element_klass()->contains_oops()) {
341 valueArrayOop va = valueArrayOop(obj);
342 NoHeaderExtendedOopClosure wrapClosure(&VerifyOopClosure::verify_oop);
343 va->oop_iterate(&wrapClosure);
344 }
345 }
346
347 void ValueArrayKlass::verify_on(outputStream* st) {
348 ArrayKlass::verify_on(st);
349 guarantee(element_klass()->is_value(), "should be value type klass");
350 }
|
54 ValueArrayKlass::ValueArrayKlass(Klass* element_klass, Symbol* name) : ArrayKlass(name) {
55 assert(element_klass->is_value(), "Expected Value");
56
57 set_element_klass(ValueKlass::cast(element_klass));
58 set_class_loader_data(element_klass->class_loader_data());
59 set_layout_helper(array_layout_helper(ValueKlass::cast(element_klass)));
60
61 assert((1 << Klass::layout_helper_log2_element_size(layout_helper())) >=
62 element_value_store_size(), "sanity");
63 assert(is_array_klass(), "sanity");
64 assert(is_valueArray_klass(), "sanity");
65
66 CMH("tweak name symbol refcnt ?")
67 #ifndef PRODUCT
68 if (PrintValueArrayLayout) {
69 print();
70 }
71 #endif
72 }
73
74 void ValueArrayKlass::set_element_klass(Klass* k) {
75 _element_klass = k;
76 _element_value_store_size = ((ValueKlass*)k)->raw_value_byte_size();
77 }
78
79 ValueArrayKlass* ValueArrayKlass::allocate_klass(Klass* element_klass,
80 Symbol* name,
81 TRAPS) {
82 assert(ValueArrayFlatten, "Flatten array required");
83 assert(ValueKlass::cast(element_klass)->is_atomic() || (!ValueArrayAtomicAccess), "Atomic by-default");
84
85 ClassLoaderData* loader_data = element_klass->class_loader_data();
86 int size = ArrayKlass::static_size(ValueArrayKlass::header_size());
87 ValueArrayKlass* vak = new (loader_data, size, THREAD) ValueArrayKlass(element_klass, name);
88 if (vak == NULL) {
89 return NULL;
90 }
91 loader_data->add_class(vak);
92 complete_create_array_klass(vak, vak->super(), vak->module(), CHECK_NULL);
93 return vak;
94 }
95
96 ValueArrayKlass* ValueArrayKlass::allocate_klass(Klass* element_klass, TRAPS) {
97 Symbol* name = ArrayKlass::create_element_klass_array_name(element_klass, CHECK_NULL);
98 return allocate_klass(element_klass, name, THREAD);
99 }
100
101 void ValueArrayKlass::initialize(TRAPS) {
102 element_klass()->initialize(THREAD);
180 if (src_pos < 0 || dst_pos < 0 || length < 0) {
181 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
182 }
183 // Check if the ranges are valid
184 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
185 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
186 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
187 }
188 // Check zero copy
189 if (length == 0)
190 return;
191
192 valueArrayOop sa = valueArrayOop(s);
193 valueArrayOop da = valueArrayOop(d);
194 address src = (address) sa->value_at_addr(src_pos, layout_helper());
195 address dst = (address) da->value_at_addr(dst_pos, layout_helper());
196 if (contains_oops()) {
197 int elem_incr = 1 << log2_element_size();
198 address src_end = src + (length << log2_element_size());
199 while (src < src_end) {
200 ((ValueKlass*)element_klass())->value_store(src, dst, element_value_store_size(), true, false);
201 src += elem_incr;
202 dst += elem_incr;
203 }
204 } else {
205 // we are basically a type array...don't bother limiting element copy
206 // it would have to be a lot wasted space to be worth value_store() calls, need a setting here ?
207 Copy::conjoint_memory_atomic(src, dst, (size_t)length << log2_element_size());
208 }
209 }
210
211
212 Klass* ValueArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
213
214 assert(dimension() <= n, "check order of chain");
215 int dim = dimension();
216 if (dim == n) return this;
217
218 if (higher_dimension() == NULL) {
219 if (or_null) return NULL;
220
277
278 int elem_size = element_byte_size();
279 st->print(" - element size %i ", elem_size);
280 st->print("aligned layout size %i", 1 << layout_helper_log2_element_size(layout_helper()));
281 st->cr();
282 #endif //PRODUCT
283 }
284
285 void ValueArrayKlass::print_value_on(outputStream* st) const {
286 assert(is_klass(), "must be klass");
287
288 element_klass()->print_value_on(st);
289 st->print("[]");
290 }
291
292
293 #ifndef PRODUCT
294 void ValueArrayKlass::oop_print_on(oop obj, outputStream* st) {
295 ArrayKlass::oop_print_on(obj, st);
296 valueArrayOop va = valueArrayOop(obj);
297 ValueKlass* vk = (ValueKlass*)element_klass();
298 int print_len = MIN2((intx) va->length(), MaxElementPrintSize);
299 for(int index = 0; index < print_len; index++) {
300 int off = (address) va->value_at_addr(index, layout_helper()) - (address) obj;
301 st->print_cr(" - Index %3d offset %3d: ", index, off);
302 oop obj = (oop) ((address)va->value_at_addr(index, layout_helper()) - vk->first_field_offset());
303 FieldPrinter print_field(st, obj);
304 vk->do_nonstatic_fields(&print_field);
305 st->cr();
306 }
307 int remaining = va->length() - print_len;
308 if (remaining > 0) {
309 st->print_cr(" - <%d more elements, increase MaxElementPrintSize to print>", remaining);
310 }
311 }
312 #endif //PRODUCT
313
314 void ValueArrayKlass::oop_print_value_on(oop obj, outputStream* st) {
315 assert(obj->is_valueArray(), "must be valueArray");
316 st->print("a ");
317 element_klass()->print_value_on(st);
320 obj->print_address_on(st);
321 if (PrintMiscellaneous && (WizardMode || Verbose)) {
322 int lh = layout_helper();
323 st->print("{");
324 for (int i = 0; i < len; i++) {
325 if (i > 4) {
326 st->print("..."); break;
327 }
328 st->print(" " INTPTR_FORMAT, (intptr_t)(void*)valueArrayOop(obj)->value_at_addr(i , lh));
329 }
330 st->print(" }");
331 }
332 }
333
334 // Verification
335
336 void ValueArrayKlass::oop_verify_on(oop obj, outputStream* st) {
337 ArrayKlass::oop_verify_on(obj, st);
338 guarantee(obj->is_valueArray(), "must be valueArray");
339
340 if (((ValueKlass*)element_klass())->contains_oops()) {
341 valueArrayOop va = valueArrayOop(obj);
342 NoHeaderExtendedOopClosure wrapClosure(&VerifyOopClosure::verify_oop);
343 va->oop_iterate(&wrapClosure);
344 }
345 }
346
347 void ValueArrayKlass::verify_on(outputStream* st) {
348 ArrayKlass::verify_on(st);
349 guarantee(element_klass()->is_value(), "should be value type klass");
350 }
|