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
This commit is contained in:
vegorov@google.com
2014-07-24 12:04:21 +00:00
parent 8a80ade1ac
commit 36cddbd749
18 changed files with 542 additions and 1341 deletions
+6 -1
View File
@@ -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());
+8 -7
View File
@@ -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);
+1
View File
@@ -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;
+5 -6
View File
@@ -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(
+2
View File
@@ -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,
+2
View File
@@ -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);
+5 -6
View File
@@ -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);
+1
View File
@@ -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;
+2
View File
@@ -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(); }
+2
View File
@@ -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(
+2
View File
@@ -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_;
+1
View File
@@ -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<uword>(new_space_); }
// Initialize the heap and register it with the isolate.
static void Init(Isolate* isolate,
+128 -316
View File
@@ -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<intptr_t>(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<intptr_t>(Object::null()));
__ b(&copy_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(&copy_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<intptr_t>(Object::null()));
__ b(&copy_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(&copy_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<intptr_t>(Object::null()));
__ b(&copy_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(&copy_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(&not_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(&not_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,
+110 -272
View File
@@ -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(&copy_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(&copy_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(&copy_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(&copy_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(&copy_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(&copy_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);
}
+103 -351
View File
@@ -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<intptr_t>(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<intptr_t>(Object::null()));
__ movl(temp, FieldAddress(instance_reg, offset_in_bytes_));
__ cmpl(temp, raw_null);
__ j(NOT_EQUAL, &copy_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(&copy_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<intptr_t>(Object::null()));
__ movl(temp, FieldAddress(instance_reg, offset_in_bytes_));
__ cmpl(temp, raw_null);
__ j(NOT_EQUAL, &copy_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(&copy_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<intptr_t>(Object::null()));
__ movl(temp, FieldAddress(instance_reg, offset_in_bytes_));
__ cmpl(temp, raw_null);
__ j(NOT_EQUAL, &copy_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(&copy_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(&not_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(&not_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.
+64 -89
View File
@@ -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<int32_t>(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<int32_t>(Object::null()),
&copy_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(&copy_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);
}
+95 -289
View File
@@ -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, &copy_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(&copy_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, &copy_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(&copy_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, &copy_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(&copy_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);
}
+5 -4
View File
@@ -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);