54 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" |
54 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" |
55 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" |
55 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" |
56 #include "oops/oop.pcgc.inline.hpp" |
56 #include "oops/oop.pcgc.inline.hpp" |
57 #endif |
57 #endif |
58 |
58 |
59 objArrayKlass* objArrayKlass::allocate(ClassLoaderData* loader_data, int n, KlassHandle klass_handle, Symbol* name, TRAPS) { |
59 ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, KlassHandle klass_handle, Symbol* name, TRAPS) { |
60 assert(objArrayKlass::header_size() <= InstanceKlass::header_size(), |
60 assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(), |
61 "array klasses must be same size as InstanceKlass"); |
61 "array klasses must be same size as InstanceKlass"); |
62 |
62 |
63 int size = arrayKlass::static_size(objArrayKlass::header_size()); |
63 int size = ArrayKlass::static_size(ObjArrayKlass::header_size()); |
64 |
64 |
65 return new (loader_data, size, THREAD) objArrayKlass(n, klass_handle, name); |
65 return new (loader_data, size, THREAD) ObjArrayKlass(n, klass_handle, name); |
66 } |
66 } |
67 |
67 |
68 Klass* objArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data, |
68 Klass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data, |
69 int n, KlassHandle element_klass, TRAPS) { |
69 int n, KlassHandle element_klass, TRAPS) { |
70 |
70 |
71 // Eagerly allocate the direct array supertype. |
71 // Eagerly allocate the direct array supertype. |
72 KlassHandle super_klass = KlassHandle(); |
72 KlassHandle super_klass = KlassHandle(); |
73 if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) { |
73 if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) { |
143 ik->set_array_name(name); |
143 ik->set_array_name(name); |
144 } |
144 } |
145 } |
145 } |
146 |
146 |
147 // Initialize instance variables |
147 // Initialize instance variables |
148 objArrayKlass* oak = objArrayKlass::allocate(loader_data, n, element_klass, name, CHECK_0); |
148 ObjArrayKlass* oak = ObjArrayKlass::allocate(loader_data, n, element_klass, name, CHECK_0); |
149 |
149 |
150 // Add all classes to our internal class loader list here, |
150 // Add all classes to our internal class loader list here, |
151 // including classes in the bootstrap (NULL) class loader. |
151 // including classes in the bootstrap (NULL) class loader. |
152 // GC walks these as strong roots. |
152 // GC walks these as strong roots. |
153 loader_data->add_class(oak); |
153 loader_data->add_class(oak); |
154 |
154 |
155 // Call complete_create_array_klass after all instance variables has been initialized. |
155 // Call complete_create_array_klass after all instance variables has been initialized. |
156 arrayKlass::complete_create_array_klass(oak, super_klass, CHECK_0); |
156 ArrayKlass::complete_create_array_klass(oak, super_klass, CHECK_0); |
157 |
157 |
158 return oak; |
158 return oak; |
159 } |
159 } |
160 |
160 |
161 objArrayKlass::objArrayKlass(int n, KlassHandle element_klass, Symbol* name) : arrayKlass(name) { |
161 ObjArrayKlass::ObjArrayKlass(int n, KlassHandle element_klass, Symbol* name) : ArrayKlass(name) { |
162 this->set_dimension(n); |
162 this->set_dimension(n); |
163 this->set_element_klass(element_klass()); |
163 this->set_element_klass(element_klass()); |
164 // decrement refcount because object arrays are not explicitly freed. The |
164 // decrement refcount because object arrays are not explicitly freed. The |
165 // InstanceKlass array_name() keeps the name counted while the klass is |
165 // InstanceKlass array_name() keeps the name counted while the klass is |
166 // loaded. |
166 // loaded. |
167 name->decrement_refcount(); |
167 name->decrement_refcount(); |
168 |
168 |
169 Klass* bk; |
169 Klass* bk; |
170 if (element_klass->oop_is_objArray()) { |
170 if (element_klass->oop_is_objArray()) { |
171 bk = objArrayKlass::cast(element_klass())->bottom_klass(); |
171 bk = ObjArrayKlass::cast(element_klass())->bottom_klass(); |
172 } else { |
172 } else { |
173 bk = element_klass(); |
173 bk = element_klass(); |
174 } |
174 } |
175 assert(bk != NULL && (Klass::cast(bk)->oop_is_instance() || Klass::cast(bk)->oop_is_typeArray()), "invalid bottom klass"); |
175 assert(bk != NULL && (Klass::cast(bk)->oop_is_instance() || Klass::cast(bk)->oop_is_typeArray()), "invalid bottom klass"); |
176 this->set_bottom_klass(bk); |
176 this->set_bottom_klass(bk); |
179 this->set_layout_helper(array_layout_helper(T_OBJECT)); |
179 this->set_layout_helper(array_layout_helper(T_OBJECT)); |
180 assert(this->oop_is_array(), "sanity"); |
180 assert(this->oop_is_array(), "sanity"); |
181 assert(this->oop_is_objArray(), "sanity"); |
181 assert(this->oop_is_objArray(), "sanity"); |
182 } |
182 } |
183 |
183 |
184 int objArrayKlass::oop_size(oop obj) const { |
184 int ObjArrayKlass::oop_size(oop obj) const { |
185 assert(obj->is_objArray(), "must be object array"); |
185 assert(obj->is_objArray(), "must be object array"); |
186 return objArrayOop(obj)->object_size(); |
186 return objArrayOop(obj)->object_size(); |
187 } |
187 } |
188 |
188 |
189 objArrayOop objArrayKlass::allocate(int length, TRAPS) { |
189 objArrayOop ObjArrayKlass::allocate(int length, TRAPS) { |
190 if (length >= 0) { |
190 if (length >= 0) { |
191 if (length <= arrayOopDesc::max_array_length(T_OBJECT)) { |
191 if (length <= arrayOopDesc::max_array_length(T_OBJECT)) { |
192 int size = objArrayOopDesc::object_size(length); |
192 int size = objArrayOopDesc::object_size(length); |
193 KlassHandle h_k(THREAD, this); |
193 KlassHandle h_k(THREAD, this); |
194 return (objArrayOop)CollectedHeap::array_allocate(h_k, size, length, CHECK_NULL); |
194 return (objArrayOop)CollectedHeap::array_allocate(h_k, size, length, CHECK_NULL); |
202 } |
202 } |
203 } |
203 } |
204 |
204 |
205 static int multi_alloc_counter = 0; |
205 static int multi_alloc_counter = 0; |
206 |
206 |
207 oop objArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) { |
207 oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) { |
208 int length = *sizes; |
208 int length = *sizes; |
209 // Call to lower_dimension uses this pointer, so most be called before a |
209 // Call to lower_dimension uses this pointer, so most be called before a |
210 // possible GC |
210 // possible GC |
211 KlassHandle h_lower_dimension(THREAD, lower_dimension()); |
211 KlassHandle h_lower_dimension(THREAD, lower_dimension()); |
212 // If length < 0 allocate will throw an exception. |
212 // If length < 0 allocate will throw an exception. |
213 objArrayOop array = allocate(length, CHECK_NULL); |
213 objArrayOop array = allocate(length, CHECK_NULL); |
214 objArrayHandle h_array (THREAD, array); |
214 objArrayHandle h_array (THREAD, array); |
215 if (rank > 1) { |
215 if (rank > 1) { |
216 if (length != 0) { |
216 if (length != 0) { |
217 for (int index = 0; index < length; index++) { |
217 for (int index = 0; index < length; index++) { |
218 arrayKlass* ak = arrayKlass::cast(h_lower_dimension()); |
218 ArrayKlass* ak = ArrayKlass::cast(h_lower_dimension()); |
219 oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL); |
219 oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL); |
220 h_array->obj_at_put(index, sub_array); |
220 h_array->obj_at_put(index, sub_array); |
221 } |
221 } |
222 } else { |
222 } else { |
223 // Since this array dimension has zero length, nothing will be |
223 // Since this array dimension has zero length, nothing will be |
233 } |
233 } |
234 return h_array(); |
234 return h_array(); |
235 } |
235 } |
236 |
236 |
237 // Either oop or narrowOop depending on UseCompressedOops. |
237 // Either oop or narrowOop depending on UseCompressedOops. |
238 template <class T> void objArrayKlass::do_copy(arrayOop s, T* src, |
238 template <class T> void ObjArrayKlass::do_copy(arrayOop s, T* src, |
239 arrayOop d, T* dst, int length, TRAPS) { |
239 arrayOop d, T* dst, int length, TRAPS) { |
240 |
240 |
241 BarrierSet* bs = Universe::heap()->barrier_set(); |
241 BarrierSet* bs = Universe::heap()->barrier_set(); |
242 // For performance reasons, we assume we are that the write barrier we |
242 // For performance reasons, we assume we are that the write barrier we |
243 // are using has optimized modes for arrays of references. At least one |
243 // are using has optimized modes for arrays of references. At least one |
250 assert(length > 0, "sanity check"); |
250 assert(length > 0, "sanity check"); |
251 bs->write_ref_array_pre(dst, length); |
251 bs->write_ref_array_pre(dst, length); |
252 Copy::conjoint_oops_atomic(src, dst, length); |
252 Copy::conjoint_oops_atomic(src, dst, length); |
253 } else { |
253 } else { |
254 // We have to make sure all elements conform to the destination array |
254 // We have to make sure all elements conform to the destination array |
255 Klass* bound = objArrayKlass::cast(d->klass())->element_klass(); |
255 Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass(); |
256 Klass* stype = objArrayKlass::cast(s->klass())->element_klass(); |
256 Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass(); |
257 if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) { |
257 if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) { |
258 // elements are guaranteed to be subtypes, so no check necessary |
258 // elements are guaranteed to be subtypes, so no check necessary |
259 bs->write_ref_array_pre(dst, length); |
259 bs->write_ref_array_pre(dst, length); |
260 Copy::conjoint_oops_atomic(src, dst, length); |
260 Copy::conjoint_oops_atomic(src, dst, length); |
261 } else { |
261 } else { |
288 } |
288 } |
289 } |
289 } |
290 bs->write_ref_array((HeapWord*)dst, length); |
290 bs->write_ref_array((HeapWord*)dst, length); |
291 } |
291 } |
292 |
292 |
293 void objArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, |
293 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, |
294 int dst_pos, int length, TRAPS) { |
294 int dst_pos, int length, TRAPS) { |
295 assert(s->is_objArray(), "must be obj array"); |
295 assert(s->is_objArray(), "must be obj array"); |
296 |
296 |
297 if (!d->is_objArray()) { |
297 if (!d->is_objArray()) { |
298 THROW(vmSymbols::java_lang_ArrayStoreException()); |
298 THROW(vmSymbols::java_lang_ArrayStoreException()); |
325 do_copy<oop> (s, src, d, dst, length, CHECK); |
325 do_copy<oop> (s, src, d, dst, length, CHECK); |
326 } |
326 } |
327 } |
327 } |
328 |
328 |
329 |
329 |
330 Klass* objArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) { |
330 Klass* ObjArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) { |
331 |
331 |
332 assert(dimension() <= n, "check order of chain"); |
332 assert(dimension() <= n, "check order of chain"); |
333 int dim = dimension(); |
333 int dim = dimension(); |
334 if (dim == n) return this; |
334 if (dim == n) return this; |
335 |
335 |
346 // Check if another thread beat us |
346 // Check if another thread beat us |
347 if (higher_dimension() == NULL) { |
347 if (higher_dimension() == NULL) { |
348 |
348 |
349 // Create multi-dim klass object and link them together |
349 // Create multi-dim klass object and link them together |
350 Klass* k = |
350 Klass* k = |
351 objArrayKlass::allocate_objArray_klass(class_loader_data(), dim + 1, this, CHECK_NULL); |
351 ObjArrayKlass::allocate_objArray_klass(class_loader_data(), dim + 1, this, CHECK_NULL); |
352 objArrayKlass* ak = objArrayKlass::cast(k); |
352 ObjArrayKlass* ak = ObjArrayKlass::cast(k); |
353 ak->set_lower_dimension(this); |
353 ak->set_lower_dimension(this); |
354 OrderAccess::storestore(); |
354 OrderAccess::storestore(); |
355 set_higher_dimension(ak); |
355 set_higher_dimension(ak); |
356 assert(ak->oop_is_objArray(), "incorrect initialization of objArrayKlass"); |
356 assert(ak->oop_is_objArray(), "incorrect initialization of ObjArrayKlass"); |
357 } |
357 } |
358 } |
358 } |
359 } else { |
359 } else { |
360 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); |
360 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); |
361 } |
361 } |
362 |
362 |
363 objArrayKlass *ak = objArrayKlass::cast(higher_dimension()); |
363 ObjArrayKlass *ak = ObjArrayKlass::cast(higher_dimension()); |
364 if (or_null) { |
364 if (or_null) { |
365 return ak->array_klass_or_null(n); |
365 return ak->array_klass_or_null(n); |
366 } |
366 } |
367 return ak->array_klass(n, CHECK_NULL); |
367 return ak->array_klass(n, CHECK_NULL); |
368 } |
368 } |
369 |
369 |
370 Klass* objArrayKlass::array_klass_impl(bool or_null, TRAPS) { |
370 Klass* ObjArrayKlass::array_klass_impl(bool or_null, TRAPS) { |
371 return array_klass_impl(or_null, dimension() + 1, CHECK_NULL); |
371 return array_klass_impl(or_null, dimension() + 1, CHECK_NULL); |
372 } |
372 } |
373 |
373 |
374 bool objArrayKlass::can_be_primary_super_slow() const { |
374 bool ObjArrayKlass::can_be_primary_super_slow() const { |
375 if (!bottom_klass()->can_be_primary_super()) |
375 if (!bottom_klass()->can_be_primary_super()) |
376 // array of interfaces |
376 // array of interfaces |
377 return false; |
377 return false; |
378 else |
378 else |
379 return Klass::can_be_primary_super_slow(); |
379 return Klass::can_be_primary_super_slow(); |
380 } |
380 } |
381 |
381 |
382 GrowableArray<Klass*>* objArrayKlass::compute_secondary_supers(int num_extra_slots) { |
382 GrowableArray<Klass*>* ObjArrayKlass::compute_secondary_supers(int num_extra_slots) { |
383 // interfaces = { cloneable_klass, serializable_klass, elemSuper[], ... }; |
383 // interfaces = { cloneable_klass, serializable_klass, elemSuper[], ... }; |
384 Array<Klass*>* elem_supers = Klass::cast(element_klass())->secondary_supers(); |
384 Array<Klass*>* elem_supers = Klass::cast(element_klass())->secondary_supers(); |
385 int num_elem_supers = elem_supers == NULL ? 0 : elem_supers->length(); |
385 int num_elem_supers = elem_supers == NULL ? 0 : elem_supers->length(); |
386 int num_secondaries = num_extra_slots + 2 + num_elem_supers; |
386 int num_secondaries = num_extra_slots + 2 + num_elem_supers; |
387 if (num_secondaries == 2) { |
387 if (num_secondaries == 2) { |
400 } |
400 } |
401 return secondaries; |
401 return secondaries; |
402 } |
402 } |
403 } |
403 } |
404 |
404 |
405 bool objArrayKlass::compute_is_subtype_of(Klass* k) { |
405 bool ObjArrayKlass::compute_is_subtype_of(Klass* k) { |
406 if (!k->oop_is_objArray()) |
406 if (!k->oop_is_objArray()) |
407 return arrayKlass::compute_is_subtype_of(k); |
407 return ArrayKlass::compute_is_subtype_of(k); |
408 |
408 |
409 objArrayKlass* oak = objArrayKlass::cast(k); |
409 ObjArrayKlass* oak = ObjArrayKlass::cast(k); |
410 return element_klass()->is_subtype_of(oak->element_klass()); |
410 return element_klass()->is_subtype_of(oak->element_klass()); |
411 } |
411 } |
412 |
412 |
413 void objArrayKlass::initialize(TRAPS) { |
413 void ObjArrayKlass::initialize(TRAPS) { |
414 Klass::cast(bottom_klass())->initialize(THREAD); // dispatches to either InstanceKlass or typeArrayKlass |
414 Klass::cast(bottom_klass())->initialize(THREAD); // dispatches to either InstanceKlass or TypeArrayKlass |
415 } |
415 } |
416 |
416 |
417 #define ObjArrayKlass_SPECIALIZED_OOP_ITERATE(T, a, p, do_oop) \ |
417 #define ObjArrayKlass_SPECIALIZED_OOP_ITERATE(T, a, p, do_oop) \ |
418 { \ |
418 { \ |
419 T* p = (T*)(a)->base(); \ |
419 T* p = (T*)(a)->base(); \ |
454 } else { \ |
454 } else { \ |
455 ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \ |
455 ObjArrayKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \ |
456 a, p, low, high, do_oop) \ |
456 a, p, low, high, do_oop) \ |
457 } |
457 } |
458 |
458 |
459 void objArrayKlass::oop_follow_contents(oop obj) { |
459 void ObjArrayKlass::oop_follow_contents(oop obj) { |
460 assert (obj->is_array(), "obj must be array"); |
460 assert (obj->is_array(), "obj must be array"); |
461 MarkSweep::follow_klass(obj->klass()); |
461 MarkSweep::follow_klass(obj->klass()); |
462 if (UseCompressedOops) { |
462 if (UseCompressedOops) { |
463 objarray_follow_contents<narrowOop>(obj, 0); |
463 objarray_follow_contents<narrowOop>(obj, 0); |
464 } else { |
464 } else { |
465 objarray_follow_contents<oop>(obj, 0); |
465 objarray_follow_contents<oop>(obj, 0); |
466 } |
466 } |
467 } |
467 } |
468 |
468 |
469 #ifndef SERIALGC |
469 #ifndef SERIALGC |
470 void objArrayKlass::oop_follow_contents(ParCompactionManager* cm, |
470 void ObjArrayKlass::oop_follow_contents(ParCompactionManager* cm, |
471 oop obj) { |
471 oop obj) { |
472 assert(obj->is_array(), "obj must be array"); |
472 assert(obj->is_array(), "obj must be array"); |
473 PSParallelCompact::follow_klass(cm, obj->klass()); |
473 PSParallelCompact::follow_klass(cm, obj->klass()); |
474 if (UseCompressedOops) { |
474 if (UseCompressedOops) { |
475 objarray_follow_contents<narrowOop>(cm, obj, 0); |
475 objarray_follow_contents<narrowOop>(cm, obj, 0); |
485 "Inconsistency in do_metadata"); \ |
485 "Inconsistency in do_metadata"); \ |
486 if (closure->do_metadata##nv_suffix()) |
486 if (closure->do_metadata##nv_suffix()) |
487 |
487 |
488 #define ObjArrayKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ |
488 #define ObjArrayKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ |
489 \ |
489 \ |
490 int objArrayKlass::oop_oop_iterate##nv_suffix(oop obj, \ |
490 int ObjArrayKlass::oop_oop_iterate##nv_suffix(oop obj, \ |
491 OopClosureType* closure) { \ |
491 OopClosureType* closure) { \ |
492 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::oa); \ |
492 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::oa); \ |
493 assert (obj->is_array(), "obj must be array"); \ |
493 assert (obj->is_array(), "obj must be array"); \ |
494 objArrayOop a = objArrayOop(obj); \ |
494 objArrayOop a = objArrayOop(obj); \ |
495 /* Get size before changing pointers. */ \ |
495 /* Get size before changing pointers. */ \ |
502 return size; \ |
502 return size; \ |
503 } |
503 } |
504 |
504 |
505 #define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \ |
505 #define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \ |
506 \ |
506 \ |
507 int objArrayKlass::oop_oop_iterate##nv_suffix##_m(oop obj, \ |
507 int ObjArrayKlass::oop_oop_iterate##nv_suffix##_m(oop obj, \ |
508 OopClosureType* closure, \ |
508 OopClosureType* closure, \ |
509 MemRegion mr) { \ |
509 MemRegion mr) { \ |
510 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::oa); \ |
510 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::oa); \ |
511 assert(obj->is_array(), "obj must be array"); \ |
511 assert(obj->is_array(), "obj must be array"); \ |
512 objArrayOop a = objArrayOop(obj); \ |
512 objArrayOop a = objArrayOop(obj); \ |
524 |
524 |
525 // Like oop_oop_iterate but only iterates over a specified range and only used |
525 // Like oop_oop_iterate but only iterates over a specified range and only used |
526 // for objArrayOops. |
526 // for objArrayOops. |
527 #define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r(OopClosureType, nv_suffix) \ |
527 #define ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r(OopClosureType, nv_suffix) \ |
528 \ |
528 \ |
529 int objArrayKlass::oop_oop_iterate_range##nv_suffix(oop obj, \ |
529 int ObjArrayKlass::oop_oop_iterate_range##nv_suffix(oop obj, \ |
530 OopClosureType* closure, \ |
530 OopClosureType* closure, \ |
531 int start, int end) { \ |
531 int start, int end) { \ |
532 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::oa); \ |
532 SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::oa); \ |
533 assert(obj->is_array(), "obj must be array"); \ |
533 assert(obj->is_array(), "obj must be array"); \ |
534 objArrayOop a = objArrayOop(obj); \ |
534 objArrayOop a = objArrayOop(obj); \ |
565 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m) |
565 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m) |
566 ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m) |
566 ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_m) |
567 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r) |
567 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r) |
568 ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r) |
568 ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayKlass_OOP_OOP_ITERATE_DEFN_r) |
569 |
569 |
570 int objArrayKlass::oop_adjust_pointers(oop obj) { |
570 int ObjArrayKlass::oop_adjust_pointers(oop obj) { |
571 assert(obj->is_objArray(), "obj must be obj array"); |
571 assert(obj->is_objArray(), "obj must be obj array"); |
572 objArrayOop a = objArrayOop(obj); |
572 objArrayOop a = objArrayOop(obj); |
573 // Get size before changing pointers. |
573 // Get size before changing pointers. |
574 // Don't call size() or oop_size() since that is a virtual call. |
574 // Don't call size() or oop_size() since that is a virtual call. |
575 int size = a->object_size(); |
575 int size = a->object_size(); |
577 ObjArrayKlass_OOP_ITERATE(a, p, MarkSweep::adjust_pointer(p)) |
577 ObjArrayKlass_OOP_ITERATE(a, p, MarkSweep::adjust_pointer(p)) |
578 return size; |
578 return size; |
579 } |
579 } |
580 |
580 |
581 #ifndef SERIALGC |
581 #ifndef SERIALGC |
582 void objArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { |
582 void ObjArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { |
583 assert(obj->is_objArray(), "obj must be obj array"); |
583 assert(obj->is_objArray(), "obj must be obj array"); |
584 ObjArrayKlass_OOP_ITERATE( \ |
584 ObjArrayKlass_OOP_ITERATE( \ |
585 objArrayOop(obj), p, \ |
585 objArrayOop(obj), p, \ |
586 if (PSScavenge::should_scavenge(p)) { \ |
586 if (PSScavenge::should_scavenge(p)) { \ |
587 pm->claim_or_forward_depth(p); \ |
587 pm->claim_or_forward_depth(p); \ |
588 }) |
588 }) |
589 } |
589 } |
590 |
590 |
591 int objArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { |
591 int ObjArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { |
592 assert (obj->is_objArray(), "obj must be obj array"); |
592 assert (obj->is_objArray(), "obj must be obj array"); |
593 objArrayOop a = objArrayOop(obj); |
593 objArrayOop a = objArrayOop(obj); |
594 int size = a->object_size(); |
594 int size = a->object_size(); |
595 a->update_header(cm); |
595 a->update_header(cm); |
596 ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p)) |
596 ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p)) |
614 } |
614 } |
615 |
615 |
616 |
616 |
617 // Printing |
617 // Printing |
618 |
618 |
619 void objArrayKlass::print_on(outputStream* st) const { |
619 void ObjArrayKlass::print_on(outputStream* st) const { |
620 #ifndef PRODUCT |
620 #ifndef PRODUCT |
621 Klass::print_on(st); |
621 Klass::print_on(st); |
622 st->print(" - instance klass: "); |
622 st->print(" - instance klass: "); |
623 element_klass()->print_value_on(st); |
623 element_klass()->print_value_on(st); |
624 st->cr(); |
624 st->cr(); |
625 #endif //PRODUCT |
625 #endif //PRODUCT |
626 } |
626 } |
627 |
627 |
628 void objArrayKlass::print_value_on(outputStream* st) const { |
628 void ObjArrayKlass::print_value_on(outputStream* st) const { |
629 assert(is_klass(), "must be klass"); |
629 assert(is_klass(), "must be klass"); |
630 |
630 |
631 element_klass()->print_value_on(st); |
631 element_klass()->print_value_on(st); |
632 st->print("[]"); |
632 st->print("[]"); |
633 } |
633 } |
634 |
634 |
635 #ifndef PRODUCT |
635 #ifndef PRODUCT |
636 |
636 |
637 void objArrayKlass::oop_print_on(oop obj, outputStream* st) { |
637 void ObjArrayKlass::oop_print_on(oop obj, outputStream* st) { |
638 arrayKlass::oop_print_on(obj, st); |
638 ArrayKlass::oop_print_on(obj, st); |
639 assert(obj->is_objArray(), "must be objArray"); |
639 assert(obj->is_objArray(), "must be objArray"); |
640 objArrayOop oa = objArrayOop(obj); |
640 objArrayOop oa = objArrayOop(obj); |
641 int print_len = MIN2((intx) oa->length(), MaxElementPrintSize); |
641 int print_len = MIN2((intx) oa->length(), MaxElementPrintSize); |
642 for(int index = 0; index < print_len; index++) { |
642 for(int index = 0; index < print_len; index++) { |
643 st->print(" - %3d : ", index); |
643 st->print(" - %3d : ", index); |
652 |
652 |
653 #endif //PRODUCT |
653 #endif //PRODUCT |
654 |
654 |
655 static int max_objArray_print_length = 4; |
655 static int max_objArray_print_length = 4; |
656 |
656 |
657 void objArrayKlass::oop_print_value_on(oop obj, outputStream* st) { |
657 void ObjArrayKlass::oop_print_value_on(oop obj, outputStream* st) { |
658 assert(obj->is_objArray(), "must be objArray"); |
658 assert(obj->is_objArray(), "must be objArray"); |
659 st->print("a "); |
659 st->print("a "); |
660 element_klass()->print_value_on(st); |
660 element_klass()->print_value_on(st); |
661 int len = objArrayOop(obj)->length(); |
661 int len = objArrayOop(obj)->length(); |
662 st->print("[%d] ", len); |
662 st->print("[%d] ", len); |
671 } |
671 } |
672 st->print(" }"); |
672 st->print(" }"); |
673 } |
673 } |
674 } |
674 } |
675 |
675 |
676 const char* objArrayKlass::internal_name() const { |
676 const char* ObjArrayKlass::internal_name() const { |
677 return external_name(); |
677 return external_name(); |
678 } |
678 } |
679 |
679 |
680 |
680 |
681 // Verification |
681 // Verification |
682 |
682 |
683 void objArrayKlass::verify_on(outputStream* st) { |
683 void ObjArrayKlass::verify_on(outputStream* st) { |
684 arrayKlass::verify_on(st); |
684 ArrayKlass::verify_on(st); |
685 guarantee(element_klass()->is_metadata(), "should be in metaspace"); |
685 guarantee(element_klass()->is_metadata(), "should be in metaspace"); |
686 guarantee(element_klass()->is_klass(), "should be klass"); |
686 guarantee(element_klass()->is_klass(), "should be klass"); |
687 guarantee(bottom_klass()->is_metadata(), "should be in metaspace"); |
687 guarantee(bottom_klass()->is_metadata(), "should be in metaspace"); |
688 guarantee(bottom_klass()->is_klass(), "should be klass"); |
688 guarantee(bottom_klass()->is_klass(), "should be klass"); |
689 Klass* bk = Klass::cast(bottom_klass()); |
689 Klass* bk = Klass::cast(bottom_klass()); |
690 guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(), "invalid bottom klass"); |
690 guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(), "invalid bottom klass"); |
691 } |
691 } |
692 |
692 |
693 void objArrayKlass::oop_verify_on(oop obj, outputStream* st) { |
693 void ObjArrayKlass::oop_verify_on(oop obj, outputStream* st) { |
694 arrayKlass::oop_verify_on(obj, st); |
694 ArrayKlass::oop_verify_on(obj, st); |
695 guarantee(obj->is_objArray(), "must be objArray"); |
695 guarantee(obj->is_objArray(), "must be objArray"); |
696 objArrayOop oa = objArrayOop(obj); |
696 objArrayOop oa = objArrayOop(obj); |
697 for(int index = 0; index < oa->length(); index++) { |
697 for(int index = 0; index < oa->length(); index++) { |
698 guarantee(oa->obj_at(index)->is_oop_or_null(), "should be oop"); |
698 guarantee(oa->obj_at(index)->is_oop_or_null(), "should be oop"); |
699 } |
699 } |