mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 20:51:50 +00:00
[vm, x64] Shorter UnboxInt64Instr with compressed Smis.
TEST=ci Change-Id: Ib80b9cd80f3656ea6c5f31e0dbc7229632d8783d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/198140 Reviewed-by: Liam Appelbe <liama@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
7131d3182c
commit
b4c64a1787
|
@ -895,6 +895,12 @@ class Assembler : public AssemblerBase {
|
||||||
void SmiTag(Register reg) { OBJ(add)(reg, reg); }
|
void SmiTag(Register reg) { OBJ(add)(reg, reg); }
|
||||||
|
|
||||||
void SmiUntag(Register reg) { OBJ(sar)(reg, Immediate(kSmiTagSize)); }
|
void SmiUntag(Register reg) { OBJ(sar)(reg, Immediate(kSmiTagSize)); }
|
||||||
|
void SmiUntag(Register dst, Register src) {
|
||||||
|
if (dst != src) {
|
||||||
|
OBJ(mov)(dst, src);
|
||||||
|
}
|
||||||
|
OBJ(sar)(dst, Immediate(kSmiTagSize));
|
||||||
|
}
|
||||||
|
|
||||||
void SmiUntagAndSignExtend(Register reg) {
|
void SmiUntagAndSignExtend(Register reg) {
|
||||||
#if !defined(DART_COMPRESSED_POINTERS)
|
#if !defined(DART_COMPRESSED_POINTERS)
|
||||||
|
@ -903,11 +909,23 @@ class Assembler : public AssemblerBase {
|
||||||
// This is shorter than
|
// This is shorter than
|
||||||
// shlq reg, 32
|
// shlq reg, 32
|
||||||
// sraq reg, 33
|
// sraq reg, 33
|
||||||
sarl(reg, Immediate(1));
|
sarl(reg, Immediate(kSmiTagSize));
|
||||||
movsxd(reg, reg);
|
movsxd(reg, reg);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SmiUntagAndSignExtend(Register dst, Register src) {
|
||||||
|
#if !defined(DART_COMPRESSED_POINTERS)
|
||||||
|
if (dst != src) {
|
||||||
|
movq(dst, src);
|
||||||
|
}
|
||||||
|
sarq(dst, Immediate(kSmiTagSize));
|
||||||
|
#else
|
||||||
|
movsxd(dst, src);
|
||||||
|
sarq(dst, Immediate(kSmiTagSize));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void BranchIfNotSmi(Register reg,
|
void BranchIfNotSmi(Register reg,
|
||||||
Label* label,
|
Label* label,
|
||||||
JumpDistance distance = kFarJump) {
|
JumpDistance distance = kFarJump) {
|
||||||
|
|
|
@ -4074,7 +4074,11 @@ LocationSummary* UnboxInstr::MakeLocationSummary(Zone* zone, bool opt) const {
|
||||||
summary->set_in(0, needs_writable_input ? Location::WritableRegister()
|
summary->set_in(0, needs_writable_input ? Location::WritableRegister()
|
||||||
: Location::RequiresRegister());
|
: Location::RequiresRegister());
|
||||||
if (RepresentationUtils::IsUnboxedInteger(representation())) {
|
if (RepresentationUtils::IsUnboxedInteger(representation())) {
|
||||||
|
#if !defined(DART_COMPRESSED_POINTERS)
|
||||||
summary->set_out(0, Location::SameAsFirstInput());
|
summary->set_out(0, Location::SameAsFirstInput());
|
||||||
|
#else
|
||||||
|
summary->set_out(0, Location::RequiresRegister());
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
summary->set_out(0, Location::RequiresFpuRegister());
|
summary->set_out(0, Location::RequiresFpuRegister());
|
||||||
}
|
}
|
||||||
|
@ -4122,14 +4126,16 @@ void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
|
||||||
const Register box = locs()->in(0).reg();
|
const Register box = locs()->in(0).reg();
|
||||||
|
|
||||||
switch (representation()) {
|
switch (representation()) {
|
||||||
case kUnboxedInt32:
|
case kUnboxedInt32: {
|
||||||
case kUnboxedInt64: {
|
|
||||||
const Register result = locs()->out(0).reg();
|
const Register result = locs()->out(0).reg();
|
||||||
ASSERT(result == box);
|
__ SmiUntag(result, box);
|
||||||
__ SmiUntagAndSignExtend(box);
|
break;
|
||||||
|
}
|
||||||
|
case kUnboxedInt64: {
|
||||||
|
const Register result = locs()->out(0).reg();
|
||||||
|
__ SmiUntagAndSignExtend(result, box);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case kUnboxedDouble: {
|
case kUnboxedDouble: {
|
||||||
const FpuRegister result = locs()->out(0).fpu_reg();
|
const FpuRegister result = locs()->out(0).fpu_reg();
|
||||||
__ SmiUntag(box);
|
__ SmiUntag(box);
|
||||||
|
@ -4146,22 +4152,18 @@ void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
|
||||||
void UnboxInstr::EmitLoadInt32FromBoxOrSmi(FlowGraphCompiler* compiler) {
|
void UnboxInstr::EmitLoadInt32FromBoxOrSmi(FlowGraphCompiler* compiler) {
|
||||||
const Register value = locs()->in(0).reg();
|
const Register value = locs()->in(0).reg();
|
||||||
const Register result = locs()->out(0).reg();
|
const Register result = locs()->out(0).reg();
|
||||||
ASSERT(value == result);
|
|
||||||
compiler::Label done;
|
compiler::Label done;
|
||||||
#if !defined(DART_COMPRESSED_POINTERS)
|
#if !defined(DART_COMPRESSED_POINTERS)
|
||||||
|
ASSERT(value == result);
|
||||||
__ SmiUntag(value);
|
__ SmiUntag(value);
|
||||||
__ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
|
__ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
|
||||||
__ movsxw(result, compiler::Address(value, TIMES_2, Mint::value_offset()));
|
__ movsxw(result, compiler::Address(value, TIMES_2, Mint::value_offset()));
|
||||||
#else
|
#else
|
||||||
// Cannot speculatively untag because it erases the upper bits needed to
|
ASSERT(value != result);
|
||||||
// dereference when it is a Mint.
|
// Cannot speculatively untag with value == result because it erases the
|
||||||
// TODO(compressed-pointers): It would probably be cheaper to make
|
// upper bits needed to dereference when it is a Mint.
|
||||||
// result != value with compressed pointers.
|
__ SmiUntagAndSignExtend(result, value);
|
||||||
compiler::Label not_smi;
|
__ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
|
||||||
__ BranchIfNotSmi(value, ¬_smi, compiler::Assembler::kNearJump);
|
|
||||||
__ SmiUntagAndSignExtend(value);
|
|
||||||
__ jmp(&done, compiler::Assembler::kNearJump);
|
|
||||||
__ Bind(¬_smi);
|
|
||||||
__ movsxw(result, compiler::FieldAddress(value, Mint::value_offset()));
|
__ movsxw(result, compiler::FieldAddress(value, Mint::value_offset()));
|
||||||
#endif
|
#endif
|
||||||
__ Bind(&done);
|
__ Bind(&done);
|
||||||
|
@ -4170,24 +4172,21 @@ void UnboxInstr::EmitLoadInt32FromBoxOrSmi(FlowGraphCompiler* compiler) {
|
||||||
void UnboxInstr::EmitLoadInt64FromBoxOrSmi(FlowGraphCompiler* compiler) {
|
void UnboxInstr::EmitLoadInt64FromBoxOrSmi(FlowGraphCompiler* compiler) {
|
||||||
const Register value = locs()->in(0).reg();
|
const Register value = locs()->in(0).reg();
|
||||||
const Register result = locs()->out(0).reg();
|
const Register result = locs()->out(0).reg();
|
||||||
ASSERT(value == result);
|
|
||||||
compiler::Label done;
|
compiler::Label done;
|
||||||
#if !defined(DART_COMPRESSED_POINTERS)
|
#if !defined(DART_COMPRESSED_POINTERS)
|
||||||
|
ASSERT(value == result);
|
||||||
__ SmiUntag(value);
|
__ SmiUntag(value);
|
||||||
__ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
|
__ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
|
||||||
__ movq(value, compiler::Address(value, TIMES_2, Mint::value_offset()));
|
__ movq(result, compiler::Address(value, TIMES_2, Mint::value_offset()));
|
||||||
__ Bind(&done);
|
|
||||||
#else
|
#else
|
||||||
// Cannot speculatively untag because it erases the upper bits needed to
|
ASSERT(value != result);
|
||||||
// dereference when it is a Mint.
|
// Cannot speculatively untag with value == result because it erases the
|
||||||
compiler::Label not_smi;
|
// upper bits needed to dereference when it is a Mint.
|
||||||
__ BranchIfNotSmi(value, ¬_smi, compiler::Assembler::kNearJump);
|
__ SmiUntagAndSignExtend(result, value);
|
||||||
__ SmiUntagAndSignExtend(value);
|
__ j(NOT_CARRY, &done, compiler::Assembler::kNearJump);
|
||||||
__ jmp(&done, compiler::Assembler::kNearJump);
|
__ movq(result, compiler::FieldAddress(value, Mint::value_offset()));
|
||||||
__ Bind(¬_smi);
|
|
||||||
__ movq(value, compiler::FieldAddress(value, Mint::value_offset()));
|
|
||||||
__ Bind(&done);
|
|
||||||
#endif
|
#endif
|
||||||
|
__ Bind(&done);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone,
|
LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone,
|
||||||
|
|
Loading…
Reference in a new issue