54 return ObjArrayAllocator::initialize(mem);
55 }
56
57 // Slow path: yield to safepoint when clearing for large arrays
58
59 // Compute clearing bounds
60 const BasicType element_type = ArrayKlass::cast(_klass)->element_type();
61 const size_t base_offset_in_bytes = (size_t)arrayOopDesc::base_offset_in_bytes(element_type);
62 const size_t process_start_offset_in_bytes = align_up(base_offset_in_bytes, (size_t)BytesPerWord);
63
64 const size_t process_start = process_start_offset_in_bytes / BytesPerWord;
65 const size_t process_size = _word_size - process_start;
66
67 // Pin the region before clearing to avoid moving the object until it is done
68 ShenandoahHeapRegion* region = heap->heap_region_containing(mem);
69 region->record_pin();
70
71 // Always initialize the mem with primitive array first so GC won't look into the elements in the array.
72 // For obj array, the header will be corrected to object array after clearing the memory.
73 Klass* filling_klass = _klass;
74 const bool is_ref_type = is_reference_type(element_type);
75
76 if (is_ref_type) {
77 filling_klass = LP64_ONLY(UseCompressedOops ? Universe::intArrayKlass() : Universe::longArrayKlass()) NOT_LP64(Universe::intArrayKlass());
78 assert(type2aelembytes(ArrayKlass::cast(filling_klass)->element_type()) == type2aelembytes(element_type), "filling element size must match ref size");
79 }
80 // Use _length directly: it matches the ref count, and the filling element size equals the ref size.
81 ObjArrayAllocator filling_array_allocator(filling_klass, _word_size, _length, /* do_zero */ false);
82 filling_array_allocator.initialize(mem);
83
84 // Invisible roots will be scanned and marked at the end of marking.
85 ShenandoahThreadLocalData::set_invisible_root(_thread, mem, _word_size);
86
87 {
88 // The mem has been initialized as primitive array, the entire clearing work is safe for safepoint
89 ThreadBlockInVM tbivm(JavaThread::cast(_thread)); // Allow safepoint to proceed.
90 // Handle potential 4-byte alignment gap before array data
91 if (process_start_offset_in_bytes != base_offset_in_bytes) {
92 assert(process_start_offset_in_bytes - base_offset_in_bytes == 4, "Must be 4-byte aligned");
93 *reinterpret_cast<int*>(reinterpret_cast<char*>(mem) + base_offset_in_bytes) = 0;
94 }
|
54 return ObjArrayAllocator::initialize(mem);
55 }
56
57 // Slow path: yield to safepoint when clearing for large arrays
58
59 // Compute clearing bounds
60 const BasicType element_type = ArrayKlass::cast(_klass)->element_type();
61 const size_t base_offset_in_bytes = (size_t)arrayOopDesc::base_offset_in_bytes(element_type);
62 const size_t process_start_offset_in_bytes = align_up(base_offset_in_bytes, (size_t)BytesPerWord);
63
64 const size_t process_start = process_start_offset_in_bytes / BytesPerWord;
65 const size_t process_size = _word_size - process_start;
66
67 // Pin the region before clearing to avoid moving the object until it is done
68 ShenandoahHeapRegion* region = heap->heap_region_containing(mem);
69 region->record_pin();
70
71 // Always initialize the mem with primitive array first so GC won't look into the elements in the array.
72 // For obj array, the header will be corrected to object array after clearing the memory.
73 Klass* filling_klass = _klass;
74
75 // Flat arrays containing oops are not supported and only contain primitives
76 // from here on out.
77 const bool is_ref_type = (element_type != T_FLAT_ELEMENT) && is_reference_type(element_type);
78
79 if (is_ref_type) {
80 filling_klass = LP64_ONLY(UseCompressedOops ? Universe::intArrayKlass() : Universe::longArrayKlass()) NOT_LP64(Universe::intArrayKlass());
81 assert(type2aelembytes(ArrayKlass::cast(filling_klass)->element_type()) == type2aelembytes(element_type), "filling element size must match ref size");
82 }
83 // Use _length directly: it matches the ref count, and the filling element size equals the ref size.
84 ObjArrayAllocator filling_array_allocator(filling_klass, _word_size, _length, /* do_zero */ false);
85 filling_array_allocator.initialize(mem);
86
87 // Invisible roots will be scanned and marked at the end of marking.
88 ShenandoahThreadLocalData::set_invisible_root(_thread, mem, _word_size);
89
90 {
91 // The mem has been initialized as primitive array, the entire clearing work is safe for safepoint
92 ThreadBlockInVM tbivm(JavaThread::cast(_thread)); // Allow safepoint to proceed.
93 // Handle potential 4-byte alignment gap before array data
94 if (process_start_offset_in_bytes != base_offset_in_bytes) {
95 assert(process_start_offset_in_bytes - base_offset_in_bytes == 4, "Must be 4-byte aligned");
96 *reinterpret_cast<int*>(reinterpret_cast<char*>(mem) + base_offset_in_bytes) = 0;
97 }
|