From 36cddbd7494ce59c8aeca52ed90d49df9eaa12e7 Mon Sep 17 00:00:00 2001 From: "vegorov@google.com" Date: Thu, 24 Jul 2014 12:04:21 +0000 Subject: [PATCH] Use shorter TryAllocate instruction sequence on ARM/ARM64/MIPS. On these architectures it's preferable to load Scavenger address into the register and then access top/end fields through this register instead of loading addresses of those fields as immediates --- which takes either two instructions or a memory load through a pool pointer. Cleanup boxing slow-paths in the optimizing compiler. We had tons of duplicated code that was essentially doing the same thing. BUG= R=johnmccutchan@google.com, regis@google.com Review URL: https://codereview.chromium.org//410333003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@38539 260f80e4-7a28-3924-810f-c04153c831b5 --- runtime/vm/assembler.cc | 7 +- runtime/vm/assembler_arm.cc | 15 +- runtime/vm/assembler_arm.h | 1 + runtime/vm/assembler_arm64.cc | 11 +- runtime/vm/assembler_arm64.h | 2 + runtime/vm/assembler_ia32.h | 2 + runtime/vm/assembler_mips.cc | 11 +- runtime/vm/assembler_mips.h | 1 + runtime/vm/assembler_x64.h | 2 + runtime/vm/flow_graph_compiler.cc | 2 + runtime/vm/flow_graph_compiler.h | 2 + runtime/vm/heap.h | 1 + runtime/vm/intermediate_language_arm.cc | 444 ++++++--------------- runtime/vm/intermediate_language_arm64.cc | 382 ++++++------------ runtime/vm/intermediate_language_ia32.cc | 454 +++++----------------- runtime/vm/intermediate_language_mips.cc | 153 +++----- runtime/vm/intermediate_language_x64.cc | 384 +++++------------- runtime/vm/intrinsifier_arm64.cc | 9 +- 18 files changed, 542 insertions(+), 1341 deletions(-) diff --git a/runtime/vm/assembler.cc b/runtime/vm/assembler.cc index 65e56276cd1..f259071c1d8 100644 --- a/runtime/vm/assembler.cc +++ b/runtime/vm/assembler.cc @@ -210,7 +210,7 @@ void Assembler::Unreachable(const char* message) { void Assembler::Comment(const char* format, ...) { - if (FLAG_code_comments || FLAG_disassemble || FLAG_disassemble_optimized) { + if (EmittingComments()) { char buffer[1024]; va_list args; @@ -225,6 +225,11 @@ void Assembler::Comment(const char* format, ...) { } +bool Assembler::EmittingComments() { + return FLAG_code_comments || FLAG_disassemble || FLAG_disassemble_optimized; +} + + const Code::Comments& Assembler::GetCodeComments() const { Code::Comments& comments = Code::Comments::New(comments_.length()); diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc index 2ddf07cabf4..6ae73b14040 100644 --- a/runtime/vm/assembler_arm.cc +++ b/runtime/vm/assembler_arm.cc @@ -3146,23 +3146,24 @@ void Assembler::TryAllocate(const Class& cls, Register temp_reg) { ASSERT(failure != NULL); if (FLAG_inline_alloc) { - Heap* heap = Isolate::Current()->heap(); + ASSERT(instance_reg != temp_reg); + ASSERT(temp_reg != IP); const intptr_t instance_size = cls.instance_size(); - LoadImmediate(instance_reg, heap->TopAddress()); - ldr(instance_reg, Address(instance_reg, 0)); + + LoadImmediate(temp_reg, Isolate::Current()->heap()->NewSpaceAddress()); + + ldr(instance_reg, Address(temp_reg, Scavenger::top_offset())); AddImmediate(instance_reg, instance_size); // instance_reg: potential next object start. - LoadImmediate(IP, heap->EndAddress()); - ldr(IP, Address(IP, 0)); + ldr(IP, Address(temp_reg, Scavenger::end_offset())); cmp(IP, Operand(instance_reg)); // fail if heap end unsigned less than or equal to instance_reg. b(failure, LS); // Successfully allocated the object, now update top to point to // next object start and store the class in the class field of object. - LoadImmediate(IP, heap->TopAddress()); - str(instance_reg, Address(IP, 0)); + str(instance_reg, Address(temp_reg, Scavenger::top_offset())); ASSERT(instance_size >= kHeapObjectTag); AddImmediate(instance_reg, -instance_size + kHeapObjectTag); diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h index a09145a0a07..fc66dec6ba8 100644 --- a/runtime/vm/assembler_arm.h +++ b/runtime/vm/assembler_arm.h @@ -337,6 +337,7 @@ class Assembler : public ValueObject { static void InitializeMemoryWithBreakpoints(uword data, intptr_t length); void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); + static bool EmittingComments(); const Code::Comments& GetCodeComments() const; diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc index 6da9770ad99..7911896dc55 100644 --- a/runtime/vm/assembler_arm64.cc +++ b/runtime/vm/assembler_arm64.cc @@ -1376,26 +1376,25 @@ void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, void Assembler::TryAllocate(const Class& cls, Label* failure, Register instance_reg, + Register temp_reg, Register pp) { ASSERT(failure != NULL); if (FLAG_inline_alloc) { Heap* heap = Isolate::Current()->heap(); const intptr_t instance_size = cls.instance_size(); - LoadImmediate(instance_reg, heap->TopAddress(), pp); - ldr(instance_reg, Address(instance_reg)); + LoadImmediate(temp_reg, heap->NewSpaceAddress(), pp); + ldr(instance_reg, Address(temp_reg, Scavenger::top_offset())); AddImmediate(instance_reg, instance_reg, instance_size, pp); // instance_reg: potential next object start. - LoadImmediate(TMP, heap->EndAddress(), pp); - ldr(TMP, Address(TMP)); + ldr(TMP, Address(temp_reg, Scavenger::end_offset())); CompareRegisters(TMP, instance_reg); // fail if heap end unsigned less than or equal to instance_reg. b(failure, LS); // Successfully allocated the object, now update top to point to // next object start and store the class in the class field of object. - LoadImmediate(TMP, heap->TopAddress(), pp); - str(instance_reg, Address(TMP)); + str(instance_reg, Address(temp_reg, Scavenger::top_offset())); ASSERT(instance_size >= kHeapObjectTag); AddImmediate( diff --git a/runtime/vm/assembler_arm64.h b/runtime/vm/assembler_arm64.h index 03224f68f37..ac082d1913b 100644 --- a/runtime/vm/assembler_arm64.h +++ b/runtime/vm/assembler_arm64.h @@ -431,6 +431,7 @@ class Assembler : public ValueObject { static void InitializeMemoryWithBreakpoints(uword data, intptr_t length); void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); + static bool EmittingComments(); const Code::Comments& GetCodeComments() const; @@ -1217,6 +1218,7 @@ class Assembler : public ValueObject { void TryAllocate(const Class& cls, Label* failure, Register instance_reg, + Register temp_reg, Register pp); Address ElementAddressForIntIndex(bool is_external, diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h index bd11704ad04..8ec66e1d6fb 100644 --- a/runtime/vm/assembler_ia32.h +++ b/runtime/vm/assembler_ia32.h @@ -821,6 +821,8 @@ class Assembler : public ValueObject { static void InitializeMemoryWithBreakpoints(uword data, intptr_t length); void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); + static bool EmittingComments(); + const Code::Comments& GetCodeComments() const; static const char* RegisterName(Register reg); diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc index 3cfcdea85b4..802dd494e93 100644 --- a/runtime/vm/assembler_mips.cc +++ b/runtime/vm/assembler_mips.cc @@ -858,20 +858,19 @@ void Assembler::TryAllocate(const Class& cls, if (FLAG_inline_alloc) { Heap* heap = Isolate::Current()->heap(); const intptr_t instance_size = cls.instance_size(); - LoadImmediate(instance_reg, heap->TopAddress()); - lw(instance_reg, Address(instance_reg, 0)); + + LoadImmediate(temp_reg, heap->NewSpaceAddress()); + lw(instance_reg, Address(temp_reg, Scavenger::top_offset())); AddImmediate(instance_reg, instance_size); // instance_reg: potential next object start. - LoadImmediate(TMP, heap->EndAddress()); - lw(TMP, Address(TMP, 0)); + lw(TMP, Address(temp_reg, Scavenger::end_offset())); // Fail if heap end unsigned less than or equal to instance_reg. BranchUnsignedLessEqual(TMP, instance_reg, failure); // Successfully allocated the object, now update top to point to // next object start and store the class in the class field of object. - LoadImmediate(TMP, heap->TopAddress()); - sw(instance_reg, Address(TMP, 0)); + sw(instance_reg, Address(temp_reg, Scavenger::top_offset())); ASSERT(instance_size >= kHeapObjectTag); AddImmediate(instance_reg, -instance_size + kHeapObjectTag); diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h index d5ee12ee9fc..f5199b8117c 100644 --- a/runtime/vm/assembler_mips.h +++ b/runtime/vm/assembler_mips.h @@ -227,6 +227,7 @@ class Assembler : public ValueObject { static void InitializeMemoryWithBreakpoints(uword data, intptr_t length); void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); + static bool EmittingComments(); const Code::Comments& GetCodeComments() const; diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h index 6644ae1bdba..e589dfe2d4d 100644 --- a/runtime/vm/assembler_x64.h +++ b/runtime/vm/assembler_x64.h @@ -770,6 +770,8 @@ class Assembler : public ValueObject { void Bind(Label* label); void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); + static bool EmittingComments(); + const Code::Comments& GetCodeComments() const; intptr_t CodeSize() const { return buffer_.Size(); } diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc index 0de5492944f..de1786b4c88 100644 --- a/runtime/vm/flow_graph_compiler.cc +++ b/runtime/vm/flow_graph_compiler.cc @@ -94,6 +94,8 @@ FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, may_reoptimize_(false), double_class_(Class::ZoneHandle( isolate_->object_store()->double_class())), + mint_class_(Class::ZoneHandle( + isolate_->object_store()->mint_class())), float32x4_class_(Class::ZoneHandle( isolate_->object_store()->float32x4_class())), float64x2_class_(Class::ZoneHandle( diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h index b7b0cb64020..efb880499d2 100644 --- a/runtime/vm/flow_graph_compiler.h +++ b/runtime/vm/flow_graph_compiler.h @@ -445,6 +445,7 @@ class FlowGraphCompiler : public ValueObject { void FinalizeStaticCallTargetsTable(const Code& code); const Class& double_class() const { return double_class_; } + const Class& mint_class() const { return mint_class_; } const Class& float32x4_class() const { return float32x4_class_; } const Class& float64x2_class() const { return float64x2_class_; } const Class& int32x4_class() const { return int32x4_class_; } @@ -611,6 +612,7 @@ class FlowGraphCompiler : public ValueObject { bool may_reoptimize_; const Class& double_class_; + const Class& mint_class_; const Class& float32x4_class_; const Class& float64x2_class_; const Class& int32x4_class_; diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h index 71354e382ad..7de2daf7513 100644 --- a/runtime/vm/heap.h +++ b/runtime/vm/heap.h @@ -164,6 +164,7 @@ class Heap { uword TopAddress(); uword EndAddress(); static intptr_t new_space_offset() { return OFFSET_OF(Heap, new_space_); } + uword NewSpaceAddress() const { return reinterpret_cast(new_space_); } // Initialize the heap and register it with the isolate. static void Init(Isolate* isolate, diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc index 81cbe5f5f91..c619a17b09c 100644 --- a/runtime/vm/intermediate_language_arm.cc +++ b/runtime/vm/intermediate_language_arm.cc @@ -1827,17 +1827,24 @@ void GuardFieldLengthInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } -class StoreInstanceFieldSlowPath : public SlowPathCode { +class BoxAllocationSlowPath : public SlowPathCode { public: - StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, - const Class& cls) - : instruction_(instruction), cls_(cls) { } + BoxAllocationSlowPath(Instruction* instruction, + const Class& cls, + Register result) + : instruction_(instruction), + cls_(cls), + result_(result) { } virtual void EmitNativeCode(FlowGraphCompiler* compiler) { Isolate* isolate = compiler->isolate(); StubCode* stub_code = isolate->stub_code(); - __ Comment("StoreInstanceFieldSlowPath"); + if (Assembler::EmittingComments()) { + __ Comment("%s slow path allocation of %s", + instruction_->DebugName(), + String::Handle(cls_.PrettyName()).ToCString()); + } __ Bind(entry_label()); const Code& stub = @@ -1845,22 +1852,40 @@ class StoreInstanceFieldSlowPath : public SlowPathCode { const ExternalLabel label(stub.EntryPoint()); LocationSummary* locs = instruction_->locs(); - locs->live_registers()->Remove(locs->temp(0)); + + locs->live_registers()->Remove(Location::RegisterLocation(result_)); compiler->SaveLiveRegisters(locs); compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. &label, RawPcDescriptors::kOther, locs); - __ MoveRegister(locs->temp(0).reg(), R0); + __ MoveRegister(result_, R0); compiler->RestoreLiveRegisters(locs); __ b(exit_label()); } + static void Allocate(FlowGraphCompiler* compiler, + Instruction* instruction, + const Class& cls, + Register result, + Register temp) { + BoxAllocationSlowPath* slow_path = + new BoxAllocationSlowPath(instruction, cls, result); + compiler->AddSlowPathCode(slow_path); + + __ TryAllocate(cls, + slow_path->entry_label(), + result, + temp); + __ Bind(slow_path->exit_label()); + } + private: - StoreInstanceFieldInstr* instruction_; + Instruction* instruction_; const Class& cls_; + Register result_; }; @@ -1899,6 +1924,28 @@ LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, } +static void EnsureMutableBox(FlowGraphCompiler* compiler, + StoreInstanceFieldInstr* instruction, + Register box_reg, + const Class& cls, + Register instance_reg, + intptr_t offset, + Register temp) { + Label done; + __ ldr(box_reg, FieldAddress(instance_reg, offset)); + __ CompareImmediate(box_reg, + reinterpret_cast(Object::null())); + __ b(&done, NE); + + BoxAllocationSlowPath::Allocate( + compiler, instruction, cls, box_reg, temp); + + __ MoveRegister(temp, box_reg); + __ StoreIntoObjectOffset(instance_reg, offset, temp); + __ Bind(&done); +} + + void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { Label skip_store; @@ -1926,15 +1973,8 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { UNREACHABLE(); } - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, *cls); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(*cls, - slow_path->entry_label(), - temp, - temp2); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, *cls, temp, temp2); __ MoveRegister(temp2, temp); __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); } else { @@ -2005,72 +2045,39 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_double); - Label copy_double; - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->double_class()); - compiler->AddSlowPathCode(slow_path); - - __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); - __ CompareImmediate(temp, - reinterpret_cast(Object::null())); - __ b(©_double, NE); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - temp, - temp2); - __ Bind(slow_path->exit_label()); - __ MoveRegister(temp2, temp); - __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); - __ Bind(©_double); + EnsureMutableBox(compiler, + this, + temp, + compiler->double_class(), + instance_reg, + offset_in_bytes_, + temp2); __ CopyDoubleField(temp, value_reg, TMP, temp2, fpu_temp); __ b(&skip_store); } { __ Bind(&store_float32x4); - Label copy_float32x4; - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->float32x4_class()); - compiler->AddSlowPathCode(slow_path); - - __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); - __ CompareImmediate(temp, - reinterpret_cast(Object::null())); - __ b(©_float32x4, NE); - - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - temp, - temp2); - __ Bind(slow_path->exit_label()); - __ MoveRegister(temp2, temp); - __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); - __ Bind(©_float32x4); + EnsureMutableBox(compiler, + this, + temp, + compiler->float32x4_class(), + instance_reg, + offset_in_bytes_, + temp2); __ CopyFloat32x4Field(temp, value_reg, TMP, temp2, fpu_temp); __ b(&skip_store); } { __ Bind(&store_float64x2); - Label copy_float64x2; - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); - compiler->AddSlowPathCode(slow_path); - - __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); - __ CompareImmediate(temp, - reinterpret_cast(Object::null())); - __ b(©_float64x2, NE); - - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - temp, - temp2); - __ Bind(slow_path->exit_label()); - __ MoveRegister(temp2, temp); - __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); - __ Bind(©_float64x2); + EnsureMutableBox(compiler, + this, + temp, + compiler->float64x2_class(), + instance_reg, + offset_in_bytes_, + temp2); __ CopyFloat64x2Field(temp, value_reg, TMP, temp2, fpu_temp); __ b(&skip_store); } @@ -2306,111 +2313,6 @@ void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } -class BoxDoubleSlowPath : public SlowPathCode { - public: - explicit BoxDoubleSlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxDoubleSlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& double_class = compiler->double_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(double_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ MoveRegister(locs->out(0).reg(), R0); - compiler->RestoreLiveRegisters(locs); - - __ b(exit_label()); - } - - private: - Instruction* instruction_; -}; - - -class BoxFloat32x4SlowPath : public SlowPathCode { - public: - explicit BoxFloat32x4SlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxFloat32x4SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& float32x4_class = compiler->float32x4_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(float32x4_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ mov(locs->out(0).reg(), Operand(R0)); - compiler->RestoreLiveRegisters(locs); - - __ b(exit_label()); - } - - private: - Instruction* instruction_; -}; - - -class BoxFloat64x2SlowPath : public SlowPathCode { - public: - explicit BoxFloat64x2SlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxFloat64x2SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& float64x2_class = compiler->float64x2_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(float64x2_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ mov(locs->out(0).reg(), Operand(R0)); - compiler->RestoreLiveRegisters(locs); - - __ b(exit_label()); - } - - private: - Instruction* instruction_; -}; - - LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, bool opt) const { const intptr_t kNumInputs = 1; @@ -2511,14 +2413,12 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_double); - BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - result_reg, - temp); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, + this, + compiler->double_class(), + result_reg, + temp); __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); __ CopyDoubleField(result_reg, temp, TMP, temp2, value); __ b(&done); @@ -2526,14 +2426,12 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_float32x4); - BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - result_reg, - temp); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, + this, + compiler->float32x4_class(), + result_reg, + temp); __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); __ CopyFloat32x4Field(result_reg, temp, TMP, temp2, value); __ b(&done); @@ -2541,14 +2439,12 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_float64x2); - BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - result_reg, - temp); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, + this, + compiler->float64x2_class(), + result_reg, + temp); __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); __ CopyFloat64x2Field(result_reg, temp, TMP, temp2, value); __ b(&done); @@ -3387,17 +3283,15 @@ LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); - compiler->AddSlowPathCode(slow_path); - const Register out_reg = locs()->out(0).reg(); const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - out_reg, - locs()->temp(0).reg()); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, + this, + compiler->double_class(), + out_reg, + locs()->temp(0).reg()); __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); } @@ -3475,19 +3369,16 @@ LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - const Register out_reg = locs()->out(0).reg(); const QRegister value = locs()->in(0).fpu_reg(); const DRegister dvalue0 = EvenDRegisterOf(value); - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - out_reg, - locs()->temp(0).reg()); - __ Bind(slow_path->exit_label()); - + BoxAllocationSlowPath::Allocate( + compiler, + this, + compiler->float32x4_class(), + out_reg, + locs()->temp(0).reg()); __ StoreMultipleDToOffset(dvalue0, 2, out_reg, Float32x4::value_offset() - kHeapObjectTag); } @@ -3546,19 +3437,16 @@ LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); - compiler->AddSlowPathCode(slow_path); - const Register out_reg = locs()->out(0).reg(); const QRegister value = locs()->in(0).fpu_reg(); const DRegister dvalue0 = EvenDRegisterOf(value); - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - out_reg, - locs()->temp(0).reg()); - __ Bind(slow_path->exit_label()); - + BoxAllocationSlowPath::Allocate( + compiler, + this, + compiler->float64x2_class(), + out_reg, + locs()->temp(0).reg()); __ StoreMultipleDToOffset(dvalue0, 2, out_reg, Float64x2::value_offset() - kHeapObjectTag); } @@ -3616,54 +3504,17 @@ LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate, } -class BoxInt32x4SlowPath : public SlowPathCode { - public: - explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxInt32x4SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& int32x4_class = compiler->int32x4_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(int32x4_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ mov(locs->out(0).reg(), Operand(R0)); - compiler->RestoreLiveRegisters(locs); - - __ b(exit_label()); - } - - private: - BoxInt32x4Instr* instruction_; -}; - - void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - const Register out_reg = locs()->out(0).reg(); const QRegister value = locs()->in(0).fpu_reg(); const DRegister dvalue0 = EvenDRegisterOf(value); - __ TryAllocate(compiler->int32x4_class(), - slow_path->entry_label(), - out_reg, - locs()->temp(0).reg()); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, + this, + compiler->int32x4_class(), + out_reg, + locs()->temp(0).reg()); __ StoreMultipleDToOffset(dvalue0, 2, out_reg, Int32x4::value_offset() - kHeapObjectTag); } @@ -5880,41 +5731,6 @@ LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, } -class BoxIntegerSlowPath : public SlowPathCode { - public: - explicit BoxIntegerSlowPath(Definition* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxIntegerSlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& mint_class = - Class::ZoneHandle(isolate->object_store()->mint_class()); - const Code& stub = - Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ mov(locs->out(0).reg(), Operand(R0)); - compiler->RestoreLiveRegisters(locs); - - __ b(exit_label()); - } - - private: - Definition* instruction_; -}; - - void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { if (is_smi()) { PairLocation* value_pair = locs()->in(0).AsPairLocation(); @@ -5925,8 +5741,6 @@ void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { return; } - BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); - compiler->AddSlowPathCode(slow_path); PairLocation* value_pair = locs()->in(0).AsPairLocation(); Register value_lo = value_pair->At(0).reg(); Register value_hi = value_pair->At(1).reg(); @@ -5964,12 +5778,12 @@ void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { // Not a smi. Box it. __ Bind(¬_smi); - __ TryAllocate( - Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), - slow_path->entry_label(), + BoxAllocationSlowPath::Allocate( + compiler, + this, + compiler->mint_class(), out_reg, tmp); - __ Bind(slow_path->exit_label()); __ StoreToOffset(kWord, value_lo, out_reg, @@ -6447,8 +6261,6 @@ LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); - compiler->AddSlowPathCode(slow_path); Register value = locs()->in(0).reg(); Register out = locs()->out(0).reg(); Register temp = locs()->temp(0).reg(); @@ -6467,12 +6279,12 @@ void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { __ b(&done); __ Bind(¬_smi); // Allocate a mint. - __ TryAllocate( - Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), - slow_path->entry_label(), + BoxAllocationSlowPath::Allocate( + compiler, + this, + compiler->mint_class(), out, temp); - __ Bind(slow_path->exit_label()); // Copy low word into mint. __ StoreToOffset(kWord, value, diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc index 16a4162b0a5..33b9deca7af 100644 --- a/runtime/vm/intermediate_language_arm64.cc +++ b/runtime/vm/intermediate_language_arm64.cc @@ -1564,17 +1564,24 @@ void GuardFieldLengthInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } -class StoreInstanceFieldSlowPath : public SlowPathCode { +class BoxAllocationSlowPath : public SlowPathCode { public: - StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, - const Class& cls) - : instruction_(instruction), cls_(cls) { } + BoxAllocationSlowPath(Instruction* instruction, + const Class& cls, + Register result) + : instruction_(instruction), + cls_(cls), + result_(result) { } virtual void EmitNativeCode(FlowGraphCompiler* compiler) { Isolate* isolate = compiler->isolate(); StubCode* stub_code = isolate->stub_code(); - __ Comment("StoreInstanceFieldSlowPath"); + if (Assembler::EmittingComments()) { + __ Comment("%s slow path allocation of %s", + instruction_->DebugName(), + String::Handle(cls_.PrettyName()).ToCString()); + } __ Bind(entry_label()); const Code& stub = @@ -1582,25 +1589,63 @@ class StoreInstanceFieldSlowPath : public SlowPathCode { const ExternalLabel label(stub.EntryPoint()); LocationSummary* locs = instruction_->locs(); - locs->live_registers()->Remove(locs->temp(0)); + + locs->live_registers()->Remove(Location::RegisterLocation(result_)); compiler->SaveLiveRegisters(locs); compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. &label, RawPcDescriptors::kOther, locs); - __ mov(locs->temp(0).reg(), R0); + __ mov(result_, R0); compiler->RestoreLiveRegisters(locs); __ b(exit_label()); } + static void Allocate(FlowGraphCompiler* compiler, + Instruction* instruction, + const Class& cls, + Register result, + Register temp) { + BoxAllocationSlowPath* slow_path = + new BoxAllocationSlowPath(instruction, cls, result); + compiler->AddSlowPathCode(slow_path); + + __ TryAllocate(cls, + slow_path->entry_label(), + result, + temp, + PP); + __ Bind(slow_path->exit_label()); + } + private: - StoreInstanceFieldInstr* instruction_; + Instruction* instruction_; const Class& cls_; + Register result_; }; +static void EnsureMutableBox(FlowGraphCompiler* compiler, + StoreInstanceFieldInstr* instruction, + Register box_reg, + const Class& cls, + Register instance_reg, + intptr_t offset, + Register temp) { + Label done; + __ LoadFieldFromOffset(box_reg, instance_reg, offset, PP); + __ CompareObject(box_reg, Object::null_object(), PP); + __ b(&done, NE); + BoxAllocationSlowPath::Allocate( + compiler, instruction, cls, box_reg, temp); + __ mov(temp, box_reg); + __ StoreIntoObjectOffset(instance_reg, offset, temp, PP); + __ Bind(&done); +} + + LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, bool opt) const { const intptr_t kNumInputs = 2; @@ -1661,15 +1706,7 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { UNREACHABLE(); } - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, *cls); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(*cls, - slow_path->entry_label(), - temp, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2); __ mov(temp2, temp); __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2, PP); } else { @@ -1739,23 +1776,13 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_double); - Label copy_double; - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->double_class()); - compiler->AddSlowPathCode(slow_path); - - __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_, PP); - __ CompareObject(temp, Object::null_object(), PP); - __ b(©_double, NE); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - temp, - PP); - __ Bind(slow_path->exit_label()); - __ mov(temp2, temp); - __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2, PP); - __ Bind(©_double); + EnsureMutableBox(compiler, + this, + temp, + compiler->double_class(), + instance_reg, + offset_in_bytes_, + temp2); __ LoadDFieldFromOffset(VTMP, value_reg, Double::value_offset(), PP); __ StoreDFieldToOffset(VTMP, temp, Double::value_offset(), PP); __ b(&skip_store); @@ -1763,23 +1790,13 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_float32x4); - Label copy_float32x4; - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->float32x4_class()); - compiler->AddSlowPathCode(slow_path); - - __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_, PP); - __ CompareObject(temp, Object::null_object(), PP); - __ b(©_float32x4, NE); - - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - temp, - PP); - __ Bind(slow_path->exit_label()); - __ mov(temp2, temp); - __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2, PP); - __ Bind(©_float32x4); + EnsureMutableBox(compiler, + this, + temp, + compiler->float32x4_class(), + instance_reg, + offset_in_bytes_, + temp2); __ LoadQFieldFromOffset(VTMP, value_reg, Float32x4::value_offset(), PP); __ StoreQFieldToOffset(VTMP, temp, Float32x4::value_offset(), PP); __ b(&skip_store); @@ -1787,23 +1804,13 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_float64x2); - Label copy_float64x2; - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); - compiler->AddSlowPathCode(slow_path); - - __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_, PP); - __ CompareObject(temp, Object::null_object(), PP); - __ b(©_float64x2, NE); - - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - temp, - PP); - __ Bind(slow_path->exit_label()); - __ mov(temp2, temp); - __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2, PP); - __ Bind(©_float64x2); + EnsureMutableBox(compiler, + this, + temp, + compiler->float64x2_class(), + instance_reg, + offset_in_bytes_, + temp2); __ LoadQFieldFromOffset(VTMP, value_reg, Float64x2::value_offset(), PP); __ StoreQFieldToOffset(VTMP, temp, Float64x2::value_offset(), PP); __ b(&skip_store); @@ -1939,111 +1946,6 @@ void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } -class BoxDoubleSlowPath : public SlowPathCode { - public: - explicit BoxDoubleSlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxDoubleSlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& double_class = compiler->double_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(double_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ mov(locs->out(0).reg(), R0); - compiler->RestoreLiveRegisters(locs); - - __ b(exit_label()); - } - - private: - Instruction* instruction_; -}; - - -class BoxFloat32x4SlowPath : public SlowPathCode { - public: - explicit BoxFloat32x4SlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxFloat32x4SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& float32x4_class = compiler->float32x4_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(float32x4_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ mov(locs->out(0).reg(), R0); - compiler->RestoreLiveRegisters(locs); - - __ b(exit_label()); - } - - private: - Instruction* instruction_; -}; - - -class BoxFloat64x2SlowPath : public SlowPathCode { - public: - explicit BoxFloat64x2SlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxFloat64x2SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& float64x2_class = compiler->float64x2_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(float64x2_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ mov(locs->out(0).reg(), R0); - compiler->RestoreLiveRegisters(locs); - - __ b(exit_label()); - } - - private: - Instruction* instruction_; -}; - - LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, bool opt) const { const intptr_t kNumInputs = 1; @@ -2134,14 +2036,11 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_double); - BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - result_reg, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate(compiler, + this, + compiler->double_class(), + result_reg, + temp); __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes(), PP); __ LoadDFieldFromOffset(VTMP, temp, Double::value_offset(), PP); __ StoreDFieldToOffset(VTMP, result_reg, Double::value_offset(), PP); @@ -2150,14 +2049,11 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_float32x4); - BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - result_reg, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate(compiler, + this, + compiler->float32x4_class(), + result_reg, + temp); __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes(), PP); __ LoadQFieldFromOffset(VTMP, temp, Float32x4::value_offset(), PP); __ StoreQFieldToOffset(VTMP, result_reg, Float32x4::value_offset(), PP); @@ -2166,14 +2062,11 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_float64x2); - BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - result_reg, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate(compiler, + this, + compiler->float64x2_class(), + result_reg, + temp); __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes(), PP); __ LoadQFieldFromOffset(VTMP, temp, Float64x2::value_offset(), PP); __ StoreQFieldToOffset(VTMP, result_reg, Float64x2::value_offset(), PP); @@ -2966,27 +2859,23 @@ void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, bool opt) const { const intptr_t kNumInputs = 1; - const intptr_t kNumTemps = 0; + const intptr_t kNumTemps = 1; LocationSummary* summary = new(isolate) LocationSummary( isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); summary->set_in(0, Location::RequiresFpuRegister()); + summary->set_temp(0, Location::RequiresRegister()); summary->set_out(0, Location::RequiresRegister()); return summary; } void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); - compiler->AddSlowPathCode(slow_path); - const Register out_reg = locs()->out(0).reg(); + const Register temp_reg = locs()->temp(0).reg(); const VRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - out_reg, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->double_class(), out_reg, temp_reg); __ StoreDFieldToOffset(value, out_reg, Double::value_offset(), PP); } @@ -3043,28 +2932,23 @@ void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, bool opt) const { const intptr_t kNumInputs = 1; - const intptr_t kNumTemps = 0; + const intptr_t kNumTemps = 1; LocationSummary* summary = new(isolate) LocationSummary( isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); summary->set_in(0, Location::RequiresFpuRegister()); + summary->set_temp(0, Location::RequiresRegister()); summary->set_out(0, Location::RequiresRegister()); return summary; } void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - const Register out_reg = locs()->out(0).reg(); + const Register temp_reg = locs()->temp(0).reg(); const VRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - out_reg, - PP); - __ Bind(slow_path->exit_label()); - + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->float32x4_class(), out_reg, temp_reg); __ StoreQFieldToOffset(value, out_reg, Float32x4::value_offset(), PP); } @@ -3101,28 +2985,23 @@ void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, bool opt) const { const intptr_t kNumInputs = 1; - const intptr_t kNumTemps = 0; + const intptr_t kNumTemps = 1; LocationSummary* summary = new(isolate) LocationSummary( isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); summary->set_in(0, Location::RequiresFpuRegister()); + summary->set_temp(0, Location::RequiresRegister()); summary->set_out(0, Location::RequiresRegister()); return summary; } void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); - compiler->AddSlowPathCode(slow_path); - const Register out_reg = locs()->out(0).reg(); + const Register temp_reg = locs()->temp(0).reg(); const VRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - out_reg, - PP); - __ Bind(slow_path->exit_label()); - + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->float64x2_class(), out_reg, temp_reg); __ StoreQFieldToOffset(value, out_reg, Float64x2::value_offset(), PP); } @@ -3159,63 +3038,22 @@ void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate, bool opt) const { const intptr_t kNumInputs = 1; - const intptr_t kNumTemps = 0; + const intptr_t kNumTemps = 1; LocationSummary* summary = new(isolate) LocationSummary( isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); summary->set_in(0, Location::RequiresFpuRegister()); + summary->set_temp(0, Location::RequiresRegister()); summary->set_out(0, Location::RequiresRegister()); return summary; } -class BoxInt32x4SlowPath : public SlowPathCode { - public: - explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxInt32x4SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& int32x4_class = compiler->int32x4_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(int32x4_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ mov(locs->out(0).reg(), R0); - compiler->RestoreLiveRegisters(locs); - - __ b(exit_label()); - } - - private: - BoxInt32x4Instr* instruction_; -}; - - void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - const Register out_reg = locs()->out(0).reg(); + const Register temp_reg = locs()->temp(0).reg(); const VRegister value = locs()->in(0).fpu_reg(); - - __ TryAllocate(compiler->int32x4_class(), - slow_path->entry_label(), - out_reg, - PP); - __ Bind(slow_path->exit_label()); - + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->int32x4_class(), out_reg, temp_reg); __ StoreQFieldToOffset(value, out_reg, Int32x4::value_offset(), PP); } diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc index 03d75b26690..7b276af4fbe 100644 --- a/runtime/vm/intermediate_language_ia32.cc +++ b/runtime/vm/intermediate_language_ia32.cc @@ -1665,37 +1665,65 @@ void GuardFieldLengthInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } -class StoreInstanceFieldSlowPath : public SlowPathCode { +class BoxAllocationSlowPath : public SlowPathCode { public: - StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, - const Class& cls) - : instruction_(instruction), cls_(cls) { } + BoxAllocationSlowPath(Instruction* instruction, + const Class& cls, + Register result) + : instruction_(instruction), + cls_(cls), + result_(result) { } virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("StoreInstanceFieldSlowPath"); - __ Bind(entry_label()); Isolate* isolate = compiler->isolate(); + StubCode* stub_code = isolate->stub_code(); + + if (Assembler::EmittingComments()) { + __ Comment("%s slow path allocation of %s", + instruction_->DebugName(), + String::Handle(cls_.PrettyName()).ToCString()); + } + __ Bind(entry_label()); + const Code& stub = - Code::Handle(isolate, - isolate->stub_code()->GetAllocationStubForClass(cls_)); + Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_)); const ExternalLabel label(stub.EntryPoint()); LocationSummary* locs = instruction_->locs(); - locs->live_registers()->Remove(locs->temp(0)); + + locs->live_registers()->Remove(Location::RegisterLocation(result_)); compiler->SaveLiveRegisters(locs); compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. &label, RawPcDescriptors::kOther, locs); - __ MoveRegister(locs->temp(0).reg(), EAX); + __ MoveRegister(result_, EAX); compiler->RestoreLiveRegisters(locs); __ jmp(exit_label()); } + static void Allocate(FlowGraphCompiler* compiler, + Instruction* instruction, + const Class& cls, + Register result, + Register temp) { + BoxAllocationSlowPath* slow_path = + new BoxAllocationSlowPath(instruction, cls, result); + compiler->AddSlowPathCode(slow_path); + + __ TryAllocate(cls, + slow_path->entry_label(), + Assembler::kFarJump, + result, + temp); + __ Bind(slow_path->exit_label()); + } + private: - StoreInstanceFieldInstr* instruction_; + Instruction* instruction_; const Class& cls_; + Register result_; }; @@ -1734,6 +1762,29 @@ LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, } +static void EnsureMutableBox(FlowGraphCompiler* compiler, + StoreInstanceFieldInstr* instruction, + Register box_reg, + const Class& cls, + Register instance_reg, + intptr_t offset, + Register temp) { + Label done; + const Immediate& raw_null = + Immediate(reinterpret_cast(Object::null())); + __ movl(box_reg, FieldAddress(instance_reg, offset)); + __ cmpl(box_reg, raw_null); + __ j(NOT_EQUAL, &done); + BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp); + __ movl(temp, box_reg); + __ StoreIntoObject(instance_reg, + FieldAddress(instance_reg, offset), + temp); + + __ Bind(&done); +} + + void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { Label skip_store; @@ -1761,16 +1812,7 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { UNREACHABLE(); } - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, *cls); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(*cls, - slow_path->entry_label(), - Assembler::kFarJump, - temp, - temp2); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2); __ movl(temp2, temp); __ StoreIntoObject(instance_reg, FieldAddress(instance_reg, offset_in_bytes_), @@ -1842,30 +1884,13 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_double); - Label copy_double; - - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->double_class()); - compiler->AddSlowPathCode(slow_path); - - const Immediate& raw_null = - Immediate(reinterpret_cast(Object::null())); - __ movl(temp, FieldAddress(instance_reg, offset_in_bytes_)); - __ cmpl(temp, raw_null); - __ j(NOT_EQUAL, ©_double); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - Assembler::kFarJump, - temp, - temp2); - __ Bind(slow_path->exit_label()); - __ movl(temp2, temp); - __ StoreIntoObject(instance_reg, - FieldAddress(instance_reg, offset_in_bytes_), - temp2); - - __ Bind(©_double); + EnsureMutableBox(compiler, + this, + temp, + compiler->double_class(), + instance_reg, + offset_in_bytes_, + temp2); __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset())); __ movsd(FieldAddress(temp, Double::value_offset()), fpu_temp); __ jmp(&skip_store); @@ -1873,30 +1898,13 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_float32x4); - Label copy_float32x4; - - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->float32x4_class()); - compiler->AddSlowPathCode(slow_path); - - const Immediate& raw_null = - Immediate(reinterpret_cast(Object::null())); - __ movl(temp, FieldAddress(instance_reg, offset_in_bytes_)); - __ cmpl(temp, raw_null); - __ j(NOT_EQUAL, ©_float32x4); - - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - Assembler::kFarJump, - temp, - temp2); - __ Bind(slow_path->exit_label()); - __ movl(temp2, temp); - __ StoreIntoObject(instance_reg, - FieldAddress(instance_reg, offset_in_bytes_), - temp2); - - __ Bind(©_float32x4); + EnsureMutableBox(compiler, + this, + temp, + compiler->float32x4_class(), + instance_reg, + offset_in_bytes_, + temp2); __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset())); __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp); __ jmp(&skip_store); @@ -1904,30 +1912,13 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_float64x2); - Label copy_float64x2; - - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); - compiler->AddSlowPathCode(slow_path); - - const Immediate& raw_null = - Immediate(reinterpret_cast(Object::null())); - __ movl(temp, FieldAddress(instance_reg, offset_in_bytes_)); - __ cmpl(temp, raw_null); - __ j(NOT_EQUAL, ©_float64x2); - - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - Assembler::kFarJump, - temp, - temp2); - __ Bind(slow_path->exit_label()); - __ movl(temp2, temp); - __ StoreIntoObject(instance_reg, - FieldAddress(instance_reg, offset_in_bytes_), - temp2); - - __ Bind(©_float64x2); + EnsureMutableBox(compiler, + this, + temp, + compiler->float64x2_class(), + instance_reg, + offset_in_bytes_, + temp2); __ movups(fpu_temp, FieldAddress(value_reg, Float64x2::value_offset())); __ movups(FieldAddress(temp, Float64x2::value_offset()), fpu_temp); __ jmp(&skip_store); @@ -2161,110 +2152,6 @@ void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } -class BoxDoubleSlowPath : public SlowPathCode { - public: - explicit BoxDoubleSlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxDoubleSlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& double_class = compiler->double_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(double_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ MoveRegister(locs->out(0).reg(), EAX); - compiler->RestoreLiveRegisters(locs); - - __ jmp(exit_label()); - } - - private: - Instruction* instruction_; -}; - - -class BoxFloat32x4SlowPath : public SlowPathCode { - public: - explicit BoxFloat32x4SlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxFloat32x4SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& float32x4_class = compiler->float32x4_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(float32x4_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ MoveRegister(locs->out(0).reg(), EAX); - compiler->RestoreLiveRegisters(locs); - - __ jmp(exit_label()); - } - - private: - Instruction* instruction_; -}; - - -class BoxFloat64x2SlowPath : public SlowPathCode { - public: - explicit BoxFloat64x2SlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxFloat64x2SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& float64x2_class = compiler->float64x2_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(float64x2_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ MoveRegister(locs->out(0).reg(), EAX); - compiler->RestoreLiveRegisters(locs); - - __ jmp(exit_label()); - } - - private: - Instruction* instruction_; -}; - - LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, bool opt) const { const intptr_t kNumInputs = 1; @@ -2356,15 +2243,8 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_double); - BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - Assembler::kFarJump, - result, - temp); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->double_class(), result, temp); __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); __ movsd(value, FieldAddress(temp, Double::value_offset())); __ movsd(FieldAddress(result, Double::value_offset()), value); @@ -2373,16 +2253,8 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_float32x4); - - BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - Assembler::kFarJump, - result, - temp); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->float32x4_class(), result, temp); __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); __ movups(value, FieldAddress(temp, Float32x4::value_offset())); __ movups(FieldAddress(result, Float32x4::value_offset()), value); @@ -2391,16 +2263,8 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_float64x2); - - BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - Assembler::kFarJump, - result, - temp); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->float64x2_class(), result, temp); __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); __ movups(value, FieldAddress(temp, Float64x2::value_offset())); __ movups(FieldAddress(result, Float64x2::value_offset()), value); @@ -3359,18 +3223,10 @@ LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); - compiler->AddSlowPathCode(slow_path); - Register out_reg = locs()->out(0).reg(); XmmRegister value = locs()->in(0).fpu_reg(); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - Assembler::kFarJump, - out_reg, - kNoRegister); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->double_class(), out_reg, kNoRegister); __ movsd(FieldAddress(out_reg, Double::value_offset()), value); } @@ -3449,18 +3305,11 @@ LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - Register out_reg = locs()->out(0).reg(); XmmRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - Assembler::kFarJump, - out_reg, - kNoRegister); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->float32x4_class(), out_reg, kNoRegister); __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); } @@ -3514,18 +3363,11 @@ LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); - compiler->AddSlowPathCode(slow_path); - Register out_reg = locs()->out(0).reg(); XmmRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - Assembler::kFarJump, - out_reg, - kNoRegister); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->float64x2_class(), out_reg, kNoRegister); __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value); } @@ -3578,54 +3420,12 @@ LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate, } -class BoxInt32x4SlowPath : public SlowPathCode { - public: - explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxInt32x4SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& int32x4_class = compiler->int32x4_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(int32x4_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ MoveRegister(locs->out(0).reg(), EAX); - compiler->RestoreLiveRegisters(locs); - - __ jmp(exit_label()); - } - - private: - BoxInt32x4Instr* instruction_; -}; - - void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - Register out_reg = locs()->out(0).reg(); XmmRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->int32x4_class(), - slow_path->entry_label(), - Assembler::kFarJump, - out_reg, - kNoRegister); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->int32x4_class(), out_reg, kNoRegister); __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); } @@ -5703,41 +5503,6 @@ LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, } -class BoxIntegerSlowPath : public SlowPathCode { - public: - explicit BoxIntegerSlowPath(Definition* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxIntegerSlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& mint_class = - Class::ZoneHandle(isolate, isolate->object_store()->mint_class()); - const Code& stub = - Code::Handle(isolate, stub_code->GetAllocationStubForClass(mint_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ MoveRegister(locs->out(0).reg(), EAX); - compiler->RestoreLiveRegisters(locs); - - __ jmp(exit_label()); - } - - private: - Definition* instruction_; -}; - - void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { if (is_smi()) { PairLocation* value_pair = locs()->in(0).AsPairLocation(); @@ -5748,8 +5513,6 @@ void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { return; } - BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); - compiler->AddSlowPathCode(slow_path); PairLocation* value_pair = locs()->in(0).AsPairLocation(); Register value_lo = value_pair->At(0).reg(); Register value_hi = value_pair->At(1).reg(); @@ -5777,15 +5540,11 @@ void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { __ SmiTag(out_reg); __ jmp(&done); __ Bind(¬_smi); - __ TryAllocate( - Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), - slow_path->entry_label(), - Assembler::kFarJump, - out_reg, - kNoRegister); - __ Bind(slow_path->exit_label()); // 3. Restore lower half of input before using it. __ subl(value_lo, Immediate(0x40000000)); + + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->mint_class(), out_reg, kNoRegister); __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo); __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi); __ Bind(&done); @@ -6338,8 +6097,6 @@ LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); - compiler->AddSlowPathCode(slow_path); Register value = locs()->in(0).reg(); Register out = locs()->out(0).reg(); ASSERT(value != out); @@ -6356,13 +6113,8 @@ void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { __ jmp(&done); __ Bind(¬_smi); // Allocate a mint. - __ TryAllocate( - Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), - slow_path->entry_label(), - Assembler::kFarJump, - out, - kNoRegister); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->mint_class(), out, kNoRegister); // Copy low word into mint. __ movl(FieldAddress(out, Mint::value_offset()), value); // Zero high word. diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc index ebf3a545e1d..a5d77da9b20 100644 --- a/runtime/vm/intermediate_language_mips.cc +++ b/runtime/vm/intermediate_language_mips.cc @@ -1674,39 +1674,65 @@ void GuardFieldLengthInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } -class StoreInstanceFieldSlowPath : public SlowPathCode { +class BoxAllocationSlowPath : public SlowPathCode { public: - StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, - const Class& cls) - : instruction_(instruction), cls_(cls) { } + BoxAllocationSlowPath(Instruction* instruction, + const Class& cls, + Register result) + : instruction_(instruction), + cls_(cls), + result_(result) { } virtual void EmitNativeCode(FlowGraphCompiler* compiler) { Isolate* isolate = compiler->isolate(); StubCode* stub_code = isolate->stub_code(); - __ Comment("StoreInstanceFieldSlowPath"); + if (Assembler::EmittingComments()) { + __ Comment("%s slow path allocation of %s", + instruction_->DebugName(), + String::Handle(cls_.PrettyName()).ToCString()); + } __ Bind(entry_label()); const Code& stub = Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_)); const ExternalLabel label(stub.EntryPoint()); LocationSummary* locs = instruction_->locs(); - locs->live_registers()->Remove(locs->temp(0)); + locs->live_registers()->Remove(Location::RegisterLocation(result_)); compiler->SaveLiveRegisters(locs); compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. &label, RawPcDescriptors::kOther, locs); - __ mov(locs->temp(0).reg(), V0); + if (result_ != V0) { + __ mov(result_, V0); + } compiler->RestoreLiveRegisters(locs); __ b(exit_label()); } + static void Allocate(FlowGraphCompiler* compiler, + Instruction* instruction, + const Class& cls, + Register result, + Register temp) { + BoxAllocationSlowPath* slow_path = + new BoxAllocationSlowPath(instruction, cls, result); + compiler->AddSlowPathCode(slow_path); + + __ TryAllocate(cls, + slow_path->entry_label(), + result, + temp); + __ Bind(slow_path->exit_label()); + } + private: - StoreInstanceFieldInstr* instruction_; + Instruction* instruction_; const Class& cls_; + Register result_; }; @@ -1745,6 +1771,24 @@ LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, } +static void EnsureMutableBox(FlowGraphCompiler* compiler, + StoreInstanceFieldInstr* instruction, + Register box_reg, + const Class& cls, + Register instance_reg, + intptr_t offset, + Register temp) { + Label done; + __ lw(box_reg, FieldAddress(instance_reg, offset)); + __ BranchNotEqual(box_reg, reinterpret_cast(Object::null()), + &done); + BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg, temp); + __ mov(temp, box_reg); + __ StoreIntoObjectOffset(instance_reg, offset, temp); + __ Bind(&done); +} + + void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { Label skip_store; @@ -1766,15 +1810,7 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { UNREACHABLE(); } - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, *cls); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(*cls, - slow_path->entry_label(), - temp, - temp2); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp, temp2); __ mov(temp2, temp); __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); } else { @@ -1821,25 +1857,13 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_double); - Label copy_double; - - __ lw(temp, FieldAddress(instance_reg, offset_in_bytes_)); - __ BranchNotEqual(temp, reinterpret_cast(Object::null()), - ©_double); - - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->double_class()); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - temp, - temp2); - __ Bind(slow_path->exit_label()); - __ mov(temp2, temp); - __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2); - - __ Bind(©_double); + EnsureMutableBox(compiler, + this, + temp, + compiler->double_class(), + instance_reg, + offset_in_bytes_, + temp2); __ LoadDFromOffset(fpu_temp, value_reg, Double::value_offset() - kHeapObjectTag); @@ -2083,43 +2107,6 @@ void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } -class BoxDoubleSlowPath : public SlowPathCode { - public: - explicit BoxDoubleSlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxDoubleSlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& double_class = compiler->double_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(double_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - if (locs->out(0).reg() != V0) { - __ mov(locs->out(0).reg(), V0); - } - compiler->RestoreLiveRegisters(locs); - - __ b(exit_label()); - } - - private: - Instruction* instruction_; -}; - - LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, bool opt) const { const intptr_t kNumInputs = 1; @@ -2194,14 +2181,8 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_double); - BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - result_reg, - temp); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->double_class(), result_reg, temp); __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag); __ StoreDToOffset(value, @@ -3046,17 +3027,11 @@ LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); - compiler->AddSlowPathCode(slow_path); - Register out_reg = locs()->out(0).reg(); DRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - out_reg, - locs()->temp(0).reg()); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->double_class(), out_reg, locs()->temp(0).reg()); __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); } diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc index 19bf8645c73..e6d39102352 100644 --- a/runtime/vm/intermediate_language_x64.cc +++ b/runtime/vm/intermediate_language_x64.cc @@ -1506,38 +1506,64 @@ void GuardFieldLengthInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } -class StoreInstanceFieldSlowPath : public SlowPathCode { +class BoxAllocationSlowPath : public SlowPathCode { public: - StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, - const Class& cls) - : instruction_(instruction), cls_(cls) { } + BoxAllocationSlowPath(Instruction* instruction, + const Class& cls, + Register result) + : instruction_(instruction), + cls_(cls), + result_(result) { } virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("StoreInstanceFieldSlowPath"); - __ Bind(entry_label()); Isolate* isolate = compiler->isolate(); StubCode* stub_code = isolate->stub_code(); - const Code& stub = Code::Handle(isolate, - stub_code->GetAllocationStubForClass(cls_)); + + if (Assembler::EmittingComments()) { + __ Comment("%s slow path allocation of %s", + instruction_->DebugName(), + String::Handle(cls_.PrettyName()).ToCString()); + } + __ Bind(entry_label()); + + const Code& stub = + Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_)); const ExternalLabel label(stub.EntryPoint()); LocationSummary* locs = instruction_->locs(); - locs->live_registers()->Remove(locs->temp(0)); + + locs->live_registers()->Remove(Location::RegisterLocation(result_)); compiler->SaveLiveRegisters(locs); compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. &label, RawPcDescriptors::kOther, locs); - __ MoveRegister(locs->temp(0).reg(), RAX); + __ MoveRegister(result_, RAX); compiler->RestoreLiveRegisters(locs); - __ jmp(exit_label()); } + static void Allocate(FlowGraphCompiler* compiler, + Instruction* instruction, + const Class& cls, + Register result) { + BoxAllocationSlowPath* slow_path = + new BoxAllocationSlowPath(instruction, cls, result); + compiler->AddSlowPathCode(slow_path); + + __ TryAllocate(cls, + slow_path->entry_label(), + Assembler::kFarJump, + result, + PP); + __ Bind(slow_path->exit_label()); + } + private: - StoreInstanceFieldInstr* instruction_; + Instruction* instruction_; const Class& cls_; + Register result_; }; @@ -1576,6 +1602,27 @@ LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Isolate* isolate, } +static void EnsureMutableBox(FlowGraphCompiler* compiler, + StoreInstanceFieldInstr* instruction, + Register box_reg, + const Class& cls, + Register instance_reg, + intptr_t offset, + Register temp) { + Label done; + __ movq(box_reg, FieldAddress(instance_reg, offset)); + __ CompareObject(box_reg, Object::null_object(), PP); + __ j(NOT_EQUAL, &done); + BoxAllocationSlowPath::Allocate(compiler, instruction, cls, box_reg); + __ movq(temp, box_reg); + __ StoreIntoObject(instance_reg, + FieldAddress(instance_reg, offset), + temp); + + __ Bind(&done); +} + + void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { Label skip_store; @@ -1603,16 +1650,7 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { UNREACHABLE(); } - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, *cls); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(*cls, - slow_path->entry_label(), - Assembler::kFarJump, - temp, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate(compiler, this, *cls, temp); __ movq(temp2, temp); __ StoreIntoObject(instance_reg, FieldAddress(instance_reg, offset_in_bytes_), @@ -1682,27 +1720,13 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_double); - Label copy_double; - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->double_class()); - compiler->AddSlowPathCode(slow_path); - - __ movq(temp, FieldAddress(instance_reg, offset_in_bytes_)); - __ CompareObject(temp, Object::null_object(), PP); - __ j(NOT_EQUAL, ©_double); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - Assembler::kFarJump, - temp, - PP); - __ Bind(slow_path->exit_label()); - __ movq(temp2, temp); - __ StoreIntoObject(instance_reg, - FieldAddress(instance_reg, offset_in_bytes_), - temp2); - - __ Bind(©_double); + EnsureMutableBox(compiler, + this, + temp, + compiler->double_class(), + instance_reg, + offset_in_bytes_, + temp2); __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset())); __ movsd(FieldAddress(temp, Double::value_offset()), fpu_temp); __ jmp(&skip_store); @@ -1710,27 +1734,13 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_float32x4); - Label copy_float32x4; - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->float32x4_class()); - compiler->AddSlowPathCode(slow_path); - - __ movq(temp, FieldAddress(instance_reg, offset_in_bytes_)); - __ CompareObject(temp, Object::null_object(), PP); - __ j(NOT_EQUAL, ©_float32x4); - - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - Assembler::kFarJump, - temp, - PP); - __ Bind(slow_path->exit_label()); - __ movq(temp2, temp); - __ StoreIntoObject(instance_reg, - FieldAddress(instance_reg, offset_in_bytes_), - temp2); - - __ Bind(©_float32x4); + EnsureMutableBox(compiler, + this, + temp, + compiler->float32x4_class(), + instance_reg, + offset_in_bytes_, + temp2); __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset())); __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp); __ jmp(&skip_store); @@ -1738,28 +1748,13 @@ void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&store_float64x2); - Label copy_float64x2; - - StoreInstanceFieldSlowPath* slow_path = - new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); - compiler->AddSlowPathCode(slow_path); - - __ movq(temp, FieldAddress(instance_reg, offset_in_bytes_)); - __ CompareObject(temp, Object::null_object(), PP); - __ j(NOT_EQUAL, ©_float64x2); - - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - Assembler::kFarJump, - temp, - temp2); - __ Bind(slow_path->exit_label()); - __ movq(temp2, temp); - __ StoreIntoObject(instance_reg, - FieldAddress(instance_reg, offset_in_bytes_), - temp2); - - __ Bind(©_float64x2); + EnsureMutableBox(compiler, + this, + temp, + compiler->float64x2_class(), + instance_reg, + offset_in_bytes_, + temp2); __ movups(fpu_temp, FieldAddress(value_reg, Float64x2::value_offset())); __ movups(FieldAddress(temp, Float64x2::value_offset()), fpu_temp); __ jmp(&skip_store); @@ -1994,111 +1989,6 @@ void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { } -class BoxDoubleSlowPath : public SlowPathCode { - public: - explicit BoxDoubleSlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxDoubleSlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& double_class = compiler->double_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(double_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ MoveRegister(locs->out(0).reg(), RAX); - compiler->RestoreLiveRegisters(locs); - - __ jmp(exit_label()); - } - - private: - Instruction* instruction_; -}; - - -class BoxFloat32x4SlowPath : public SlowPathCode { - public: - explicit BoxFloat32x4SlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxFloat32x4SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& float32x4_class = compiler->float32x4_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(float32x4_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ MoveRegister(locs->out(0).reg(), RAX); - compiler->RestoreLiveRegisters(locs); - - __ jmp(exit_label()); - } - - private: - Instruction* instruction_; -}; - - -class BoxFloat64x2SlowPath : public SlowPathCode { - public: - explicit BoxFloat64x2SlowPath(Instruction* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxFloat64x2SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& float64x2_class = compiler->float64x2_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(float64x2_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ MoveRegister(locs->out(0).reg(), RAX); - compiler->RestoreLiveRegisters(locs); - - __ jmp(exit_label()); - } - - private: - Instruction* instruction_; -}; - - LocationSummary* LoadFieldInstr::MakeLocationSummary(Isolate* isolate, bool opt) const { const intptr_t kNumInputs = 1; @@ -2189,15 +2079,8 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_double); - BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - Assembler::kFarJump, - result, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->double_class(), result); __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); __ movsd(value, FieldAddress(temp, Double::value_offset())); __ movsd(FieldAddress(result, Double::value_offset()), value); @@ -2206,15 +2089,8 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_float32x4); - BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - Assembler::kFarJump, - result, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->float32x4_class(), result); __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); __ movups(value, FieldAddress(temp, Float32x4::value_offset())); __ movups(FieldAddress(result, Float32x4::value_offset()), value); @@ -2223,15 +2099,8 @@ void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { { __ Bind(&load_float64x2); - BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); - compiler->AddSlowPathCode(slow_path); - - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - Assembler::kFarJump, - result, - temp); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->float64x2_class(), result); __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); __ movups(value, FieldAddress(temp, Float64x2::value_offset())); __ movups(FieldAddress(result, Float64x2::value_offset()), value); @@ -3197,18 +3066,11 @@ LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); - compiler->AddSlowPathCode(slow_path); - Register out_reg = locs()->out(0).reg(); XmmRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->double_class(), - slow_path->entry_label(), - Assembler::kFarJump, - out_reg, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->double_class(), out_reg); __ movsd(FieldAddress(out_reg, Double::value_offset()), value); } @@ -3282,18 +3144,11 @@ LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - Register out_reg = locs()->out(0).reg(); XmmRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->float32x4_class(), - slow_path->entry_label(), - Assembler::kFarJump, - out_reg, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->float32x4_class(), out_reg); __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); } @@ -3339,18 +3194,11 @@ LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); - compiler->AddSlowPathCode(slow_path); - Register out_reg = locs()->out(0).reg(); XmmRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->float64x2_class(), - slow_path->entry_label(), - Assembler::kFarJump, - out_reg, - kNoRegister); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->float64x2_class(), out_reg); __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value); } @@ -3398,54 +3246,12 @@ LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate, } -class BoxInt32x4SlowPath : public SlowPathCode { - public: - explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) - : instruction_(instruction) { } - - virtual void EmitNativeCode(FlowGraphCompiler* compiler) { - __ Comment("BoxInt32x4SlowPath"); - __ Bind(entry_label()); - Isolate* isolate = compiler->isolate(); - StubCode* stub_code = isolate->stub_code(); - const Class& int32x4_class = compiler->int32x4_class(); - const Code& stub = - Code::Handle(isolate, - stub_code->GetAllocationStubForClass(int32x4_class)); - const ExternalLabel label(stub.EntryPoint()); - - LocationSummary* locs = instruction_->locs(); - ASSERT(!locs->live_registers()->Contains(locs->out(0))); - - compiler->SaveLiveRegisters(locs); - compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. - &label, - RawPcDescriptors::kOther, - locs); - __ MoveRegister(locs->out(0).reg(), RAX); - compiler->RestoreLiveRegisters(locs); - - __ jmp(exit_label()); - } - - private: - BoxInt32x4Instr* instruction_; -}; - - void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { - BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); - compiler->AddSlowPathCode(slow_path); - Register out_reg = locs()->out(0).reg(); XmmRegister value = locs()->in(0).fpu_reg(); - __ TryAllocate(compiler->int32x4_class(), - slow_path->entry_label(), - Assembler::kFarJump, - out_reg, - PP); - __ Bind(slow_path->exit_label()); + BoxAllocationSlowPath::Allocate( + compiler, this, compiler->int32x4_class(), out_reg); __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); } diff --git a/runtime/vm/intrinsifier_arm64.cc b/runtime/vm/intrinsifier_arm64.cc index 6e26b2ec003..ef10775200c 100644 --- a/runtime/vm/intrinsifier_arm64.cc +++ b/runtime/vm/intrinsifier_arm64.cc @@ -427,6 +427,7 @@ void Intrinsifier::Float64Array_getIndexed(Assembler* assembler) { __ TryAllocate(double_class, &fall_through, R0, // Result register. + R1, // Temp register. kNoPP); __ StoreDFieldToOffset(V0, R0, Double::value_offset(), kNoPP); __ ret(); @@ -1074,7 +1075,7 @@ static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { } const Class& double_class = Class::Handle( Isolate::Current()->object_store()->double_class()); - __ TryAllocate(double_class, &fall_through, R0, kNoPP); + __ TryAllocate(double_class, &fall_through, R0, R1, kNoPP); __ StoreDFieldToOffset(V0, R0, Double::value_offset(), kNoPP); __ ret(); __ Bind(&fall_through); @@ -1116,7 +1117,7 @@ void Intrinsifier::Double_mulFromInteger(Assembler* assembler) { __ fmuld(V0, V0, V1); const Class& double_class = Class::Handle( Isolate::Current()->object_store()->double_class()); - __ TryAllocate(double_class, &fall_through, R0, kNoPP); + __ TryAllocate(double_class, &fall_through, R0, R1, kNoPP); __ StoreDFieldToOffset(V0, R0, Double::value_offset(), kNoPP); __ ret(); __ Bind(&fall_through); @@ -1134,7 +1135,7 @@ void Intrinsifier::Double_fromInteger(Assembler* assembler) { __ scvtfd(V0, R0); const Class& double_class = Class::Handle( Isolate::Current()->object_store()->double_class()); - __ TryAllocate(double_class, &fall_through, R0, kNoPP); + __ TryAllocate(double_class, &fall_through, R0, R1, kNoPP); __ StoreDFieldToOffset(V0, R0, Double::value_offset(), kNoPP); __ ret(); __ Bind(&fall_through); @@ -1214,7 +1215,7 @@ void Intrinsifier::Math_sqrt(Assembler* assembler) { __ fsqrtd(V0, V1); const Class& double_class = Class::Handle( Isolate::Current()->object_store()->double_class()); - __ TryAllocate(double_class, &fall_through, R0, kNoPP); + __ TryAllocate(double_class, &fall_through, R0, R1, kNoPP); __ StoreDFieldToOffset(V0, R0, Double::value_offset(), kNoPP); __ ret(); __ Bind(&is_smi);