summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Mythri Alle <mythria@google.com> 2024-07-12 14:51:36 +0000
committer Mythri Alle <mythria@google.com> 2024-07-15 14:49:21 +0000
commit5514bcedf59460571e26ce68508ef4a9fa2b0077 (patch)
treee2218640e0bfe4de221a824bd522e13661bee34a /compiler/optimizing
parentff18b2cbfb1c11e259348890dbfc2e46e81b70cf (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.cc27
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc25
-rw-r--r--compiler/optimizing/code_generator_riscv64.cc22
-rw-r--r--compiler/optimizing/code_generator_x86.cc30
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc39
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());
}