114 report_java_out_of_memory("Requested array size exceeds VM limit");
115 JvmtiExport::post_array_size_exhausted();
116 THROW_OOP_0(Universe::out_of_memory_error_array_size());
117 }
118 } else {
119 THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length));
120 }
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("arraycopy: source index %d out of bounds for %s[%d]",
146 src_pos, type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length());
147 } else if (dst_pos < 0) {
148 ss.print("arraycopy: destination index %d out of bounds for %s[%d]",
149 dst_pos, type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
150 } else {
151 ss.print("arraycopy: length %d is negative", length);
152 }
153 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
154 }
155 // Check if the ranges are valid
156 if ((((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) ||
157 (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length())) {
158 // Pass specific exception reason.
159 ResourceMark rm;
160 stringStream ss;
161 if (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) {
162 ss.print("arraycopy: last source index %u out of bounds for %s[%d]",
163 (unsigned int) length + (unsigned int) src_pos,
164 type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length());
165 } else {
166 ss.print("arraycopy: last destination index %u out of bounds for %s[%d]",
167 (unsigned int) length + (unsigned int) dst_pos,
168 type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
169 }
170 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
171 }
172 // Check zero copy
173 if (length == 0)
174 return;
175
176 // This is an attempt to make the copy_array fast.
177 int l2es = log2_element_size();
178 size_t src_offset = arrayOopDesc::base_offset_in_bytes(element_type()) + ((size_t)src_pos << l2es);
179 size_t dst_offset = arrayOopDesc::base_offset_in_bytes(element_type()) + ((size_t)dst_pos << l2es);
|
114 report_java_out_of_memory("Requested array size exceeds VM limit");
115 JvmtiExport::post_array_size_exhausted();
116 THROW_OOP_0(Universe::out_of_memory_error_array_size());
117 }
118 } else {
119 THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length));
120 }
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 type.
135 if (!d->is_typeArray()) {
136 ResourceMark rm(THREAD);
137 stringStream ss;
138 if (d->is_objArray()) {
139 ss.print("arraycopy: type mismatch: can not copy %s[] into object array[]",
140 type2name_tab[ArrayKlass::cast(s->klass())->element_type()]);
141 } else {
142 ss.print("arraycopy: destination type %s is not an array", d->klass()->external_name());
143 }
144 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
145 }
146 if (element_type() != TypeArrayKlass::cast(d->klass())->element_type()) {
147 ResourceMark rm(THREAD);
148 stringStream ss;
149 ss.print("arraycopy: type mismatch: can not copy %s[] into %s[]",
150 type2name_tab[ArrayKlass::cast(s->klass())->element_type()],
151 type2name_tab[ArrayKlass::cast(d->klass())->element_type()]);
152 THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
153 }
154
155 // Check if all offsets and lengths are non negative.
156 if (src_pos < 0 || dst_pos < 0 || length < 0) {
157 // Pass specific exception reason.
158 ResourceMark rm(THREAD);
159 stringStream ss;
160 if (src_pos < 0) {
161 ss.print("arraycopy: source index %d out of bounds for %s[%d]",
162 src_pos, type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length());
163 } else if (dst_pos < 0) {
164 ss.print("arraycopy: destination index %d out of bounds for %s[%d]",
165 dst_pos, type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
166 } else {
167 ss.print("arraycopy: length %d is negative", length);
168 }
169 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
170 }
171 // Check if the ranges are valid
172 if ((((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) ||
173 (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length())) {
174 // Pass specific exception reason.
175 ResourceMark rm(THREAD);
176 stringStream ss;
177 if (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) {
178 ss.print("arraycopy: last source index %u out of bounds for %s[%d]",
179 (unsigned int) length + (unsigned int) src_pos,
180 type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length());
181 } else {
182 ss.print("arraycopy: last destination index %u out of bounds for %s[%d]",
183 (unsigned int) length + (unsigned int) dst_pos,
184 type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
185 }
186 THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
187 }
188 // Check zero copy
189 if (length == 0)
190 return;
191
192 // This is an attempt to make the copy_array fast.
193 int l2es = log2_element_size();
194 size_t src_offset = arrayOopDesc::base_offset_in_bytes(element_type()) + ((size_t)src_pos << l2es);
195 size_t dst_offset = arrayOopDesc::base_offset_in_bytes(element_type()) + ((size_t)dst_pos << l2es);
|