diff options
author | 2020-06-19 15:31:23 +0100 | |
---|---|---|
committer | 2020-06-22 08:05:28 +0000 | |
commit | dec7817522eeaf8f88dcae9ce065969aeebda3b3 (patch) | |
tree | a15fd16ccb4a1929ec60584ead8f095b565c9e3e /compiler/optimizing | |
parent | ea4d7d2d52dd9795cf39eccd46cb07551c62392f (diff) |
Optimizing: Introduce {Increase,Decrease}Frame().
And use it to clean up code generators.
Also fix CFI in MaybeIncrementHotness() for arm/arm64/x86.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: testrunner.py --host --debuggable --ndebuggable \
--optimizing --jit --jit-on-first-use -t 178
Test: aosp_cf_x86_phone-userdebug boots.
Test: aosp_cf_x86_phone-userdebug/jitzygote boots.
Test: # On blueline:
testrunner.py --target --debuggable --ndebuggable \
--optimizing --jit --jit-on-first-use -t 178
Bug: 112189621
Change-Id: I524e6c3054ffe1b05e2860fd7988cd9995df2963
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator.cc | 8 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.h | 14 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 27 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.h | 3 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 34 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.h | 3 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 86 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.h | 3 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 27 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.h | 3 |
10 files changed, 113 insertions, 95 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index f74a938d4a..8e64e1819e 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -545,8 +545,10 @@ void CodeGenerator::PrepareCriticalNativeArgumentMoves( } } -void CodeGenerator::AdjustCriticalNativeArgumentMoves(size_t out_frame_size, - /*inout*/HParallelMove* parallel_move) { +void CodeGenerator::FinishCriticalNativeFrameSetup(size_t out_frame_size, + /*inout*/HParallelMove* parallel_move) { + DCHECK_NE(out_frame_size, 0u); + IncreaseFrame(out_frame_size); // Adjust the source stack offsets by `out_frame_size`, i.e. the additional // frame size needed for outgoing stack arguments. for (size_t i = 0, num = parallel_move->NumMoves(); i != num; ++i) { @@ -558,6 +560,8 @@ void CodeGenerator::AdjustCriticalNativeArgumentMoves(size_t out_frame_size, operands->SetSource(Location::DoubleStackSlot(source.GetStackIndex() + out_frame_size)); } } + // Emit the moves. + GetMoveResolver()->EmitNativeCode(parallel_move); } const char* CodeGenerator::GetCriticalNativeShorty(HInvokeStaticOrDirect* invoke, diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 4bfc14a12b..12e2e9745e 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -573,12 +573,12 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { template <typename CriticalNativeCallingConventionVisitor, size_t kNativeStackAlignment, size_t GetCriticalNativeDirectCallFrameSize(const char* shorty, uint32_t shorty_len)> - static size_t PrepareCriticalNativeCall(HInvokeStaticOrDirect* invoke, - /*out*/HParallelMove* parallel_move) { + size_t PrepareCriticalNativeCall(HInvokeStaticOrDirect* invoke) { DCHECK(!invoke->GetLocations()->Intrinsified()); CriticalNativeCallingConventionVisitor calling_convention_visitor( /*for_register_allocation=*/ false); - PrepareCriticalNativeArgumentMoves(invoke, &calling_convention_visitor, parallel_move); + HParallelMove parallel_move(GetGraph()->GetAllocator()); + PrepareCriticalNativeArgumentMoves(invoke, &calling_convention_visitor, ¶llel_move); size_t out_frame_size = RoundUp(calling_convention_visitor.GetStackOffset(), kNativeStackAlignment); if (kIsDebugBuild) { @@ -587,7 +587,7 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { DCHECK_EQ(GetCriticalNativeDirectCallFrameSize(shorty, shorty_len), out_frame_size); } if (out_frame_size != 0u) { - AdjustCriticalNativeArgumentMoves(out_frame_size, parallel_move); + FinishCriticalNativeFrameSetup(out_frame_size, ¶llel_move); } return out_frame_size; } @@ -690,6 +690,9 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { // Copy the result of a call into the given target. virtual void MoveFromReturnRegister(Location trg, DataType::Type type) = 0; + virtual void IncreaseFrame(size_t adjustment) = 0; + virtual void DecreaseFrame(size_t adjustment) = 0; + virtual void GenerateNop() = 0; static QuickEntrypointEnum GetArrayAllocationEntrypoint(HNewArray* new_array); @@ -826,8 +829,7 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { /*inout*/InvokeDexCallingConventionVisitor* visitor, /*out*/HParallelMove* parallel_move); - static void AdjustCriticalNativeArgumentMoves(size_t out_frame_size, - /*inout*/HParallelMove* parallel_move); + void FinishCriticalNativeFrameSetup(size_t out_frame_size, /*inout*/HParallelMove* parallel_move); static const char* GetCriticalNativeShorty(HInvokeStaticOrDirect* invoke, uint32_t* shorty_len); diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index d108623615..b7f519b805 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -1157,9 +1157,9 @@ void CodeGeneratorARM64::MaybeIncrementHotness(bool is_frame_entry) { __ B(ne, &done); if (is_frame_entry) { if (HasEmptyFrame()) { - // The entyrpoint expects the method at the bottom of the stack. We + // The entrypoint expects the method at the bottom of the stack. We // claim stack space necessary for alignment. - __ Claim(kStackAlignment); + IncreaseFrame(kStackAlignment); __ Stp(kArtMethodRegister, lr, MemOperand(sp, 0)); } else if (!RequiresCurrentMethod()) { __ Str(kArtMethodRegister, MemOperand(sp, 0)); @@ -1176,7 +1176,7 @@ void CodeGeneratorARM64::MaybeIncrementHotness(bool is_frame_entry) { if (HasEmptyFrame()) { CHECK(is_frame_entry); __ Ldr(lr, MemOperand(sp, 8)); - __ Drop(kStackAlignment); + DecreaseFrame(kStackAlignment); } __ Bind(&done); } @@ -3654,6 +3654,16 @@ void InstructionCodeGeneratorARM64::VisitNativeDebugInfo(HNativeDebugInfo*) { // MaybeRecordNativeDebugInfo is already called implicitly in CodeGenerator::Compile. } +void CodeGeneratorARM64::IncreaseFrame(size_t adjustment) { + __ Claim(adjustment); + GetAssembler()->cfi().AdjustCFAOffset(adjustment); +} + +void CodeGeneratorARM64::DecreaseFrame(size_t adjustment) { + __ Drop(adjustment); + GetAssembler()->cfi().AdjustCFAOffset(-adjustment); +} + void CodeGeneratorARM64::GenerateNop() { __ Nop(); } @@ -4448,16 +4458,10 @@ void CodeGeneratorARM64::GenerateStaticOrDirectCall( } break; case HInvokeStaticOrDirect::CodePtrLocation::kCallCriticalNative: { - HParallelMove parallel_move(GetGraph()->GetAllocator()); size_t out_frame_size = PrepareCriticalNativeCall<CriticalNativeCallingConventionVisitorARM64, kAapcs64StackAlignment, - GetCriticalNativeDirectCallFrameSize>(invoke, ¶llel_move); - if (out_frame_size != 0u) { - __ Claim(out_frame_size); - GetAssembler()->cfi().AdjustCFAOffset(out_frame_size); - GetMoveResolver()->EmitNativeCode(¶llel_move); - } + GetCriticalNativeDirectCallFrameSize>(invoke); call_code_pointer_member(ArtMethod::EntryPointFromJniOffset(kArm64PointerSize)); // Zero-/sign-extend the result when needed due to native and managed ABI mismatch. switch (invoke->GetType()) { @@ -4484,8 +4488,7 @@ void CodeGeneratorARM64::GenerateStaticOrDirectCall( break; } if (out_frame_size != 0u) { - __ Drop(out_frame_size); - GetAssembler()->cfi().AdjustCFAOffset(-out_frame_size); + DecreaseFrame(out_frame_size); } break; } diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index bebf43d9d1..5c62e0a824 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -894,6 +894,9 @@ class CodeGeneratorARM64 : public CodeGenerator { // artReadBarrierForRootSlow. void GenerateReadBarrierForRootSlow(HInstruction* instruction, Location out, Location root); + void IncreaseFrame(size_t adjustment) override; + void DecreaseFrame(size_t adjustment) override; + void GenerateNop() override; void GenerateImplicitNullCheck(HNullCheck* instruction) override; diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 9916257aa6..cafb601eed 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -2088,6 +2088,7 @@ void CodeGeneratorARMVIXL::MaybeIncrementHotness(bool is_frame_entry) { static_assert(ArtMethod::MaxCounter() == 0xFFFF, "asm is probably wrong"); if (!is_frame_entry) { __ Push(vixl32::Register(kMethodRegister)); + GetAssembler()->cfi().AdjustCFAOffset(kArmWordSize); GetAssembler()->LoadFromOffset(kLoadWord, kMethodRegister, sp, kArmWordSize); } // Load with zero extend to clear the high bits for integer overflow check. @@ -2098,6 +2099,7 @@ void CodeGeneratorARMVIXL::MaybeIncrementHotness(bool is_frame_entry) { __ Strh(temp, MemOperand(kMethodRegister, ArtMethod::HotnessCountOffset().Int32Value())); if (!is_frame_entry) { __ Pop(vixl32::Register(kMethodRegister)); + GetAssembler()->cfi().AdjustCFAOffset(-static_cast<int>(kArmWordSize)); } } @@ -2111,6 +2113,7 @@ void CodeGeneratorARMVIXL::MaybeIncrementHotness(bool is_frame_entry) { temps.Exclude(ip); if (!is_frame_entry) { __ Push(r4); // Will be used as temporary. For frame entry, r4 is always available. + GetAssembler()->cfi().AdjustCFAOffset(kArmWordSize); } __ Mov(r4, address); __ Ldrh(ip, MemOperand(r4, ProfilingInfo::BaselineHotnessCountOffset().Int32Value())); @@ -2118,6 +2121,7 @@ void CodeGeneratorARMVIXL::MaybeIncrementHotness(bool is_frame_entry) { __ Strh(ip, MemOperand(r4, ProfilingInfo::BaselineHotnessCountOffset().Int32Value())); if (!is_frame_entry) { __ Pop(r4); + GetAssembler()->cfi().AdjustCFAOffset(-static_cast<int>(kArmWordSize)); } __ Lsls(ip, ip, 16); __ B(ne, &done); @@ -2130,9 +2134,12 @@ void CodeGeneratorARMVIXL::MaybeIncrementHotness(bool is_frame_entry) { uint32_t core_spill_mask = (1 << lr.GetCode()) | (1 << r0.GetCode()) | (1 << r1.GetCode()) | (1 << r2.GetCode()); __ Push(RegisterList(core_spill_mask)); + GetAssembler()->cfi().AdjustCFAOffset(kArmWordSize * POPCOUNT(core_spill_mask)); __ Ldr(lr, MemOperand(tr, entry_point_offset)); __ Blx(lr); __ Pop(RegisterList(core_spill_mask)); + GetAssembler()->cfi().AdjustCFAOffset( + -static_cast<int>(kArmWordSize) * POPCOUNT(core_spill_mask)); } else { if (!RequiresCurrentMethod()) { CHECK(is_frame_entry); @@ -2240,8 +2247,7 @@ void CodeGeneratorARMVIXL::GenerateFrameEntry() { __ Push(RegisterList(MaxInt<uint32_t>(fp_spills_offset / kArmWordSize))); GetAssembler()->cfi().AdjustCFAOffset(fp_spills_offset); } else { - __ Sub(sp, sp, dchecked_integral_cast<int32_t>(fp_spills_offset)); - GetAssembler()->cfi().AdjustCFAOffset(fp_spills_offset); + IncreaseFrame(fp_spills_offset); if (RequiresCurrentMethod()) { GetAssembler()->StoreToOffset(kStoreWord, kMethodRegister, sp, 0); } @@ -2297,8 +2303,7 @@ void CodeGeneratorARMVIXL::GenerateFrameExit() { } } else { GetAssembler()->cfi().RememberState(); - __ Add(sp, sp, fp_spills_offset); - GetAssembler()->cfi().AdjustCFAOffset(-dchecked_integral_cast<int32_t>(fp_spills_offset)); + DecreaseFrame(fp_spills_offset); if (fpu_spill_mask_ != 0) { uint32_t first = LeastSignificantBit(fpu_spill_mask_); @@ -2995,6 +3000,16 @@ void InstructionCodeGeneratorARMVIXL::VisitNativeDebugInfo(HNativeDebugInfo*) { // MaybeRecordNativeDebugInfo is already called implicitly in CodeGenerator::Compile. } +void CodeGeneratorARMVIXL::IncreaseFrame(size_t adjustment) { + __ Claim(adjustment); + GetAssembler()->cfi().AdjustCFAOffset(adjustment); +} + +void CodeGeneratorARMVIXL::DecreaseFrame(size_t adjustment) { + __ Drop(adjustment); + GetAssembler()->cfi().AdjustCFAOffset(-adjustment); +} + void CodeGeneratorARMVIXL::GenerateNop() { __ Nop(); } @@ -9013,16 +9028,10 @@ void CodeGeneratorARMVIXL::GenerateStaticOrDirectCall( } break; case HInvokeStaticOrDirect::CodePtrLocation::kCallCriticalNative: { - HParallelMove parallel_move(GetGraph()->GetAllocator()); size_t out_frame_size = PrepareCriticalNativeCall<CriticalNativeCallingConventionVisitorARMVIXL, kAapcsStackAlignment, - GetCriticalNativeDirectCallFrameSize>(invoke, ¶llel_move); - if (out_frame_size != 0u) { - __ Claim(out_frame_size); - GetAssembler()->cfi().AdjustCFAOffset(out_frame_size); - GetMoveResolver()->EmitNativeCode(¶llel_move); - } + GetCriticalNativeDirectCallFrameSize>(invoke); call_code_pointer_member(ArtMethod::EntryPointFromJniOffset(kArmPointerSize)); // Move the result when needed due to native and managed ABI mismatch. switch (invoke->GetType()) { @@ -9045,8 +9054,7 @@ void CodeGeneratorARMVIXL::GenerateStaticOrDirectCall( break; } if (out_frame_size != 0u) { - __ Drop(out_frame_size); - GetAssembler()->cfi().AdjustCFAOffset(-out_frame_size); + DecreaseFrame(out_frame_size); } break; } diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h index d6300c7c20..b8d20d15ae 100644 --- a/compiler/optimizing/code_generator_arm_vixl.h +++ b/compiler/optimizing/code_generator_arm_vixl.h @@ -756,6 +756,9 @@ class CodeGeneratorARMVIXL : public CodeGenerator { // artReadBarrierForRootSlow. void GenerateReadBarrierForRootSlow(HInstruction* instruction, Location out, Location root); + void IncreaseFrame(size_t adjustment) override; + void DecreaseFrame(size_t adjustment) override; + void GenerateNop() override; void GenerateImplicitNullCheck(HNullCheck* instruction) override; diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 595b31ec26..99d3240706 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -1080,6 +1080,7 @@ void CodeGeneratorX86::MaybeIncrementHotness(bool is_frame_entry) { reg = kMethodRegisterArgument; } else { __ pushl(EAX); + __ cfi().AdjustCFAOffset(4); __ movl(EAX, Address(ESP, kX86WordSize)); } NearLabel overflow; @@ -1091,6 +1092,7 @@ void CodeGeneratorX86::MaybeIncrementHotness(bool is_frame_entry) { __ Bind(&overflow); if (!is_frame_entry) { __ popl(EAX); + __ cfi().AdjustCFAOffset(-4); } } @@ -1103,8 +1105,7 @@ void CodeGeneratorX86::MaybeIncrementHotness(bool is_frame_entry) { if (HasEmptyFrame()) { CHECK(is_frame_entry); // Alignment - __ subl(ESP, Immediate(8)); - __ cfi().AdjustCFAOffset(8); + IncreaseFrame(8); // We need a temporary. The stub also expects the method at bottom of stack. __ pushl(EAX); __ cfi().AdjustCFAOffset(4); @@ -1119,8 +1120,7 @@ void CodeGeneratorX86::MaybeIncrementHotness(bool is_frame_entry) { // code easier to reason about. __ popl(EAX); __ cfi().AdjustCFAOffset(-4); - __ addl(ESP, Immediate(8)); - __ cfi().AdjustCFAOffset(-8); + DecreaseFrame(8); } else { if (!RequiresCurrentMethod()) { CHECK(is_frame_entry); @@ -1167,8 +1167,7 @@ void CodeGeneratorX86::GenerateFrameEntry() { } int adjust = GetFrameSize() - FrameEntrySpillSize(); - __ subl(ESP, Immediate(adjust)); - __ cfi().AdjustCFAOffset(adjust); + IncreaseFrame(adjust); // Save the current method if we need it. Note that we do not // do this in HCurrentMethod, as the instruction might have been removed // in the SSA graph. @@ -1189,8 +1188,7 @@ void CodeGeneratorX86::GenerateFrameExit() { __ cfi().RememberState(); if (!HasEmptyFrame()) { int adjust = GetFrameSize() - FrameEntrySpillSize(); - __ addl(ESP, Immediate(adjust)); - __ cfi().AdjustCFAOffset(-adjust); + DecreaseFrame(adjust); for (size_t i = 0; i < arraysize(kCoreCalleeSaves); ++i) { Register reg = kCoreCalleeSaves[i]; @@ -1401,15 +1399,14 @@ void CodeGeneratorX86::Move64(Location destination, Location source) { __ movsd(destination.AsFpuRegister<XmmRegister>(), Address(ESP, source.GetStackIndex())); } else if (source.IsRegisterPair()) { size_t elem_size = DataType::Size(DataType::Type::kInt32); - // Create stack space for 2 elements. - __ subl(ESP, Immediate(2 * elem_size)); - __ cfi().AdjustCFAOffset(2 * elem_size); - __ movl(Address(ESP, 0), source.AsRegisterPairLow<Register>()); - __ movl(Address(ESP, elem_size), source.AsRegisterPairHigh<Register>()); + // Push the 2 source registers to the stack. + __ pushl(source.AsRegisterPairHigh<Register>()); + __ cfi().AdjustCFAOffset(elem_size); + __ pushl(source.AsRegisterPairLow<Register>()); + __ cfi().AdjustCFAOffset(elem_size); __ movsd(destination.AsFpuRegister<XmmRegister>(), Address(ESP, 0)); // And remove the temporary stack space we allocated. - __ addl(ESP, Immediate(2 * elem_size)); - __ cfi().AdjustCFAOffset(-(2 * elem_size)); + DecreaseFrame(2 * elem_size); } else { LOG(FATAL) << "Unimplemented"; } @@ -1970,6 +1967,16 @@ void InstructionCodeGeneratorX86::VisitNativeDebugInfo(HNativeDebugInfo*) { // MaybeRecordNativeDebugInfo is already called implicitly in CodeGenerator::Compile. } +void CodeGeneratorX86::IncreaseFrame(size_t adjustment) { + __ subl(ESP, Immediate(adjustment)); + __ cfi().AdjustCFAOffset(adjustment); +} + +void CodeGeneratorX86::DecreaseFrame(size_t adjustment) { + __ addl(ESP, Immediate(adjustment)); + __ cfi().AdjustCFAOffset(-adjustment); +} + void CodeGeneratorX86::GenerateNop() { __ nop(); } @@ -3025,8 +3032,7 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio // TODO: enhance register allocator to ask for stack temporaries. if (!in.IsDoubleStackSlot() || !out.IsStackSlot()) { adjustment = DataType::Size(DataType::Type::kInt64); - __ subl(ESP, Immediate(adjustment)); - __ cfi().AdjustCFAOffset(adjustment); + codegen_->IncreaseFrame(adjustment); } // Load the value to the FP stack, using temporaries if needed. @@ -3042,8 +3048,7 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio // Remove the temporary stack space we allocated. if (adjustment != 0) { - __ addl(ESP, Immediate(adjustment)); - __ cfi().AdjustCFAOffset(-adjustment); + codegen_->DecreaseFrame(adjustment); } break; } @@ -3077,8 +3082,7 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio // TODO: enhance register allocator to ask for stack temporaries. if (!in.IsDoubleStackSlot() || !out.IsDoubleStackSlot()) { adjustment = DataType::Size(DataType::Type::kInt64); - __ subl(ESP, Immediate(adjustment)); - __ cfi().AdjustCFAOffset(adjustment); + codegen_->IncreaseFrame(adjustment); } // Load the value to the FP stack, using temporaries if needed. @@ -3094,8 +3098,7 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio // Remove the temporary stack space we allocated. if (adjustment != 0) { - __ addl(ESP, Immediate(adjustment)); - __ cfi().AdjustCFAOffset(-adjustment); + codegen_->DecreaseFrame(adjustment); } break; } @@ -3591,8 +3594,7 @@ void InstructionCodeGeneratorX86::GenerateRemFP(HRem *rem) { // Create stack space for 2 elements. // TODO: enhance register allocator to ask for stack temporaries. - __ subl(ESP, Immediate(2 * elem_size)); - __ cfi().AdjustCFAOffset(2 * elem_size); + codegen_->IncreaseFrame(2 * elem_size); // Load the values to the FP stack in reverse order, using temporaries if needed. const bool is_wide = !is_float; @@ -3632,8 +3634,7 @@ void InstructionCodeGeneratorX86::GenerateRemFP(HRem *rem) { } // And remove the temporary stack space we allocated. - __ addl(ESP, Immediate(2 * elem_size)); - __ cfi().AdjustCFAOffset(-(2 * elem_size)); + codegen_->DecreaseFrame(2 * elem_size); } @@ -5054,16 +5055,10 @@ void CodeGeneratorX86::GenerateStaticOrDirectCall( RecordPcInfo(invoke, invoke->GetDexPc(), slow_path); break; case HInvokeStaticOrDirect::CodePtrLocation::kCallCriticalNative: { - HParallelMove parallel_move(GetGraph()->GetAllocator()); size_t out_frame_size = PrepareCriticalNativeCall<CriticalNativeCallingConventionVisitorX86, kNativeStackAlignment, - GetCriticalNativeDirectCallFrameSize>(invoke, ¶llel_move); - if (out_frame_size != 0u) { - __ subl(ESP, Immediate(out_frame_size)); - __ cfi().AdjustCFAOffset(out_frame_size); - GetMoveResolver()->EmitNativeCode(¶llel_move); - } + GetCriticalNativeDirectCallFrameSize>(invoke); // (callee_method + offset_of_jni_entry_point)() __ call(Address(callee_method.AsRegister<Register>(), ArtMethod::EntryPointFromJniOffset(kX86PointerSize).Int32Value())); @@ -5071,8 +5066,7 @@ void CodeGeneratorX86::GenerateStaticOrDirectCall( if (out_frame_size == 0u && DataType::IsFloatingPointType(invoke->GetType())) { // Create space for conversion. out_frame_size = 8u; - __ subl(ESP, Immediate(out_frame_size)); - __ cfi().AdjustCFAOffset(out_frame_size); + IncreaseFrame(out_frame_size); } // Zero-/sign-extend or move the result when needed due to native and managed ABI mismatch. switch (invoke->GetType()) { @@ -5105,8 +5099,7 @@ void CodeGeneratorX86::GenerateStaticOrDirectCall( break; } if (out_frame_size != 0u) { - __ addl(ESP, Immediate(out_frame_size)); - __ cfi().AdjustCFAOffset(-out_frame_size); + DecreaseFrame(out_frame_size); } break; } @@ -6466,7 +6459,7 @@ void ParallelMoveResolverX86::EmitMove(size_t index) { __ movl(destination.AsRegisterPairHigh<Register>(), source.AsRegisterPairHigh<Register>()); } else if (destination.IsFpuRegister()) { size_t elem_size = DataType::Size(DataType::Type::kInt32); - // Push the 2 source registers to stack. + // Push the 2 source registers to the stack. __ pushl(source.AsRegisterPairHigh<Register>()); __ cfi().AdjustCFAOffset(elem_size); __ pushl(source.AsRegisterPairLow<Register>()); @@ -6474,8 +6467,7 @@ void ParallelMoveResolverX86::EmitMove(size_t index) { // Load the destination register. __ movsd(destination.AsFpuRegister<XmmRegister>(), Address(ESP, 0)); // And remove the temporary stack space we allocated. - __ addl(ESP, Immediate(2 * elem_size)); - __ cfi().AdjustCFAOffset(-(2 * elem_size)); + codegen_->DecreaseFrame(2 * elem_size); } else { DCHECK(destination.IsDoubleStackSlot()); __ movl(Address(ESP, destination.GetStackIndex()), source.AsRegisterPairLow<Register>()); @@ -6490,8 +6482,7 @@ void ParallelMoveResolverX86::EmitMove(size_t index) { } else if (destination.IsRegisterPair()) { size_t elem_size = DataType::Size(DataType::Type::kInt32); // Create stack space for 2 elements. - __ subl(ESP, Immediate(2 * elem_size)); - __ cfi().AdjustCFAOffset(2 * elem_size); + codegen_->IncreaseFrame(2 * elem_size); // Store the source register. __ movsd(Address(ESP, 0), source.AsFpuRegister<XmmRegister>()); // And pop the values into destination registers. @@ -6600,8 +6591,7 @@ void ParallelMoveResolverX86::EmitMove(size_t index) { __ pushl(low); __ cfi().AdjustCFAOffset(4); __ movsd(dest, Address(ESP, 0)); - __ addl(ESP, Immediate(8)); - __ cfi().AdjustCFAOffset(-8); + codegen_->DecreaseFrame(8); } } else { DCHECK(destination.IsDoubleStackSlot()) << destination; @@ -6638,13 +6628,11 @@ void ParallelMoveResolverX86::Exchange32(XmmRegister reg, int mem) { void ParallelMoveResolverX86::Exchange128(XmmRegister reg, int mem) { size_t extra_slot = 4 * kX86WordSize; - __ subl(ESP, Immediate(extra_slot)); - __ cfi().AdjustCFAOffset(extra_slot); + codegen_->IncreaseFrame(extra_slot); __ movups(Address(ESP, 0), XmmRegister(reg)); ExchangeMemory(0, mem + extra_slot, 4); __ movups(XmmRegister(reg), Address(ESP, 0)); - __ addl(ESP, Immediate(extra_slot)); - __ cfi().AdjustCFAOffset(-extra_slot); + codegen_->DecreaseFrame(extra_slot); } void ParallelMoveResolverX86::ExchangeMemory(int mem1, int mem2, int number_of_words) { diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index 22d8778b48..c267f76579 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -647,6 +647,9 @@ class CodeGeneratorX86 : public CodeGenerator { } } + void IncreaseFrame(size_t adjustment) override; + void DecreaseFrame(size_t adjustment) override; + void GenerateNop() override; void GenerateImplicitNullCheck(HNullCheck* instruction) override; void GenerateExplicitNullCheck(HNullCheck* instruction) override; diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 4a0cc78205..2df2d16031 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -1046,16 +1046,10 @@ void CodeGeneratorX86_64::GenerateStaticOrDirectCall( RecordPcInfo(invoke, invoke->GetDexPc(), slow_path); break; case HInvokeStaticOrDirect::CodePtrLocation::kCallCriticalNative: { - HParallelMove parallel_move(GetGraph()->GetAllocator()); size_t out_frame_size = PrepareCriticalNativeCall<CriticalNativeCallingConventionVisitorX86_64, kNativeStackAlignment, - GetCriticalNativeDirectCallFrameSize>(invoke, ¶llel_move); - if (out_frame_size != 0u) { - __ subq(CpuRegister(RSP), Immediate(out_frame_size)); - __ cfi().AdjustCFAOffset(out_frame_size); - GetMoveResolver()->EmitNativeCode(¶llel_move); - } + GetCriticalNativeDirectCallFrameSize>(invoke); // (callee_method + offset_of_jni_entry_point)() __ call(Address(callee_method.AsRegister<CpuRegister>(), ArtMethod::EntryPointFromJniOffset(kX86_64PointerSize).SizeValue())); @@ -1085,8 +1079,7 @@ void CodeGeneratorX86_64::GenerateStaticOrDirectCall( break; } if (out_frame_size != 0u) { - __ addq(CpuRegister(RSP), Immediate(out_frame_size)); - __ cfi().AdjustCFAOffset(-out_frame_size); + DecreaseFrame(out_frame_size); } break; } @@ -1477,8 +1470,7 @@ void CodeGeneratorX86_64::GenerateFrameEntry() { } int adjust = GetFrameSize() - GetCoreSpillSize(); - __ subq(CpuRegister(RSP), Immediate(adjust)); - __ cfi().AdjustCFAOffset(adjust); + IncreaseFrame(adjust); uint32_t xmm_spill_location = GetFpuSpillStart(); size_t xmm_spill_slot_size = GetCalleePreservedFPWidth(); @@ -1523,8 +1515,7 @@ void CodeGeneratorX86_64::GenerateFrameExit() { } int adjust = GetFrameSize() - GetCoreSpillSize(); - __ addq(CpuRegister(RSP), Immediate(adjust)); - __ cfi().AdjustCFAOffset(-adjust); + DecreaseFrame(adjust); for (size_t i = 0; i < arraysize(kCoreCalleeSaves); ++i) { Register reg = kCoreCalleeSaves[i]; @@ -2045,6 +2036,16 @@ void InstructionCodeGeneratorX86_64::VisitNativeDebugInfo(HNativeDebugInfo*) { // MaybeRecordNativeDebugInfo is already called implicitly in CodeGenerator::Compile. } +void CodeGeneratorX86_64::IncreaseFrame(size_t adjustment) { + __ subq(CpuRegister(RSP), Immediate(adjustment)); + __ cfi().AdjustCFAOffset(adjustment); +} + +void CodeGeneratorX86_64::DecreaseFrame(size_t adjustment) { + __ addq(CpuRegister(RSP), Immediate(adjustment)); + __ cfi().AdjustCFAOffset(-adjustment); +} + void CodeGeneratorX86_64::GenerateNop() { __ nop(); } diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h index dcdd632b24..d7c5b54218 100644 --- a/compiler/optimizing/code_generator_x86_64.h +++ b/compiler/optimizing/code_generator_x86_64.h @@ -626,6 +626,9 @@ class CodeGeneratorX86_64 : public CodeGenerator { } } + void IncreaseFrame(size_t adjustment) override; + void DecreaseFrame(size_t adjustment) override; + void GenerateNop() override; void GenerateImplicitNullCheck(HNullCheck* instruction) override; void GenerateExplicitNullCheck(HNullCheck* instruction) override; |