Commit 09e4a11b authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Improve memory consumption for state values descriptors.

Review-Url: https://codereview.chromium.org/2546113002
Cr-Commit-Position: refs/heads/master@{#41469}
parent c17ea79e
...@@ -58,6 +58,7 @@ CodeGenerator::CodeGenerator( ...@@ -58,6 +58,7 @@ CodeGenerator::CodeGenerator(
jump_tables_(nullptr), jump_tables_(nullptr),
ools_(nullptr), ools_(nullptr),
osr_pc_offset_(-1), osr_pc_offset_(-1),
optimized_out_literal_id_(-1),
source_position_table_builder_(code->zone(), source_position_table_builder_(code->zone(),
info->SourcePositionRecordingMode()), info->SourcePositionRecordingMode()),
protected_instructions_(protected_instructions) { protected_instructions_(protected_instructions) {
...@@ -640,15 +641,6 @@ void CodeGenerator::RecordCallPosition(Instruction* instr) { ...@@ -640,15 +641,6 @@ void CodeGenerator::RecordCallPosition(Instruction* instr) {
deopt_state_id = BuildTranslation(instr, -1, frame_state_offset, deopt_state_id = BuildTranslation(instr, -1, frame_state_offset,
OutputFrameStateCombine::Ignore()); OutputFrameStateCombine::Ignore());
} }
#if DEBUG
// Make sure all the values live in stack slots or they are immediates.
// (The values should not live in register because registers are clobbered
// by calls.)
for (size_t i = 0; i < descriptor->GetSize(); i++) {
InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i);
CHECK(op->IsStackSlot() || op->IsFPStackSlot() || op->IsImmediate());
}
#endif
safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id);
} }
} }
...@@ -678,19 +670,26 @@ DeoptimizeReason CodeGenerator::GetDeoptimizationReason( ...@@ -678,19 +670,26 @@ DeoptimizeReason CodeGenerator::GetDeoptimizationReason(
} }
void CodeGenerator::TranslateStateValueDescriptor( void CodeGenerator::TranslateStateValueDescriptor(
StateValueDescriptor* desc, Translation* translation, StateValueDescriptor* desc, StateValueList* nested,
InstructionOperandIterator* iter) { Translation* translation, InstructionOperandIterator* iter) {
if (desc->IsNested()) { if (desc->IsNested()) {
translation->BeginCapturedObject(static_cast<int>(desc->size())); translation->BeginCapturedObject(static_cast<int>(nested->size()));
for (size_t index = 0; index < desc->fields().size(); index++) { for (auto field : *nested) {
TranslateStateValueDescriptor(&desc->fields()[index], translation, iter); TranslateStateValueDescriptor(field.desc, field.nested, translation,
iter);
} }
} else if (desc->IsDuplicate()) { } else if (desc->IsDuplicate()) {
translation->DuplicateObject(static_cast<int>(desc->id())); translation->DuplicateObject(static_cast<int>(desc->id()));
} else { } else if (desc->IsPlain()) {
DCHECK(desc->IsPlain());
AddTranslationForOperand(translation, iter->instruction(), iter->Advance(), AddTranslationForOperand(translation, iter->instruction(), iter->Advance(),
desc->type()); desc->type());
} else {
DCHECK(desc->IsOptimizedOut());
if (optimized_out_literal_id_ == -1) {
optimized_out_literal_id_ =
DefineDeoptimizationLiteral(isolate()->factory()->optimized_out());
}
translation->StoreLiteral(optimized_out_literal_id_);
} }
} }
...@@ -698,24 +697,11 @@ void CodeGenerator::TranslateStateValueDescriptor( ...@@ -698,24 +697,11 @@ void CodeGenerator::TranslateStateValueDescriptor(
void CodeGenerator::TranslateFrameStateDescriptorOperands( void CodeGenerator::TranslateFrameStateDescriptorOperands(
FrameStateDescriptor* desc, InstructionOperandIterator* iter, FrameStateDescriptor* desc, InstructionOperandIterator* iter,
OutputFrameStateCombine combine, Translation* translation) { OutputFrameStateCombine combine, Translation* translation) {
for (size_t index = 0; index < desc->GetSize(combine); index++) { size_t index = 0;
switch (combine.kind()) { StateValueList* values = desc->GetStateValueDescriptors();
case OutputFrameStateCombine::kPushOutput: { for (StateValueList::iterator it = values->begin(); it != values->end();
DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount()); ++it, ++index) {
size_t size_without_output = if (combine.kind() == OutputFrameStateCombine::kPokeAt) {
desc->GetSize(OutputFrameStateCombine::Ignore());
// If the index is past the existing stack items in values_.
if (index >= size_without_output) {
// Materialize the result of the call instruction in this slot.
AddTranslationForOperand(
translation, iter->instruction(),
iter->instruction()->OutputAt(index - size_without_output),
MachineType::AnyTagged());
continue;
}
break;
}
case OutputFrameStateCombine::kPokeAt:
// The result of the call should be placed at position // The result of the call should be placed at position
// [index_from_top] in the stack (overwriting whatever was // [index_from_top] in the stack (overwriting whatever was
// previously there). // previously there).
...@@ -731,11 +717,19 @@ void CodeGenerator::TranslateFrameStateDescriptorOperands( ...@@ -731,11 +717,19 @@ void CodeGenerator::TranslateFrameStateDescriptorOperands(
// advace, as the input got replaced. // advace, as the input got replaced.
continue; continue;
} }
break;
} }
StateValueDescriptor* value_desc = desc->GetStateValueDescriptor(); TranslateStateValueDescriptor((*it).desc, (*it).nested, translation, iter);
TranslateStateValueDescriptor(&value_desc->fields()[index], translation, }
iter); DCHECK_EQ(desc->GetSize(OutputFrameStateCombine::Ignore()), index);
if (combine.kind() == OutputFrameStateCombine::kPushOutput) {
DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount());
for (size_t output = 0; output < combine.GetPushCount(); output++) {
// Materialize the result of the call instruction in this slot.
AddTranslationForOperand(translation, iter->instruction(),
iter->instruction()->OutputAt(output),
MachineType::AnyTagged());
}
} }
} }
......
...@@ -218,6 +218,7 @@ class CodeGenerator final : public GapResolver::Assembler { ...@@ -218,6 +218,7 @@ class CodeGenerator final : public GapResolver::Assembler {
FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
Translation* translation, OutputFrameStateCombine state_combine); Translation* translation, OutputFrameStateCombine state_combine);
void TranslateStateValueDescriptor(StateValueDescriptor* desc, void TranslateStateValueDescriptor(StateValueDescriptor* desc,
StateValueList* nested,
Translation* translation, Translation* translation,
InstructionOperandIterator* iter); InstructionOperandIterator* iter);
void TranslateFrameStateDescriptorOperands(FrameStateDescriptor* desc, void TranslateFrameStateDescriptorOperands(FrameStateDescriptor* desc,
...@@ -284,6 +285,7 @@ class CodeGenerator final : public GapResolver::Assembler { ...@@ -284,6 +285,7 @@ class CodeGenerator final : public GapResolver::Assembler {
JumpTable* jump_tables_; JumpTable* jump_tables_;
OutOfLineCode* ools_; OutOfLineCode* ools_;
int osr_pc_offset_; int osr_pc_offset_;
int optimized_out_literal_id_;
SourcePositionTableBuilder source_position_table_builder_; SourcePositionTableBuilder source_position_table_builder_;
ZoneVector<trap_handler::ProtectedInstructionData>* protected_instructions_; ZoneVector<trap_handler::ProtectedInstructionData>* protected_instructions_;
}; };
......
...@@ -414,11 +414,8 @@ void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, ...@@ -414,11 +414,8 @@ void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node)); sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node));
} }
namespace { namespace {
enum class FrameStateInputKind { kAny, kStackSlot };
InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
FrameStateInputKind kind, FrameStateInputKind kind,
MachineRepresentation rep) { MachineRepresentation rep) {
...@@ -452,6 +449,7 @@ InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, ...@@ -452,6 +449,7 @@ InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
return InstructionOperand(); return InstructionOperand();
} }
} // namespace
class StateObjectDeduplicator { class StateObjectDeduplicator {
public: public:
...@@ -477,14 +475,11 @@ class StateObjectDeduplicator { ...@@ -477,14 +475,11 @@ class StateObjectDeduplicator {
ZoneVector<Node*> objects_; ZoneVector<Node*> objects_;
}; };
// Returns the number of instruction operands added to inputs. // Returns the number of instruction operands added to inputs.
size_t AddOperandToStateValueDescriptor(StateValueDescriptor* descriptor, size_t InstructionSelector::AddOperandToStateValueDescriptor(
InstructionOperandVector* inputs, StateValueList* values, InstructionOperandVector* inputs,
OperandGenerator* g, OperandGenerator* g, StateObjectDeduplicator* deduplicator, Node* input,
StateObjectDeduplicator* deduplicator, MachineType type, FrameStateInputKind kind, Zone* zone) {
Node* input, MachineType type,
FrameStateInputKind kind, Zone* zone) {
switch (input->opcode()) { switch (input->opcode()) {
case IrOpcode::kObjectState: { case IrOpcode::kObjectState: {
UNREACHABLE(); UNREACHABLE();
...@@ -495,29 +490,36 @@ size_t AddOperandToStateValueDescriptor(StateValueDescriptor* descriptor, ...@@ -495,29 +490,36 @@ size_t AddOperandToStateValueDescriptor(StateValueDescriptor* descriptor,
if (id == StateObjectDeduplicator::kNotDuplicated) { if (id == StateObjectDeduplicator::kNotDuplicated) {
size_t entries = 0; size_t entries = 0;
id = deduplicator->InsertObject(input); id = deduplicator->InsertObject(input);
descriptor->fields().push_back( StateValueList* nested = values->PushRecursiveField(zone, id);
StateValueDescriptor::Recursive(zone, id));
StateValueDescriptor* new_desc = &descriptor->fields().back();
int const input_count = input->op()->ValueInputCount(); int const input_count = input->op()->ValueInputCount();
ZoneVector<MachineType> const* types = MachineTypesOf(input->op()); ZoneVector<MachineType> const* types = MachineTypesOf(input->op());
for (int i = 0; i < input_count; ++i) { for (int i = 0; i < input_count; ++i) {
entries += AddOperandToStateValueDescriptor( entries += AddOperandToStateValueDescriptor(
new_desc, inputs, g, deduplicator, input->InputAt(i), nested, inputs, g, deduplicator, input->InputAt(i), types->at(i),
types->at(i), kind, zone); kind, zone);
} }
return entries; return entries;
} else { } else {
// Crankshaft counts duplicate objects for the running id, so we have // Crankshaft counts duplicate objects for the running id, so we have
// to push the input again. // to push the input again.
deduplicator->InsertObject(input); deduplicator->InsertObject(input);
descriptor->fields().push_back( values->PushDuplicate(id);
StateValueDescriptor::Duplicate(zone, id));
return 0; return 0;
} }
} }
default: { 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;
}
}
inputs->push_back(OperandForDeopt(g, input, kind, type.representation())); inputs->push_back(OperandForDeopt(g, input, kind, type.representation()));
descriptor->fields().push_back(StateValueDescriptor::Plain(zone, type)); values->PushPlain(type);
return 1; return 1;
} }
} }
...@@ -525,10 +527,9 @@ size_t AddOperandToStateValueDescriptor(StateValueDescriptor* descriptor, ...@@ -525,10 +527,9 @@ size_t AddOperandToStateValueDescriptor(StateValueDescriptor* descriptor,
// Returns the number of instruction operands added to inputs. // Returns the number of instruction operands added to inputs.
size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor, size_t InstructionSelector::AddInputsToFrameStateDescriptor(
Node* state, OperandGenerator* g, FrameStateDescriptor* descriptor, Node* state, OperandGenerator* g,
StateObjectDeduplicator* deduplicator, StateObjectDeduplicator* deduplicator, InstructionOperandVector* inputs,
InstructionOperandVector* inputs,
FrameStateInputKind kind, Zone* zone) { FrameStateInputKind kind, Zone* zone) {
DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode()); DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
...@@ -553,8 +554,7 @@ size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor, ...@@ -553,8 +554,7 @@ size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor,
DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size()); DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size()); DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
StateValueDescriptor* values_descriptor = StateValueList* values_descriptor = descriptor->GetStateValueDescriptors();
descriptor->GetStateValueDescriptor();
entries += AddOperandToStateValueDescriptor( entries += AddOperandToStateValueDescriptor(
values_descriptor, inputs, g, deduplicator, function, values_descriptor, inputs, g, deduplicator, function,
MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone); MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
...@@ -583,8 +583,6 @@ size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor, ...@@ -583,8 +583,6 @@ size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor,
return entries; return entries;
} }
} // namespace
// An internal helper class for generating the operands to calls. // An internal helper class for generating the operands to calls.
// TODO(bmeurer): Get rid of the CallBuffer business and make // TODO(bmeurer): Get rid of the CallBuffer business and make
......
...@@ -26,6 +26,7 @@ class FlagsContinuation; ...@@ -26,6 +26,7 @@ class FlagsContinuation;
class Linkage; class Linkage;
class OperandGenerator; class OperandGenerator;
struct SwitchInfo; struct SwitchInfo;
class StateObjectDeduplicator;
// This struct connects nodes of parameters which are going to be pushed on the // This struct connects nodes of parameters which are going to be pushed on the
// call stack with their parameter index in the call descriptor of the callee. // call stack with their parameter index in the call descriptor of the callee.
...@@ -42,6 +43,8 @@ class PushParameter { ...@@ -42,6 +43,8 @@ class PushParameter {
MachineType type_; MachineType type_;
}; };
enum class FrameStateInputKind { kAny, kStackSlot };
// Instruction selection generates an InstructionSequence for a given Schedule. // Instruction selection generates an InstructionSequence for a given Schedule.
class V8_EXPORT_PRIVATE InstructionSelector final { class V8_EXPORT_PRIVATE InstructionSelector final {
public: public:
...@@ -286,6 +289,17 @@ class V8_EXPORT_PRIVATE InstructionSelector final { ...@@ -286,6 +289,17 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
int GetTempsCountForTailCallFromJSFunction(); int GetTempsCountForTailCallFromJSFunction();
FrameStateDescriptor* GetFrameStateDescriptor(Node* node); FrameStateDescriptor* GetFrameStateDescriptor(Node* node);
size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor,
Node* state, OperandGenerator* g,
StateObjectDeduplicator* deduplicator,
InstructionOperandVector* inputs,
FrameStateInputKind kind, Zone* zone);
size_t AddOperandToStateValueDescriptor(StateValueList* values,
InstructionOperandVector* inputs,
OperandGenerator* g,
StateObjectDeduplicator* deduplicator,
Node* input, MachineType type,
FrameStateInputKind kind, Zone* zone);
// =========================================================================== // ===========================================================================
// ============= Architecture-specific graph covering methods. =============== // ============= Architecture-specific graph covering methods. ===============
......
...@@ -1104,52 +1104,123 @@ std::ostream& operator<<(std::ostream& os, const Constant& constant); ...@@ -1104,52 +1104,123 @@ std::ostream& operator<<(std::ostream& os, const Constant& constant);
// Forward declarations. // Forward declarations.
class FrameStateDescriptor; class FrameStateDescriptor;
enum class StateValueKind : uint8_t {
enum class StateValueKind { kPlain, kNested, kDuplicate }; kPlain,
kOptimizedOut,
kNested,
kDuplicate
};
class StateValueDescriptor { class StateValueDescriptor {
public: public:
explicit StateValueDescriptor(Zone* zone) StateValueDescriptor()
: kind_(StateValueKind::kPlain), : kind_(StateValueKind::kPlain),
type_(MachineType::AnyTagged()), type_(MachineType::AnyTagged()),
id_(0), id_(0) {}
fields_(zone) {}
static StateValueDescriptor Plain(Zone* zone, MachineType type) { static StateValueDescriptor Plain(MachineType type) {
return StateValueDescriptor(StateValueKind::kPlain, zone, type, 0); return StateValueDescriptor(StateValueKind::kPlain, type, 0);
} }
static StateValueDescriptor Recursive(Zone* zone, size_t id) { static StateValueDescriptor OptimizedOut() {
return StateValueDescriptor(StateValueKind::kNested, zone, return StateValueDescriptor(StateValueKind::kOptimizedOut,
MachineType::AnyTagged(), 0);
}
static StateValueDescriptor Recursive(size_t id) {
return StateValueDescriptor(StateValueKind::kNested,
MachineType::AnyTagged(), id); MachineType::AnyTagged(), id);
} }
static StateValueDescriptor Duplicate(Zone* zone, size_t id) { static StateValueDescriptor Duplicate(size_t id) {
return StateValueDescriptor(StateValueKind::kDuplicate, zone, return StateValueDescriptor(StateValueKind::kDuplicate,
MachineType::AnyTagged(), id); MachineType::AnyTagged(), id);
} }
size_t size() { return fields_.size(); }
ZoneVector<StateValueDescriptor>& fields() { return fields_; }
int IsPlain() { return kind_ == StateValueKind::kPlain; } int IsPlain() { return kind_ == StateValueKind::kPlain; }
int IsOptimizedOut() { return kind_ == StateValueKind::kOptimizedOut; }
int IsNested() { return kind_ == StateValueKind::kNested; } int IsNested() { return kind_ == StateValueKind::kNested; }
int IsDuplicate() { return kind_ == StateValueKind::kDuplicate; } int IsDuplicate() { return kind_ == StateValueKind::kDuplicate; }
MachineType type() const { return type_; } MachineType type() const { return type_; }
MachineType GetOperandType(size_t index) const {
return fields_[index].type_;
}
size_t id() const { return id_; } size_t id() const { return id_; }
private: private:
StateValueDescriptor(StateValueKind kind, Zone* zone, MachineType type, StateValueDescriptor(StateValueKind kind, MachineType type, size_t id)
size_t id) : kind_(kind), type_(type), id_(id) {}
: kind_(kind), type_(type), id_(id), fields_(zone) {}
StateValueKind kind_; StateValueKind kind_;
MachineType type_; MachineType type_;
size_t id_; size_t id_;
ZoneVector<StateValueDescriptor> fields_;
}; };
class StateValueList {
public:
explicit StateValueList(Zone* zone) : fields_(zone), nested_(zone) {}
size_t size() { return fields_.size(); }
struct Value {
StateValueDescriptor* desc;
StateValueList* nested;
Value(StateValueDescriptor* desc, StateValueList* nested)
: desc(desc), nested(nested) {}
};
class iterator {
public:
// Bare minimum of operators needed for range iteration.
bool operator!=(const iterator& other) const {
return field_iterator != other.field_iterator;
}
bool operator==(const iterator& other) const {
return field_iterator == other.field_iterator;
}
iterator& operator++() {
if (field_iterator->IsNested()) {
nested_iterator++;
}
++field_iterator;
return *this;
}
Value operator*() {
StateValueDescriptor* desc = &(*field_iterator);
StateValueList* nested = desc->IsNested() ? *nested_iterator : nullptr;
return Value(desc, nested);
}
private:
friend class StateValueList;
iterator(ZoneVector<StateValueDescriptor>::iterator it,
ZoneVector<StateValueList*>::iterator nested)
: field_iterator(it), nested_iterator(nested) {}
ZoneVector<StateValueDescriptor>::iterator field_iterator;
ZoneVector<StateValueList*>::iterator nested_iterator;
};
StateValueList* PushRecursiveField(Zone* zone, size_t id) {
fields_.push_back(StateValueDescriptor::Recursive(id));
StateValueList* nested =
new (zone->New(sizeof(StateValueList))) StateValueList(zone);
nested_.push_back(nested);
return nested;
}
void PushDuplicate(size_t id) {
fields_.push_back(StateValueDescriptor::Duplicate(id));
}
void PushPlain(MachineType type) {
fields_.push_back(StateValueDescriptor::Plain(type));
}
void PushOptimizedOut() {
fields_.push_back(StateValueDescriptor::OptimizedOut());
}
iterator begin() { return iterator(fields_.begin(), nested_.begin()); }
iterator end() { return iterator(fields_.end(), nested_.end()); }
private:
ZoneVector<StateValueDescriptor> fields_;
ZoneVector<StateValueList*> nested_;
};
class FrameStateDescriptor : public ZoneObject { class FrameStateDescriptor : public ZoneObject {
public: public:
...@@ -1178,10 +1249,7 @@ class FrameStateDescriptor : public ZoneObject { ...@@ -1178,10 +1249,7 @@ class FrameStateDescriptor : public ZoneObject {
size_t GetFrameCount() const; size_t GetFrameCount() const;
size_t GetJSFrameCount() const; size_t GetJSFrameCount() const;
MachineType GetType(size_t index) const { StateValueList* GetStateValueDescriptors() { return &values_; }
return values_.GetOperandType(index);
}
StateValueDescriptor* GetStateValueDescriptor() { return &values_; }
static const int kImpossibleValue = 0xdead; static const int kImpossibleValue = 0xdead;
...@@ -1192,7 +1260,7 @@ class FrameStateDescriptor : public ZoneObject { ...@@ -1192,7 +1260,7 @@ class FrameStateDescriptor : public ZoneObject {
size_t parameters_count_; size_t parameters_count_;
size_t locals_count_; size_t locals_count_;
size_t stack_count_; size_t stack_count_;
StateValueDescriptor values_; StateValueList values_;
MaybeHandle<SharedFunctionInfo> const shared_info_; MaybeHandle<SharedFunctionInfo> const shared_info_;
FrameStateDescriptor* outer_state_; FrameStateDescriptor* outer_state_;
}; };
......
...@@ -477,15 +477,6 @@ TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeopt) { ...@@ -477,15 +477,6 @@ TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeopt) {
// We inserted 0 here. // We inserted 0 here.
EXPECT_EQ(0.5, s.ToFloat64(call_instr->InputAt(5))); EXPECT_EQ(0.5, s.ToFloat64(call_instr->InputAt(5)));
EXPECT_TRUE(s.ToHeapObject(call_instr->InputAt(6))->IsUndefined(isolate())); EXPECT_TRUE(s.ToHeapObject(call_instr->InputAt(6))->IsUndefined(isolate()));
EXPECT_EQ(MachineType::AnyTagged(),
desc_before->GetType(0)); // function is always
// tagged/any.
EXPECT_EQ(MachineType::Int32(), desc_before->GetType(1));
EXPECT_EQ(MachineType::AnyTagged(),
desc_before->GetType(2)); // context is always
// tagged/any.
EXPECT_EQ(MachineType::Float64(), desc_before->GetType(3));
EXPECT_EQ(MachineType::AnyTagged(), desc_before->GetType(4));
// Function. // Function.
EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(7))); EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(7)));
...@@ -585,31 +576,20 @@ TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeoptRecursiveFrameState) { ...@@ -585,31 +576,20 @@ TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeoptRecursiveFrameState) {
EXPECT_EQ(1u, desc_before_outer->locals_count()); EXPECT_EQ(1u, desc_before_outer->locals_count());
EXPECT_EQ(1u, desc_before_outer->stack_count()); EXPECT_EQ(1u, desc_before_outer->stack_count());
// Values from parent environment. // Values from parent environment.
EXPECT_EQ(MachineType::AnyTagged(), desc_before->GetType(0));
EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(3))); EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(3)));
EXPECT_EQ(MachineType::Int32(), desc_before_outer->GetType(1));
// Context: // Context:
EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(4))); EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(4)));
EXPECT_EQ(MachineType::AnyTagged(), desc_before_outer->GetType(2));
EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(5))); EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(5)));
EXPECT_EQ(MachineType::Int32(), desc_before_outer->GetType(3));
EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(6))); EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(6)));
EXPECT_EQ(MachineType::Int32(), desc_before_outer->GetType(4));
// Values from the nested frame. // Values from the nested frame.
EXPECT_EQ(1u, desc_before->parameters_count()); EXPECT_EQ(1u, desc_before->parameters_count());
EXPECT_EQ(1u, desc_before->locals_count()); EXPECT_EQ(1u, desc_before->locals_count());
EXPECT_EQ(2u, desc_before->stack_count()); EXPECT_EQ(2u, desc_before->stack_count());
EXPECT_EQ(MachineType::AnyTagged(), desc_before->GetType(0));
EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(8))); EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(8)));
EXPECT_EQ(MachineType::Int32(), desc_before->GetType(1));
EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(9))); EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(9)));
EXPECT_EQ(MachineType::AnyTagged(), desc_before->GetType(2));
EXPECT_EQ(0.25, s.ToFloat64(call_instr->InputAt(10))); EXPECT_EQ(0.25, s.ToFloat64(call_instr->InputAt(10)));
EXPECT_EQ(MachineType::Float64(), desc_before->GetType(3));
EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(11))); EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(11)));
EXPECT_EQ(MachineType::Int32(), desc_before->GetType(4));
EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(12))); EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(12)));
EXPECT_EQ(MachineType::Int32(), desc_before->GetType(5));
// Function. // Function.
EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(13))); EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(13)));
......
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