| Index: test/unittests/compiler/bytecode-graph-builder-unittest.cc
|
| diff --git a/test/unittests/compiler/bytecode-graph-builder-unittest.cc b/test/unittests/compiler/bytecode-graph-builder-unittest.cc
|
| index 61863db02eb9ab991014199bc7a2b7546924a70a..8267599b86e273f09b9b47d13836e537f91ee89a 100644
|
| --- a/test/unittests/compiler/bytecode-graph-builder-unittest.cc
|
| +++ b/test/unittests/compiler/bytecode-graph-builder-unittest.cc
|
| @@ -56,11 +56,21 @@ namespace compiler {
|
| REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) SEP() __VA_ARGS__
|
|
|
|
|
| +Handle<TypeFeedbackVector> NewTypeFeedbackVector(
|
| + Isolate* isolate, FeedbackVectorSpec* spec) {
|
| + Handle<TypeFeedbackMetadata> vector_metadata =
|
| + TypeFeedbackMetadata::New(isolate, spec);
|
| + return TypeFeedbackVector::New(isolate, vector_metadata);
|
| +}
|
| +
|
| +
|
| class BytecodeGraphBuilderTest : public TestWithIsolateAndZone {
|
| public:
|
| BytecodeGraphBuilderTest() {}
|
|
|
| - Graph* GetCompletedGraph(Handle<BytecodeArray> bytecode_array);
|
| + Graph* GetCompletedGraph(Handle<BytecodeArray> bytecode_array,
|
| + MaybeHandle<TypeFeedbackVector> feedback_vector =
|
| + MaybeHandle<TypeFeedbackVector>());
|
|
|
| Matcher<Node*> IsUndefinedConstant();
|
| Matcher<Node*> IsNullConstant();
|
| @@ -81,7 +91,8 @@ class BytecodeGraphBuilderTest : public TestWithIsolateAndZone {
|
|
|
|
|
| Graph* BytecodeGraphBuilderTest::GetCompletedGraph(
|
| - Handle<BytecodeArray> bytecode_array) {
|
| + Handle<BytecodeArray> bytecode_array,
|
| + MaybeHandle<TypeFeedbackVector> feedback_vector) {
|
| MachineOperatorBuilder* machine = new (zone()) MachineOperatorBuilder(
|
| zone(), kMachPtr, InstructionSelector::SupportedMachineOperatorFlags());
|
| CommonOperatorBuilder* common = new (zone()) CommonOperatorBuilder(zone());
|
| @@ -95,6 +106,9 @@ Graph* BytecodeGraphBuilderTest::GetCompletedGraph(
|
| Handle<SharedFunctionInfo> shared_info =
|
| factory()->NewSharedFunctionInfo(name, MaybeHandle<Code>());
|
| shared_info->set_script(*factory()->NewScript(script));
|
| + if (!feedback_vector.is_null()) {
|
| + shared_info->set_feedback_vector(*feedback_vector.ToHandleChecked());
|
| + }
|
|
|
| ParseInfo parse_info(zone(), shared_info);
|
| CompilationInfo info(&parse_info);
|
| @@ -403,6 +417,96 @@ TEST_F(BytecodeGraphBuilderTest, NamedLoadSloppyWide) {
|
| }
|
|
|
|
|
| +TEST_F(BytecodeGraphBuilderTest, CallProperty0) {
|
| + FeedbackVectorSpec feedback_spec(zone());
|
| + FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot();
|
| + FeedbackVectorSlot load_slot = feedback_spec.AddLoadICSlot();
|
| + Handle<TypeFeedbackVector> vector =
|
| + NewTypeFeedbackVector(isolate(), &feedback_spec);
|
| +
|
| + interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
|
| + array_builder.set_locals_count(1);
|
| + array_builder.set_context_count(0);
|
| + array_builder.set_parameter_count(2);
|
| +
|
| + Handle<Name> func_name = GetName(isolate(), "func");
|
| + size_t func_name_index = array_builder.GetConstantPoolEntry(func_name);
|
| +
|
| + interpreter::Register reg0 = interpreter::Register(0);
|
| + array_builder.LoadNamedProperty(
|
| + array_builder.Parameter(1), func_name_index,
|
| + vector->GetIndex(load_slot), LanguageMode::SLOPPY)
|
| + .StoreAccumulatorInRegister(reg0)
|
| + .Call(reg0, array_builder.Parameter(1), 0, vector->GetIndex(call_slot))
|
| + .Return();
|
| +
|
| + Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector);
|
| + Node* ret = graph->end()->InputAt(0);
|
| + Node* start = graph->start();
|
| +
|
| + Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
|
| + Matcher<Node*> load_named_matcher = IsJSLoadNamed(
|
| + func_name, IsParameter(1), feedback_vector_matcher, start, start);
|
| + std::vector<Matcher<Node*>> call_inputs;
|
| + call_inputs.push_back(load_named_matcher);
|
| + call_inputs.push_back(IsParameter(1));
|
| + Matcher<Node*> call_matcher =
|
| + IsJSCallFunction(call_inputs, load_named_matcher, IsIfSuccess(_));
|
| +
|
| + EXPECT_THAT(ret, IsReturn(call_matcher, _, _));
|
| +}
|
| +
|
| +
|
| +TEST_F(BytecodeGraphBuilderTest, CallProperty2) {
|
| + FeedbackVectorSpec feedback_spec(zone());
|
| + FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot();
|
| + FeedbackVectorSlot load_slot = feedback_spec.AddLoadICSlot();
|
| + Handle<TypeFeedbackVector> vector =
|
| + NewTypeFeedbackVector(isolate(), &feedback_spec);
|
| +
|
| + interpreter::BytecodeArrayBuilder array_builder(isolate(), zone());
|
| + array_builder.set_locals_count(4);
|
| + array_builder.set_context_count(0);
|
| + array_builder.set_parameter_count(4);
|
| +
|
| + Handle<Name> func_name = GetName(isolate(), "func");
|
| + size_t func_name_index = array_builder.GetConstantPoolEntry(func_name);
|
| +
|
| + interpreter::Register reg0 = interpreter::Register(0);
|
| + interpreter::Register reg1 = interpreter::Register(1);
|
| + interpreter::Register reg2 = interpreter::Register(2);
|
| + interpreter::Register reg3 = interpreter::Register(3);
|
| + array_builder.LoadNamedProperty(
|
| + array_builder.Parameter(1), func_name_index,
|
| + vector->GetIndex(load_slot), LanguageMode::SLOPPY)
|
| + .StoreAccumulatorInRegister(reg0)
|
| + .LoadAccumulatorWithRegister(array_builder.Parameter(1))
|
| + .StoreAccumulatorInRegister(reg1)
|
| + .LoadAccumulatorWithRegister(array_builder.Parameter(2))
|
| + .StoreAccumulatorInRegister(reg2)
|
| + .LoadAccumulatorWithRegister(array_builder.Parameter(3))
|
| + .StoreAccumulatorInRegister(reg3)
|
| + .Call(reg0, reg1, 2, vector->GetIndex(call_slot))
|
| + .Return();
|
| +
|
| + Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector);
|
| + Node* ret = graph->end()->InputAt(0);
|
| + Node* start = graph->start();
|
| +
|
| + Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start);
|
| + Matcher<Node*> load_named_matcher = IsJSLoadNamed(
|
| + func_name, IsParameter(1), feedback_vector_matcher, start, start);
|
| + std::vector<Matcher<Node*>> call_inputs;
|
| + call_inputs.push_back(load_named_matcher);
|
| + call_inputs.push_back(IsParameter(1));
|
| + call_inputs.push_back(IsParameter(2));
|
| + call_inputs.push_back(IsParameter(3));
|
| + Matcher<Node*> call_matcher =
|
| + IsJSCallFunction(call_inputs, load_named_matcher, IsIfSuccess(_));
|
| +
|
| + EXPECT_THAT(ret, IsReturn(call_matcher, _, _));
|
| +}
|
| +
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|