From 27ceaaa97324c34ad83f7092bbcc9d268ea6763b Mon Sep 17 00:00:00 2001 From: Mythri Alle Date: Tue, 16 May 2023 10:44:27 +0000 Subject: Encode trace action in the last two bits of method pointer When recording method entry / exit events we used an entire entry for recording the trace action (method enter / method exit / method unwind) which only requires two bits. This change encodes the trace action in the last two bits of method pointer. Given the alignment requirements of method pointers last two bits are ensured to be 0, so it is safe to use those bits. Bug: 259258187 Test: art/test.py --streaming Change-Id: I854b82f407503085dfa5304813d1d96df9ce27f3 --- compiler/optimizing/code_generator_arm64.cc | 13 ++++++++----- compiler/optimizing/code_generator_arm_vixl.cc | 14 +++++++++----- compiler/optimizing/code_generator_x86.cc | 12 ++++++++---- compiler/optimizing/code_generator_x86_64.cc | 12 ++++++++---- 4 files changed, 33 insertions(+), 18 deletions(-) (limited to 'compiler/optimizing') diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index d9fefc1568..d530d08b98 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -1243,13 +1243,16 @@ void InstructionCodeGeneratorARM64::GenerateMethodEntryExitHook(HInstruction* in __ Str(index, MemOperand(tr, trace_buffer_index_addr)); Register tmp = index; - // Record method pointer + // 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 + // so no need to set the bits since they are 0 already. + if (instruction->IsMethodExitHook()) { + DCHECK_GE(ArtMethod::Alignment(kRuntimePointerSize), static_cast(4)); + uint32_t trace_action = 1; + __ Orr(tmp, tmp, Operand(trace_action)); + } __ Str(tmp, MemOperand(addr, kMethodOffsetInBytes)); - // Record the method action - uint32_t trace_action = instruction->IsMethodExitHook() ? 1 : 0; - __ Mov(tmp, Operand(trace_action)); - __ Str(tmp, MemOperand(addr, kTraceActionOffsetInBytes)); // Record the timestamp. __ Mrs(tmp, (SystemRegister)SYS_CNTVCT_EL0); __ Str(tmp, MemOperand(addr, kTimestampOffsetInBytes)); diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 99e4bda73d..ecc7a68b94 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -2243,13 +2243,17 @@ void InstructionCodeGeneratorARMVIXL::GenerateMethodEntryExitHook(HInstruction* __ Sub(index, index, kNumEntriesForWallClock); __ Str(index, MemOperand(tr, trace_buffer_index_addr)); - // Record method pointer + // 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 + // so no need to set the bits since they are 0 already. + if (instruction->IsMethodExitHook()) { + DCHECK_GE(ArtMethod::Alignment(kRuntimePointerSize), static_cast(4)); + uint32_t trace_action = 1; + __ Orr(tmp, tmp, Operand(trace_action)); + } __ Str(tmp, MemOperand(addr, kMethodOffsetInBytes)); - // Record the method action - uint32_t trace_action = instruction->IsMethodExitHook() ? 1 : 0; - __ Mov(tmp, Operand(trace_action)); - __ Str(tmp, MemOperand(addr, kTraceActionOffsetInBytes)); + vixl32::Register tmp1 = index; // See Architecture Reference Manual ARMv7-A and ARMv7-R edition section B4.1.34. __ Mrrc(/* lower 32-bit */ tmp, diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 16aa5c1cfa..bcf5ea0907 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -1277,13 +1277,17 @@ void InstructionCodeGeneratorX86::GenerateMethodEntryExitHook(HInstruction* inst __ subl(index, Immediate(kNumEntriesForWallClock)); __ fs()->movl(Address::Absolute(trace_buffer_index_addr), index); - // Record method pointer + // Record method pointer and trace action. Register method = index; __ 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. + if (instruction->IsMethodExitHook()) { + DCHECK_GE(ArtMethod::Alignment(kRuntimePointerSize), static_cast(4)); + uint32_t trace_action = 1; + __ orl(method, Immediate(trace_action)); + } __ movl(Address(entry_addr, kMethodOffsetInBytes), method); - // Record the method action - uint32_t trace_action = instruction->IsMethodExitHook() ? 1 : 0; - __ movl(Address(entry_addr, kTraceActionOffsetInBytes), Immediate(trace_action)); // Get the timestamp. rdtsc returns timestamp in EAX + EDX. __ rdtsc(); __ movl(Address(entry_addr, kTimestampOffsetInBytes), EDX); diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 15893b1fec..2e03f1f3b4 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -1644,13 +1644,17 @@ void InstructionCodeGeneratorX86_64::GenerateMethodEntryExitHook(HInstruction* i __ subq(CpuRegister(index), Immediate(kNumEntriesForWallClock)); __ gs()->movq(Address::Absolute(trace_buffer_index_addr, /* no_rip= */ true), CpuRegister(index)); - // Record method pointer + // Record method pointer and action. CpuRegister method = index; __ 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. + if (instruction->IsMethodExitHook()) { + DCHECK_GE(ArtMethod::Alignment(kRuntimePointerSize), static_cast(4)); + uint32_t trace_action = 1; + __ orq(method, Immediate(trace_action)); + } __ movq(Address(entry_addr, kMethodOffsetInBytes), CpuRegister(method)); - // Record the method action - uint32_t trace_action = instruction->IsMethodExitHook() ? 1 : 0; - __ movq(Address(entry_addr, kTraceActionOffsetInBytes), Immediate(trace_action)); // Get the timestamp. rdtsc returns timestamp in RAX + RDX even in 64-bit architectures. __ rdtsc(); __ shlq(CpuRegister(RDX), Immediate(32)); -- cgit v1.2.3-59-g8ed1b