Fix uses of range analysis results in HChange.
BUG=v8:3204 LOG=y R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/195023002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19872 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
98042ac82d
commit
750f2d98f8
@ -1152,13 +1152,11 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
}
|
||||
} else if (to.IsSmi()) {
|
||||
LOperand* value = UseRegisterAtStart(instr->value());
|
||||
LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
|
||||
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
|
||||
LUint32ToSmi* result = new(zone()) LUint32ToSmi(value);
|
||||
return AssignEnvironment(DefineAsRegister(result));
|
||||
} else {
|
||||
// This cannot deoptimize because an A64 smi can represent any int32.
|
||||
return DefineAsRegister(new(zone()) LInteger32ToSmi(value));
|
||||
result = AssignEnvironment(result);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
ASSERT(to.IsDouble());
|
||||
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
|
||||
|
@ -113,7 +113,6 @@ class LCodeGen;
|
||||
V(InstanceOfKnownGlobal) \
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(Integer32ToSmi) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsObjectAndBranch) \
|
||||
@ -191,7 +190,6 @@ class LCodeGen;
|
||||
V(Typeof) \
|
||||
V(TypeofIsAndBranch) \
|
||||
V(Uint32ToDouble) \
|
||||
V(Uint32ToSmi) \
|
||||
V(UnknownOSRValue) \
|
||||
V(WrapReceiver)
|
||||
|
||||
@ -1507,19 +1505,6 @@ class LInteger32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LInteger32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LInteger32ToSmi(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-smi")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
class LCallWithDescriptor V8_FINAL : public LTemplateResultInstruction<1> {
|
||||
public:
|
||||
LCallWithDescriptor(const CallInterfaceDescriptor* descriptor,
|
||||
@ -2334,6 +2319,7 @@ class LSmiTag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
@ -2897,19 +2883,6 @@ class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LUint32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LUint32ToSmi(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
class LCheckMapValue V8_FINAL : public LTemplateInstruction<0, 2, 1> {
|
||||
public:
|
||||
LCheckMapValue(LOperand* value, LOperand* map, LOperand* temp) {
|
||||
|
@ -3102,17 +3102,6 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
|
||||
// A64 smis can represent all Integer32 values, so this cannot deoptimize.
|
||||
ASSERT(!instr->hydrogen()->value()->HasRange() ||
|
||||
instr->hydrogen()->value()->range()->IsInSmiRange());
|
||||
|
||||
Register value = ToRegister32(instr->value());
|
||||
Register result = ToRegister(instr->result());
|
||||
__ SmiTag(result, value.X());
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
|
||||
ASSERT(ToRegister(instr->context()).is(cp));
|
||||
// The function is required to be in x1.
|
||||
@ -4723,8 +4712,14 @@ void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoSmiTag(LSmiTag* instr) {
|
||||
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
|
||||
__ SmiTag(ToRegister(instr->result()), ToRegister(instr->value()));
|
||||
HChange* hchange = instr->hydrogen();
|
||||
Register input = ToRegister(instr->value());
|
||||
Register output = ToRegister(instr->result());
|
||||
if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
||||
hchange->value()->CheckFlag(HValue::kUint32)) {
|
||||
DeoptimizeIfNegative(input.W(), instr->environment());
|
||||
}
|
||||
__ SmiTag(output, input);
|
||||
}
|
||||
|
||||
|
||||
@ -5759,21 +5754,6 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) {
|
||||
Register value = ToRegister(instr->value());
|
||||
Register result = ToRegister(instr->result());
|
||||
|
||||
if (!instr->hydrogen()->value()->HasRange() ||
|
||||
!instr->hydrogen()->value()->range()->IsInSmiRange() ||
|
||||
instr->hydrogen()->value()->range()->upper() == kMaxInt) {
|
||||
// The Range class can't express upper bounds in the (kMaxInt, kMaxUint32]
|
||||
// interval, so we treat kMaxInt as a sentinel for this entire interval.
|
||||
DeoptimizeIfNegative(value.W(), instr->environment());
|
||||
}
|
||||
__ SmiTag(result, value);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
|
||||
Register object = ToRegister(instr->value());
|
||||
Register map = ToRegister(instr->map());
|
||||
|
@ -1898,13 +1898,13 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
if (to.IsTagged()) {
|
||||
HValue* val = instr->value();
|
||||
LOperand* value = UseRegisterAtStart(val);
|
||||
if (val->CheckFlag(HInstruction::kUint32)) {
|
||||
if (!instr->CheckFlag(HValue::kCanOverflow)) {
|
||||
return DefineAsRegister(new(zone()) LSmiTag(value));
|
||||
} else if (val->CheckFlag(HInstruction::kUint32)) {
|
||||
LOperand* temp1 = TempRegister();
|
||||
LOperand* temp2 = TempRegister();
|
||||
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
|
||||
return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
|
||||
} else if (val->HasRange() && val->range()->IsInSmiRange()) {
|
||||
return DefineAsRegister(new(zone()) LSmiTag(value));
|
||||
} else {
|
||||
LOperand* temp1 = TempRegister();
|
||||
LOperand* temp2 = TempRegister();
|
||||
@ -1914,13 +1914,11 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
} else if (to.IsSmi()) {
|
||||
HValue* val = instr->value();
|
||||
LOperand* value = UseRegister(val);
|
||||
LInstruction* result = val->CheckFlag(HInstruction::kUint32)
|
||||
? DefineAsRegister(new(zone()) LUint32ToSmi(value))
|
||||
: DefineAsRegister(new(zone()) LInteger32ToSmi(value));
|
||||
if (val->HasRange() && val->range()->IsInSmiRange()) {
|
||||
return result;
|
||||
LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
|
||||
if (instr->CheckFlag(HValue::kCanOverflow)) {
|
||||
result = AssignEnvironment(result);
|
||||
}
|
||||
return AssignEnvironment(result);
|
||||
return result;
|
||||
} else {
|
||||
ASSERT(to.IsDouble());
|
||||
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
|
||||
|
@ -109,7 +109,6 @@ class LCodeGen;
|
||||
V(InstanceOfKnownGlobal) \
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(Integer32ToSmi) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsObjectAndBranch) \
|
||||
@ -181,7 +180,6 @@ class LCodeGen;
|
||||
V(Typeof) \
|
||||
V(TypeofIsAndBranch) \
|
||||
V(Uint32ToDouble) \
|
||||
V(Uint32ToSmi) \
|
||||
V(UnknownOSRValue) \
|
||||
V(WrapReceiver)
|
||||
|
||||
@ -1991,19 +1989,6 @@ class LInteger32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LInteger32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LInteger32ToSmi(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LUint32ToDouble(LOperand* value) {
|
||||
@ -2016,19 +2001,6 @@ class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LUint32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LUint32ToSmi(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
|
||||
public:
|
||||
LNumberTagI(LOperand* value, LOperand* temp1, LOperand* temp2) {
|
||||
@ -2140,6 +2112,7 @@ class LSmiTag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
|
@ -4513,20 +4513,6 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
|
||||
LOperand* input = instr->value();
|
||||
LOperand* output = instr->result();
|
||||
ASSERT(output->IsRegister());
|
||||
if (!instr->hydrogen()->value()->HasRange() ||
|
||||
!instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
||||
__ SmiTag(ToRegister(output), ToRegister(input), SetCC);
|
||||
DeoptimizeIf(vs, instr->environment());
|
||||
} else {
|
||||
__ SmiTag(ToRegister(output), ToRegister(input));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
||||
LOperand* input = instr->value();
|
||||
LOperand* output = instr->result();
|
||||
@ -4537,18 +4523,6 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) {
|
||||
LOperand* input = instr->value();
|
||||
LOperand* output = instr->result();
|
||||
if (!instr->hydrogen()->value()->HasRange() ||
|
||||
!instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
||||
__ tst(ToRegister(input), Operand(0xc0000000));
|
||||
DeoptimizeIf(ne, instr->environment());
|
||||
}
|
||||
__ SmiTag(ToRegister(output), ToRegister(input));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
|
||||
class DeferredNumberTagI V8_FINAL : public LDeferredCode {
|
||||
public:
|
||||
@ -4728,8 +4702,21 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoSmiTag(LSmiTag* instr) {
|
||||
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
|
||||
__ SmiTag(ToRegister(instr->result()), ToRegister(instr->value()));
|
||||
HChange* hchange = instr->hydrogen();
|
||||
Register input = ToRegister(instr->value());
|
||||
Register output = ToRegister(instr->result());
|
||||
if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
||||
hchange->value()->CheckFlag(HValue::kUint32)) {
|
||||
__ tst(input, Operand(0xc0000000));
|
||||
DeoptimizeIf(ne, instr->environment());
|
||||
}
|
||||
if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
||||
!hchange->value()->CheckFlag(HValue::kUint32)) {
|
||||
__ SmiTag(output, input, SetCC);
|
||||
DeoptimizeIf(vs, instr->environment());
|
||||
} else {
|
||||
__ SmiTag(output, input);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1674,6 +1674,16 @@ Range* HChange::InferRange(Zone* zone) {
|
||||
set_type(HType::Smi());
|
||||
ClearChangesFlag(kNewSpacePromotion);
|
||||
}
|
||||
if (to().IsSmiOrTagged() &&
|
||||
input_range != NULL &&
|
||||
input_range->IsInSmiRange() &&
|
||||
(!SmiValuesAre32Bits() ||
|
||||
!value()->CheckFlag(HValue::kUint32) ||
|
||||
input_range->upper() != kMaxInt)) {
|
||||
// The Range class can't express upper bounds in the (kMaxInt, kMaxUint32]
|
||||
// interval, so we treat kMaxInt as a sentinel for this entire interval.
|
||||
ClearFlag(kCanOverflow);
|
||||
}
|
||||
Range* result = (input_range != NULL)
|
||||
? input_range->Copy(zone)
|
||||
: HValue::InferRange(zone);
|
||||
|
@ -1731,6 +1731,7 @@ class HChange V8_FINAL : public HUnaryOperation {
|
||||
ASSERT(!value->representation().Equals(to));
|
||||
set_representation(to);
|
||||
SetFlag(kUseGVN);
|
||||
SetFlag(kCanOverflow);
|
||||
if (is_truncating_to_smi) {
|
||||
SetFlag(kTruncatingToSmi);
|
||||
SetFlag(kTruncatingToInt32);
|
||||
|
@ -4875,16 +4875,6 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
|
||||
Register input = ToRegister(instr->value());
|
||||
__ SmiTag(input);
|
||||
if (!instr->hydrogen()->value()->HasRange() ||
|
||||
!instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
||||
LOperand* input = instr->value();
|
||||
LOperand* output = instr->result();
|
||||
@ -4904,17 +4894,6 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) {
|
||||
Register input = ToRegister(instr->value());
|
||||
if (!instr->hydrogen()->value()->HasRange() ||
|
||||
!instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
||||
__ test(input, Immediate(0xc0000000));
|
||||
DeoptimizeIf(not_zero, instr->environment());
|
||||
}
|
||||
__ SmiTag(input);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
|
||||
class DeferredNumberTagI V8_FINAL : public LDeferredCode {
|
||||
public:
|
||||
@ -5116,10 +5095,18 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoSmiTag(LSmiTag* instr) {
|
||||
LOperand* input = instr->value();
|
||||
ASSERT(input->IsRegister() && input->Equals(instr->result()));
|
||||
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
|
||||
__ SmiTag(ToRegister(input));
|
||||
HChange* hchange = instr->hydrogen();
|
||||
Register input = ToRegister(instr->value());
|
||||
if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
||||
hchange->value()->CheckFlag(HValue::kUint32)) {
|
||||
__ test(input, Immediate(0xc0000000));
|
||||
DeoptimizeIf(not_zero, instr->environment());
|
||||
}
|
||||
__ SmiTag(input);
|
||||
if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
||||
!hchange->value()->CheckFlag(HValue::kUint32)) {
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1947,7 +1947,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
if (to.IsTagged()) {
|
||||
HValue* val = instr->value();
|
||||
LOperand* value = UseRegister(val);
|
||||
if (val->HasRange() && val->range()->IsInSmiRange()) {
|
||||
if (!instr->CheckFlag(HValue::kCanOverflow)) {
|
||||
return DefineSameAsFirst(new(zone()) LSmiTag(value));
|
||||
} else if (val->CheckFlag(HInstruction::kUint32)) {
|
||||
LOperand* temp1 = TempRegister();
|
||||
@ -1963,13 +1963,11 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
} else if (to.IsSmi()) {
|
||||
HValue* val = instr->value();
|
||||
LOperand* value = UseRegister(val);
|
||||
LInstruction* result = val->CheckFlag(HInstruction::kUint32)
|
||||
? DefineSameAsFirst(new(zone()) LUint32ToSmi(value))
|
||||
: DefineSameAsFirst(new(zone()) LInteger32ToSmi(value));
|
||||
if (val->HasRange() && val->range()->IsInSmiRange()) {
|
||||
return result;
|
||||
LInstruction* result = DefineSameAsFirst(new(zone()) LSmiTag(value));
|
||||
if (instr->CheckFlag(HValue::kCanOverflow)) {
|
||||
result = AssignEnvironment(result);
|
||||
}
|
||||
return AssignEnvironment(result);
|
||||
return result;
|
||||
} else {
|
||||
ASSERT(to.IsDouble());
|
||||
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
|
||||
|
@ -111,7 +111,6 @@ class LCodeGen;
|
||||
V(InstanceOfKnownGlobal) \
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(Integer32ToSmi) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsObjectAndBranch) \
|
||||
@ -180,7 +179,6 @@ class LCodeGen;
|
||||
V(Typeof) \
|
||||
V(TypeofIsAndBranch) \
|
||||
V(Uint32ToDouble) \
|
||||
V(Uint32ToSmi) \
|
||||
V(UnknownOSRValue) \
|
||||
V(WrapReceiver)
|
||||
|
||||
@ -2014,19 +2012,6 @@ class LInteger32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LInteger32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LInteger32ToSmi(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 1> {
|
||||
public:
|
||||
explicit LUint32ToDouble(LOperand* value, LOperand* temp) {
|
||||
@ -2041,19 +2026,6 @@ class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 1> {
|
||||
};
|
||||
|
||||
|
||||
class LUint32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LUint32ToSmi(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 1> {
|
||||
public:
|
||||
LNumberTagI(LOperand* value, LOperand* temp) {
|
||||
@ -2157,6 +2129,7 @@ class LSmiTag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
|
@ -4522,18 +4522,6 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
|
||||
LOperand* input = instr->value();
|
||||
ASSERT(input->IsRegister());
|
||||
LOperand* output = instr->result();
|
||||
__ Integer32ToSmi(ToRegister(output), ToRegister(input));
|
||||
if (!instr->hydrogen()->value()->HasRange() ||
|
||||
!instr->hydrogen()->value()->range()->IsInSmiRange()) {
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
||||
LOperand* input = instr->value();
|
||||
LOperand* output = instr->result();
|
||||
@ -4545,22 +4533,6 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) {
|
||||
LOperand* input = instr->value();
|
||||
ASSERT(input->IsRegister());
|
||||
LOperand* output = instr->result();
|
||||
if (!instr->hydrogen()->value()->HasRange() ||
|
||||
!instr->hydrogen()->value()->range()->IsInSmiRange() ||
|
||||
instr->hydrogen()->value()->range()->upper() == kMaxInt) {
|
||||
// The Range class can't express upper bounds in the (kMaxInt, kMaxUint32]
|
||||
// interval, so we treat kMaxInt as a sentinel for this entire interval.
|
||||
__ testl(ToRegister(input), Immediate(0x80000000));
|
||||
DeoptimizeIf(not_zero, instr->environment());
|
||||
}
|
||||
__ Integer32ToSmi(ToRegister(output), ToRegister(input));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
|
||||
LOperand* input = instr->value();
|
||||
ASSERT(input->IsRegister() && input->Equals(instr->result()));
|
||||
@ -4695,10 +4667,19 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoSmiTag(LSmiTag* instr) {
|
||||
ASSERT(instr->value()->Equals(instr->result()));
|
||||
HChange* hchange = instr->hydrogen();
|
||||
Register input = ToRegister(instr->value());
|
||||
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
|
||||
__ Integer32ToSmi(input, input);
|
||||
Register output = ToRegister(instr->result());
|
||||
if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
||||
hchange->value()->CheckFlag(HValue::kUint32)) {
|
||||
__ testl(input, Immediate(0x80000000));
|
||||
DeoptimizeIf(not_zero, instr->environment());
|
||||
}
|
||||
__ Integer32ToSmi(output, input);
|
||||
if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
||||
!hchange->value()->CheckFlag(HValue::kUint32)) {
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1837,13 +1837,13 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
if (to.IsTagged()) {
|
||||
HValue* val = instr->value();
|
||||
LOperand* value = UseRegister(val);
|
||||
if (val->CheckFlag(HInstruction::kUint32)) {
|
||||
if (!instr->CheckFlag(HValue::kCanOverflow)) {
|
||||
return DefineAsRegister(new(zone()) LSmiTag(value));
|
||||
} else if (val->CheckFlag(HInstruction::kUint32)) {
|
||||
LOperand* temp1 = TempRegister();
|
||||
LOperand* temp2 = FixedTemp(xmm1);
|
||||
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
|
||||
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
|
||||
} else if (val->HasRange() && val->range()->IsInSmiRange()) {
|
||||
return DefineSameAsFirst(new(zone()) LSmiTag(value));
|
||||
} else {
|
||||
LNumberTagI* result = new(zone()) LNumberTagI(value);
|
||||
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
|
||||
@ -1851,20 +1851,12 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
} else if (to.IsSmi()) {
|
||||
HValue* val = instr->value();
|
||||
LOperand* value = UseRegister(val);
|
||||
LInstruction* result = NULL;
|
||||
if (val->CheckFlag(HInstruction::kUint32)) {
|
||||
result = DefineAsRegister(new(zone()) LUint32ToSmi(value));
|
||||
if (val->HasRange() && val->range()->IsInSmiRange() &&
|
||||
val->range()->upper() != kMaxInt) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
result = DefineAsRegister(new(zone()) LInteger32ToSmi(value));
|
||||
if (val->HasRange() && val->range()->IsInSmiRange()) {
|
||||
return result;
|
||||
}
|
||||
LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
|
||||
if (instr->CheckFlag(HValue::kCanOverflow)) {
|
||||
ASSERT(val->CheckFlag(HValue::kUint32));
|
||||
result = AssignEnvironment(result);
|
||||
}
|
||||
return AssignEnvironment(result);
|
||||
return result;
|
||||
} else {
|
||||
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
|
||||
LOperand* temp = FixedTemp(xmm1);
|
||||
|
@ -109,7 +109,6 @@ class LCodeGen;
|
||||
V(InstanceOfKnownGlobal) \
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(Integer32ToSmi) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsObjectAndBranch) \
|
||||
@ -178,7 +177,6 @@ class LCodeGen;
|
||||
V(Typeof) \
|
||||
V(TypeofIsAndBranch) \
|
||||
V(Uint32ToDouble) \
|
||||
V(Uint32ToSmi) \
|
||||
V(UnknownOSRValue) \
|
||||
V(WrapReceiver)
|
||||
|
||||
@ -1956,19 +1954,6 @@ class LInteger32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LInteger32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LInteger32ToSmi(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 1> {
|
||||
public:
|
||||
explicit LUint32ToDouble(LOperand* value, LOperand* temp) {
|
||||
@ -1983,19 +1968,6 @@ class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 1> {
|
||||
};
|
||||
|
||||
|
||||
class LUint32ToSmi V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LUint32ToSmi(LOperand* value) {
|
||||
inputs_[0] = value;
|
||||
}
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Uint32ToSmi, "uint32-to-smi")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
explicit LNumberTagI(LOperand* value) {
|
||||
@ -2095,6 +2067,7 @@ class LSmiTag V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change)
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user