< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahObjArrayAllocator.cpp

Print this page

 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     }
< prev index next >