[turbofan] Handle the impossible value representation mismatch in instruction selector.

Review-Url: https://codereview.chromium.org/2579743002
Cr-Commit-Position: refs/heads/master@{#41718}
This commit is contained in:
jarin 2016-12-15 04:13:06 -08:00 committed by Commit bot
parent ee7281f8ff
commit 01de216fd7
2 changed files with 49 additions and 15 deletions

View File

@ -416,8 +416,8 @@ void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
namespace {
InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
FrameStateInputKind kind,
InstructionOperand OperandForDeopt(Isolate* isolate, OperandGenerator* g,
Node* input, FrameStateInputKind kind,
MachineRepresentation rep) {
if (rep == MachineRepresentation::kNone) {
return g->TempImmediate(FrameStateDescriptor::kImpossibleValue);
@ -429,8 +429,30 @@ InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
case IrOpcode::kNumberConstant:
case IrOpcode::kFloat32Constant:
case IrOpcode::kFloat64Constant:
case IrOpcode::kHeapConstant:
return g->UseImmediate(input);
case IrOpcode::kHeapConstant: {
if (!CanBeTaggedPointer(rep)) {
// If we have inconsistent static and dynamic types, e.g. if we
// smi-check a string, we can get here with a heap object that
// says it is a smi. In that case, we return an invalid instruction
// operand, which will be interpreted as an optimized-out value.
// TODO(jarin) Ideally, we should turn the current instruction
// into an abort (we should never execute it).
return InstructionOperand();
}
Handle<HeapObject> constant = OpParameter<Handle<HeapObject>>(input);
Heap::RootListIndex root_index;
if (isolate->heap()->IsRootHandle(constant, &root_index) &&
root_index == Heap::kOptimizedOutRootIndex) {
// For an optimized-out object we return an invalid instruction
// operand, so that we take the fast path for optimized-out values.
return InstructionOperand();
}
return g->UseImmediate(input);
}
case IrOpcode::kObjectState:
case IrOpcode::kTypedObjectState:
UNREACHABLE();
@ -508,19 +530,17 @@ size_t InstructionSelector::AddOperandToStateValueDescriptor(
}
}
default: {
Heap* const heap = isolate()->heap();
if (input->opcode() == IrOpcode::kHeapConstant) {
Handle<HeapObject> constant = OpParameter<Handle<HeapObject>>(input);
Heap::RootListIndex root_index;
if (heap->IsRootHandle(constant, &root_index) &&
root_index == Heap::kOptimizedOutRootIndex) {
values->PushOptimizedOut();
return 0;
}
InstructionOperand op =
OperandForDeopt(isolate(), g, input, kind, type.representation());
if (op.kind() == InstructionOperand::INVALID) {
// Invalid operand means the value is impossible or optimized-out.
values->PushOptimizedOut();
return 0;
} else {
inputs->push_back(op);
values->PushPlain(type);
return 1;
}
inputs->push_back(OperandForDeopt(g, input, kind, type.representation()));
values->PushPlain(type);
return 1;
}
}
}

View File

@ -0,0 +1,14 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
global = -1073741824;
global = 2;
function foo() {
global = "a";
global = global;
var o = global;
while (o < 2) {
}
}
foo();