diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 185 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips.h | 8 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips64.cc | 99 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips64.h | 7 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 123 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.h | 9 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 99 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.h | 9 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_mips.cc | 47 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_mips64.cc | 45 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_x86.cc | 18 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_x86_64.cc | 24 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 48 |
13 files changed, 210 insertions, 511 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 8f2fc2687e..fe6069c242 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -171,14 +171,10 @@ class BoundsCheckSlowPathMIPS : public SlowPathCodeMIPS { locations->InAt(1), Location::RegisterLocation(calling_convention.GetRegisterAt(1)), Primitive::kPrimInt); - uint32_t entry_point_offset = instruction_->AsBoundsCheck()->IsStringCharAt() - ? QUICK_ENTRY_POINT(pThrowStringBounds) - : QUICK_ENTRY_POINT(pThrowArrayBounds); - mips_codegen->InvokeRuntime(entry_point_offset, - instruction_, - instruction_->GetDexPc(), - this, - IsDirectEntrypoint(kQuickThrowArrayBounds)); + QuickEntrypointEnum entrypoint = instruction_->AsBoundsCheck()->IsStringCharAt() + ? kQuickThrowStringBounds + : kQuickThrowArrayBounds; + mips_codegen->InvokeRuntime(entrypoint, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickThrowStringBounds, void, int32_t, int32_t>(); CheckEntrypointTypes<kQuickThrowArrayBounds, void, int32_t, int32_t>(); } @@ -202,11 +198,7 @@ class DivZeroCheckSlowPathMIPS : public SlowPathCodeMIPS { // Live registers will be restored in the catch block if caught. SaveLiveRegisters(codegen, instruction_->GetLocations()); } - mips_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowDivZero), - instruction_, - instruction_->GetDexPc(), - this, - IsDirectEntrypoint(kQuickThrowDivZero)); + mips_codegen->InvokeRuntime(kQuickThrowDivZero, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickThrowDivZero, void, void>(); } @@ -238,12 +230,9 @@ class LoadClassSlowPathMIPS : public SlowPathCodeMIPS { InvokeRuntimeCallingConvention calling_convention; __ LoadConst32(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex()); - int32_t entry_point_offset = do_clinit_ ? QUICK_ENTRY_POINT(pInitializeStaticStorage) - : QUICK_ENTRY_POINT(pInitializeType); - bool direct = do_clinit_ ? IsDirectEntrypoint(kQuickInitializeStaticStorage) - : IsDirectEntrypoint(kQuickInitializeType); - - mips_codegen->InvokeRuntime(entry_point_offset, at_, dex_pc_, this, direct); + QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage + : kQuickInitializeType; + mips_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); if (do_clinit_) { CheckEntrypointTypes<kQuickInitializeStaticStorage, void*, uint32_t>(); } else { @@ -296,11 +285,7 @@ class LoadStringSlowPathMIPS : public SlowPathCodeMIPS { InvokeRuntimeCallingConvention calling_convention; const uint32_t string_index = instruction_->AsLoadString()->GetStringIndex(); __ LoadConst32(calling_convention.GetRegisterAt(0), string_index); - mips_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pResolveString), - instruction_, - instruction_->GetDexPc(), - this, - IsDirectEntrypoint(kQuickResolveString)); + mips_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickResolveString, void*, uint32_t>(); Primitive::Type type = instruction_->GetType(); mips_codegen->MoveLocation(locations->Out(), @@ -328,11 +313,10 @@ class NullCheckSlowPathMIPS : public SlowPathCodeMIPS { // Live registers will be restored in the catch block if caught. SaveLiveRegisters(codegen, instruction_->GetLocations()); } - mips_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowNullPointer), + mips_codegen->InvokeRuntime(kQuickThrowNullPointer, instruction_, instruction_->GetDexPc(), - this, - IsDirectEntrypoint(kQuickThrowNullPointer)); + this); CheckEntrypointTypes<kQuickThrowNullPointer, void, void>(); } @@ -352,11 +336,7 @@ class SuspendCheckSlowPathMIPS : public SlowPathCodeMIPS { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorMIPS* mips_codegen = down_cast<CodeGeneratorMIPS*>(codegen); __ Bind(GetEntryLabel()); - mips_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pTestSuspend), - instruction_, - instruction_->GetDexPc(), - this, - IsDirectEntrypoint(kQuickTestSuspend)); + mips_codegen->InvokeRuntime(kQuickTestSuspend, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); if (successor_ == nullptr) { __ B(GetReturnLabel()); @@ -408,11 +388,7 @@ class TypeCheckSlowPathMIPS : public SlowPathCodeMIPS { Primitive::kPrimNot); if (instruction_->IsInstanceOf()) { - mips_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pInstanceofNonTrivial), - instruction_, - dex_pc, - this, - IsDirectEntrypoint(kQuickInstanceofNonTrivial)); + mips_codegen->InvokeRuntime(kQuickInstanceofNonTrivial, instruction_, dex_pc, this); CheckEntrypointTypes< kQuickInstanceofNonTrivial, size_t, const mirror::Class*, const mirror::Class*>(); Primitive::Type ret_type = instruction_->GetType(); @@ -420,11 +396,7 @@ class TypeCheckSlowPathMIPS : public SlowPathCodeMIPS { mips_codegen->MoveLocation(locations->Out(), ret_loc, ret_type); } else { DCHECK(instruction_->IsCheckCast()); - mips_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pCheckCast), - instruction_, - dex_pc, - this, - IsDirectEntrypoint(kQuickCheckCast)); + mips_codegen->InvokeRuntime(kQuickCheckCast, instruction_, dex_pc, this); CheckEntrypointTypes<kQuickCheckCast, void, const mirror::Class*, const mirror::Class*>(); } @@ -447,11 +419,7 @@ class DeoptimizationSlowPathMIPS : public SlowPathCodeMIPS { CodeGeneratorMIPS* mips_codegen = down_cast<CodeGeneratorMIPS*>(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, instruction_->GetLocations()); - mips_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pDeoptimize), - instruction_, - instruction_->GetDexPc(), - this, - IsDirectEntrypoint(kQuickDeoptimize)); + mips_codegen->InvokeRuntime(kQuickDeoptimize, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickDeoptimize, void, void>(); } @@ -1246,28 +1214,17 @@ void CodeGeneratorMIPS::DumpFloatingPointRegister(std::ostream& stream, int reg) stream << FRegister(reg); } -void CodeGeneratorMIPS::InvokeRuntime(QuickEntrypointEnum entrypoint, - HInstruction* instruction, - uint32_t dex_pc, - SlowPathCode* slow_path) { - InvokeRuntime(GetThreadOffset<kMipsPointerSize>(entrypoint).Int32Value(), - instruction, - dex_pc, - slow_path, - IsDirectEntrypoint(entrypoint)); -} - constexpr size_t kMipsDirectEntrypointRuntimeOffset = 16; -void CodeGeneratorMIPS::InvokeRuntime(int32_t entry_point_offset, +void CodeGeneratorMIPS::InvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, uint32_t dex_pc, - SlowPathCode* slow_path, - bool is_direct_entrypoint) { + SlowPathCode* slow_path) { + ValidateInvokeRuntime(instruction, slow_path); bool reordering = __ SetReorder(false); - __ LoadFromOffset(kLoadWord, T9, TR, entry_point_offset); + __ LoadFromOffset(kLoadWord, T9, TR, GetThreadOffset<kMipsPointerSize>(entrypoint).Int32Value()); __ Jalr(T9); - if (is_direct_entrypoint) { + if (IsDirectEntrypoint(entrypoint)) { // Reserve argument space on stack (for $a0-$a3) for // entrypoints that directly reference native implementations. // Called function may use this space to store $a0-$a3 regs. @@ -1277,7 +1234,9 @@ void CodeGeneratorMIPS::InvokeRuntime(int32_t entry_point_offset, __ Nop(); // In delay slot. } __ SetReorder(reordering); - RecordPcInfo(instruction, dex_pc, slow_path); + if (EntrypointRequiresStackMap(entrypoint)) { + RecordPcInfo(instruction, dex_pc, slow_path); + } } void InstructionCodeGeneratorMIPS::GenerateClassInitializationCheck(SlowPathCodeMIPS* slow_path, @@ -2081,11 +2040,7 @@ void InstructionCodeGeneratorMIPS::VisitArraySet(HArraySet* instruction) { } } else { DCHECK_EQ(value_type, Primitive::kPrimNot); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject), - instruction, - instruction->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickAputObject)); + codegen_->InvokeRuntime(kQuickAputObject, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAputObject, void, mirror::Array*, int32_t, mirror::Object*>(); } break; @@ -2651,11 +2606,7 @@ void InstructionCodeGeneratorMIPS::VisitDiv(HDiv* instruction) { GenerateDivRemIntegral(instruction); break; case Primitive::kPrimLong: { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLdiv), - instruction, - instruction->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickLdiv)); + codegen_->InvokeRuntime(kQuickLdiv, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickLdiv, int64_t, int64_t, int64_t>(); break; } @@ -3641,11 +3592,7 @@ void InstructionCodeGeneratorMIPS::HandleFieldGet(HInstruction* instruction, // Do implicit Null check __ Lw(ZERO, locations->GetTemp(0).AsRegister<Register>(), 0); codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pA64Load), - instruction, - dex_pc, - nullptr, - IsDirectEntrypoint(kQuickA64Load)); + codegen_->InvokeRuntime(kQuickA64Load, instruction, dex_pc); CheckEntrypointTypes<kQuickA64Load, int64_t, volatile const int64_t*>(); if (type == Primitive::kPrimDouble) { // FP results are returned in core registers. Need to move them. @@ -3793,11 +3740,7 @@ void InstructionCodeGeneratorMIPS::HandleFieldSet(HInstruction* instruction, value); } } - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pA64Store), - instruction, - dex_pc, - nullptr, - IsDirectEntrypoint(kQuickA64Store)); + codegen_->InvokeRuntime(kQuickA64Store, instruction, dex_pc); CheckEntrypointTypes<kQuickA64Store, void, volatile int64_t *, int64_t>(); } else { if (!Primitive::IsFloatingPointType(type)) { @@ -4381,11 +4324,7 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pInitializeTypeAndVerifyAccess), - cls, - cls->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickInitializeTypeAndVerifyAccess)); + codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; } @@ -4653,18 +4592,10 @@ void LocationsBuilderMIPS::VisitMonitorOperation(HMonitorOperation* instruction) void InstructionCodeGeneratorMIPS::VisitMonitorOperation(HMonitorOperation* instruction) { if (instruction->IsEnter()) { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLockObject), - instruction, - instruction->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickLockObject)); + codegen_->InvokeRuntime(kQuickLockObject, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickLockObject, void, mirror::Object*>(); } else { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pUnlockObject), - instruction, - instruction->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickUnlockObject)); + codegen_->InvokeRuntime(kQuickUnlockObject, instruction, instruction->GetDexPc()); } CheckEntrypointTypes<kQuickUnlockObject, void, mirror::Object*>(); } @@ -4839,12 +4770,7 @@ void InstructionCodeGeneratorMIPS::VisitNewArray(HNewArray* instruction) { __ Lw(current_method_register, SP, kCurrentMethodStackOffset); // Move an uint16_t value to a register. __ LoadConst32(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex()); - codegen_->InvokeRuntime( - GetThreadOffset<kMipsPointerSize>(instruction->GetEntrypoint()).Int32Value(), - instruction, - instruction->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickAllocArrayWithAccessCheck)); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); } @@ -4873,12 +4799,7 @@ void InstructionCodeGeneratorMIPS::VisitNewInstance(HNewInstance* instruction) { __ NopIfNoReordering(); codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); } else { - codegen_->InvokeRuntime( - GetThreadOffset<kMipsPointerSize>(instruction->GetEntrypoint()).Int32Value(), - instruction, - instruction->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickAllocObjectWithAccessCheck)); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocObjectWithAccessCheck, void*, uint32_t, ArtMethod*>(); } } @@ -5063,27 +4984,17 @@ void InstructionCodeGeneratorMIPS::VisitRem(HRem* instruction) { GenerateDivRemIntegral(instruction); break; case Primitive::kPrimLong: { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLmod), - instruction, - instruction->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickLmod)); + codegen_->InvokeRuntime(kQuickLmod, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickLmod, int64_t, int64_t, int64_t>(); break; } case Primitive::kPrimFloat: { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pFmodf), - instruction, instruction->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickFmodf)); + codegen_->InvokeRuntime(kQuickFmodf, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickFmodf, float, float, float>(); break; } case Primitive::kPrimDouble: { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pFmod), - instruction, instruction->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickFmod)); + codegen_->InvokeRuntime(kQuickFmod, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickFmod, double, double, double>(); break; } @@ -5264,11 +5175,7 @@ void LocationsBuilderMIPS::VisitThrow(HThrow* instruction) { } void InstructionCodeGeneratorMIPS::VisitThrow(HThrow* instruction) { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pDeliverException), - instruction, - instruction->GetDexPc(), - nullptr, - IsDirectEntrypoint(kQuickDeliverException)); + codegen_->InvokeRuntime(kQuickDeliverException, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickDeliverException, void, mirror::Object*>(); } @@ -5389,15 +5296,9 @@ void InstructionCodeGeneratorMIPS::VisitTypeConversion(HTypeConversion* conversi __ Cvtdl(dst, FTMP); } } else { - int32_t entry_offset = (result_type == Primitive::kPrimFloat) ? QUICK_ENTRY_POINT(pL2f) - : QUICK_ENTRY_POINT(pL2d); - bool direct = (result_type == Primitive::kPrimFloat) ? IsDirectEntrypoint(kQuickL2f) - : IsDirectEntrypoint(kQuickL2d); - codegen_->InvokeRuntime(entry_offset, - conversion, - conversion->GetDexPc(), - nullptr, - direct); + QuickEntrypointEnum entrypoint = (result_type == Primitive::kPrimFloat) ? kQuickL2f + : kQuickL2d; + codegen_->InvokeRuntime(entrypoint, conversion, conversion->GetDexPc()); if (result_type == Primitive::kPrimFloat) { CheckEntrypointTypes<kQuickL2f, float, int64_t>(); } else { @@ -5490,11 +5391,9 @@ void InstructionCodeGeneratorMIPS::VisitTypeConversion(HTypeConversion* conversi __ Bind(&done); } else { - int32_t entry_offset = (input_type == Primitive::kPrimFloat) ? QUICK_ENTRY_POINT(pF2l) - : QUICK_ENTRY_POINT(pD2l); - bool direct = (result_type == Primitive::kPrimFloat) ? IsDirectEntrypoint(kQuickF2l) - : IsDirectEntrypoint(kQuickD2l); - codegen_->InvokeRuntime(entry_offset, conversion, conversion->GetDexPc(), nullptr, direct); + QuickEntrypointEnum entrypoint = (input_type == Primitive::kPrimFloat) ? kQuickF2l + : kQuickD2l; + codegen_->InvokeRuntime(entrypoint, conversion, conversion->GetDexPc()); if (input_type == Primitive::kPrimFloat) { CheckEntrypointTypes<kQuickF2l, int64_t, float>(); } else { diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h index 46810d658f..4ce54b6097 100644 --- a/compiler/optimizing/code_generator_mips.h +++ b/compiler/optimizing/code_generator_mips.h @@ -347,13 +347,7 @@ class CodeGeneratorMIPS : public CodeGenerator { void InvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, uint32_t dex_pc, - SlowPathCode* slow_path) OVERRIDE; - - void InvokeRuntime(int32_t offset, - HInstruction* instruction, - uint32_t dex_pc, - SlowPathCode* slow_path, - bool is_direct_entrypoint); + SlowPathCode* slow_path = nullptr) OVERRIDE; ParallelMoveResolver* GetMoveResolver() OVERRIDE { return &move_resolver_; } diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 4a5755c925..71d35bd0d2 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -127,13 +127,10 @@ class BoundsCheckSlowPathMIPS64 : public SlowPathCodeMIPS64 { locations->InAt(1), Location::RegisterLocation(calling_convention.GetRegisterAt(1)), Primitive::kPrimInt); - uint32_t entry_point_offset = instruction_->AsBoundsCheck()->IsStringCharAt() - ? QUICK_ENTRY_POINT(pThrowStringBounds) - : QUICK_ENTRY_POINT(pThrowArrayBounds); - mips64_codegen->InvokeRuntime(entry_point_offset, - instruction_, - instruction_->GetDexPc(), - this); + QuickEntrypointEnum entrypoint = instruction_->AsBoundsCheck()->IsStringCharAt() + ? kQuickThrowStringBounds + : kQuickThrowArrayBounds; + mips64_codegen->InvokeRuntime(entrypoint, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickThrowStringBounds, void, int32_t, int32_t>(); CheckEntrypointTypes<kQuickThrowArrayBounds, void, int32_t, int32_t>(); } @@ -157,10 +154,7 @@ class DivZeroCheckSlowPathMIPS64 : public SlowPathCodeMIPS64 { // Live registers will be restored in the catch block if caught. SaveLiveRegisters(codegen, instruction_->GetLocations()); } - mips64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowDivZero), - instruction_, - instruction_->GetDexPc(), - this); + mips64_codegen->InvokeRuntime(kQuickThrowDivZero, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickThrowDivZero, void, void>(); } @@ -191,9 +185,9 @@ class LoadClassSlowPathMIPS64 : public SlowPathCodeMIPS64 { InvokeRuntimeCallingConvention calling_convention; __ LoadConst32(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex()); - int32_t entry_point_offset = do_clinit_ ? QUICK_ENTRY_POINT(pInitializeStaticStorage) - : QUICK_ENTRY_POINT(pInitializeType); - mips64_codegen->InvokeRuntime(entry_point_offset, at_, dex_pc_, this); + QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage + : kQuickInitializeType; + mips64_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); if (do_clinit_) { CheckEntrypointTypes<kQuickInitializeStaticStorage, void*, uint32_t>(); } else { @@ -246,7 +240,7 @@ class LoadStringSlowPathMIPS64 : public SlowPathCodeMIPS64 { InvokeRuntimeCallingConvention calling_convention; const uint32_t string_index = instruction_->AsLoadString()->GetStringIndex(); __ LoadConst32(calling_convention.GetRegisterAt(0), string_index); - mips64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pResolveString), + mips64_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this); @@ -277,7 +271,7 @@ class NullCheckSlowPathMIPS64 : public SlowPathCodeMIPS64 { // Live registers will be restored in the catch block if caught. SaveLiveRegisters(codegen, instruction_->GetLocations()); } - mips64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowNullPointer), + mips64_codegen->InvokeRuntime(kQuickThrowNullPointer, instruction_, instruction_->GetDexPc(), this); @@ -300,10 +294,7 @@ class SuspendCheckSlowPathMIPS64 : public SlowPathCodeMIPS64 { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorMIPS64* mips64_codegen = down_cast<CodeGeneratorMIPS64*>(codegen); __ Bind(GetEntryLabel()); - mips64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pTestSuspend), - instruction_, - instruction_->GetDexPc(), - this); + mips64_codegen->InvokeRuntime(kQuickTestSuspend, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); if (successor_ == nullptr) { __ Bc(GetReturnLabel()); @@ -355,10 +346,7 @@ class TypeCheckSlowPathMIPS64 : public SlowPathCodeMIPS64 { Primitive::kPrimNot); if (instruction_->IsInstanceOf()) { - mips64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pInstanceofNonTrivial), - instruction_, - dex_pc, - this); + mips64_codegen->InvokeRuntime(kQuickInstanceofNonTrivial, instruction_, dex_pc, this); CheckEntrypointTypes< kQuickInstanceofNonTrivial, size_t, const mirror::Class*, const mirror::Class*>(); Primitive::Type ret_type = instruction_->GetType(); @@ -366,7 +354,7 @@ class TypeCheckSlowPathMIPS64 : public SlowPathCodeMIPS64 { mips64_codegen->MoveLocation(locations->Out(), ret_loc, ret_type); } else { DCHECK(instruction_->IsCheckCast()); - mips64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pCheckCast), instruction_, dex_pc, this); + mips64_codegen->InvokeRuntime(kQuickCheckCast, instruction_, dex_pc, this); CheckEntrypointTypes<kQuickCheckCast, void, const mirror::Class*, const mirror::Class*>(); } @@ -389,10 +377,7 @@ class DeoptimizationSlowPathMIPS64 : public SlowPathCodeMIPS64 { CodeGeneratorMIPS64* mips64_codegen = down_cast<CodeGeneratorMIPS64*>(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, instruction_->GetLocations()); - mips64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pDeoptimize), - instruction_, - instruction_->GetDexPc(), - this); + mips64_codegen->InvokeRuntime(kQuickDeoptimize, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickDeoptimize, void, void>(); } @@ -959,25 +944,20 @@ void CodeGeneratorMIPS64::DumpFloatingPointRegister(std::ostream& stream, int re } void CodeGeneratorMIPS64::InvokeRuntime(QuickEntrypointEnum entrypoint, - HInstruction* instruction, - uint32_t dex_pc, - SlowPathCode* slow_path) { - InvokeRuntime(GetThreadOffset<kMips64PointerSize>(entrypoint).Int32Value(), - instruction, - dex_pc, - slow_path); -} - -void CodeGeneratorMIPS64::InvokeRuntime(int32_t entry_point_offset, HInstruction* instruction, uint32_t dex_pc, SlowPathCode* slow_path) { ValidateInvokeRuntime(instruction, slow_path); // TODO: anything related to T9/GP/GOT/PIC/.so's? - __ LoadFromOffset(kLoadDoubleword, T9, TR, entry_point_offset); + __ LoadFromOffset(kLoadDoubleword, + T9, + TR, + GetThreadOffset<kMips64PointerSize>(entrypoint).Int32Value()); __ Jalr(T9); __ Nop(); - RecordPcInfo(instruction, dex_pc, slow_path); + if (EntrypointRequiresStackMap(entrypoint)) { + RecordPcInfo(instruction, dex_pc, slow_path); + } } void InstructionCodeGeneratorMIPS64::GenerateClassInitializationCheck(SlowPathCodeMIPS64* slow_path, @@ -1514,10 +1494,7 @@ void InstructionCodeGeneratorMIPS64::VisitArraySet(HArraySet* instruction) { } } else { DCHECK_EQ(value_type, Primitive::kPrimNot); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickAputObject, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAputObject, void, mirror::Array*, int32_t, mirror::Object*>(); } break; @@ -3187,10 +3164,7 @@ void InstructionCodeGeneratorMIPS64::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pInitializeTypeAndVerifyAccess), - cls, - cls->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; } @@ -3285,12 +3259,9 @@ void LocationsBuilderMIPS64::VisitMonitorOperation(HMonitorOperation* instructio } void InstructionCodeGeneratorMIPS64::VisitMonitorOperation(HMonitorOperation* instruction) { - codegen_->InvokeRuntime(instruction->IsEnter() - ? QUICK_ENTRY_POINT(pLockObject) - : QUICK_ENTRY_POINT(pUnlockObject), + codegen_->InvokeRuntime(instruction->IsEnter() ? kQuickLockObject : kQuickUnlockObject, instruction, - instruction->GetDexPc(), - nullptr); + instruction->GetDexPc()); if (instruction->IsEnter()) { CheckEntrypointTypes<kQuickLockObject, void, mirror::Object*>(); } else { @@ -3418,10 +3389,7 @@ void InstructionCodeGeneratorMIPS64::VisitNewArray(HNewArray* instruction) { LocationSummary* locations = instruction->GetLocations(); // Move an uint16_t value to a register. __ LoadConst32(locations->GetTemp(0).AsRegister<GpuRegister>(), instruction->GetTypeIndex()); - codegen_->InvokeRuntime(instruction->GetEntrypoint(), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); } @@ -3450,10 +3418,7 @@ void InstructionCodeGeneratorMIPS64::VisitNewInstance(HNewInstance* instruction) __ Nop(); codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); } else { - codegen_->InvokeRuntime(instruction->GetEntrypoint(), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocObjectWithAccessCheck, void*, uint32_t, ArtMethod*>(); } } @@ -3624,9 +3589,8 @@ void InstructionCodeGeneratorMIPS64::VisitRem(HRem* instruction) { case Primitive::kPrimFloat: case Primitive::kPrimDouble: { - int32_t entry_offset = (type == Primitive::kPrimFloat) ? QUICK_ENTRY_POINT(pFmodf) - : QUICK_ENTRY_POINT(pFmod); - codegen_->InvokeRuntime(entry_offset, instruction, instruction->GetDexPc(), nullptr); + QuickEntrypointEnum entrypoint = (type == Primitive::kPrimFloat) ? kQuickFmodf : kQuickFmod; + codegen_->InvokeRuntime(entrypoint, instruction, instruction->GetDexPc()); if (type == Primitive::kPrimFloat) { CheckEntrypointTypes<kQuickFmodf, float, float, float>(); } else { @@ -3807,10 +3771,7 @@ void LocationsBuilderMIPS64::VisitThrow(HThrow* instruction) { } void InstructionCodeGeneratorMIPS64::VisitThrow(HThrow* instruction) { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pDeliverException), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickDeliverException, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickDeliverException, void, mirror::Object*>(); } diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h index 197f86b22b..3910530eb5 100644 --- a/compiler/optimizing/code_generator_mips64.h +++ b/compiler/optimizing/code_generator_mips64.h @@ -323,12 +323,7 @@ class CodeGeneratorMIPS64 : public CodeGenerator { void InvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, uint32_t dex_pc, - SlowPathCode* slow_path) OVERRIDE; - - void InvokeRuntime(int32_t offset, - HInstruction* instruction, - uint32_t dex_pc, - SlowPathCode* slow_path); + SlowPathCode* slow_path = nullptr) OVERRIDE; ParallelMoveResolver* GetMoveResolver() OVERRIDE { return &move_resolver_; } diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 675c5e0699..1369e5f413 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -62,7 +62,7 @@ class NullCheckSlowPathX86 : public SlowPathCode { // Live registers will be restored in the catch block if caught. SaveLiveRegisters(codegen, instruction_->GetLocations()); } - x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowNullPointer), + x86_codegen->InvokeRuntime(kQuickThrowNullPointer, instruction_, instruction_->GetDexPc(), this); @@ -88,10 +88,7 @@ class DivZeroCheckSlowPathX86 : public SlowPathCode { // Live registers will be restored in the catch block if caught. SaveLiveRegisters(codegen, instruction_->GetLocations()); } - x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowDivZero), - instruction_, - instruction_->GetDexPc(), - this); + x86_codegen->InvokeRuntime(kQuickThrowDivZero, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickThrowDivZero, void, void>(); } @@ -165,13 +162,10 @@ class BoundsCheckSlowPathX86 : public SlowPathCode { length_loc, Location::RegisterLocation(calling_convention.GetRegisterAt(1)), Primitive::kPrimInt); - uint32_t entry_point_offset = instruction_->AsBoundsCheck()->IsStringCharAt() - ? QUICK_ENTRY_POINT(pThrowStringBounds) - : QUICK_ENTRY_POINT(pThrowArrayBounds); - x86_codegen->InvokeRuntime(entry_point_offset, - instruction_, - instruction_->GetDexPc(), - this); + QuickEntrypointEnum entrypoint = instruction_->AsBoundsCheck()->IsStringCharAt() + ? kQuickThrowStringBounds + : kQuickThrowArrayBounds; + x86_codegen->InvokeRuntime(entrypoint, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickThrowStringBounds, void, int32_t, int32_t>(); CheckEntrypointTypes<kQuickThrowArrayBounds, void, int32_t, int32_t>(); } @@ -192,10 +186,7 @@ class SuspendCheckSlowPathX86 : public SlowPathCode { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorX86* x86_codegen = down_cast<CodeGeneratorX86*>(codegen); __ Bind(GetEntryLabel()); - x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pTestSuspend), - instruction_, - instruction_->GetDexPc(), - this); + x86_codegen->InvokeRuntime(kQuickTestSuspend, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); if (successor_ == nullptr) { __ jmp(GetReturnLabel()); @@ -237,10 +228,7 @@ class LoadStringSlowPathX86 : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; const uint32_t string_index = instruction_->AsLoadString()->GetStringIndex(); __ movl(calling_convention.GetRegisterAt(0), Immediate(string_index)); - x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pResolveString), - instruction_, - instruction_->GetDexPc(), - this); + x86_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickResolveString, void*, uint32_t>(); x86_codegen->Move32(locations->Out(), Location::RegisterLocation(EAX)); RestoreLiveRegisters(codegen, locations); @@ -272,8 +260,8 @@ class LoadClassSlowPathX86 : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; __ movl(calling_convention.GetRegisterAt(0), Immediate(cls_->GetTypeIndex())); - x86_codegen->InvokeRuntime(do_clinit_ ? QUICK_ENTRY_POINT(pInitializeStaticStorage) - : QUICK_ENTRY_POINT(pInitializeType), + x86_codegen->InvokeRuntime(do_clinit_ ? kQuickInitializeStaticStorage + : kQuickInitializeType, at_, dex_pc_, this); if (do_clinit_) { CheckEntrypointTypes<kQuickInitializeStaticStorage, void*, uint32_t>(); @@ -342,7 +330,7 @@ class TypeCheckSlowPathX86 : public SlowPathCode { Primitive::kPrimNot); if (instruction_->IsInstanceOf()) { - x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pInstanceofNonTrivial), + x86_codegen->InvokeRuntime(kQuickInstanceofNonTrivial, instruction_, instruction_->GetDexPc(), this); @@ -350,10 +338,7 @@ class TypeCheckSlowPathX86 : public SlowPathCode { kQuickInstanceofNonTrivial, size_t, const mirror::Class*, const mirror::Class*>(); } else { DCHECK(instruction_->IsCheckCast()); - x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pCheckCast), - instruction_, - instruction_->GetDexPc(), - this); + x86_codegen->InvokeRuntime(kQuickCheckCast, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickCheckCast, void, const mirror::Class*, const mirror::Class*>(); } @@ -385,10 +370,7 @@ class DeoptimizationSlowPathX86 : public SlowPathCode { CodeGeneratorX86* x86_codegen = down_cast<CodeGeneratorX86*>(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, instruction_->GetLocations()); - x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pDeoptimize), - instruction_, - instruction_->GetDexPc(), - this); + x86_codegen->InvokeRuntime(kQuickDeoptimize, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickDeoptimize, void, void>(); } @@ -427,10 +409,7 @@ class ArraySetSlowPathX86 : public SlowPathCode { codegen->GetMoveResolver()->EmitNativeCode(¶llel_move); CodeGeneratorX86* x86_codegen = down_cast<CodeGeneratorX86*>(codegen); - x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject), - instruction_, - instruction_->GetDexPc(), - this); + x86_codegen->InvokeRuntime(kQuickAputObject, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickAputObject, void, mirror::Array*, int32_t, mirror::Object*>(); RestoreLiveRegisters(codegen, locations); __ jmp(GetExitLabel()); @@ -648,10 +627,7 @@ class ReadBarrierForHeapReferenceSlowPathX86 : public SlowPathCode { codegen->GetMoveResolver()->EmitNativeCode(¶llel_move); __ movl(calling_convention.GetRegisterAt(2), Immediate(offset_)); } - x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pReadBarrierSlow), - instruction_, - instruction_->GetDexPc(), - this); + x86_codegen->InvokeRuntime(kQuickReadBarrierSlow, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes< kQuickReadBarrierSlow, mirror::Object*, mirror::Object*, mirror::Object*, uint32_t>(); x86_codegen->Move32(out_, Location::RegisterLocation(EAX)); @@ -715,7 +691,7 @@ class ReadBarrierForRootSlowPathX86 : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; CodeGeneratorX86* x86_codegen = down_cast<CodeGeneratorX86*>(codegen); x86_codegen->Move32(Location::RegisterLocation(calling_convention.GetRegisterAt(0)), root_); - x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pReadBarrierForRootSlow), + x86_codegen->InvokeRuntime(kQuickReadBarrierForRootSlow, instruction_, instruction_->GetDexPc(), this); @@ -808,25 +784,21 @@ void CodeGeneratorX86::InvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, uint32_t dex_pc, SlowPathCode* slow_path) { - InvokeRuntime(GetThreadOffset<kX86PointerSize>(entrypoint).Int32Value(), - instruction, - dex_pc, - slow_path); -} - -void CodeGeneratorX86::InvokeRuntime(int32_t entry_point_offset, - HInstruction* instruction, - uint32_t dex_pc, - SlowPathCode* slow_path) { ValidateInvokeRuntime(instruction, slow_path); - __ fs()->call(Address::Absolute(entry_point_offset)); - RecordPcInfo(instruction, dex_pc, slow_path); + GenerateInvokeRuntime(GetThreadOffset<kX86PointerSize>(entrypoint).Int32Value()); + if (EntrypointRequiresStackMap(entrypoint)) { + RecordPcInfo(instruction, dex_pc, slow_path); + } } void CodeGeneratorX86::InvokeRuntimeWithoutRecordingPcInfo(int32_t entry_point_offset, HInstruction* instruction, SlowPathCode* slow_path) { ValidateInvokeRuntimeWithoutRecordingPcInfo(instruction, slow_path); + GenerateInvokeRuntime(entry_point_offset); +} + +void CodeGeneratorX86::GenerateInvokeRuntime(int32_t entry_point_offset) { __ fs()->call(Address::Absolute(entry_point_offset)); } @@ -2597,19 +2569,13 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio case Primitive::kPrimFloat: // Processing a Dex `float-to-long' instruction. - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pF2l), - conversion, - conversion->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickF2l, conversion, conversion->GetDexPc()); CheckEntrypointTypes<kQuickF2l, int64_t, float>(); break; case Primitive::kPrimDouble: // Processing a Dex `double-to-long' instruction. - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pD2l), - conversion, - conversion->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickD2l, conversion, conversion->GetDexPc()); CheckEntrypointTypes<kQuickD2l, int64_t, double>(); break; @@ -3455,16 +3421,10 @@ void InstructionCodeGeneratorX86::GenerateDivRemIntegral(HBinaryOperation* instr DCHECK_EQ(EDX, out.AsRegisterPairHigh<Register>()); if (is_div) { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLdiv), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickLdiv, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickLdiv, int64_t, int64_t, int64_t>(); } else { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLmod), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickLmod, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickLmod, int64_t, int64_t, int64_t>(); } break; @@ -4044,10 +4004,7 @@ void InstructionCodeGeneratorX86::VisitNewInstance(HNewInstance* instruction) { __ call(Address(temp, code_offset.Int32Value())); codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); } else { - codegen_->InvokeRuntime(instruction->GetEntrypoint(), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocObjectWithAccessCheck, void*, uint32_t, ArtMethod*>(); DCHECK(!codegen_->IsLeafMethod()); } @@ -4068,10 +4025,7 @@ void InstructionCodeGeneratorX86::VisitNewArray(HNewArray* instruction) { __ movl(calling_convention.GetRegisterAt(0), Immediate(instruction->GetTypeIndex())); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. - codegen_->InvokeRuntime(instruction->GetEntrypoint(), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); DCHECK(!codegen_->IsLeafMethod()); } @@ -6069,10 +6023,7 @@ void InstructionCodeGeneratorX86::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pInitializeTypeAndVerifyAccess), - cls, - cls->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; } @@ -6313,10 +6264,7 @@ void LocationsBuilderX86::VisitThrow(HThrow* instruction) { } void InstructionCodeGeneratorX86::VisitThrow(HThrow* instruction) { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pDeliverException), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickDeliverException, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickDeliverException, void, mirror::Object*>(); } @@ -6761,11 +6709,10 @@ void LocationsBuilderX86::VisitMonitorOperation(HMonitorOperation* instruction) } void InstructionCodeGeneratorX86::VisitMonitorOperation(HMonitorOperation* instruction) { - codegen_->InvokeRuntime(instruction->IsEnter() ? QUICK_ENTRY_POINT(pLockObject) - : QUICK_ENTRY_POINT(pUnlockObject), + codegen_->InvokeRuntime(instruction->IsEnter() ? kQuickLockObject + : kQuickUnlockObject, instruction, - instruction->GetDexPc(), - nullptr); + instruction->GetDexPc()); if (instruction->IsEnter()) { CheckEntrypointTypes<kQuickLockObject, void, mirror::Object*>(); } else { diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index c644e401ff..df65fa2f4a 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -327,12 +327,7 @@ class CodeGeneratorX86 : public CodeGenerator { void InvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, uint32_t dex_pc, - SlowPathCode* slow_path) OVERRIDE; - - void InvokeRuntime(int32_t entry_point_offset, - HInstruction* instruction, - uint32_t dex_pc, - SlowPathCode* slow_path); + SlowPathCode* slow_path = nullptr) OVERRIDE; // Generate code to invoke a runtime entry point, but do not record // PC-related information in a stack map. @@ -340,6 +335,8 @@ class CodeGeneratorX86 : public CodeGenerator { HInstruction* instruction, SlowPathCode* slow_path); + void GenerateInvokeRuntime(int32_t entry_point_offset); + size_t GetWordSize() const OVERRIDE { return kX86WordSize; } diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 87b6de3f39..aef4cd7ef5 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -66,7 +66,7 @@ class NullCheckSlowPathX86_64 : public SlowPathCode { // Live registers will be restored in the catch block if caught. SaveLiveRegisters(codegen, instruction_->GetLocations()); } - x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowNullPointer), + x86_64_codegen->InvokeRuntime(kQuickThrowNullPointer, instruction_, instruction_->GetDexPc(), this); @@ -92,10 +92,7 @@ class DivZeroCheckSlowPathX86_64 : public SlowPathCode { // Live registers will be restored in the catch block if caught. SaveLiveRegisters(codegen, instruction_->GetLocations()); } - x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowDivZero), - instruction_, - instruction_->GetDexPc(), - this); + x86_64_codegen->InvokeRuntime(kQuickThrowDivZero, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickThrowDivZero, void, void>(); } @@ -149,10 +146,7 @@ class SuspendCheckSlowPathX86_64 : public SlowPathCode { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorX86_64* x86_64_codegen = down_cast<CodeGeneratorX86_64*>(codegen); __ Bind(GetEntryLabel()); - x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pTestSuspend), - instruction_, - instruction_->GetDexPc(), - this); + x86_64_codegen->InvokeRuntime(kQuickTestSuspend, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); if (successor_ == nullptr) { __ jmp(GetReturnLabel()); @@ -219,13 +213,10 @@ class BoundsCheckSlowPathX86_64 : public SlowPathCode { length_loc, Location::RegisterLocation(calling_convention.GetRegisterAt(1)), Primitive::kPrimInt); - uint32_t entry_point_offset = instruction_->AsBoundsCheck()->IsStringCharAt() - ? QUICK_ENTRY_POINT(pThrowStringBounds) - : QUICK_ENTRY_POINT(pThrowArrayBounds); - x86_64_codegen->InvokeRuntime(entry_point_offset, - instruction_, - instruction_->GetDexPc(), - this); + QuickEntrypointEnum entrypoint = instruction_->AsBoundsCheck()->IsStringCharAt() + ? kQuickThrowStringBounds + : kQuickThrowArrayBounds; + x86_64_codegen->InvokeRuntime(entrypoint, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickThrowStringBounds, void, int32_t, int32_t>(); CheckEntrypointTypes<kQuickThrowArrayBounds, void, int32_t, int32_t>(); } @@ -257,9 +248,7 @@ class LoadClassSlowPathX86_64 : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; __ movl(CpuRegister(calling_convention.GetRegisterAt(0)), Immediate(cls_->GetTypeIndex())); - x86_64_codegen->InvokeRuntime(do_clinit_ ? - QUICK_ENTRY_POINT(pInitializeStaticStorage) : - QUICK_ENTRY_POINT(pInitializeType), + x86_64_codegen->InvokeRuntime(do_clinit_ ? kQuickInitializeStaticStorage : kQuickInitializeType, at_, dex_pc_, this); @@ -314,7 +303,7 @@ class LoadStringSlowPathX86_64 : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; const uint32_t string_index = instruction_->AsLoadString()->GetStringIndex(); __ movl(CpuRegister(calling_convention.GetRegisterAt(0)), Immediate(string_index)); - x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pResolveString), + x86_64_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this); @@ -362,18 +351,12 @@ class TypeCheckSlowPathX86_64 : public SlowPathCode { Primitive::kPrimNot); if (instruction_->IsInstanceOf()) { - x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pInstanceofNonTrivial), - instruction_, - dex_pc, - this); + x86_64_codegen->InvokeRuntime(kQuickInstanceofNonTrivial, instruction_, dex_pc, this); CheckEntrypointTypes< kQuickInstanceofNonTrivial, size_t, const mirror::Class*, const mirror::Class*>(); } else { DCHECK(instruction_->IsCheckCast()); - x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pCheckCast), - instruction_, - dex_pc, - this); + x86_64_codegen->InvokeRuntime(kQuickCheckCast, instruction_, dex_pc, this); CheckEntrypointTypes<kQuickCheckCast, void, const mirror::Class*, const mirror::Class*>(); } @@ -406,10 +389,7 @@ class DeoptimizationSlowPathX86_64 : public SlowPathCode { CodeGeneratorX86_64* x86_64_codegen = down_cast<CodeGeneratorX86_64*>(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, instruction_->GetLocations()); - x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pDeoptimize), - instruction_, - instruction_->GetDexPc(), - this); + x86_64_codegen->InvokeRuntime(kQuickDeoptimize, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickDeoptimize, void, void>(); } @@ -448,10 +428,7 @@ class ArraySetSlowPathX86_64 : public SlowPathCode { codegen->GetMoveResolver()->EmitNativeCode(¶llel_move); CodeGeneratorX86_64* x86_64_codegen = down_cast<CodeGeneratorX86_64*>(codegen); - x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject), - instruction_, - instruction_->GetDexPc(), - this); + x86_64_codegen->InvokeRuntime(kQuickAputObject, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickAputObject, void, mirror::Array*, int32_t, mirror::Object*>(); RestoreLiveRegisters(codegen, locations); __ jmp(GetExitLabel()); @@ -666,7 +643,7 @@ class ReadBarrierForHeapReferenceSlowPathX86_64 : public SlowPathCode { codegen->GetMoveResolver()->EmitNativeCode(¶llel_move); __ movl(CpuRegister(calling_convention.GetRegisterAt(2)), Immediate(offset_)); } - x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pReadBarrierSlow), + x86_64_codegen->InvokeRuntime(kQuickReadBarrierSlow, instruction_, instruction_->GetDexPc(), this); @@ -734,7 +711,7 @@ class ReadBarrierForRootSlowPathX86_64 : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; CodeGeneratorX86_64* x86_64_codegen = down_cast<CodeGeneratorX86_64*>(codegen); x86_64_codegen->Move(Location::RegisterLocation(calling_convention.GetRegisterAt(0)), root_); - x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pReadBarrierForRootSlow), + x86_64_codegen->InvokeRuntime(kQuickReadBarrierForRootSlow, instruction_, instruction_->GetDexPc(), this); @@ -1036,25 +1013,21 @@ void CodeGeneratorX86_64::InvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, uint32_t dex_pc, SlowPathCode* slow_path) { - InvokeRuntime(GetThreadOffset<kX86_64PointerSize>(entrypoint).Int32Value(), - instruction, - dex_pc, - slow_path); -} - -void CodeGeneratorX86_64::InvokeRuntime(int32_t entry_point_offset, - HInstruction* instruction, - uint32_t dex_pc, - SlowPathCode* slow_path) { ValidateInvokeRuntime(instruction, slow_path); - __ gs()->call(Address::Absolute(entry_point_offset, /* no_rip */ true)); - RecordPcInfo(instruction, dex_pc, slow_path); + GenerateInvokeRuntime(GetThreadOffset<kX86_64PointerSize>(entrypoint).Int32Value()); + if (EntrypointRequiresStackMap(entrypoint)) { + RecordPcInfo(instruction, dex_pc, slow_path); + } } void CodeGeneratorX86_64::InvokeRuntimeWithoutRecordingPcInfo(int32_t entry_point_offset, HInstruction* instruction, SlowPathCode* slow_path) { ValidateInvokeRuntimeWithoutRecordingPcInfo(instruction, slow_path); + GenerateInvokeRuntime(entry_point_offset); +} + +void CodeGeneratorX86_64::GenerateInvokeRuntime(int32_t entry_point_offset) { __ gs()->call(Address::Absolute(entry_point_offset, /* no_rip */ true)); } @@ -3972,10 +3945,7 @@ void InstructionCodeGeneratorX86_64::VisitNewInstance(HNewInstance* instruction) __ call(Address(temp, code_offset.SizeValue())); codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); } else { - codegen_->InvokeRuntime(instruction->GetEntrypoint(), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocObjectWithAccessCheck, void*, uint32_t, ArtMethod*>(); DCHECK(!codegen_->IsLeafMethod()); } @@ -3997,10 +3967,7 @@ void InstructionCodeGeneratorX86_64::VisitNewArray(HNewArray* instruction) { instruction->GetTypeIndex()); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. - codegen_->InvokeRuntime(instruction->GetEntrypoint(), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); DCHECK(!codegen_->IsLeafMethod()); @@ -5495,10 +5462,7 @@ void InstructionCodeGeneratorX86_64::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pInitializeTypeAndVerifyAccess), - cls, - cls->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; } @@ -5715,10 +5679,7 @@ void LocationsBuilderX86_64::VisitThrow(HThrow* instruction) { } void InstructionCodeGeneratorX86_64::VisitThrow(HThrow* instruction) { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pDeliverException), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickDeliverException, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickDeliverException, void, mirror::Object*>(); } @@ -6216,11 +6177,9 @@ void LocationsBuilderX86_64::VisitMonitorOperation(HMonitorOperation* instructio } void InstructionCodeGeneratorX86_64::VisitMonitorOperation(HMonitorOperation* instruction) { - codegen_->InvokeRuntime(instruction->IsEnter() ? QUICK_ENTRY_POINT(pLockObject) - : QUICK_ENTRY_POINT(pUnlockObject), + codegen_->InvokeRuntime(instruction->IsEnter() ? kQuickLockObject : kQuickUnlockObject, instruction, - instruction->GetDexPc(), - nullptr); + instruction->GetDexPc()); if (instruction->IsEnter()) { CheckEntrypointTypes<kQuickLockObject, void, mirror::Object*>(); } else { diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h index 44844ac67a..f23bff5e1f 100644 --- a/compiler/optimizing/code_generator_x86_64.h +++ b/compiler/optimizing/code_generator_x86_64.h @@ -309,12 +309,7 @@ class CodeGeneratorX86_64 : public CodeGenerator { void InvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, uint32_t dex_pc, - SlowPathCode* slow_path) OVERRIDE; - - void InvokeRuntime(int32_t entry_point_offset, - HInstruction* instruction, - uint32_t dex_pc, - SlowPathCode* slow_path); + SlowPathCode* slow_path = nullptr) OVERRIDE; // Generate code to invoke a runtime entry point, but do not record // PC-related information in a stack map. @@ -322,6 +317,8 @@ class CodeGeneratorX86_64 : public CodeGenerator { HInstruction* instruction, SlowPathCode* slow_path); + void GenerateInvokeRuntime(int32_t entry_point_offset); + size_t GetWordSize() const OVERRIDE { return kX86_64WordSize; } diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc index e6e9c6552e..5239f8f020 100644 --- a/compiler/optimizing/intrinsics_mips.cc +++ b/compiler/optimizing/intrinsics_mips.cc @@ -1874,7 +1874,7 @@ void IntrinsicCodeGeneratorMIPS::VisitUnsafeCASObject(HInvoke* invoke) { // int java.lang.String.compareTo(String anotherString) void IntrinsicLocationsBuilderMIPS::VisitStringCompareTo(HInvoke* invoke) { LocationSummary* locations = new (arena_) LocationSummary(invoke, - LocationSummary::kCallOnMainOnly, + LocationSummary::kCallOnMainAndSlowPath, kIntrinsified); InvokeRuntimeCallingConvention calling_convention; locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); @@ -1894,13 +1894,7 @@ void IntrinsicCodeGeneratorMIPS::VisitStringCompareTo(HInvoke* invoke) { SlowPathCodeMIPS* slow_path = new (GetAllocator()) IntrinsicSlowPathMIPS(invoke); codegen_->AddSlowPath(slow_path); __ Beqz(argument, slow_path->GetEntryLabel()); - - __ LoadFromOffset(kLoadWord, - T9, - TR, - QUICK_ENTRYPOINT_OFFSET(kMipsPointerSize, pStringCompareTo).Int32Value()); - __ Jalr(T9); - __ NopIfNoReordering(); + codegen_->InvokeRuntime(kQuickStringCompareTo, invoke, invoke->GetDexPc(), slow_path); __ Bind(slow_path->GetExitLabel()); } @@ -2054,13 +2048,7 @@ static void GenerateStringIndexOf(HInvoke* invoke, __ Clear(tmp_reg); } - __ LoadFromOffset(kLoadWord, - T9, - TR, - QUICK_ENTRYPOINT_OFFSET(kMipsPointerSize, pIndexOf).Int32Value()); - __ Jalr(T9); - __ NopIfNoReordering(); - + codegen->InvokeRuntime(kQuickIndexOf, invoke, invoke->GetDexPc(), slow_path); if (slow_path != nullptr) { __ Bind(slow_path->GetExitLabel()); } @@ -2139,14 +2127,7 @@ void IntrinsicCodeGeneratorMIPS::VisitStringNewStringFromBytes(HInvoke* invoke) SlowPathCodeMIPS* slow_path = new (GetAllocator()) IntrinsicSlowPathMIPS(invoke); codegen_->AddSlowPath(slow_path); __ Beqz(byte_array, slow_path->GetEntryLabel()); - - __ LoadFromOffset(kLoadWord, - T9, - TR, - QUICK_ENTRYPOINT_OFFSET(kMipsPointerSize, pAllocStringFromBytes).Int32Value()); - __ Jalr(T9); - __ NopIfNoReordering(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); + codegen_->InvokeRuntime(kQuickAllocStringFromBytes, invoke, invoke->GetDexPc(), slow_path); __ Bind(slow_path->GetExitLabel()); } @@ -2164,22 +2145,13 @@ void IntrinsicLocationsBuilderMIPS::VisitStringNewStringFromChars(HInvoke* invok } void IntrinsicCodeGeneratorMIPS::VisitStringNewStringFromChars(HInvoke* invoke) { - MipsAssembler* assembler = GetAssembler(); - // No need to emit code checking whether `locations->InAt(2)` is a null // pointer, as callers of the native method // // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) // // all include a null check on `data` before calling that method. - - __ LoadFromOffset(kLoadWord, - T9, - TR, - QUICK_ENTRYPOINT_OFFSET(kMipsPointerSize, pAllocStringFromChars).Int32Value()); - __ Jalr(T9); - __ NopIfNoReordering(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); + codegen_->InvokeRuntime(kQuickAllocStringFromChars, invoke, invoke->GetDexPc()); } // java.lang.StringFactory.newStringFromString(String toCopy) @@ -2201,14 +2173,7 @@ void IntrinsicCodeGeneratorMIPS::VisitStringNewStringFromString(HInvoke* invoke) SlowPathCodeMIPS* slow_path = new (GetAllocator()) IntrinsicSlowPathMIPS(invoke); codegen_->AddSlowPath(slow_path); __ Beqz(string_to_copy, slow_path->GetEntryLabel()); - - __ LoadFromOffset(kLoadWord, - T9, - TR, - QUICK_ENTRYPOINT_OFFSET(kMipsPointerSize, pAllocStringFromString).Int32Value()); - __ Jalr(T9); - __ NopIfNoReordering(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); + codegen_->InvokeRuntime(kQuickAllocStringFromString, invoke, invoke->GetDexPc()); __ Bind(slow_path->GetExitLabel()); } diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc index 1e18540e1a..be8eb51e42 100644 --- a/compiler/optimizing/intrinsics_mips64.cc +++ b/compiler/optimizing/intrinsics_mips64.cc @@ -1519,7 +1519,7 @@ void IntrinsicCodeGeneratorMIPS64::VisitUnsafeCASObject(HInvoke* invoke) { // int java.lang.String.compareTo(String anotherString) void IntrinsicLocationsBuilderMIPS64::VisitStringCompareTo(HInvoke* invoke) { LocationSummary* locations = new (arena_) LocationSummary(invoke, - LocationSummary::kCallOnMainOnly, + LocationSummary::kCallOnMainAndSlowPath, kIntrinsified); InvokeRuntimeCallingConvention calling_convention; locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); @@ -1540,12 +1540,7 @@ void IntrinsicCodeGeneratorMIPS64::VisitStringCompareTo(HInvoke* invoke) { codegen_->AddSlowPath(slow_path); __ Beqzc(argument, slow_path->GetEntryLabel()); - __ LoadFromOffset(kLoadDoubleword, - T9, - TR, - QUICK_ENTRYPOINT_OFFSET(kMips64PointerSize, pStringCompareTo).Int32Value()); - __ Jalr(T9); - __ Nop(); + codegen_->InvokeRuntime(kQuickStringCompareTo, invoke, invoke->GetDexPc(), slow_path); __ Bind(slow_path->GetExitLabel()); } @@ -1691,13 +1686,8 @@ static void GenerateStringIndexOf(HInvoke* invoke, __ Clear(tmp_reg); } - __ LoadFromOffset(kLoadDoubleword, - T9, - TR, - QUICK_ENTRYPOINT_OFFSET(kMips64PointerSize, pIndexOf).Int32Value()); + codegen->InvokeRuntime(kQuickIndexOf, invoke, invoke->GetDexPc(), slow_path); CheckEntrypointTypes<kQuickIndexOf, int32_t, void*, uint32_t, uint32_t>(); - __ Jalr(T9); - __ Nop(); if (slow_path != nullptr) { __ Bind(slow_path->GetExitLabel()); @@ -1768,15 +1758,8 @@ void IntrinsicCodeGeneratorMIPS64::VisitStringNewStringFromBytes(HInvoke* invoke codegen_->AddSlowPath(slow_path); __ Beqzc(byte_array, slow_path->GetEntryLabel()); - __ LoadFromOffset(kLoadDoubleword, - T9, - TR, - QUICK_ENTRYPOINT_OFFSET(kMips64PointerSize, - pAllocStringFromBytes).Int32Value()); + codegen_->InvokeRuntime(kQuickAllocStringFromBytes, invoke, invoke->GetDexPc(), slow_path); CheckEntrypointTypes<kQuickAllocStringFromBytes, void*, void*, int32_t, int32_t, int32_t>(); - __ Jalr(T9); - __ Nop(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); __ Bind(slow_path->GetExitLabel()); } @@ -1794,23 +1777,14 @@ void IntrinsicLocationsBuilderMIPS64::VisitStringNewStringFromChars(HInvoke* inv } void IntrinsicCodeGeneratorMIPS64::VisitStringNewStringFromChars(HInvoke* invoke) { - Mips64Assembler* assembler = GetAssembler(); - // No need to emit code checking whether `locations->InAt(2)` is a null // pointer, as callers of the native method // // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) // // all include a null check on `data` before calling that method. - __ LoadFromOffset(kLoadDoubleword, - T9, - TR, - QUICK_ENTRYPOINT_OFFSET(kMips64PointerSize, - pAllocStringFromChars).Int32Value()); + codegen_->InvokeRuntime(kQuickAllocStringFromChars, invoke, invoke->GetDexPc()); CheckEntrypointTypes<kQuickAllocStringFromChars, void*, int32_t, int32_t, void*>(); - __ Jalr(T9); - __ Nop(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); } // java.lang.StringFactory.newStringFromString(String toCopy) @@ -1833,15 +1807,8 @@ void IntrinsicCodeGeneratorMIPS64::VisitStringNewStringFromString(HInvoke* invok codegen_->AddSlowPath(slow_path); __ Beqzc(string_to_copy, slow_path->GetEntryLabel()); - __ LoadFromOffset(kLoadDoubleword, - T9, - TR, - QUICK_ENTRYPOINT_OFFSET(kMips64PointerSize, - pAllocStringFromString).Int32Value()); + codegen_->InvokeRuntime(kQuickAllocStringFromString, invoke, invoke->GetDexPc(), slow_path); CheckEntrypointTypes<kQuickAllocStringFromString, void*, void*>(); - __ Jalr(T9); - __ Nop(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); __ Bind(slow_path->GetExitLabel()); } diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc index cf4a040551..ef4d0f1d2e 100644 --- a/compiler/optimizing/intrinsics_x86.cc +++ b/compiler/optimizing/intrinsics_x86.cc @@ -963,7 +963,7 @@ static void GenFPToFPCall(HInvoke* invoke, CodeGeneratorX86* codegen, QuickEntry } // Now do the actual call. - __ fs()->call(Address::Absolute(GetThreadOffset<kX86PointerSize>(entry))); + codegen->InvokeRuntime(entry, invoke, invoke->GetDexPc()); // Extract the return value from the FP stack. __ fstpl(Address(ESP, 0)); @@ -972,8 +972,6 @@ static void GenFPToFPCall(HInvoke* invoke, CodeGeneratorX86* codegen, QuickEntry // And clean up the stack. __ addl(ESP, Immediate(16)); __ cfi().AdjustCFAOffset(-16); - - codegen->RecordPcInfo(invoke, invoke->GetDexPc()); } void IntrinsicLocationsBuilderX86::VisitMathCos(HInvoke* invoke) { @@ -1343,7 +1341,7 @@ void IntrinsicCodeGeneratorX86::VisitStringCompareTo(HInvoke* invoke) { codegen_->AddSlowPath(slow_path); __ j(kEqual, slow_path->GetEntryLabel()); - __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86PointerSize, pStringCompareTo))); + codegen_->InvokeRuntime(kQuickStringCompareTo, invoke, invoke->GetDexPc(), slow_path); __ Bind(slow_path->GetExitLabel()); } @@ -1616,9 +1614,8 @@ void IntrinsicCodeGeneratorX86::VisitStringNewStringFromBytes(HInvoke* invoke) { codegen_->AddSlowPath(slow_path); __ j(kEqual, slow_path->GetEntryLabel()); - __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86PointerSize, pAllocStringFromBytes))); + codegen_->InvokeRuntime(kQuickAllocStringFromBytes, invoke, invoke->GetDexPc()); CheckEntrypointTypes<kQuickAllocStringFromBytes, void*, void*, int32_t, int32_t, int32_t>(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); __ Bind(slow_path->GetExitLabel()); } @@ -1634,17 +1631,14 @@ void IntrinsicLocationsBuilderX86::VisitStringNewStringFromChars(HInvoke* invoke } void IntrinsicCodeGeneratorX86::VisitStringNewStringFromChars(HInvoke* invoke) { - X86Assembler* assembler = GetAssembler(); - // No need to emit code checking whether `locations->InAt(2)` is a null // pointer, as callers of the native method // // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) // // all include a null check on `data` before calling that method. - __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86PointerSize, pAllocStringFromChars))); + codegen_->InvokeRuntime(kQuickAllocStringFromChars, invoke, invoke->GetDexPc()); CheckEntrypointTypes<kQuickAllocStringFromChars, void*, int32_t, int32_t, void*>(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); } void IntrinsicLocationsBuilderX86::VisitStringNewStringFromString(HInvoke* invoke) { @@ -1666,10 +1660,8 @@ void IntrinsicCodeGeneratorX86::VisitStringNewStringFromString(HInvoke* invoke) codegen_->AddSlowPath(slow_path); __ j(kEqual, slow_path->GetEntryLabel()); - __ fs()->call( - Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86PointerSize, pAllocStringFromString))); + codegen_->InvokeRuntime(kQuickAllocStringFromString, invoke, invoke->GetDexPc()); CheckEntrypointTypes<kQuickAllocStringFromString, void*, void*>(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); __ Bind(slow_path->GetExitLabel()); } diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc index a4ee546237..c7e30071f0 100644 --- a/compiler/optimizing/intrinsics_x86_64.cc +++ b/compiler/optimizing/intrinsics_x86_64.cc @@ -766,10 +766,8 @@ static void GenFPToFPCall(HInvoke* invoke, CodeGeneratorX86_64* codegen, LocationSummary* locations = invoke->GetLocations(); DCHECK(locations->WillCall()); DCHECK(invoke->IsInvokeStaticOrDirect()); - X86_64Assembler* assembler = codegen->GetAssembler(); - __ gs()->call(Address::Absolute(GetThreadOffset<kX86_64PointerSize>(entry), true)); - codegen->RecordPcInfo(invoke, invoke->GetDexPc()); + codegen->InvokeRuntime(entry, invoke, invoke->GetDexPc()); } void IntrinsicLocationsBuilderX86_64::VisitMathCos(HInvoke* invoke) { @@ -1510,8 +1508,7 @@ void IntrinsicCodeGeneratorX86_64::VisitStringCompareTo(HInvoke* invoke) { codegen_->AddSlowPath(slow_path); __ j(kEqual, slow_path->GetEntryLabel()); - __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86_64PointerSize, pStringCompareTo), - /* no_rip */ true)); + codegen_->InvokeRuntime(kQuickStringCompareTo, invoke, invoke->GetDexPc(), slow_path); __ Bind(slow_path->GetExitLabel()); } @@ -1783,11 +1780,8 @@ void IntrinsicCodeGeneratorX86_64::VisitStringNewStringFromBytes(HInvoke* invoke codegen_->AddSlowPath(slow_path); __ j(kEqual, slow_path->GetEntryLabel()); - __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86_64PointerSize, - pAllocStringFromBytes), - /* no_rip */ true)); + codegen_->InvokeRuntime(kQuickAllocStringFromBytes, invoke, invoke->GetDexPc()); CheckEntrypointTypes<kQuickAllocStringFromBytes, void*, void*, int32_t, int32_t, int32_t>(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); __ Bind(slow_path->GetExitLabel()); } @@ -1803,19 +1797,14 @@ void IntrinsicLocationsBuilderX86_64::VisitStringNewStringFromChars(HInvoke* inv } void IntrinsicCodeGeneratorX86_64::VisitStringNewStringFromChars(HInvoke* invoke) { - X86_64Assembler* assembler = GetAssembler(); - // No need to emit code checking whether `locations->InAt(2)` is a null // pointer, as callers of the native method // // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) // // all include a null check on `data` before calling that method. - __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86_64PointerSize, - pAllocStringFromChars), - /* no_rip */ true)); + codegen_->InvokeRuntime(kQuickAllocStringFromChars, invoke, invoke->GetDexPc()); CheckEntrypointTypes<kQuickAllocStringFromChars, void*, int32_t, int32_t, void*>(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); } void IntrinsicLocationsBuilderX86_64::VisitStringNewStringFromString(HInvoke* invoke) { @@ -1837,11 +1826,8 @@ void IntrinsicCodeGeneratorX86_64::VisitStringNewStringFromString(HInvoke* invok codegen_->AddSlowPath(slow_path); __ j(kEqual, slow_path->GetEntryLabel()); - __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86_64PointerSize, - pAllocStringFromString), - /* no_rip */ true)); + codegen_->InvokeRuntime(kQuickAllocStringFromString, invoke, invoke->GetDexPc()); CheckEntrypointTypes<kQuickAllocStringFromString, void*, void*>(); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); __ Bind(slow_path->GetExitLabel()); } diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 62e39f5a0b..19e499ba8c 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -5021,7 +5021,7 @@ class HInstanceFieldGet FINAL : public HExpression<1> { Handle<mirror::DexCache> dex_cache, uint32_t dex_pc) : HExpression(field_type, - SideEffects::FieldReadOfType(field_type, is_volatile), + SideEffectsForArchRuntimeCalls(field_type, is_volatile), dex_pc), field_info_(field_offset, field_type, @@ -5053,6 +5053,16 @@ class HInstanceFieldGet FINAL : public HExpression<1> { Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); } bool IsVolatile() const { return field_info_.IsVolatile(); } + static SideEffects SideEffectsForArchRuntimeCalls(Primitive::Type field_type, bool is_volatile) { + SideEffects side_effects = SideEffects::FieldReadOfType(field_type, is_volatile); + + // MIPS delegates volatile kPrimLong and kPrimDouble loads to a runtime helper. + if (Primitive::Is64BitType(field_type)) { + side_effects.Add(SideEffects::CanTriggerGC()); + } + return side_effects; + } + DECLARE_INSTRUCTION(InstanceFieldGet); private: @@ -5073,7 +5083,7 @@ class HInstanceFieldSet FINAL : public HTemplateInstruction<2> { const DexFile& dex_file, Handle<mirror::DexCache> dex_cache, uint32_t dex_pc) - : HTemplateInstruction(SideEffects::FieldWriteOfType(field_type, is_volatile), + : HTemplateInstruction(SideEffectsForArchRuntimeCalls(field_type, is_volatile), dex_pc), field_info_(field_offset, field_type, @@ -5099,6 +5109,16 @@ class HInstanceFieldSet FINAL : public HTemplateInstruction<2> { bool GetValueCanBeNull() const { return GetPackedFlag<kFlagValueCanBeNull>(); } void ClearValueCanBeNull() { SetPackedFlag<kFlagValueCanBeNull>(false); } + static SideEffects SideEffectsForArchRuntimeCalls(Primitive::Type field_type, bool is_volatile) { + SideEffects side_effects = SideEffects::FieldWriteOfType(field_type, is_volatile); + + // MIPS delegates volatile kPrimLong and kPrimDouble stores to a runtime helper. + if (Primitive::Is64BitType(field_type)) { + side_effects.Add(SideEffects::CanTriggerGC()); + } + return side_effects; + } + DECLARE_INSTRUCTION(InstanceFieldSet); private: @@ -5896,7 +5916,7 @@ class HStaticFieldGet FINAL : public HExpression<1> { Handle<mirror::DexCache> dex_cache, uint32_t dex_pc) : HExpression(field_type, - SideEffects::FieldReadOfType(field_type, is_volatile), + SideEffectsForArchRuntimeCalls(field_type, is_volatile), dex_pc), field_info_(field_offset, field_type, @@ -5925,6 +5945,16 @@ class HStaticFieldGet FINAL : public HExpression<1> { Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); } bool IsVolatile() const { return field_info_.IsVolatile(); } + static SideEffects SideEffectsForArchRuntimeCalls(Primitive::Type field_type, bool is_volatile) { + SideEffects side_effects = SideEffects::FieldReadOfType(field_type, is_volatile); + + // MIPS delegates volatile kPrimLong and kPrimDouble loads to a runtime helper. + if (Primitive::Is64BitType(field_type)) { + side_effects.Add(SideEffects::CanTriggerGC()); + } + return side_effects; + } + DECLARE_INSTRUCTION(StaticFieldGet); private: @@ -5945,7 +5975,7 @@ class HStaticFieldSet FINAL : public HTemplateInstruction<2> { const DexFile& dex_file, Handle<mirror::DexCache> dex_cache, uint32_t dex_pc) - : HTemplateInstruction(SideEffects::FieldWriteOfType(field_type, is_volatile), + : HTemplateInstruction(SideEffectsForArchRuntimeCalls(field_type, is_volatile), dex_pc), field_info_(field_offset, field_type, @@ -5968,6 +5998,16 @@ class HStaticFieldSet FINAL : public HTemplateInstruction<2> { bool GetValueCanBeNull() const { return GetPackedFlag<kFlagValueCanBeNull>(); } void ClearValueCanBeNull() { SetPackedFlag<kFlagValueCanBeNull>(false); } + static SideEffects SideEffectsForArchRuntimeCalls(Primitive::Type field_type, bool is_volatile) { + SideEffects side_effects = SideEffects::FieldWriteOfType(field_type, is_volatile); + + // MIPS delegates volatile kPrimLong and kPrimDouble stores to a runtime helper. + if (Primitive::Is64BitType(field_type)) { + side_effects.Add(SideEffects::CanTriggerGC()); + } + return side_effects; + } + DECLARE_INSTRUCTION(StaticFieldSet); private: |