24
25 #include "precompiled.hpp"
26 #include "classfile/moduleEntry.hpp"
27 #include "classfile/packageEntry.hpp"
28 #include "classfile/symbolTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "classfile/vmSymbols.hpp"
31 #include "gc/shared/collectedHeap.inline.hpp"
32 #include "gc/shared/specialized_oop_closures.hpp"
33 #include "memory/iterator.inline.hpp"
34 #include "memory/metadataFactory.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "memory/universe.inline.hpp"
37 #include "oops/arrayKlass.inline.hpp"
38 #include "oops/instanceKlass.hpp"
39 #include "oops/klass.inline.hpp"
40 #include "oops/objArrayKlass.inline.hpp"
41 #include "oops/objArrayOop.inline.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "oops/symbol.hpp"
44 #include "runtime/handles.inline.hpp"
45 #include "runtime/mutexLocker.hpp"
46 #include "utilities/copy.hpp"
47 #include "utilities/macros.hpp"
48
49 ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS) {
50 assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(),
51 "array klasses must be same size as InstanceKlass");
52
53 int size = ArrayKlass::static_size(ObjArrayKlass::header_size());
54
55 return new (loader_data, size, THREAD) ObjArrayKlass(n, k, name);
56 }
57
58 Klass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data,
59 int n, Klass* element_klass, TRAPS) {
60
61 // Eagerly allocate the direct array supertype.
62 Klass* super_klass = NULL;
63 if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) {
64 Klass* element_super = element_klass->super();
65 if (element_super != NULL) {
66 // The element type has a direct super. E.g., String[] has direct super of Object[].
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
224 BarrierSet* bs = Universe::heap()->barrier_set();
225 // For performance reasons, we assume we are that the write barrier we
226 // are using has optimized modes for arrays of references. At least one
227 // of the asserts below will fail if this is not the case.
228 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt");
229 assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well.");
230
231 if (s == d) {
232 // since source and destination are equal we do not need conversion checks.
233 assert(length > 0, "sanity check");
234 bs->write_ref_array_pre(dst, length);
235 Copy::conjoint_oops_atomic(src, dst, length);
236 } else {
237 // We have to make sure all elements conform to the destination array
238 Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
239 Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
240 if (stype == bound || stype->is_subtype_of(bound)) {
241 // elements are guaranteed to be subtypes, so no check necessary
242 bs->write_ref_array_pre(dst, length);
243 Copy::conjoint_oops_atomic(src, dst, length);
244 } else {
245 // slow case: need individual subtype checks
246 // note: don't use obj_at_put below because it includes a redundant store check
247 T* from = src;
248 T* end = from + length;
249 for (T* p = dst; from < end; from++, p++) {
250 // XXX this is going to be slow.
251 T element = *from;
252 // even slower now
253 bool element_is_null = oopDesc::is_null(element);
254 oop new_val = element_is_null ? oop(NULL)
255 : oopDesc::decode_heap_oop_not_null(element);
256 if (element_is_null ||
257 (new_val->klass())->is_subtype_of(bound)) {
258 bs->write_ref_field_pre(p, new_val);
259 *p = element;
260 } else {
261 // We must do a barrier to cover the partial copy.
262 const size_t pd = pointer_delta(p, dst, (size_t)heapOopSize);
263 // pointer delta is scaled to number of elements (length field in
264 // objArrayOop) which we assume is 32 bit.
265 assert(pd == (size_t)(int)pd, "length field overflow");
266 bs->write_ref_array((HeapWord*)dst, pd);
267 THROW(vmSymbols::java_lang_ArrayStoreException());
268 return;
269 }
270 }
271 }
272 }
273 bs->write_ref_array((HeapWord*)dst, length);
274 }
275
276 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
277 int dst_pos, int length, TRAPS) {
278 assert(s->is_objArray(), "must be obj array");
279
280 if (!d->is_objArray()) {
281 THROW(vmSymbols::java_lang_ArrayStoreException());
282 }
283
284 // Check is all offsets and lengths are non negative
285 if (src_pos < 0 || dst_pos < 0 || length < 0) {
286 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
287 }
288 // Check if the ranges are valid
289 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
290 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
291 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
292 }
293
|
24
25 #include "precompiled.hpp"
26 #include "classfile/moduleEntry.hpp"
27 #include "classfile/packageEntry.hpp"
28 #include "classfile/symbolTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "classfile/vmSymbols.hpp"
31 #include "gc/shared/collectedHeap.inline.hpp"
32 #include "gc/shared/specialized_oop_closures.hpp"
33 #include "memory/iterator.inline.hpp"
34 #include "memory/metadataFactory.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "memory/universe.inline.hpp"
37 #include "oops/arrayKlass.inline.hpp"
38 #include "oops/instanceKlass.hpp"
39 #include "oops/klass.inline.hpp"
40 #include "oops/objArrayKlass.inline.hpp"
41 #include "oops/objArrayOop.inline.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "oops/symbol.hpp"
44 #include "runtime/access.inline.hpp"
45 #include "runtime/handles.inline.hpp"
46 #include "runtime/mutexLocker.hpp"
47 #include "utilities/macros.hpp"
48
49 ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS) {
50 assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(),
51 "array klasses must be same size as InstanceKlass");
52
53 int size = ArrayKlass::static_size(ObjArrayKlass::header_size());
54
55 return new (loader_data, size, THREAD) ObjArrayKlass(n, k, name);
56 }
57
58 Klass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data,
59 int n, Klass* element_klass, TRAPS) {
60
61 // Eagerly allocate the direct array supertype.
62 Klass* super_klass = NULL;
63 if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) {
64 Klass* element_super = element_klass->super();
65 if (element_super != NULL) {
66 // The element type has a direct super. E.g., String[] has direct super of Object[].
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 (s == d) {
224 // since source and destination are equal we do not need conversion checks.
225 assert(length > 0, "sanity check");
226 HeapAccess<DEST_CONJOINT | DEST_COVARIANT | ACCESS_ATOMIC>::oop_copy(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
233 HeapAccess<DEST_DISJOINT | DEST_COVARIANT | ACCESS_ATOMIC>::oop_copy(s, d, src, dst, length);
234 } else {
235 // slow case: need individual subtype checks
236 if (!HeapAccess<DEST_DISJOINT | DEST_CONTRAVARIANT | ACCESS_ATOMIC>::oop_copy(s, d, src, dst, length)) {
237 THROW(vmSymbols::java_lang_ArrayStoreException());
238 }
239 }
240 }
241 }
242
243 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
244 int dst_pos, int length, TRAPS) {
245 assert(s->is_objArray(), "must be obj array");
246
247 if (!d->is_objArray()) {
248 THROW(vmSymbols::java_lang_ArrayStoreException());
249 }
250
251 // Check is all offsets and lengths are non negative
252 if (src_pos < 0 || dst_pos < 0 || length < 0) {
253 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
254 }
255 // Check if the ranges are valid
256 if ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
257 || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
258 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
259 }
260
|