diff options
author | 2024-07-12 14:51:36 +0000 | |
---|---|---|
committer | 2024-07-15 14:49:21 +0000 | |
commit | 5514bcedf59460571e26ce68508ef4a9fa2b0077 (patch) | |
tree | e2218640e0bfe4de221a824bd522e13661bee34a /compiler/optimizing | |
parent | ff18b2cbfb1c11e259348890dbfc2e46e81b70cf (diff) |
Revert^2 "Use a current entry pointer instead of index for the method trace buffer"
This reverts commit 44b5204a81e9263a612af65f426e66395ae9426b.
Reason for revert: Relanding after fix for failures. The curr_entry
should use a register that isn't rax or rdx on x86 and x86_64.
Change-Id: I9e19eae72b93b4c49c619a1b58a892040d975e3e
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 27 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 25 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_riscv64.cc | 22 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 30 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 39 |
5 files changed, 68 insertions, 75 deletions
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index e3a76e807e..3ec67afce9 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -1212,8 +1212,8 @@ void InstructionCodeGeneratorARM64::GenerateMethodEntryExitHook(HInstruction* in MacroAssembler* masm = GetVIXLAssembler(); UseScratchRegisterScope temps(masm); Register addr = temps.AcquireX(); - Register index = temps.AcquireX(); - Register value = index.W(); + Register curr_entry = temps.AcquireX(); + Register value = curr_entry.W(); SlowPathCodeARM64* slow_path = new (codegen_->GetScopedAllocator()) MethodEntryExitHooksSlowPathARM64(instruction); @@ -1242,21 +1242,20 @@ void InstructionCodeGeneratorARM64::GenerateMethodEntryExitHook(HInstruction* in // If yes, just take the slow path. __ B(gt, slow_path->GetEntryLabel()); + Register init_entry = addr; // Check if there is place in the buffer to store a new entry, if no, take slow path. - uint32_t trace_buffer_index_offset = - Thread::TraceBufferIndexOffset<kArm64PointerSize>().Int32Value(); - __ Ldr(index, MemOperand(tr, trace_buffer_index_offset)); - __ Subs(index, index, kNumEntriesForWallClock); + uint32_t trace_buffer_curr_entry_offset = + Thread::TraceBufferCurrPtrOffset<kArm64PointerSize>().Int32Value(); + __ Ldr(curr_entry, MemOperand(tr, trace_buffer_curr_entry_offset)); + __ Sub(curr_entry, curr_entry, kNumEntriesForWallClock * sizeof(void*)); + __ Ldr(init_entry, MemOperand(tr, Thread::TraceBufferPtrOffset<kArm64PointerSize>().SizeValue())); + __ Cmp(curr_entry, init_entry); __ B(lt, slow_path->GetEntryLabel()); // Update the index in the `Thread`. - __ Str(index, MemOperand(tr, trace_buffer_index_offset)); - // Calculate the entry address in the buffer. - // addr = base_addr + sizeof(void*) * index; - __ Ldr(addr, MemOperand(tr, Thread::TraceBufferPtrOffset<kArm64PointerSize>().SizeValue())); - __ ComputeAddress(addr, MemOperand(addr, index, LSL, TIMES_8)); + __ Str(curr_entry, MemOperand(tr, trace_buffer_curr_entry_offset)); - Register tmp = index; + Register tmp = init_entry; // Record method pointer and trace action. __ Ldr(tmp, MemOperand(sp, 0)); // Use last two bits to encode trace method action. For MethodEntry it is 0 @@ -1267,10 +1266,10 @@ void InstructionCodeGeneratorARM64::GenerateMethodEntryExitHook(HInstruction* in static_assert(enum_cast<int32_t>(TraceAction::kTraceMethodExit) == 1); __ Orr(tmp, tmp, Operand(enum_cast<int32_t>(TraceAction::kTraceMethodExit))); } - __ Str(tmp, MemOperand(addr, kMethodOffsetInBytes)); + __ Str(tmp, MemOperand(curr_entry, kMethodOffsetInBytes)); // Record the timestamp. __ Mrs(tmp, (SystemRegister)SYS_CNTVCT_EL0); - __ Str(tmp, MemOperand(addr, kTimestampOffsetInBytes)); + __ Str(tmp, MemOperand(curr_entry, kTimestampOffsetInBytes)); __ Bind(slow_path->GetExitLabel()); } diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index fc2fc34dde..34227a5480 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -2220,19 +2220,18 @@ void InstructionCodeGeneratorARMVIXL::GenerateMethodEntryExitHook(HInstruction* __ B(gt, slow_path->GetEntryLabel()); // Check if there is place in the buffer to store a new entry, if no, take slow path. - uint32_t trace_buffer_index_offset = - Thread::TraceBufferIndexOffset<kArmPointerSize>().Int32Value(); - vixl32::Register index = value; - __ Ldr(index, MemOperand(tr, trace_buffer_index_offset)); - __ Subs(index, index, kNumEntriesForWallClock); + uint32_t trace_buffer_curr_entry_offset = + Thread::TraceBufferCurrPtrOffset<kArmPointerSize>().Int32Value(); + vixl32::Register curr_entry = value; + vixl32::Register init_entry = addr; + __ Ldr(curr_entry, MemOperand(tr, trace_buffer_curr_entry_offset)); + __ Subs(curr_entry, curr_entry, static_cast<uint32_t>(kNumEntriesForWallClock * sizeof(void*))); + __ Ldr(init_entry, MemOperand(tr, Thread::TraceBufferPtrOffset<kArmPointerSize>().SizeValue())); + __ Cmp(curr_entry, init_entry); __ B(lt, slow_path->GetEntryLabel()); // Update the index in the `Thread`. - __ Str(index, MemOperand(tr, trace_buffer_index_offset)); - // Calculate the entry address in the buffer. - // addr = base_addr + sizeof(void*) * index - __ Ldr(addr, MemOperand(tr, Thread::TraceBufferPtrOffset<kArmPointerSize>().SizeValue())); - __ Add(addr, addr, Operand(index, LSL, TIMES_4)); + __ Str(curr_entry, MemOperand(tr, trace_buffer_curr_entry_offset)); // Record method pointer and trace action. __ Ldr(tmp, MemOperand(sp, 0)); @@ -2244,9 +2243,9 @@ void InstructionCodeGeneratorARMVIXL::GenerateMethodEntryExitHook(HInstruction* static_assert(enum_cast<int32_t>(TraceAction::kTraceMethodExit) == 1); __ Orr(tmp, tmp, Operand(enum_cast<int32_t>(TraceAction::kTraceMethodExit))); } - __ Str(tmp, MemOperand(addr, kMethodOffsetInBytes)); + __ Str(tmp, MemOperand(curr_entry, kMethodOffsetInBytes)); - vixl32::Register tmp1 = index; + vixl32::Register tmp1 = init_entry; // See Architecture Reference Manual ARMv7-A and ARMv7-R edition section B4.1.34. __ Mrrc(/* lower 32-bit */ tmp, /* higher 32-bit */ tmp1, @@ -2255,7 +2254,7 @@ void InstructionCodeGeneratorARMVIXL::GenerateMethodEntryExitHook(HInstruction* /* crm= */ 14); static_assert(kHighTimestampOffsetInBytes == kTimestampOffsetInBytes + static_cast<uint32_t>(kRuntimePointerSize)); - __ Strd(tmp, tmp1, MemOperand(addr, kTimestampOffsetInBytes)); + __ Strd(tmp, tmp1, MemOperand(curr_entry, kTimestampOffsetInBytes)); __ Bind(slow_path->GetExitLabel()); } diff --git a/compiler/optimizing/code_generator_riscv64.cc b/compiler/optimizing/code_generator_riscv64.cc index 8581c38895..f6067a5468 100644 --- a/compiler/optimizing/code_generator_riscv64.cc +++ b/compiler/optimizing/code_generator_riscv64.cc @@ -2640,24 +2640,20 @@ void InstructionCodeGeneratorRISCV64::GenerateMethodEntryExitHook(HInstruction* __ Addi(tmp, tmp, -1); __ Bnez(tmp, slow_path->GetEntryLabel()); - // Check if there is place in the buffer to store a new entry, if no, take the slow path. - int32_t trace_buffer_index_offset = - Thread::TraceBufferIndexOffset<kRiscv64PointerSize>().Int32Value(); - __ Loadd(tmp, TR, trace_buffer_index_offset); - __ Addi(tmp, tmp, -dchecked_integral_cast<int32_t>(kNumEntriesForWallClock)); - __ Bltz(tmp, slow_path->GetEntryLabel()); - - // Update the index in the `Thread`. - __ Stored(tmp, TR, trace_buffer_index_offset); - // Allocate second core scratch register. We can no longer use `Stored()` // and similar macro instructions because there is no core scratch register left. XRegister tmp2 = temps.AllocateXRegister(); - // Calculate the entry address in the buffer. - // /*addr*/ tmp = TR->GetMethodTraceBuffer() + sizeof(void*) * /*index*/ tmp; + // Check if there is place in the buffer to store a new entry, if no, take the slow path. + int32_t trace_buffer_curr_entry_offset = + Thread::TraceBufferCurrPtrOffset<kRiscv64PointerSize>().Int32Value(); + __ Loadd(tmp, TR, trace_buffer_curr_entry_offset); __ Loadd(tmp2, TR, Thread::TraceBufferPtrOffset<kRiscv64PointerSize>().SizeValue()); - __ Sh3Add(tmp, tmp, tmp2); + __ Addi(tmp, tmp, -dchecked_integral_cast<int32_t>(kNumEntriesForWallClock * sizeof(void*))); + __ Blt(tmp, tmp2, slow_path->GetEntryLabel()); + + // Update the index in the `Thread`. + __ Sd(tmp, TR, trace_buffer_curr_entry_offset); // Record method pointer and trace action. __ Ld(tmp2, SP, 0); diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index f549da189f..91f4a89ced 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -1274,29 +1274,27 @@ void InstructionCodeGeneratorX86::GenerateMethodEntryExitHook(HInstruction* inst // If yes, just take the slow path. __ j(kGreater, slow_path->GetEntryLabel()); - // For entry_addr use the first temp that isn't EAX or EDX. We need this after + // For curr_entry use the register that isn't EAX or EDX. We need this after // rdtsc which returns values in EAX + EDX. - Register entry_addr = locations->GetTemp(2).AsRegister<Register>(); - Register index = locations->GetTemp(1).AsRegister<Register>(); + Register curr_entry = locations->GetTemp(2).AsRegister<Register>(); + Register init_entry = locations->GetTemp(1).AsRegister<Register>(); // Check if there is place in the buffer for a new entry, if no, take slow path. uint32_t trace_buffer_ptr = Thread::TraceBufferPtrOffset<kX86PointerSize>().Int32Value(); - uint64_t trace_buffer_index_offset = - Thread::TraceBufferIndexOffset<kX86PointerSize>().Int32Value(); + uint64_t trace_buffer_curr_entry_offset = + Thread::TraceBufferCurrPtrOffset<kX86PointerSize>().Int32Value(); - __ fs()->movl(index, Address::Absolute(trace_buffer_index_offset)); - __ subl(index, Immediate(kNumEntriesForWallClock)); + __ fs()->movl(curr_entry, Address::Absolute(trace_buffer_curr_entry_offset)); + __ subl(curr_entry, Immediate(kNumEntriesForWallClock * sizeof(void*))); + __ fs()->movl(init_entry, Address::Absolute(trace_buffer_ptr)); + __ cmpl(curr_entry, init_entry); __ j(kLess, slow_path->GetEntryLabel()); // Update the index in the `Thread`. - __ fs()->movl(Address::Absolute(trace_buffer_index_offset), index); - // Calculate the entry address in the buffer. - // entry_addr = base_addr + sizeof(void*) * index - __ fs()->movl(entry_addr, Address::Absolute(trace_buffer_ptr)); - __ leal(entry_addr, Address(entry_addr, index, TIMES_4, 0)); + __ fs()->movl(Address::Absolute(trace_buffer_curr_entry_offset), curr_entry); // Record method pointer and trace action. - Register method = index; + Register method = init_entry; __ movl(method, Address(ESP, kCurrentMethodStackOffset)); // Use last two bits to encode trace method action. For MethodEntry it is 0 // so no need to set the bits since they are 0 already. @@ -1306,11 +1304,11 @@ void InstructionCodeGeneratorX86::GenerateMethodEntryExitHook(HInstruction* inst static_assert(enum_cast<int32_t>(TraceAction::kTraceMethodExit) == 1); __ orl(method, Immediate(enum_cast<int32_t>(TraceAction::kTraceMethodExit))); } - __ movl(Address(entry_addr, kMethodOffsetInBytes), method); + __ movl(Address(curr_entry, kMethodOffsetInBytes), method); // Get the timestamp. rdtsc returns timestamp in EAX + EDX. __ rdtsc(); - __ movl(Address(entry_addr, kTimestampOffsetInBytes), EAX); - __ movl(Address(entry_addr, kHighTimestampOffsetInBytes), EDX); + __ movl(Address(curr_entry, kTimestampOffsetInBytes), EAX); + __ movl(Address(curr_entry, kHighTimestampOffsetInBytes), EDX); __ Bind(slow_path->GetExitLabel()); } diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index f61bb39ccc..7d2a9213fd 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -1695,28 +1695,29 @@ void InstructionCodeGeneratorX86_64::GenerateMethodEntryExitHook(HInstruction* i __ j(kGreater, slow_path->GetEntryLabel()); // Check if there is place in the buffer for a new entry, if no, take slow path. - CpuRegister index = locations->GetTemp(0).AsRegister<CpuRegister>(); - CpuRegister entry_addr = CpuRegister(TMP); - uint64_t trace_buffer_index_offset = - Thread::TraceBufferIndexOffset<kX86_64PointerSize>().SizeValue(); - __ gs()->movq(CpuRegister(index), - Address::Absolute(trace_buffer_index_offset, /* no_rip= */ true)); - __ subq(CpuRegister(index), Immediate(kNumEntriesForWallClock)); + CpuRegister init_entry = locations->GetTemp(0).AsRegister<CpuRegister>(); + // Use a register that is different from RAX and RDX. RDTSC returns result in RAX and RDX and we + // use curr entry to store the result into the buffer. + CpuRegister curr_entry = CpuRegister(TMP); + DCHECK(curr_entry.AsRegister() != RAX); + DCHECK(curr_entry.AsRegister() != RDX); + uint64_t trace_buffer_curr_entry_offset = + Thread::TraceBufferCurrPtrOffset<kX86_64PointerSize>().SizeValue(); + __ gs()->movq(CpuRegister(curr_entry), + Address::Absolute(trace_buffer_curr_entry_offset, /* no_rip= */ true)); + __ subq(CpuRegister(curr_entry), Immediate(kNumEntriesForWallClock * sizeof(void*))); + __ gs()->movq(init_entry, + Address::Absolute(Thread::TraceBufferPtrOffset<kX86_64PointerSize>().SizeValue(), + /* no_rip= */ true)); + __ cmpq(curr_entry, init_entry); __ j(kLess, slow_path->GetEntryLabel()); // Update the index in the `Thread`. - __ gs()->movq(Address::Absolute(trace_buffer_index_offset, /* no_rip= */ true), - CpuRegister(index)); - // Calculate the entry address in the buffer. - // entry_addr = base_addr + sizeof(void*) * index - __ gs()->movq(entry_addr, - Address::Absolute(Thread::TraceBufferPtrOffset<kX86_64PointerSize>().SizeValue(), - /* no_rip= */ true)); - __ leaq(CpuRegister(entry_addr), - Address(CpuRegister(entry_addr), CpuRegister(index), TIMES_8, 0)); + __ gs()->movq(Address::Absolute(trace_buffer_curr_entry_offset, /* no_rip= */ true), + CpuRegister(curr_entry)); // Record method pointer and action. - CpuRegister method = index; + CpuRegister method = init_entry; __ movq(CpuRegister(method), Address(CpuRegister(RSP), kCurrentMethodStackOffset)); // Use last two bits to encode trace method action. For MethodEntry it is 0 // so no need to set the bits since they are 0 already. @@ -1726,12 +1727,12 @@ void InstructionCodeGeneratorX86_64::GenerateMethodEntryExitHook(HInstruction* i static_assert(enum_cast<int32_t>(TraceAction::kTraceMethodExit) == 1); __ orq(method, Immediate(enum_cast<int32_t>(TraceAction::kTraceMethodExit))); } - __ movq(Address(entry_addr, kMethodOffsetInBytes), CpuRegister(method)); + __ movq(Address(curr_entry, kMethodOffsetInBytes), CpuRegister(method)); // Get the timestamp. rdtsc returns timestamp in RAX + RDX even in 64-bit architectures. __ rdtsc(); __ shlq(CpuRegister(RDX), Immediate(32)); __ orq(CpuRegister(RAX), CpuRegister(RDX)); - __ movq(Address(entry_addr, kTimestampOffsetInBytes), CpuRegister(RAX)); + __ movq(Address(curr_entry, kTimestampOffsetInBytes), CpuRegister(RAX)); __ Bind(slow_path->GetExitLabel()); } |