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 |
deleted file mode 100644 |
index ebb0b2c393b6df9ef3161a915537cca57ec861f0..0000000000000000000000000000000000000000 |
--- a/test/unittests/compiler/bytecode-graph-builder-unittest.cc |
+++ /dev/null |
@@ -1,812 +0,0 @@ |
-// Copyright 2015 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. |
- |
-#include <iostream> |
- |
-#include "src/compiler/bytecode-graph-builder.h" |
-#include "src/compiler/common-operator.h" |
-#include "src/compiler/graph-visualizer.h" |
-#include "src/compiler/instruction.h" |
-#include "src/compiler/instruction-selector.h" |
-#include "src/compiler/js-graph.h" |
-#include "src/compiler/js-operator.h" |
-#include "src/compiler/linkage.h" |
-#include "src/interpreter/bytecode-array-builder.h" |
-#include "src/parser.h" |
-#include "test/unittests/compiler/compiler-test-utils.h" |
-#include "test/unittests/compiler/graph-unittest.h" |
-#include "test/unittests/compiler/node-test-utils.h" |
-#include "test/unittests/test-utils.h" |
- |
-using ::testing::_; |
- |
-namespace v8 { |
-namespace internal { |
-namespace compiler { |
- |
-static const LanguageMode kLanguageModes[] = {LanguageMode::SLOPPY, |
- LanguageMode::STRICT}; |
- |
-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, |
- MaybeHandle<TypeFeedbackVector> feedback_vector = |
- MaybeHandle<TypeFeedbackVector>(), |
- LanguageMode language_mode = LanguageMode::SLOPPY); |
- |
- Matcher<Node*> IsUndefinedConstant(); |
- Matcher<Node*> IsNullConstant(); |
- Matcher<Node*> IsTheHoleConstant(); |
- Matcher<Node*> IsFalseConstant(); |
- Matcher<Node*> IsTrueConstant(); |
- Matcher<Node*> IsIntPtrConstant(int value); |
- Matcher<Node*> IsFeedbackVector(Node* effect, Node* control); |
- |
- static Handle<String> GetName(Isolate* isolate, const char* name) { |
- Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(name); |
- return isolate->factory()->string_table()->LookupString(isolate, result); |
- } |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilderTest); |
-}; |
- |
- |
-Graph* BytecodeGraphBuilderTest::GetCompletedGraph( |
- Handle<BytecodeArray> bytecode_array, |
- MaybeHandle<TypeFeedbackVector> feedback_vector, |
- LanguageMode language_mode) { |
- MachineOperatorBuilder* machine = new (zone()) MachineOperatorBuilder( |
- zone(), kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()); |
- CommonOperatorBuilder* common = new (zone()) CommonOperatorBuilder(zone()); |
- JSOperatorBuilder* javascript = new (zone()) JSOperatorBuilder(zone()); |
- Graph* graph = new (zone()) Graph(zone()); |
- JSGraph* jsgraph = new (zone()) |
- JSGraph(isolate(), graph, common, javascript, nullptr, machine); |
- |
- Handle<String> name = factory()->NewStringFromStaticChars("test"); |
- Handle<String> script = factory()->NewStringFromStaticChars("test() {}"); |
- Handle<SharedFunctionInfo> shared_info = |
- factory()->NewSharedFunctionInfo(name, MaybeHandle<Code>(), true); |
- 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); |
- parse_info.set_language_mode(language_mode); |
- CompilationInfo info(&parse_info); |
- info.shared_info()->set_function_data(*bytecode_array); |
- |
- BytecodeGraphBuilder graph_builder(zone(), &info, jsgraph); |
- graph_builder.CreateGraph(); |
- return graph; |
-} |
- |
- |
-Matcher<Node*> BytecodeGraphBuilderTest::IsUndefinedConstant() { |
- return IsHeapConstant(factory()->undefined_value()); |
-} |
- |
- |
-Matcher<Node*> BytecodeGraphBuilderTest::IsNullConstant() { |
- return IsHeapConstant(factory()->null_value()); |
-} |
- |
- |
-Matcher<Node*> BytecodeGraphBuilderTest::IsTheHoleConstant() { |
- return IsHeapConstant(factory()->the_hole_value()); |
-} |
- |
- |
-Matcher<Node*> BytecodeGraphBuilderTest::IsFalseConstant() { |
- return IsHeapConstant(factory()->false_value()); |
-} |
- |
- |
-Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() { |
- return IsHeapConstant(factory()->true_value()); |
-} |
- |
- |
-Matcher<Node*> BytecodeGraphBuilderTest::IsIntPtrConstant(int value) { |
- if (kPointerSize == 8) { |
- return IsInt64Constant(value); |
- } else { |
- return IsInt32Constant(value); |
- } |
-} |
- |
- |
-Matcher<Node*> BytecodeGraphBuilderTest::IsFeedbackVector(Node* effect, |
- Node* control) { |
- int offset = SharedFunctionInfo::kFeedbackVectorOffset - kHeapObjectTag; |
- int offset1 = JSFunction::kSharedFunctionInfoOffset - kHeapObjectTag; |
- |
- return IsLoad( |
- kMachAnyTagged, |
- IsLoad(kMachAnyTagged, IsParameter(Linkage::kJSCallClosureParamIndex), |
- IsIntPtrConstant(offset1), effect, control), |
- IsIntPtrConstant(offset), effect, control); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(0); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(1); |
- array_builder.LoadUndefined().Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* end = graph->end(); |
- EXPECT_EQ(1, end->InputCount()); |
- Node* ret = end->InputAt(0); |
- Node* effect = graph->start(); |
- Node* control = graph->start(); |
- EXPECT_THAT(ret, IsReturn(IsUndefinedConstant(), effect, control)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, ReturnNull) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(0); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(1); |
- array_builder.LoadNull().Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* end = graph->end(); |
- EXPECT_EQ(1, end->InputCount()); |
- Node* ret = end->InputAt(0); |
- EXPECT_THAT(ret, IsReturn(IsNullConstant(), graph->start(), graph->start())); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(0); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(1); |
- array_builder.LoadTheHole().Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* end = graph->end(); |
- EXPECT_EQ(1, end->InputCount()); |
- Node* ret = end->InputAt(0); |
- Node* effect = graph->start(); |
- Node* control = graph->start(); |
- EXPECT_THAT(ret, IsReturn(IsTheHoleConstant(), effect, control)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, ReturnTrue) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(0); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(1); |
- array_builder.LoadTrue().Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* end = graph->end(); |
- EXPECT_EQ(1, end->InputCount()); |
- Node* ret = end->InputAt(0); |
- Node* effect = graph->start(); |
- Node* control = graph->start(); |
- EXPECT_THAT(ret, IsReturn(IsTrueConstant(), effect, control)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, ReturnFalse) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(0); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(1); |
- array_builder.LoadFalse().Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* end = graph->end(); |
- EXPECT_EQ(1, end->InputCount()); |
- Node* ret = end->InputAt(0); |
- Node* effect = graph->start(); |
- Node* control = graph->start(); |
- EXPECT_THAT(ret, IsReturn(IsFalseConstant(), effect, control)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, ReturnInt8) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- static const int kValue = 3; |
- array_builder.set_locals_count(0); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(1); |
- array_builder.LoadLiteral(Smi::FromInt(kValue)).Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* end = graph->end(); |
- EXPECT_EQ(1, end->InputCount()); |
- Node* ret = end->InputAt(0); |
- Node* effect = graph->start(); |
- Node* control = graph->start(); |
- EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, ReturnDouble) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- const double kValue = 0.123456789; |
- array_builder.set_locals_count(0); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(1); |
- array_builder.LoadLiteral(factory()->NewHeapNumber(kValue)); |
- array_builder.Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* end = graph->end(); |
- EXPECT_EQ(1, end->InputCount()); |
- Node* ret = end->InputAt(0); |
- Node* effect = graph->start(); |
- Node* control = graph->start(); |
- EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), effect, control)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(1); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(3); |
- array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1)) |
- .BinaryOperation(Token::Value::ADD, array_builder.Parameter(2), |
- Strength::WEAK) |
- .StoreAccumulatorInRegister(interpreter::Register(0)) |
- .Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* end = graph->end(); |
- EXPECT_EQ(1, end->InputCount()); |
- Node* ret = end->InputAt(0); |
- // NB binary operation is <reg> <op> <acc>. The register represents |
- // the left-hand side, which is why parameters appear in opposite |
- // order to construction via the builder. |
- EXPECT_THAT(ret, IsReturn(IsJSAdd(IsParameter(2), IsParameter(1)), _, _)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithRegister) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- static const int kLeft = -655371; |
- static const int kRight = +2000000; |
- array_builder.set_locals_count(1); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(1); |
- array_builder.LoadLiteral(Smi::FromInt(kLeft)) |
- .StoreAccumulatorInRegister(interpreter::Register(0)) |
- .LoadLiteral(Smi::FromInt(kRight)) |
- .BinaryOperation(Token::Value::ADD, interpreter::Register(0), |
- Strength::WEAK) |
- .Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* end = graph->end(); |
- EXPECT_EQ(1, end->InputCount()); |
- Node* ret = end->InputAt(0); |
- EXPECT_THAT( |
- ret, IsReturn(IsJSAdd(IsNumberConstant(kLeft), IsNumberConstant(kRight)), |
- _, _)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, NamedLoad) { |
- const bool kWideBytecode[] = {false, true}; |
- TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
- TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) { |
- FeedbackVectorSpec feedback_spec(zone()); |
- if (wide_bytecode) { |
- for (int i = 0; i < 128; i++) { |
- feedback_spec.AddLoadICSlot(); |
- } |
- } |
- FeedbackVectorSlot 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> name = GetName(isolate(), "val"); |
- size_t name_index = array_builder.GetConstantPoolEntry(name); |
- |
- array_builder.LoadNamedProperty(array_builder.Parameter(1), name_index, |
- vector->GetIndex(slot), language_mode) |
- .Return(); |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector, |
- language_mode); |
- |
- Node* ret = graph->end()->InputAt(0); |
- Node* start = graph->start(); |
- |
- Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
- Matcher<Node*> load_named_matcher = IsJSLoadNamed( |
- name, IsParameter(1), feedback_vector_matcher, start, start); |
- |
- EXPECT_THAT(ret, IsReturn(load_named_matcher, _, _)); |
- } |
- } |
-} |
- |
- |
-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, _, _)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, LoadGlobal) { |
- const TypeofMode kTypeOfModes[] = {TypeofMode::NOT_INSIDE_TYPEOF, |
- TypeofMode::INSIDE_TYPEOF}; |
- const bool kWideBytecode[] = {false, true}; |
- TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
- TRACED_FOREACH(TypeofMode, typeof_mode, kTypeOfModes) { |
- TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) { |
- FeedbackVectorSpec feedback_spec(zone()); |
- if (wide_bytecode) { |
- for (int i = 0; i < 128; i++) { |
- feedback_spec.AddLoadICSlot(); |
- } |
- } |
- FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); |
- Handle<TypeFeedbackVector> vector = |
- NewTypeFeedbackVector(isolate(), &feedback_spec); |
- |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(0); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(1); |
- |
- Handle<Name> name = GetName(isolate(), "global"); |
- size_t name_index = array_builder.GetConstantPoolEntry(name); |
- |
- array_builder.LoadGlobal(name_index, vector->GetIndex(slot), |
- language_mode, typeof_mode) |
- .Return(); |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), |
- vector, language_mode); |
- |
- Node* ret = graph->end()->InputAt(0); |
- Node* start = graph->start(); |
- |
- Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
- Matcher<Node*> load_global_matcher = IsJSLoadGlobal( |
- name, typeof_mode, feedback_vector_matcher, start, start); |
- |
- EXPECT_THAT(ret, IsReturn(load_global_matcher, _, _)); |
- } |
- } |
- } |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, StoreGlobal) { |
- const bool kWideBytecode[] = {false, true}; |
- TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
- TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) { |
- FeedbackVectorSpec feedback_spec(zone()); |
- if (wide_bytecode) { |
- for (int i = 0; i < 128; i++) { |
- feedback_spec.AddStoreICSlot(); |
- } |
- } |
- FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot(); |
- Handle<TypeFeedbackVector> vector = |
- NewTypeFeedbackVector(isolate(), &feedback_spec); |
- |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(0); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(1); |
- |
- Handle<Name> name = GetName(isolate(), "global"); |
- size_t name_index = array_builder.GetConstantPoolEntry(name); |
- |
- array_builder.LoadLiteral(Smi::FromInt(321)) |
- .StoreGlobal(name_index, vector->GetIndex(slot), language_mode) |
- .Return(); |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector, |
- language_mode); |
- |
- Node* ret = graph->end()->InputAt(0); |
- Node* start = graph->start(); |
- |
- Matcher<Node*> value_matcher = IsNumberConstant(321); |
- Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
- Matcher<Node*> store_global_matcher = IsJSStoreGlobal( |
- name, value_matcher, feedback_vector_matcher, start, start); |
- |
- EXPECT_THAT(ret, IsReturn(_, store_global_matcher, _)); |
- } |
- } |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, LogicalNot) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(1); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(2); |
- array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1)) |
- .LogicalNot() |
- .Return(); |
- |
- FeedbackVectorSpec feedback_spec(zone()); |
- Handle<TypeFeedbackVector> vector = |
- NewTypeFeedbackVector(isolate(), &feedback_spec); |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector); |
- |
- Node* ret = graph->end()->InputAt(0); |
- EXPECT_THAT(ret, IsReturn(IsJSUnaryNot(IsParameter(1)), _, _)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, TypeOf) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(1); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(2); |
- array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1)) |
- .TypeOf() |
- .Return(); |
- |
- FeedbackVectorSpec feedback_spec(zone()); |
- Handle<TypeFeedbackVector> vector = |
- NewTypeFeedbackVector(isolate(), &feedback_spec); |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector); |
- |
- Node* ret = graph->end()->InputAt(0); |
- EXPECT_THAT(ret, IsReturn(IsJSTypeOf(IsParameter(1)), _, _)); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, Delete) { |
- TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
- 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> name = GetName(isolate(), "val"); |
- array_builder.LoadLiteral(name) |
- .Delete(array_builder.Parameter(1), language_mode) |
- .Return(); |
- |
- FeedbackVectorSpec feedback_spec(zone()); |
- Handle<TypeFeedbackVector> vector = |
- NewTypeFeedbackVector(isolate(), &feedback_spec); |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector, |
- language_mode); |
- |
- Node* start = graph->start(); |
- Node* ret = graph->end()->InputAt(0); |
- |
- Matcher<Node*> delete_matcher = |
- IsJSDeleteProperty(IsParameter(1), IsHeapConstant(name), start, start); |
- EXPECT_THAT(ret, IsReturn(delete_matcher, _, _)); |
- } |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, KeyedLoad) { |
- const int kValue = 100; |
- const bool kWideBytecode[] = {false, true}; |
- TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
- TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) { |
- FeedbackVectorSpec feedback_spec(zone()); |
- if (wide_bytecode) { |
- for (int i = 0; i < 128; i++) { |
- feedback_spec.AddLoadICSlot(); |
- } |
- } |
- FeedbackVectorSlot 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); |
- |
- array_builder.LoadLiteral(Smi::FromInt(kValue)) |
- .LoadKeyedProperty(array_builder.Parameter(1), vector->GetIndex(slot), |
- language_mode) |
- .Return(); |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector, |
- language_mode); |
- |
- Node* ret = graph->end()->InputAt(0); |
- Node* start = graph->start(); |
- |
- Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
- Matcher<Node*> load_keyed_matcher = |
- IsJSLoadProperty(IsParameter(1), IsNumberConstant(kValue), |
- feedback_vector_matcher, start, start); |
- |
- EXPECT_THAT(ret, IsReturn(load_keyed_matcher, _, _)); |
- } |
- } |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, NamedStore) { |
- const int kValue = 100; |
- const bool kWideBytecode[] = {false, true}; |
- TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
- TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) { |
- FeedbackVectorSpec feedback_spec(zone()); |
- if (wide_bytecode) { |
- for (int i = 0; i < 128; i++) { |
- feedback_spec.AddLoadICSlot(); |
- } |
- } |
- FeedbackVectorSlot 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> name = GetName(isolate(), "val"); |
- size_t name_index = array_builder.GetConstantPoolEntry(name); |
- |
- array_builder.LoadLiteral(Smi::FromInt(kValue)) |
- .StoreNamedProperty(array_builder.Parameter(1), name_index, |
- vector->GetIndex(slot), language_mode) |
- .Return(); |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector, |
- language_mode); |
- |
- Node* ret = graph->end()->InputAt(0); |
- Node* start = graph->start(); |
- |
- Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
- Matcher<Node*> store_named_matcher = |
- IsJSStoreNamed(name, IsParameter(1), IsNumberConstant(kValue), |
- feedback_vector_matcher, start, start); |
- |
- EXPECT_THAT(ret, IsReturn(_, store_named_matcher, _)); |
- } |
- } |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, KeyedStore) { |
- const int kValue = 100; |
- const int kKey = 10; |
- const bool kWideBytecode[] = {false, true}; |
- TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
- TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) { |
- FeedbackVectorSpec feedback_spec(zone()); |
- if (wide_bytecode) { |
- for (int i = 0; i < 128; i++) { |
- feedback_spec.AddStoreICSlot(); |
- } |
- } |
- FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot(); |
- 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); |
- |
- array_builder.LoadLiteral(Smi::FromInt(kKey)) |
- .StoreAccumulatorInRegister(interpreter::Register(0)) |
- .LoadLiteral(Smi::FromInt(kValue)) |
- .StoreKeyedProperty(array_builder.Parameter(1), |
- interpreter::Register(0), vector->GetIndex(slot), |
- language_mode) |
- .Return(); |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector, |
- language_mode); |
- |
- Node* ret = graph->end()->InputAt(0); |
- Node* start = graph->start(); |
- |
- Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
- Matcher<Node*> store_keyed_matcher = IsJSStoreProperty( |
- IsParameter(1), IsNumberConstant(kKey), IsNumberConstant(kValue), |
- feedback_vector_matcher, start, start); |
- |
- EXPECT_THAT(ret, IsReturn(_, store_keyed_matcher, _)); |
- } |
- } |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, CallRuntime) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(2); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(3); |
- |
- array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1)) |
- .StoreAccumulatorInRegister(interpreter::Register(0)) |
- .LoadAccumulatorWithRegister(array_builder.Parameter(2)) |
- .StoreAccumulatorInRegister(interpreter::Register(1)) |
- .CallRuntime(Runtime::kAdd, interpreter::Register(0), 2) |
- .Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* start = graph->start(); |
- Node* ret = graph->end()->InputAt(0); |
- std::vector<Matcher<Node*>> call_inputs; |
- call_inputs.push_back(IsParameter(1)); |
- call_inputs.push_back(IsParameter(2)); |
- Matcher<Node*> call_js_runtime = IsJSCallRuntime(call_inputs, start, start); |
- |
- EXPECT_THAT(ret, IsReturn(call_js_runtime, call_js_runtime, IsIfSuccess(_))); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, CallJSRuntime) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(1); |
- array_builder.set_context_count(1); |
- array_builder.set_parameter_count(2); |
- |
- // function f(arg) { return %spread_arguments(arg0); } |
- interpreter::Register reg0 = interpreter::Register(0); |
- array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1)) |
- .StoreAccumulatorInRegister(reg0) |
- .CallJSRuntime(Context::SPREAD_ARGUMENTS_INDEX, reg0, 1) |
- .Return(); |
- |
- Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
- Node* ret = graph->end()->InputAt(0); |
- Matcher<Node*> load_context = |
- IsLoadContext(ContextAccess(0, Context::SPREAD_ARGUMENTS_INDEX, true), _); |
- std::vector<Matcher<Node*>> call_inputs; |
- call_inputs.push_back(load_context); |
- call_inputs.push_back(IsParameter(1)); |
- Matcher<Node*> call_js_function = |
- IsJSCallFunction(call_inputs, load_context, graph->start()); |
- |
- EXPECT_THAT(ret, |
- IsReturn(call_js_function, call_js_function, IsIfSuccess(_))); |
-} |
- |
- |
-TEST_F(BytecodeGraphBuilderTest, New) { |
- interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
- array_builder.set_locals_count(4); |
- array_builder.set_context_count(0); |
- array_builder.set_parameter_count(5); |
- |
- array_builder.LoadAccumulatorWithRegister(array_builder.Parameter(1)) |
- .StoreAccumulatorInRegister(interpreter::Register(0)) |
- .LoadAccumulatorWithRegister(array_builder.Parameter(2)) |
- .StoreAccumulatorInRegister(interpreter::Register(1)) |
- .LoadAccumulatorWithRegister(array_builder.Parameter(3)) |
- .StoreAccumulatorInRegister(interpreter::Register(2)) |
- .LoadAccumulatorWithRegister(array_builder.Parameter(4)) |
- .StoreAccumulatorInRegister(interpreter::Register(3)) |
- .New(interpreter::Register(0), interpreter::Register(1), 3) |
- .Return(); |
- auto bytecode_array = array_builder.ToBytecodeArray(); |
- Graph* graph = GetCompletedGraph(bytecode_array); |
- |
- Node* start = graph->start(); |
- Node* ret = graph->end()->InputAt(0); |
- std::vector<Matcher<Node*>> construct_inputs; |
- construct_inputs.push_back(IsParameter(1)); |
- construct_inputs.push_back(IsParameter(2)); |
- construct_inputs.push_back(IsParameter(3)); |
- construct_inputs.push_back(IsParameter(4)); |
- construct_inputs.push_back(IsParameter(1)); |
- Matcher<Node*> call_construct = |
- IsJSCallConstruct(construct_inputs, start, start); |
- EXPECT_THAT(ret, IsReturn(call_construct, call_construct, IsIfSuccess(_))); |
-} |
- |
-} // namespace compiler |
-} // namespace internal |
-} // namespace v8 |