diff options
| author | 2016-07-14 09:21:59 +0100 | |
|---|---|---|
| committer | 2016-08-31 17:22:54 +0100 | |
| commit | fca16663334e5838790631d8eac95f4ffdb0cc2e (patch) | |
| tree | 2a1f018b428ef0f4097004af92ab44c82e987d12 | |
| parent | ba45db072c48783e19a2a73ab4e45ae143c1c7c9 (diff) | |
Extend the InvokeRuntime() changes to mips.
Also fix the side effects for <Static/Instance>Field<Get/Set>.
Test: test-art-target
Change-Id: Ia4284ccd9d0c88210eaa4458f74728c805e2e076
| -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/intrinsics_mips.cc | 47 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.h | 48 | ||||
| -rw-r--r-- | runtime/entrypoints/quick/quick_entrypoints_enum.cc | 5 |
5 files changed, 98 insertions, 195 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index e0de03bf8f..cec3ca1103 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -170,14 +170,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>(); } @@ -201,11 +197,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>(); } @@ -237,12 +229,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 { @@ -295,11 +284,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(), @@ -327,11 +312,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>(); } @@ -351,11 +335,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()); @@ -407,11 +387,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(); @@ -419,11 +395,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*>(); } @@ -446,11 +418,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>(); } @@ -1245,28 +1213,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. @@ -1276,7 +1233,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, @@ -2080,11 +2039,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; @@ -2650,11 +2605,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; } @@ -3640,11 +3591,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. @@ -3792,11 +3739,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)) { @@ -4380,11 +4323,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; } @@ -4652,18 +4591,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*>(); } @@ -4838,12 +4769,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*>(); } @@ -4872,12 +4798,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*>(); } } @@ -5062,27 +4983,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; } @@ -5263,11 +5174,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*>(); } @@ -5388,15 +5295,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 { @@ -5489,11 +5390,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/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc index 862a93f9d6..99ad898fd6 100644 --- a/compiler/optimizing/intrinsics_mips.cc +++ b/compiler/optimizing/intrinsics_mips.cc @@ -1875,7 +1875,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))); @@ -1895,13 +1895,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()); } @@ -2055,13 +2049,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()); } @@ -2140,14 +2128,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()); } @@ -2165,22 +2146,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) @@ -2202,14 +2174,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/nodes.h b/compiler/optimizing/nodes.h index dfa8276651..94913fc562 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: diff --git a/runtime/entrypoints/quick/quick_entrypoints_enum.cc b/runtime/entrypoints/quick/quick_entrypoints_enum.cc index 5153f0f48e..7b80af6477 100644 --- a/runtime/entrypoints/quick/quick_entrypoints_enum.cc +++ b/runtime/entrypoints/quick/quick_entrypoints_enum.cc @@ -61,6 +61,11 @@ bool EntrypointRequiresStackMap(QuickEntrypointEnum trampoline) { case kQuickUshrLong: return false; + /* Used by mips for 64bit volatile load/stores. */ + case kQuickA64Load: + case kQuickA64Store: + return false; + default: return true; } |