--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Mon Jan 11 14:23:35 2016 +0100
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Tue Jan 12 09:19:09 2016 +0100
@@ -5426,7 +5426,7 @@
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 @@
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,