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 27ff4ca359a25a327d6518f192d780fffb164927..773bfdcf80f6b0e28c1c0d1bcc6c007642ec0f9b 100644 |
--- a/test/unittests/compiler/bytecode-graph-builder-unittest.cc |
+++ b/test/unittests/compiler/bytecode-graph-builder-unittest.cc |
@@ -11,6 +11,7 @@ |
#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" |
@@ -24,28 +25,47 @@ 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() : array_builder_(isolate(), zone()) {} |
+ BytecodeGraphBuilderTest() {} |
- Graph* GetCompletedGraph(); |
+ 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); |
- interpreter::BytecodeArrayBuilder* array_builder() { return &array_builder_; } |
+ 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: |
- interpreter::BytecodeArrayBuilder array_builder_; |
- |
DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilderTest); |
}; |
-Graph* BytecodeGraphBuilderTest::GetCompletedGraph() { |
+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()); |
@@ -59,10 +79,13 @@ 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); |
+ parse_info.set_language_mode(language_mode); |
CompilationInfo info(&parse_info); |
- Handle<BytecodeArray> bytecode_array = array_builder()->ToBytecodeArray(); |
info.shared_info()->set_function_data(*bytecode_array); |
BytecodeGraphBuilder graph_builder(zone(), &info, jsgraph); |
@@ -96,13 +119,36 @@ Matcher<Node*> BytecodeGraphBuilderTest::IsTrueConstant() { |
} |
+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::kJSFunctionCallClosureParamIndex), |
+ IsIntPtrConstant(offset1), effect, control), |
+ IsIntPtrConstant(offset), effect, control); |
+} |
+ |
+ |
TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) { |
- array_builder()->set_locals_count(0); |
- array_builder()->set_context_count(0); |
- array_builder()->set_parameter_count(1); |
- array_builder()->LoadUndefined().Return(); |
+ 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(); |
+ Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
Node* end = graph->end(); |
EXPECT_EQ(1, end->InputCount()); |
Node* ret = end->InputAt(0); |
@@ -113,12 +159,13 @@ TEST_F(BytecodeGraphBuilderTest, ReturnUndefined) { |
TEST_F(BytecodeGraphBuilderTest, ReturnNull) { |
- array_builder()->set_locals_count(0); |
- array_builder()->set_context_count(0); |
- array_builder()->set_parameter_count(1); |
- array_builder()->LoadNull().Return(); |
+ 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(); |
+ Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
Node* end = graph->end(); |
EXPECT_EQ(1, end->InputCount()); |
Node* ret = end->InputAt(0); |
@@ -127,12 +174,13 @@ TEST_F(BytecodeGraphBuilderTest, ReturnNull) { |
TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) { |
- array_builder()->set_locals_count(0); |
- array_builder()->set_context_count(0); |
- array_builder()->set_parameter_count(1); |
- array_builder()->LoadTheHole().Return(); |
+ 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(); |
+ Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
Node* end = graph->end(); |
EXPECT_EQ(1, end->InputCount()); |
Node* ret = end->InputAt(0); |
@@ -143,12 +191,13 @@ TEST_F(BytecodeGraphBuilderTest, ReturnTheHole) { |
TEST_F(BytecodeGraphBuilderTest, ReturnTrue) { |
- array_builder()->set_locals_count(0); |
- array_builder()->set_context_count(0); |
- array_builder()->set_parameter_count(1); |
- array_builder()->LoadTrue().Return(); |
+ 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(); |
+ Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
Node* end = graph->end(); |
EXPECT_EQ(1, end->InputCount()); |
Node* ret = end->InputAt(0); |
@@ -159,12 +208,13 @@ TEST_F(BytecodeGraphBuilderTest, ReturnTrue) { |
TEST_F(BytecodeGraphBuilderTest, ReturnFalse) { |
- array_builder()->set_locals_count(0); |
- array_builder()->set_context_count(0); |
- array_builder()->set_parameter_count(1); |
- array_builder()->LoadFalse().Return(); |
+ 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(); |
+ Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
Node* end = graph->end(); |
EXPECT_EQ(1, end->InputCount()); |
Node* ret = end->InputAt(0); |
@@ -175,13 +225,14 @@ TEST_F(BytecodeGraphBuilderTest, ReturnFalse) { |
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(); |
+ 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(); |
+ Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
Node* end = graph->end(); |
EXPECT_EQ(1, end->InputCount()); |
Node* ret = end->InputAt(0); |
@@ -192,14 +243,15 @@ TEST_F(BytecodeGraphBuilderTest, ReturnInt8) { |
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(); |
+ 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(); |
+ Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
Node* end = graph->end(); |
EXPECT_EQ(1, end->InputCount()); |
Node* ret = end->InputAt(0); |
@@ -210,17 +262,17 @@ TEST_F(BytecodeGraphBuilderTest, ReturnDouble) { |
TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) { |
- 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), |
+ 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(); |
+ Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
Node* end = graph->end(); |
EXPECT_EQ(1, end->InputCount()); |
Node* ret = end->InputAt(0); |
@@ -232,20 +284,20 @@ TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithParameters) { |
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)) |
+ 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(); |
+ Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray()); |
Node* end = graph->end(); |
EXPECT_EQ(1, end->InputCount()); |
Node* ret = end->InputAt(0); |
@@ -254,6 +306,47 @@ TEST_F(BytecodeGraphBuilderTest, SimpleExpressionWithRegister) { |
_, _)); |
} |
+ |
+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, _, _)); |
+ } |
+ } |
+} |
+ |
} // namespace compiler |
} // namespace internal |
} // namespace v8 |