1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/compiler/state-values-utils.h" 6 #include "test/unittests/compiler/graph-unittest.h" 7 #include "test/unittests/compiler/node-test-utils.h" 8 #include "test/unittests/test-utils.h" 9 #include "testing/gmock/include/gmock/gmock.h" 10 11 namespace v8 { 12 namespace internal { 13 namespace compiler { 14 15 class StateValuesIteratorTest : public GraphTest { 16 public: 17 StateValuesIteratorTest() : GraphTest(3) {} 18 19 Node* StateValuesFromVector(NodeVector* nodes) { 20 int count = static_cast<int>(nodes->size()); 21 return graph()->NewNode(common()->StateValues(count), count, 22 count == 0 ? nullptr : &(nodes->front())); 23 } 24 }; 25 26 27 TEST_F(StateValuesIteratorTest, SimpleIteration) { 28 NodeVector inputs(zone()); 29 const int count = 10; 30 for (int i = 0; i < count; i++) { 31 inputs.push_back(Int32Constant(i)); 32 } 33 Node* state_values = StateValuesFromVector(&inputs); 34 int i = 0; 35 for (StateValuesAccess::TypedNode node : StateValuesAccess(state_values)) { 36 EXPECT_THAT(node.node, IsInt32Constant(i)); 37 i++; 38 } 39 EXPECT_EQ(count, i); 40 } 41 42 43 TEST_F(StateValuesIteratorTest, EmptyIteration) { 44 NodeVector inputs(zone()); 45 Node* state_values = StateValuesFromVector(&inputs); 46 for (auto node : StateValuesAccess(state_values)) { 47 USE(node); 48 FAIL(); 49 } 50 } 51 52 53 TEST_F(StateValuesIteratorTest, NestedIteration) { 54 NodeVector inputs(zone()); 55 int count = 0; 56 for (int i = 0; i < 8; i++) { 57 if (i == 2) { 58 // Single nested in index 2. 59 NodeVector nested_inputs(zone()); 60 for (int j = 0; j < 8; j++) { 61 nested_inputs.push_back(Int32Constant(count++)); 62 } 63 inputs.push_back(StateValuesFromVector(&nested_inputs)); 64 } else if (i == 5) { 65 // Double nested at index 5. 66 NodeVector nested_inputs(zone()); 67 for (int j = 0; j < 8; j++) { 68 if (j == 7) { 69 NodeVector doubly_nested_inputs(zone()); 70 for (int k = 0; k < 2; k++) { 71 doubly_nested_inputs.push_back(Int32Constant(count++)); 72 } 73 nested_inputs.push_back(StateValuesFromVector(&doubly_nested_inputs)); 74 } else { 75 nested_inputs.push_back(Int32Constant(count++)); 76 } 77 } 78 inputs.push_back(StateValuesFromVector(&nested_inputs)); 79 } else { 80 inputs.push_back(Int32Constant(count++)); 81 } 82 } 83 Node* state_values = StateValuesFromVector(&inputs); 84 int i = 0; 85 for (StateValuesAccess::TypedNode node : StateValuesAccess(state_values)) { 86 EXPECT_THAT(node.node, IsInt32Constant(i)); 87 i++; 88 } 89 EXPECT_EQ(count, i); 90 } 91 92 93 TEST_F(StateValuesIteratorTest, TreeFromVector) { 94 int sizes[] = {0, 1, 2, 100, 5000, 30000}; 95 TRACED_FOREACH(int, count, sizes) { 96 JSOperatorBuilder javascript(zone()); 97 MachineOperatorBuilder machine(zone()); 98 JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr, 99 &machine); 100 101 // Generate the input vector. 102 NodeVector inputs(zone()); 103 for (int i = 0; i < count; i++) { 104 inputs.push_back(Int32Constant(i)); 105 } 106 107 // Build the tree. 108 StateValuesCache builder(&jsgraph); 109 Node* values_node = builder.GetNodeForValues( 110 inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size()); 111 112 // Check the tree contents with vector. 113 int i = 0; 114 for (StateValuesAccess::TypedNode node : StateValuesAccess(values_node)) { 115 EXPECT_THAT(node.node, IsInt32Constant(i)); 116 i++; 117 } 118 EXPECT_EQ(inputs.size(), static_cast<size_t>(i)); 119 } 120 } 121 122 123 TEST_F(StateValuesIteratorTest, BuildTreeIdentical) { 124 int sizes[] = {0, 1, 2, 100, 5000, 30000}; 125 TRACED_FOREACH(int, count, sizes) { 126 JSOperatorBuilder javascript(zone()); 127 MachineOperatorBuilder machine(zone()); 128 JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr, 129 &machine); 130 131 // Generate the input vector. 132 NodeVector inputs(zone()); 133 for (int i = 0; i < count; i++) { 134 inputs.push_back(Int32Constant(i)); 135 } 136 137 // Build two trees from the same data. 138 StateValuesCache builder(&jsgraph); 139 Node* node1 = builder.GetNodeForValues( 140 inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size()); 141 Node* node2 = builder.GetNodeForValues( 142 inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size()); 143 144 // The trees should be equal since the data was the same. 145 EXPECT_EQ(node1, node2); 146 } 147 } 148 149 } // namespace compiler 150 } // namespace internal 151 } // namespace v8 152