Handle holes in smi-untag from LoadKeyed requiring hole handling.
R=jkummerow@chromium.org Review URL: https://chromiumcodereview.appspot.com/15737003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14756 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b353b1d131
commit
d1b5a2518d
@ -1900,6 +1900,13 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
if (instr->value()->type().IsSmi()) {
|
||||
value = UseRegisterAtStart(instr->value());
|
||||
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 {
|
||||
value = UseRegister(instr->value());
|
||||
LOperand* temp1 = TempRegister();
|
||||
|
@ -2087,6 +2087,7 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
bool needs_check() const { return needs_check_; }
|
||||
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change);
|
||||
DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
|
||||
|
||||
private:
|
||||
|
@ -4905,6 +4905,21 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
||||
// If the input is a HeapObject, SmiUntag will set the carry flag.
|
||||
__ SmiUntag(result, input, SetCC);
|
||||
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 {
|
||||
__ SmiUntag(result, input);
|
||||
}
|
||||
|
@ -5411,7 +5411,7 @@ class HLoadKeyed
|
||||
IsFastDoubleElementsKind(elements_kind));
|
||||
|
||||
if (IsFastSmiOrObjectElementsKind(elements_kind)) {
|
||||
if (elements_kind == FAST_SMI_ELEMENTS) {
|
||||
if (IsFastSmiElementsKind(elements_kind)) {
|
||||
set_type(HType::Smi());
|
||||
}
|
||||
|
||||
|
@ -5026,14 +5026,30 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) {
|
||||
|
||||
void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
||||
LOperand* input = instr->value();
|
||||
Register result = ToRegister(input);
|
||||
ASSERT(input->IsRegister() && input->Equals(instr->result()));
|
||||
if (instr->needs_check()) {
|
||||
__ test(ToRegister(input), Immediate(kSmiTagMask));
|
||||
__ test(result, Immediate(kSmiTagMask));
|
||||
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 {
|
||||
__ AssertSmi(ToRegister(input));
|
||||
__ AssertSmi(result);
|
||||
}
|
||||
__ SmiUntag(ToRegister(input));
|
||||
__ SmiUntag(result);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1929,7 +1929,16 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
ASSERT(to.IsInteger32());
|
||||
if (instr->value()->type().IsSmi()) {
|
||||
LOperand* value = UseRegister(instr->value());
|
||||
return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
|
||||
LInstruction* result =
|
||||
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 {
|
||||
bool truncating = instr->CanTruncateToInt32();
|
||||
if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
|
||||
|
@ -2153,6 +2153,7 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change);
|
||||
|
||||
bool needs_check() const { return needs_check_; }
|
||||
|
||||
|
@ -4606,6 +4606,21 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
||||
if (instr->needs_check()) {
|
||||
Condition is_smi = __ CheckSmi(input);
|
||||
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 {
|
||||
__ AssertSmi(input);
|
||||
}
|
||||
|
@ -1825,7 +1825,16 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
||||
ASSERT(to.IsInteger32());
|
||||
LOperand* value = UseRegister(instr->value());
|
||||
if (instr->value()->type().IsSmi()) {
|
||||
return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
|
||||
LInstruction* result =
|
||||
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 {
|
||||
bool truncating = instr->CanTruncateToInt32();
|
||||
LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
|
||||
|
@ -2011,6 +2011,7 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
bool needs_check() const { return needs_check_; }
|
||||
|
||||
DECLARE_HYDROGEN_ACCESSOR(Change);
|
||||
DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user