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:
Zoltan Majo 2016-01-12 09:19:09 +01:00
parent 5be1924e89
commit dfa6539a6a
18 changed files with 215 additions and 128 deletions

View file

@ -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,