mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 02:54:35 +02:00
8086053: Address inconsistencies regarding ZeroTLAB
Add zero-initialization to C1 for fast TLAB refills; strenghten C2 conditions for skipping zero-initialization. Reviewed-by: kvn, thartmann
This commit is contained in:
parent
5be1924e89
commit
dfa6539a6a
18 changed files with 215 additions and 128 deletions
|
@ -5426,7 +5426,7 @@ Register MacroAssembler::tlab_refill(Label& retry,
|
|||
Label& try_eden,
|
||||
Label& slow_case) {
|
||||
Register top = rax;
|
||||
Register t1 = rcx;
|
||||
Register t1 = rcx; // object size
|
||||
Register t2 = rsi;
|
||||
Register thread_reg = NOT_LP64(rdi) LP64_ONLY(r15_thread);
|
||||
assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx);
|
||||
|
@ -5522,12 +5522,76 @@ Register MacroAssembler::tlab_refill(Label& retry,
|
|||
addptr(top, t1);
|
||||
subptr(top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
|
||||
movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top);
|
||||
|
||||
if (ZeroTLAB) {
|
||||
// This is a fast TLAB refill, therefore the GC is not notified of it.
|
||||
// So compiled code must fill the new TLAB with zeroes.
|
||||
movptr(top, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
|
||||
zero_memory(top, t1, 0, t2);
|
||||
}
|
||||
|
||||
verify_tlab();
|
||||
jmp(retry);
|
||||
|
||||
return thread_reg; // for use by caller
|
||||
}
|
||||
|
||||
// Preserves the contents of address, destroys the contents length_in_bytes and temp.
|
||||
void MacroAssembler::zero_memory(Register address, Register length_in_bytes, int offset_in_bytes, Register temp) {
|
||||
assert(address != length_in_bytes && address != temp && temp != length_in_bytes, "registers must be different");
|
||||
assert((offset_in_bytes & (BytesPerWord - 1)) == 0, "offset must be a multiple of BytesPerWord");
|
||||
Label done;
|
||||
|
||||
testptr(length_in_bytes, length_in_bytes);
|
||||
jcc(Assembler::zero, done);
|
||||
|
||||
// initialize topmost word, divide index by 2, check if odd and test if zero
|
||||
// note: for the remaining code to work, index must be a multiple of BytesPerWord
|
||||
#ifdef ASSERT
|
||||
{
|
||||
Label L;
|
||||
testptr(length_in_bytes, BytesPerWord - 1);
|
||||
jcc(Assembler::zero, L);
|
||||
stop("length must be a multiple of BytesPerWord");
|
||||
bind(L);
|
||||
}
|
||||
#endif
|
||||
Register index = length_in_bytes;
|
||||
xorptr(temp, temp); // use _zero reg to clear memory (shorter code)
|
||||
if (UseIncDec) {
|
||||
shrptr(index, 3); // divide by 8/16 and set carry flag if bit 2 was set
|
||||
} else {
|
||||
shrptr(index, 2); // use 2 instructions to avoid partial flag stall
|
||||
shrptr(index, 1);
|
||||
}
|
||||
#ifndef _LP64
|
||||
// index could have not been a multiple of 8 (i.e., bit 2 was set)
|
||||
{
|
||||
Label even;
|
||||
// note: if index was a multiple of 8, then it cannot
|
||||
// be 0 now otherwise it must have been 0 before
|
||||
// => if it is even, we don't need to check for 0 again
|
||||
jcc(Assembler::carryClear, even);
|
||||
// clear topmost word (no jump would be needed if conditional assignment worked here)
|
||||
movptr(Address(address, index, Address::times_8, offset_in_bytes - 0*BytesPerWord), temp);
|
||||
// index could be 0 now, must check again
|
||||
jcc(Assembler::zero, done);
|
||||
bind(even);
|
||||
}
|
||||
#endif // !_LP64
|
||||
// initialize remaining object fields: index is a multiple of 2 now
|
||||
{
|
||||
Label loop;
|
||||
bind(loop);
|
||||
movptr(Address(address, index, Address::times_8, offset_in_bytes - 1*BytesPerWord), temp);
|
||||
NOT_LP64(movptr(Address(address, index, Address::times_8, offset_in_bytes - 2*BytesPerWord), temp);)
|
||||
decrement(index);
|
||||
jcc(Assembler::notZero, loop);
|
||||
}
|
||||
|
||||
bind(done);
|
||||
}
|
||||
|
||||
void MacroAssembler::incr_allocated_bytes(Register thread,
|
||||
Register var_size_in_bytes,
|
||||
int con_size_in_bytes,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue