164 assert(this->is_array_klass(), "sanity");
165 assert(this->is_objArray_klass(), "sanity");
166 }
167
168 int ObjArrayKlass::oop_size(oop obj) const {
169 assert(obj->is_objArray(), "must be object array");
170 return objArrayOop(obj)->object_size();
171 }
172
173 objArrayOop ObjArrayKlass::allocate(int length, TRAPS) {
174 if (length >= 0) {
175 if (length <= arrayOopDesc::max_array_length(T_OBJECT)) {
176 int size = objArrayOopDesc::object_size(length);
177 return (objArrayOop)CollectedHeap::array_allocate(this, size, length, THREAD);
178 } else {
179 report_java_out_of_memory("Requested array size exceeds VM limit");
180 JvmtiExport::post_array_size_exhausted();
181 THROW_OOP_0(Universe::out_of_memory_error_array_size());
182 }
183 } else {
184 THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
185 }
186 }
187
188 static int multi_alloc_counter = 0;
189
190 oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) {
191 int length = *sizes;
192 // Call to lower_dimension uses this pointer, so most be called before a
193 // possible GC
194 Klass* ld_klass = lower_dimension();
195 // If length < 0 allocate will throw an exception.
196 objArrayOop array = allocate(length, CHECK_NULL);
197 objArrayHandle h_array (THREAD, array);
198 if (rank > 1) {
199 if (length != 0) {
200 for (int index = 0; index < length; index++) {
201 ArrayKlass* ak = ArrayKlass::cast(ld_klass);
202 oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL);
203 h_array->obj_at_put(index, sub_array);
204 }
205 } else {
206 // Since this array dimension has zero length, nothing will be
207 // allocated, however the lower dimension values must be checked
208 // for illegal values.
209 for (int i = 0; i < rank - 1; ++i) {
210 sizes += 1;
211 if (*sizes < 0) {
212 THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
213 }
214 }
215 }
216 }
217 return h_array();
218 }
219
220 // Either oop or narrowOop depending on UseCompressedOops.
221 template <class T> void ObjArrayKlass::do_copy(arrayOop s, T* src,
222 arrayOop d, T* dst, int length, TRAPS) {
223 if (oopDesc::equals(s, d)) {
224 // since source and destination are equal we do not need conversion checks.
225 assert(length > 0, "sanity check");
226 HeapAccess<>::oop_arraycopy(s, d, src, dst, length);
227 } else {
228 // We have to make sure all elements conform to the destination array
229 Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
230 Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
231 if (stype == bound || stype->is_subtype_of(bound)) {
232 // elements are guaranteed to be subtypes, so no check necessary
|
164 assert(this->is_array_klass(), "sanity");
165 assert(this->is_objArray_klass(), "sanity");
166 }
167
168 int ObjArrayKlass::oop_size(oop obj) const {
169 assert(obj->is_objArray(), "must be object array");
170 return objArrayOop(obj)->object_size();
171 }
172
173 objArrayOop ObjArrayKlass::allocate(int length, TRAPS) {
174 if (length >= 0) {
175 if (length <= arrayOopDesc::max_array_length(T_OBJECT)) {
176 int size = objArrayOopDesc::object_size(length);
177 return (objArrayOop)CollectedHeap::array_allocate(this, size, length, THREAD);
178 } else {
179 report_java_out_of_memory("Requested array size exceeds VM limit");
180 JvmtiExport::post_array_size_exhausted();
181 THROW_OOP_0(Universe::out_of_memory_error_array_size());
182 }
183 } else {
184 THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length));
185 }
186 }
187
188 static int multi_alloc_counter = 0;
189
190 oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) {
191 int length = *sizes;
192 // Call to lower_dimension uses this pointer, so most be called before a
193 // possible GC
194 Klass* ld_klass = lower_dimension();
195 // If length < 0 allocate will throw an exception.
196 objArrayOop array = allocate(length, CHECK_NULL);
197 objArrayHandle h_array (THREAD, array);
198 if (rank > 1) {
199 if (length != 0) {
200 for (int index = 0; index < length; index++) {
201 ArrayKlass* ak = ArrayKlass::cast(ld_klass);
202 oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL);
203 h_array->obj_at_put(index, sub_array);
204 }
205 } else {
206 // Since this array dimension has zero length, nothing will be
207 // allocated, however the lower dimension values must be checked
208 // for illegal values.
209 for (int i = 0; i < rank - 1; ++i) {
210 sizes += 1;
211 if (*sizes < 0) {
212 THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", *sizes));
213 }
214 }
215 }
216 }
217 return h_array();
218 }
219
220 // Either oop or narrowOop depending on UseCompressedOops.
221 template <class T> void ObjArrayKlass::do_copy(arrayOop s, T* src,
222 arrayOop d, T* dst, int length, TRAPS) {
223 if (oopDesc::equals(s, d)) {
224 // since source and destination are equal we do not need conversion checks.
225 assert(length > 0, "sanity check");
226 HeapAccess<>::oop_arraycopy(s, d, src, dst, length);
227 } else {
228 // We have to make sure all elements conform to the destination array
229 Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
230 Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
231 if (stype == bound || stype->is_subtype_of(bound)) {
232 // elements are guaranteed to be subtypes, so no check necessary
|