121 }
122
123 oop TypeArrayKlass::multi_allocate(int rank, jint* last_size, TRAPS) {
124 // For typeArrays this is only called for the last dimension
125 assert(rank == 1, "just checking");
126 int length = *last_size;
127 return allocate(length, THREAD);
128 }
129
130
131 void TypeArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) {
132 assert(s->is_typeArray(), "must be type array");
133
134 // Check destination
135 if (!d->is_typeArray() || element_type() != TypeArrayKlass::cast(d->klass())->element_type()) {
136 THROW(vmSymbols::java_lang_ArrayStoreException());
137 }
138
139 // Check is all offsets and lengths are non negative
140 if (src_pos < 0 || dst_pos < 0 || length < 0) {
141 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
142 }
143 // Check if the ranges are valid
144 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
145 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
146 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
147 }
148 // Check zero copy
149 if (length == 0)
150 return;
151
152 // This is an attempt to make the copy_array fast.
153 int l2es = log2_element_size();
154 int ihs = array_header_in_bytes() / wordSize;
155 void* src = (char*) (s->base(element_type())) + ((size_t)src_pos << l2es);
156 void* dst = (char*) (d->base(element_type())) + ((size_t)dst_pos << l2es);
157 HeapAccess<ARRAYCOPY_ATOMIC>::arraycopy(s, d, src, dst, (size_t)length << l2es);
158 }
159
160
161 // create a klass of array holding typeArrays
162 Klass* TypeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
163 int dim = dimension();
164 assert(dim <= n, "check order of chain");
165 if (dim == n)
166 return this;
167
168 // lock-free read needs acquire semantics
169 if (higher_dimension_acquire() == NULL) {
170 if (or_null) return NULL;
171
172 ResourceMark rm;
173 JavaThread *jt = (JavaThread *)THREAD;
174 {
175 MutexLocker mc(Compile_lock, THREAD); // for vtables
176 // Atomic create higher dimension and link into list
177 MutexLocker mu(MultiArray_lock, THREAD);
178
179 if (higher_dimension() == NULL) {
180 Klass* oak = ObjArrayKlass::allocate_objArray_klass(
223 case T_LONG: return "[J";
224 default: ShouldNotReachHere();
225 }
226 return NULL;
227 }
228
229
230 // Printing
231
232 void TypeArrayKlass::print_on(outputStream* st) const {
233 #ifndef PRODUCT
234 assert(is_klass(), "must be klass");
235 print_value_on(st);
236 Klass::print_on(st);
237 #endif //PRODUCT
238 }
239
240 void TypeArrayKlass::print_value_on(outputStream* st) const {
241 assert(is_klass(), "must be klass");
242 st->print("{type array ");
243 switch (element_type()) {
244 case T_BOOLEAN: st->print("bool"); break;
245 case T_CHAR: st->print("char"); break;
246 case T_FLOAT: st->print("float"); break;
247 case T_DOUBLE: st->print("double"); break;
248 case T_BYTE: st->print("byte"); break;
249 case T_SHORT: st->print("short"); break;
250 case T_INT: st->print("int"); break;
251 case T_LONG: st->print("long"); break;
252 default: ShouldNotReachHere();
253 }
254 st->print("}");
255 }
256
257 #ifndef PRODUCT
258
259 static void print_boolean_array(typeArrayOop ta, int print_len, outputStream* st) {
260 for (int index = 0; index < print_len; index++) {
261 st->print_cr(" - %3d: %s", index, (ta->bool_at(index) == 0) ? "false" : "true");
262 }
263 }
264
265
266 static void print_char_array(typeArrayOop ta, int print_len, outputStream* st) {
267 for (int index = 0; index < print_len; index++) {
268 jchar c = ta->char_at(index);
269 st->print_cr(" - %3d: %x %c", index, c, isprint(c) ? c : ' ');
270 }
271 }
272
|
121 }
122
123 oop TypeArrayKlass::multi_allocate(int rank, jint* last_size, TRAPS) {
124 // For typeArrays this is only called for the last dimension
125 assert(rank == 1, "just checking");
126 int length = *last_size;
127 return allocate(length, THREAD);
128 }
129
130
131 void TypeArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) {
132 assert(s->is_typeArray(), "must be type array");
133
134 // Check destination
135 if (!d->is_typeArray() || element_type() != TypeArrayKlass::cast(d->klass())->element_type()) {
136 THROW(vmSymbols::java_lang_ArrayStoreException());
137 }
138
139 // Check is all offsets and lengths are non negative
140 if (src_pos < 0 || dst_pos < 0 || length < 0) {
141 // Pass specific exception reason.
142 ResourceMark rm;
143 stringStream ss;
144 if (src_pos < 0) {
145 ss.print("while trying to copy from index %i of a %s array with length %i",
146 src_pos, type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length());
147 } else if (dst_pos < 0) {
148 ss.print("while trying to copy to index %i of a %s array with length %i",
149 dst_pos, type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
150 } else {
151 ss.print("while trying to copy a negative range %i from a %s array with length %i to a %s array with length %i",
152 length, type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length(),
153 type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
154 }
155 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
156 }
157 // Check if the ranges are valid
158 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
159 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
160 // Pass specific exception reason.
161 ResourceMark rm;
162 stringStream ss;
163 if (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) {
164 ss.print("while trying to copy from index %u of a %s array with length %i",
165 (unsigned int) length + (unsigned int) src_pos,
166 type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length());
167 } else {
168 ss.print("while trying to copy to index %u of a %s array with length %i",
169 (unsigned int) length + (unsigned int) dst_pos,
170 type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
171 }
172 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
173 }
174 // Check zero copy
175 if (length == 0)
176 return;
177
178 // This is an attempt to make the copy_array fast.
179 int l2es = log2_element_size();
180 int ihs = array_header_in_bytes() / wordSize;
181 void* src = (char*) (s->base(element_type())) + ((size_t)src_pos << l2es);
182 void* dst = (char*) (d->base(element_type())) + ((size_t)dst_pos << l2es);
183 HeapAccess<ARRAYCOPY_ATOMIC>::arraycopy(s, d, src, dst, (size_t)length << l2es);
184 }
185
186 // create a klass of array holding typeArrays
187 Klass* TypeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
188 int dim = dimension();
189 assert(dim <= n, "check order of chain");
190 if (dim == n)
191 return this;
192
193 // lock-free read needs acquire semantics
194 if (higher_dimension_acquire() == NULL) {
195 if (or_null) return NULL;
196
197 ResourceMark rm;
198 JavaThread *jt = (JavaThread *)THREAD;
199 {
200 MutexLocker mc(Compile_lock, THREAD); // for vtables
201 // Atomic create higher dimension and link into list
202 MutexLocker mu(MultiArray_lock, THREAD);
203
204 if (higher_dimension() == NULL) {
205 Klass* oak = ObjArrayKlass::allocate_objArray_klass(
248 case T_LONG: return "[J";
249 default: ShouldNotReachHere();
250 }
251 return NULL;
252 }
253
254
255 // Printing
256
257 void TypeArrayKlass::print_on(outputStream* st) const {
258 #ifndef PRODUCT
259 assert(is_klass(), "must be klass");
260 print_value_on(st);
261 Klass::print_on(st);
262 #endif //PRODUCT
263 }
264
265 void TypeArrayKlass::print_value_on(outputStream* st) const {
266 assert(is_klass(), "must be klass");
267 st->print("{type array ");
268 BasicType bt = element_type();
269 if (bt == T_BOOLEAN) {
270 st->print("bool");
271 } else {
272 st->print("%s", type2name_tab[bt]);
273 }
274 st->print("}");
275 }
276
277 #ifndef PRODUCT
278
279 static void print_boolean_array(typeArrayOop ta, int print_len, outputStream* st) {
280 for (int index = 0; index < print_len; index++) {
281 st->print_cr(" - %3d: %s", index, (ta->bool_at(index) == 0) ? "false" : "true");
282 }
283 }
284
285
286 static void print_char_array(typeArrayOop ta, int print_len, outputStream* st) {
287 for (int index = 0; index < print_len; index++) {
288 jchar c = ta->char_at(index);
289 st->print_cr(" - %3d: %x %c", index, c, isprint(c) ? c : ' ');
290 }
291 }
292
|