< prev index next >
src/cpu/aarch64/vm/c1_MacroAssembler_aarch64.cpp
Print this page
rev 12409 : 8169177: aarch64: SIGSEGV when "-XX:+ZeroTLAB" is specified along with GC options
Summary: Add zero-initialization to C1 for fast TLAB refills
Reviewed-by: aph, drwhite
Contributed-by: kavitha.natarajan@linaro.org
*** 193,311 ****
} else if (UseCompressedClassPointers) {
store_klass_gap(obj, zr);
}
}
- // Zero words; len is in bytes
- // Destroys all registers except addr
- // len must be a nonzero multiple of wordSize
- void C1_MacroAssembler::zero_memory(Register addr, Register len, Register t1) {
- assert_different_registers(addr, len, t1, rscratch1, rscratch2);
-
- #ifdef ASSERT
- { Label L;
- tst(len, BytesPerWord - 1);
- br(Assembler::EQ, L);
- stop("len is not a multiple of BytesPerWord");
- bind(L);
- }
- #endif
-
- #ifndef PRODUCT
- block_comment("zero memory");
- #endif
-
- Label loop;
- Label entry;
-
- // Algorithm:
- //
- // scratch1 = cnt & 7;
- // cnt -= scratch1;
- // p += scratch1;
- // switch (scratch1) {
- // do {
- // cnt -= 8;
- // p[-8] = 0;
- // case 7:
- // p[-7] = 0;
- // case 6:
- // p[-6] = 0;
- // // ...
- // case 1:
- // p[-1] = 0;
- // case 0:
- // p += 8;
- // } while (cnt);
- // }
-
- const int unroll = 8; // Number of str(zr) instructions we'll unroll
-
- lsr(len, len, LogBytesPerWord);
- andr(rscratch1, len, unroll - 1); // tmp1 = cnt % unroll
- sub(len, len, rscratch1); // cnt -= unroll
- // t1 always points to the end of the region we're about to zero
- add(t1, addr, rscratch1, Assembler::LSL, LogBytesPerWord);
- adr(rscratch2, entry);
- sub(rscratch2, rscratch2, rscratch1, Assembler::LSL, 2);
- br(rscratch2);
- bind(loop);
- sub(len, len, unroll);
- for (int i = -unroll; i < 0; i++)
- str(zr, Address(t1, i * wordSize));
- bind(entry);
- add(t1, t1, unroll * wordSize);
- cbnz(len, loop);
- }
-
// preserves obj, destroys len_in_bytes
void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) {
Label done;
! assert(obj != len_in_bytes && obj != t1 && t1 != len_in_bytes, "registers must be different");
! assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, "header size is not a multiple of BytesPerWord");
! Register index = len_in_bytes;
! // index is positive and ptr sized
! subs(index, index, hdr_size_in_bytes);
br(Assembler::EQ, done);
- // note: for the remaining code to work, index must be a multiple of BytesPerWord
- #ifdef ASSERT
- { Label L;
- tst(index, BytesPerWord - 1);
- br(Assembler::EQ, L);
- stop("index is not a multiple of BytesPerWord");
- bind(L);
- }
- #endif
// Preserve obj
if (hdr_size_in_bytes)
add(obj, obj, hdr_size_in_bytes);
! zero_memory(obj, index, t1);
if (hdr_size_in_bytes)
sub(obj, obj, hdr_size_in_bytes);
- // done
bind(done);
}
void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
assert_different_registers(obj, t1, t2); // XXX really?
assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
! initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2);
}
! void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) {
assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
"con_size_in_bytes is not multiple of alignment");
const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
initialize_header(obj, klass, noreg, t1, t2);
// clear rest of allocated space
const Register index = t2;
const int threshold = 16 * BytesPerWord; // approximate break even point for code size (see comments below)
if (var_size_in_bytes != noreg) {
mov(index, var_size_in_bytes);
--- 193,239 ----
} else if (UseCompressedClassPointers) {
store_klass_gap(obj, zr);
}
}
// preserves obj, destroys len_in_bytes
void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) {
+ assert(hdr_size_in_bytes >= 0, "header size must be positive or 0");
Label done;
!
! // len_in_bytes is positive and ptr sized
! subs(len_in_bytes, len_in_bytes, hdr_size_in_bytes);
br(Assembler::EQ, done);
// Preserve obj
if (hdr_size_in_bytes)
add(obj, obj, hdr_size_in_bytes);
! zero_memory(obj, len_in_bytes, t1);
if (hdr_size_in_bytes)
sub(obj, obj, hdr_size_in_bytes);
bind(done);
}
void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
assert_different_registers(obj, t1, t2); // XXX really?
assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
! initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2, UseTLAB);
}
! void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, bool is_tlab_allocated) {
assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
"con_size_in_bytes is not multiple of alignment");
const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
initialize_header(obj, klass, noreg, t1, t2);
+ if (!(UseTLAB && ZeroTLAB && is_tlab_allocated)) {
// clear rest of allocated space
const Register index = t2;
const int threshold = 16 * BytesPerWord; // approximate break even point for code size (see comments below)
if (var_size_in_bytes != noreg) {
mov(index, var_size_in_bytes);
*** 344,353 ****
--- 272,282 ----
bind(entry_point);
add(rscratch1, rscratch1, unroll * wordSize);
cbnz(index, loop);
}
+ }
membar(StoreStore);
if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == r0, "must be");
< prev index next >