Commit 2a28f53b authored by verwaest@chromium.org's avatar verwaest@chromium.org

Fix hole handling, and ensure smi representation is handled properly

R=jkummerow@chromium.org

Review URL: https://chromiumcodereview.appspot.com/16013003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14807 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 77f85fa0
...@@ -710,9 +710,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { ...@@ -710,9 +710,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
LInstruction* LChunkBuilder::DoShift(Token::Value op, LInstruction* LChunkBuilder::DoShift(Token::Value op,
HBitwiseBinaryOperation* instr) { HBitwiseBinaryOperation* instr) {
if (instr->representation().IsTagged()) { if (instr->representation().IsSmiOrTagged()) {
ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->left()->representation().IsSmiOrTagged());
ASSERT(instr->right()->representation().IsTagged()); ASSERT(instr->right()->representation().IsSmiOrTagged());
LOperand* left = UseFixed(instr->left(), r1); LOperand* left = UseFixed(instr->left(), r1);
LOperand* right = UseFixed(instr->right(), r0); LOperand* right = UseFixed(instr->right(), r0);
...@@ -780,8 +780,8 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, ...@@ -780,8 +780,8 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
op == Token::SUB); op == Token::SUB);
HValue* left = instr->left(); HValue* left = instr->left();
HValue* right = instr->right(); HValue* right = instr->right();
ASSERT(left->representation().IsTagged()); ASSERT(left->representation().IsSmiOrTagged());
ASSERT(right->representation().IsTagged()); ASSERT(right->representation().IsSmiOrTagged());
LOperand* left_operand = UseFixed(left, r1); LOperand* left_operand = UseFixed(left, r1);
LOperand* right_operand = UseFixed(right, r0); LOperand* right_operand = UseFixed(right, r0);
LArithmeticT* result = LArithmeticT* result =
...@@ -1303,9 +1303,9 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { ...@@ -1303,9 +1303,9 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
return DefineAsRegister(new(zone()) LBitI(left, right)); return DefineAsRegister(new(zone()) LBitI(left, right));
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->left()->representation().IsSmiOrTagged());
ASSERT(instr->right()->representation().IsTagged()); ASSERT(instr->right()->representation().IsSmiOrTagged());
LOperand* left = UseFixed(instr->left(), r1); LOperand* left = UseFixed(instr->left(), r1);
LOperand* right = UseFixed(instr->right(), r0); LOperand* right = UseFixed(instr->right(), r0);
...@@ -1459,7 +1459,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) { ...@@ -1459,7 +1459,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
} else { } else {
return DefineAsRegister(mod); return DefineAsRegister(mod);
} }
} else if (instr->representation().IsTagged()) { } else if (instr->representation().IsSmiOrTagged()) {
return DoArithmeticT(Token::MOD, instr); return DoArithmeticT(Token::MOD, instr);
} else { } else {
ASSERT(instr->representation().IsDouble()); ASSERT(instr->representation().IsDouble());
...@@ -1617,7 +1617,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { ...@@ -1617,7 +1617,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
return DoArithmeticD(Token::ADD, instr); return DoArithmeticD(Token::ADD, instr);
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
return DoArithmeticT(Token::ADD, instr); return DoArithmeticT(Token::ADD, instr);
} }
} }
...@@ -1889,12 +1889,6 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { ...@@ -1889,12 +1889,6 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
if (from.IsSmi()) { if (from.IsSmi()) {
if (to.IsTagged()) { if (to.IsTagged()) {
LOperand* value = UseRegister(instr->value()); LOperand* value = UseRegister(instr->value());
// For now, always deopt on hole.
if (instr->value()->IsLoadKeyed() &&
HLoadKeyed::cast(instr->value())->UsesMustHandleHole()) {
return AssignEnvironment(
DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value)));
}
return DefineSameAsFirst(new(zone()) LDummyUse(value)); return DefineSameAsFirst(new(zone()) LDummyUse(value));
} }
from = Representation::Tagged(); from = Representation::Tagged();
...@@ -1920,13 +1914,6 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { ...@@ -1920,13 +1914,6 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
if (instr->value()->type().IsSmi()) { if (instr->value()->type().IsSmi()) {
value = UseRegisterAtStart(instr->value()); value = UseRegisterAtStart(instr->value());
res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
if (instr->value()->IsLoadKeyed()) {
HLoadKeyed* load_keyed = HLoadKeyed::cast(instr->value());
if (load_keyed->UsesMustHandleHole() &&
load_keyed->hole_mode() == NEVER_RETURN_HOLE) {
res = AssignEnvironment(res);
}
}
} else { } else {
value = UseRegister(instr->value()); value = UseRegister(instr->value());
LOperand* temp1 = TempRegister(); LOperand* temp1 = TempRegister();
......
...@@ -2122,7 +2122,6 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> { ...@@ -2122,7 +2122,6 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
LOperand* value() { return inputs_[0]; } LOperand* value() { return inputs_[0]; }
bool needs_check() const { return needs_check_; } bool needs_check() const { return needs_check_; }
DECLARE_HYDROGEN_ACCESSOR(Change);
DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag") DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
private: private:
......
...@@ -3952,7 +3952,10 @@ void LCodeGen::DoPower(LPower* instr) { ...@@ -3952,7 +3952,10 @@ void LCodeGen::DoPower(LPower* instr) {
ASSERT(ToDoubleRegister(instr->left()).is(d1)); ASSERT(ToDoubleRegister(instr->left()).is(d1));
ASSERT(ToDoubleRegister(instr->result()).is(d3)); ASSERT(ToDoubleRegister(instr->result()).is(d3));
if (exponent_type.IsTagged()) { if (exponent_type.IsSmi()) {
MathPowStub stub(MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsTagged()) {
Label no_deopt; Label no_deopt;
__ JumpIfSmi(r2, &no_deopt); __ JumpIfSmi(r2, &no_deopt);
__ ldr(r7, FieldMemOperand(r2, HeapObject::kMapOffset)); __ ldr(r7, FieldMemOperand(r2, HeapObject::kMapOffset));
...@@ -4942,21 +4945,6 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) { ...@@ -4942,21 +4945,6 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
// If the input is a HeapObject, SmiUntag will set the carry flag. // If the input is a HeapObject, SmiUntag will set the carry flag.
__ SmiUntag(result, input, SetCC); __ SmiUntag(result, input, SetCC);
DeoptimizeIf(cs, instr->environment()); DeoptimizeIf(cs, instr->environment());
} else if (instr->hydrogen()->value()->IsLoadKeyed()) {
HLoadKeyed* load = HLoadKeyed::cast(instr->hydrogen()->value());
if (load->UsesMustHandleHole()) {
__ SmiUntag(result, input, SetCC);
if (load->hole_mode() == ALLOW_RETURN_HOLE) {
Label done;
__ b(cc, &done);
__ mov(result, Operand(Smi::FromInt(0)));
__ bind(&done);
} else {
DeoptimizeIf(cs, instr->environment());
}
} else {
__ SmiUntag(result, input);
}
} else { } else {
__ SmiUntag(result, input); __ SmiUntag(result, input);
} }
......
...@@ -2716,7 +2716,7 @@ bool HLoadKeyed::UsesMustHandleHole() const { ...@@ -2716,7 +2716,7 @@ bool HLoadKeyed::UsesMustHandleHole() const {
for (HUseIterator it(uses()); !it.Done(); it.Advance()) { for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
HValue* use = it.value(); HValue* use = it.value();
if (!use->IsChange()) { if (!use->IsChange() || !HChange::cast(use)->to().IsDouble()) {
return false; return false;
} }
} }
......
...@@ -5467,7 +5467,9 @@ class HLoadKeyed ...@@ -5467,7 +5467,9 @@ class HLoadKeyed
IsFastDoubleElementsKind(elements_kind)); IsFastDoubleElementsKind(elements_kind));
if (IsFastSmiOrObjectElementsKind(elements_kind)) { if (IsFastSmiOrObjectElementsKind(elements_kind)) {
if (IsFastSmiElementsKind(elements_kind)) { if (IsFastSmiElementsKind(elements_kind) &&
(!IsHoleyElementsKind(elements_kind) ||
mode == NEVER_RETURN_HOLE)) {
set_type(HType::Smi()); set_type(HType::Smi());
set_representation(Representation::Smi()); set_representation(Representation::Smi());
} else { } else {
...@@ -5773,6 +5775,7 @@ class HStoreKeyed ...@@ -5773,6 +5775,7 @@ class HStoreKeyed
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
// kind_fast: tagged[int32] = tagged // kind_fast: tagged[int32] = tagged
// kind_double: tagged[int32] = double // kind_double: tagged[int32] = double
// kind_smi : tagged[int32] = smi
// kind_external: external[int32] = (double | int32) // kind_external: external[int32] = (double | int32)
if (index == 0) { if (index == 0) {
return is_external() ? Representation::External() return is_external() ? Representation::External()
...@@ -5801,6 +5804,9 @@ class HStoreKeyed ...@@ -5801,6 +5804,9 @@ class HStoreKeyed
virtual Representation observed_input_representation(int index) { virtual Representation observed_input_representation(int index) {
if (index < 2) return RequiredInputRepresentation(index); if (index < 2) return RequiredInputRepresentation(index);
if (IsFastSmiElementsKind(elements_kind())) {
return Representation::Smi();
}
if (IsDoubleOrFloatElementsKind(elements_kind())) { if (IsDoubleOrFloatElementsKind(elements_kind())) {
return Representation::Double(); return Representation::Double();
} }
......
...@@ -3935,7 +3935,10 @@ void LCodeGen::DoPower(LPower* instr) { ...@@ -3935,7 +3935,10 @@ void LCodeGen::DoPower(LPower* instr) {
ASSERT(ToDoubleRegister(instr->left()).is(xmm2)); ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
if (exponent_type.IsTagged()) { if (exponent_type.IsSmi()) {
MathPowStub stub(MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsTagged()) {
Label no_deopt; Label no_deopt;
__ JumpIfSmi(eax, &no_deopt); __ JumpIfSmi(eax, &no_deopt);
__ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx); __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx);
...@@ -5058,21 +5061,6 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) { ...@@ -5058,21 +5061,6 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
if (instr->needs_check()) { if (instr->needs_check()) {
__ test(result, Immediate(kSmiTagMask)); __ test(result, Immediate(kSmiTagMask));
DeoptimizeIf(not_zero, instr->environment()); DeoptimizeIf(not_zero, instr->environment());
} else if (instr->hydrogen()->value()->IsLoadKeyed()) {
HLoadKeyed* load = HLoadKeyed::cast(instr->hydrogen()->value());
if (load->UsesMustHandleHole()) {
__ test(result, Immediate(kSmiTagMask));
if (load->hole_mode() == ALLOW_RETURN_HOLE) {
Label done;
__ j(equal, &done);
__ xor_(result, result);
__ bind(&done);
} else {
DeoptimizeIf(not_zero, instr->environment());
}
} else {
__ AssertSmi(result);
}
} else { } else {
__ AssertSmi(result); __ AssertSmi(result);
} }
......
...@@ -769,9 +769,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { ...@@ -769,9 +769,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
LInstruction* LChunkBuilder::DoShift(Token::Value op, LInstruction* LChunkBuilder::DoShift(Token::Value op,
HBitwiseBinaryOperation* instr) { HBitwiseBinaryOperation* instr) {
if (instr->representation().IsTagged()) { if (instr->representation().IsSmiOrTagged()) {
ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->left()->representation().IsSmiOrTagged());
ASSERT(instr->right()->representation().IsTagged()); ASSERT(instr->right()->representation().IsSmiOrTagged());
LOperand* context = UseFixed(instr->context(), esi); LOperand* context = UseFixed(instr->context(), esi);
LOperand* left = UseFixed(instr->left(), edx); LOperand* left = UseFixed(instr->left(), edx);
...@@ -840,8 +840,8 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, ...@@ -840,8 +840,8 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
op == Token::SUB); op == Token::SUB);
HValue* left = instr->left(); HValue* left = instr->left();
HValue* right = instr->right(); HValue* right = instr->right();
ASSERT(left->representation().IsTagged()); ASSERT(left->representation().IsSmiOrTagged());
ASSERT(right->representation().IsTagged()); ASSERT(right->representation().IsSmiOrTagged());
LOperand* context = UseFixed(instr->context(), esi); LOperand* context = UseFixed(instr->context(), esi);
LOperand* left_operand = UseFixed(left, edx); LOperand* left_operand = UseFixed(left, edx);
LOperand* right_operand = UseFixed(right, eax); LOperand* right_operand = UseFixed(right, eax);
...@@ -1391,9 +1391,9 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { ...@@ -1391,9 +1391,9 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
return DefineSameAsFirst(new(zone()) LBitI(left, right)); return DefineSameAsFirst(new(zone()) LBitI(left, right));
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->left()->representation().IsSmiOrTagged());
ASSERT(instr->right()->representation().IsTagged()); ASSERT(instr->right()->representation().IsSmiOrTagged());
LOperand* context = UseFixed(instr->context(), esi); LOperand* context = UseFixed(instr->context(), esi);
LOperand* left = UseFixed(instr->left(), edx); LOperand* left = UseFixed(instr->left(), edx);
...@@ -1434,7 +1434,7 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { ...@@ -1434,7 +1434,7 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
LDivI* result = new(zone()) LDivI(dividend, divisor, temp); LDivI* result = new(zone()) LDivI(dividend, divisor, temp);
return AssignEnvironment(DefineFixed(result, eax)); return AssignEnvironment(DefineFixed(result, eax));
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
return DoArithmeticT(Token::DIV, instr); return DoArithmeticT(Token::DIV, instr);
} }
} }
...@@ -1537,7 +1537,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) { ...@@ -1537,7 +1537,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
instr->CheckFlag(HValue::kCanOverflow)) instr->CheckFlag(HValue::kCanOverflow))
? AssignEnvironment(result) ? AssignEnvironment(result)
: result; : result;
} else if (instr->representation().IsTagged()) { } else if (instr->representation().IsSmiOrTagged()) {
return DoArithmeticT(Token::MOD, instr); return DoArithmeticT(Token::MOD, instr);
} else { } else {
ASSERT(instr->representation().IsDouble()); ASSERT(instr->representation().IsDouble());
...@@ -1571,7 +1571,7 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) { ...@@ -1571,7 +1571,7 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
} else if (instr->representation().IsDouble()) { } else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::MUL, instr); return DoArithmeticD(Token::MUL, instr);
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
return DoArithmeticT(Token::MUL, instr); return DoArithmeticT(Token::MUL, instr);
} }
} }
...@@ -1592,7 +1592,7 @@ LInstruction* LChunkBuilder::DoSub(HSub* instr) { ...@@ -1592,7 +1592,7 @@ LInstruction* LChunkBuilder::DoSub(HSub* instr) {
} else if (instr->representation().IsDouble()) { } else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::SUB, instr); return DoArithmeticD(Token::SUB, instr);
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
return DoArithmeticT(Token::SUB, instr); return DoArithmeticT(Token::SUB, instr);
} }
} }
...@@ -1624,7 +1624,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { ...@@ -1624,7 +1624,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
} else if (instr->representation().IsDouble()) { } else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::ADD, instr); return DoArithmeticD(Token::ADD, instr);
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
return DoArithmeticT(Token::ADD, instr); return DoArithmeticT(Token::ADD, instr);
} }
} }
...@@ -1668,7 +1668,7 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) { ...@@ -1668,7 +1668,7 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
LInstruction* LChunkBuilder::DoRandom(HRandom* instr) { LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
ASSERT(instr->representation().IsDouble()); ASSERT(instr->representation().IsDouble());
ASSERT(instr->global_object()->representation().IsTagged()); ASSERT(instr->global_object()->representation().IsSmiOrTagged());
LOperand* global_object = UseFixed(instr->global_object(), eax); LOperand* global_object = UseFixed(instr->global_object(), eax);
LRandom* result = new(zone()) LRandom(global_object); LRandom* result = new(zone()) LRandom(global_object);
return MarkAsCall(DefineFixedDouble(result, xmm1), instr); return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
...@@ -1676,8 +1676,8 @@ LInstruction* LChunkBuilder::DoRandom(HRandom* instr) { ...@@ -1676,8 +1676,8 @@ LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->left()->representation().IsSmiOrTagged());
ASSERT(instr->right()->representation().IsTagged()); ASSERT(instr->right()->representation().IsSmiOrTagged());
LOperand* context = UseFixed(instr->context(), esi); LOperand* context = UseFixed(instr->context(), esi);
LOperand* left = UseFixed(instr->left(), edx); LOperand* left = UseFixed(instr->left(), edx);
LOperand* right = UseFixed(instr->right(), eax); LOperand* right = UseFixed(instr->right(), eax);
...@@ -1729,7 +1729,7 @@ LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch( ...@@ -1729,7 +1729,7 @@ LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch(
LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
ASSERT(instr->value()->representation().IsTagged()); ASSERT(instr->value()->representation().IsSmiOrTagged());
LOperand* temp = TempRegister(); LOperand* temp = TempRegister();
return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp); return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp);
} }
...@@ -1750,7 +1750,7 @@ LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) { ...@@ -1750,7 +1750,7 @@ LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
LInstruction* LChunkBuilder::DoIsUndetectableAndBranch( LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
HIsUndetectableAndBranch* instr) { HIsUndetectableAndBranch* instr) {
ASSERT(instr ->value()->representation().IsTagged()); ASSERT(instr->value()->representation().IsTagged());
return new(zone()) LIsUndetectableAndBranch( return new(zone()) LIsUndetectableAndBranch(
UseRegisterAtStart(instr->value()), TempRegister()); UseRegisterAtStart(instr->value()), TempRegister());
} }
...@@ -1909,14 +1909,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { ...@@ -1909,14 +1909,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
if (from.IsSmi()) { if (from.IsSmi()) {
if (to.IsTagged()) { if (to.IsTagged()) {
LOperand* value = UseRegister(instr->value()); LOperand* value = UseRegister(instr->value());
// For now, always deopt on hole. return DefineSameAsFirst(new(zone()) LDummyUse(value));
if (instr->value()->IsLoadKeyed() &&
HLoadKeyed::cast(instr->value())->UsesMustHandleHole()) {
return AssignEnvironment(
DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value)));
} else {
return DefineSameAsFirst(new(zone()) LDummyUse(value));
}
} }
from = Representation::Tagged(); from = Representation::Tagged();
} }
...@@ -1949,16 +1942,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { ...@@ -1949,16 +1942,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
ASSERT(to.IsInteger32()); ASSERT(to.IsInteger32());
if (instr->value()->type().IsSmi()) { if (instr->value()->type().IsSmi()) {
LOperand* value = UseRegister(instr->value()); LOperand* value = UseRegister(instr->value());
LInstruction* result = return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
if (instr->value()->IsLoadKeyed()) {
HLoadKeyed* load_keyed = HLoadKeyed::cast(instr->value());
if (load_keyed->UsesMustHandleHole() &&
load_keyed->hole_mode() == NEVER_RETURN_HOLE) {
return AssignEnvironment(result);
}
}
return result;
} else { } else {
bool truncating = instr->CanTruncateToInt32(); bool truncating = instr->CanTruncateToInt32();
if (CpuFeatures::IsSafeForSnapshot(SSE2)) { if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
...@@ -2099,7 +2083,7 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { ...@@ -2099,7 +2083,7 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
LOperand* reg = UseFixed(value, eax); LOperand* reg = UseFixed(value, eax);
return DefineFixed(new(zone()) LClampIToUint8(reg), eax); return DefineFixed(new(zone()) LClampIToUint8(reg), eax);
} else { } else {
ASSERT(input_rep.IsTagged()); ASSERT(input_rep.IsSmiOrTagged());
if (CpuFeatures::IsSupported(SSE2)) { if (CpuFeatures::IsSupported(SSE2)) {
LOperand* reg = UseFixed(value, eax); LOperand* reg = UseFixed(value, eax);
// Register allocator doesn't (yet) support allocation of double // Register allocator doesn't (yet) support allocation of double
......
...@@ -2182,7 +2182,6 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> { ...@@ -2182,7 +2182,6 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
LOperand* value() { return inputs_[0]; } LOperand* value() { return inputs_[0]; }
DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag") DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
DECLARE_HYDROGEN_ACCESSOR(Change);
bool needs_check() const { return needs_check_; } bool needs_check() const { return needs_check_; }
......
...@@ -3648,7 +3648,10 @@ void LCodeGen::DoPower(LPower* instr) { ...@@ -3648,7 +3648,10 @@ void LCodeGen::DoPower(LPower* instr) {
ASSERT(ToDoubleRegister(instr->left()).is(xmm2)); ASSERT(ToDoubleRegister(instr->left()).is(xmm2));
ASSERT(ToDoubleRegister(instr->result()).is(xmm3)); ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
if (exponent_type.IsTagged()) { if (exponent_type.IsSmi()) {
MathPowStub stub(MathPowStub::TAGGED);
__ CallStub(&stub);
} else if (exponent_type.IsTagged()) {
Label no_deopt; Label no_deopt;
__ JumpIfSmi(exponent, &no_deopt); __ JumpIfSmi(exponent, &no_deopt);
__ CmpObjectType(exponent, HEAP_NUMBER_TYPE, rcx); __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, rcx);
...@@ -4645,21 +4648,6 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) { ...@@ -4645,21 +4648,6 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
if (instr->needs_check()) { if (instr->needs_check()) {
Condition is_smi = __ CheckSmi(input); Condition is_smi = __ CheckSmi(input);
DeoptimizeIf(NegateCondition(is_smi), instr->environment()); DeoptimizeIf(NegateCondition(is_smi), instr->environment());
} else if (instr->hydrogen()->value()->IsLoadKeyed()) {
HLoadKeyed* load = HLoadKeyed::cast(instr->hydrogen()->value());
if (load->UsesMustHandleHole()) {
Condition cc = masm()->CheckSmi(input);
if (load->hole_mode() == ALLOW_RETURN_HOLE) {
Label done;
__ j(cc, &done);
__ xor_(input, input);
__ bind(&done);
} else {
DeoptimizeIf(NegateCondition(cc), instr->environment());
}
} else {
__ AssertSmi(input);
}
} else { } else {
__ AssertSmi(input); __ AssertSmi(input);
} }
......
...@@ -718,9 +718,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { ...@@ -718,9 +718,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
LInstruction* LChunkBuilder::DoShift(Token::Value op, LInstruction* LChunkBuilder::DoShift(Token::Value op,
HBitwiseBinaryOperation* instr) { HBitwiseBinaryOperation* instr) {
if (instr->representation().IsTagged()) { if (instr->representation().IsSmiOrTagged()) {
ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->left()->representation().IsSmiOrTagged());
ASSERT(instr->right()->representation().IsTagged()); ASSERT(instr->right()->representation().IsSmiOrTagged());
LOperand* left = UseFixed(instr->left(), rdx); LOperand* left = UseFixed(instr->left(), rdx);
LOperand* right = UseFixed(instr->right(), rax); LOperand* right = UseFixed(instr->right(), rax);
...@@ -788,8 +788,8 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, ...@@ -788,8 +788,8 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
op == Token::SUB); op == Token::SUB);
HValue* left = instr->left(); HValue* left = instr->left();
HValue* right = instr->right(); HValue* right = instr->right();
ASSERT(left->representation().IsTagged()); ASSERT(left->representation().IsSmiOrTagged());
ASSERT(right->representation().IsTagged()); ASSERT(right->representation().IsSmiOrTagged());
LOperand* left_operand = UseFixed(left, rdx); LOperand* left_operand = UseFixed(left, rdx);
LOperand* right_operand = UseFixed(right, rax); LOperand* right_operand = UseFixed(right, rax);
LArithmeticT* result = LArithmeticT* result =
...@@ -1308,9 +1308,9 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { ...@@ -1308,9 +1308,9 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
return DefineSameAsFirst(new(zone()) LBitI(left, right)); return DefineSameAsFirst(new(zone()) LBitI(left, right));
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->left()->representation().IsSmiOrTagged());
ASSERT(instr->right()->representation().IsTagged()); ASSERT(instr->right()->representation().IsSmiOrTagged());
LOperand* left = UseFixed(instr->left(), rdx); LOperand* left = UseFixed(instr->left(), rdx);
LOperand* right = UseFixed(instr->right(), rax); LOperand* right = UseFixed(instr->right(), rax);
...@@ -1349,7 +1349,7 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { ...@@ -1349,7 +1349,7 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
LDivI* result = new(zone()) LDivI(dividend, divisor, temp); LDivI* result = new(zone()) LDivI(dividend, divisor, temp);
return AssignEnvironment(DefineFixed(result, rax)); return AssignEnvironment(DefineFixed(result, rax));
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
return DoArithmeticT(Token::DIV, instr); return DoArithmeticT(Token::DIV, instr);
} }
} }
...@@ -1450,7 +1450,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) { ...@@ -1450,7 +1450,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
instr->CheckFlag(HValue::kCanOverflow)) instr->CheckFlag(HValue::kCanOverflow))
? AssignEnvironment(result) ? AssignEnvironment(result)
: result; : result;
} else if (instr->representation().IsTagged()) { } else if (instr->representation().IsSmiOrTagged()) {
return DoArithmeticT(Token::MOD, instr); return DoArithmeticT(Token::MOD, instr);
} else { } else {
ASSERT(instr->representation().IsDouble()); ASSERT(instr->representation().IsDouble());
...@@ -1480,7 +1480,7 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) { ...@@ -1480,7 +1480,7 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
} else if (instr->representation().IsDouble()) { } else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::MUL, instr); return DoArithmeticD(Token::MUL, instr);
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
return DoArithmeticT(Token::MUL, instr); return DoArithmeticT(Token::MUL, instr);
} }
} }
...@@ -1501,7 +1501,7 @@ LInstruction* LChunkBuilder::DoSub(HSub* instr) { ...@@ -1501,7 +1501,7 @@ LInstruction* LChunkBuilder::DoSub(HSub* instr) {
} else if (instr->representation().IsDouble()) { } else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::SUB, instr); return DoArithmeticD(Token::SUB, instr);
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
return DoArithmeticT(Token::SUB, instr); return DoArithmeticT(Token::SUB, instr);
} }
} }
...@@ -1533,7 +1533,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { ...@@ -1533,7 +1533,7 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
} else if (instr->representation().IsDouble()) { } else if (instr->representation().IsDouble()) {
return DoArithmeticD(Token::ADD, instr); return DoArithmeticD(Token::ADD, instr);
} else { } else {
ASSERT(instr->representation().IsTagged()); ASSERT(instr->representation().IsSmiOrTagged());
return DoArithmeticT(Token::ADD, instr); return DoArithmeticT(Token::ADD, instr);
} }
return NULL; return NULL;
...@@ -1814,12 +1814,6 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { ...@@ -1814,12 +1814,6 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
if (from.IsSmi()) { if (from.IsSmi()) {
if (to.IsTagged()) { if (to.IsTagged()) {
LOperand* value = UseRegister(instr->value()); LOperand* value = UseRegister(instr->value());
// For now, always deopt on hole.
if (instr->value()->IsLoadKeyed() &&
HLoadKeyed::cast(instr->value())->UsesMustHandleHole()) {
return AssignEnvironment(
DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value)));
}
return DefineSameAsFirst(new(zone()) LDummyUse(value)); return DefineSameAsFirst(new(zone()) LDummyUse(value));
} }
from = Representation::Tagged(); from = Representation::Tagged();
...@@ -1845,16 +1839,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { ...@@ -1845,16 +1839,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
ASSERT(to.IsInteger32()); ASSERT(to.IsInteger32());
LOperand* value = UseRegister(instr->value()); LOperand* value = UseRegister(instr->value());
if (instr->value()->type().IsSmi()) { if (instr->value()->type().IsSmi()) {
LInstruction* result = return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
if (instr->value()->IsLoadKeyed()) {
HLoadKeyed* load_keyed = HLoadKeyed::cast(instr->value());
if (load_keyed->UsesMustHandleHole() &&
load_keyed->hole_mode() == NEVER_RETURN_HOLE) {
return AssignEnvironment(result);
}
}
return result;
} else { } else {
bool truncating = instr->CanTruncateToInt32(); bool truncating = instr->CanTruncateToInt32();
LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1); LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
...@@ -1971,7 +1956,7 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { ...@@ -1971,7 +1956,7 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
} else if (input_rep.IsInteger32()) { } else if (input_rep.IsInteger32()) {
return DefineSameAsFirst(new(zone()) LClampIToUint8(reg)); return DefineSameAsFirst(new(zone()) LClampIToUint8(reg));
} else { } else {
ASSERT(input_rep.IsTagged()); ASSERT(input_rep.IsSmiOrTagged());
// Register allocator doesn't (yet) support allocation of double // Register allocator doesn't (yet) support allocation of double
// temps. Reserve xmm1 explicitly. // temps. Reserve xmm1 explicitly.
LClampTToUint8* result = new(zone()) LClampTToUint8(reg, LClampTToUint8* result = new(zone()) LClampTToUint8(reg,
......
...@@ -2040,7 +2040,6 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> { ...@@ -2040,7 +2040,6 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
LOperand* value() { return inputs_[0]; } LOperand* value() { return inputs_[0]; }
bool needs_check() const { return needs_check_; } bool needs_check() const { return needs_check_; }
DECLARE_HYDROGEN_ACCESSOR(Change);
DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag") DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
private: private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment