OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "test/unittests/compiler/interpreter-assembler-unittest.h" | 5 #include "test/unittests/interpreter/interpreter-assembler-unittest.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
9 #include "src/compiler/node.h" | 9 #include "src/compiler/node.h" |
10 #include "src/interface-descriptors.h" | 10 #include "src/interface-descriptors.h" |
11 #include "src/isolate.h" | 11 #include "src/isolate.h" |
12 #include "test/unittests/compiler/compiler-test-utils.h" | 12 #include "test/unittests/compiler/compiler-test-utils.h" |
13 #include "test/unittests/compiler/node-test-utils.h" | 13 #include "test/unittests/compiler/node-test-utils.h" |
14 | 14 |
15 using ::testing::_; | 15 using ::testing::_; |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 namespace internal { | 18 namespace internal { |
19 namespace compiler { | 19 |
| 20 using namespace compiler; |
| 21 |
| 22 namespace interpreter { |
20 | 23 |
21 const interpreter::Bytecode kBytecodes[] = { | 24 const interpreter::Bytecode kBytecodes[] = { |
22 #define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name, | 25 #define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name, |
23 BYTECODE_LIST(DEFINE_BYTECODE) | 26 BYTECODE_LIST(DEFINE_BYTECODE) |
24 #undef DEFINE_BYTECODE | 27 #undef DEFINE_BYTECODE |
25 }; | 28 }; |
26 | 29 |
27 | |
28 Matcher<Node*> IsIntPtrConstant(const intptr_t value) { | 30 Matcher<Node*> IsIntPtrConstant(const intptr_t value) { |
29 return kPointerSize == 8 ? IsInt64Constant(static_cast<int64_t>(value)) | 31 return kPointerSize == 8 ? IsInt64Constant(static_cast<int64_t>(value)) |
30 : IsInt32Constant(static_cast<int32_t>(value)); | 32 : IsInt32Constant(static_cast<int32_t>(value)); |
31 } | 33 } |
32 | 34 |
33 | |
34 Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher, | 35 Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher, |
35 const Matcher<Node*>& rhs_matcher) { | 36 const Matcher<Node*>& rhs_matcher) { |
36 return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher) | 37 return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher) |
37 : IsInt32Add(lhs_matcher, rhs_matcher); | 38 : IsInt32Add(lhs_matcher, rhs_matcher); |
38 } | 39 } |
39 | 40 |
40 | |
41 Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher, | 41 Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher, |
42 const Matcher<Node*>& rhs_matcher) { | 42 const Matcher<Node*>& rhs_matcher) { |
43 return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher) | 43 return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher) |
44 : IsInt32Sub(lhs_matcher, rhs_matcher); | 44 : IsInt32Sub(lhs_matcher, rhs_matcher); |
45 } | 45 } |
46 | 46 |
47 | |
48 Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher, | 47 Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher, |
49 const Matcher<Node*>& rhs_matcher) { | 48 const Matcher<Node*>& rhs_matcher) { |
50 return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher) | 49 return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher) |
51 : IsWord32Shl(lhs_matcher, rhs_matcher); | 50 : IsWord32Shl(lhs_matcher, rhs_matcher); |
52 } | 51 } |
53 | 52 |
54 | |
55 Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher, | 53 Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher, |
56 const Matcher<Node*>& rhs_matcher) { | 54 const Matcher<Node*>& rhs_matcher) { |
57 return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher) | 55 return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher) |
58 : IsWord32Sar(lhs_matcher, rhs_matcher); | 56 : IsWord32Sar(lhs_matcher, rhs_matcher); |
59 } | 57 } |
60 | 58 |
61 | |
62 Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher, | 59 Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher, |
63 const Matcher<Node*>& rhs_matcher) { | 60 const Matcher<Node*>& rhs_matcher) { |
64 return kPointerSize == 8 ? IsWord64Or(lhs_matcher, rhs_matcher) | 61 return kPointerSize == 8 ? IsWord64Or(lhs_matcher, rhs_matcher) |
65 : IsWord32Or(lhs_matcher, rhs_matcher); | 62 : IsWord32Or(lhs_matcher, rhs_matcher); |
66 } | 63 } |
67 | 64 |
68 | |
69 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad( | 65 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad( |
70 const Matcher<LoadRepresentation>& rep_matcher, | 66 const Matcher<LoadRepresentation>& rep_matcher, |
71 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) { | 67 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) { |
72 return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, _, _); | 68 return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, _, _); |
73 } | 69 } |
74 | 70 |
75 | |
76 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore( | 71 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore( |
77 const Matcher<StoreRepresentation>& rep_matcher, | 72 const Matcher<StoreRepresentation>& rep_matcher, |
78 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher, | 73 const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher, |
79 const Matcher<Node*>& value_matcher) { | 74 const Matcher<Node*>& value_matcher) { |
80 return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher, | 75 return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher, |
81 value_matcher, _, _); | 76 value_matcher, _, _); |
82 } | 77 } |
83 | 78 |
84 | |
85 Matcher<Node*> | 79 Matcher<Node*> |
86 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand( | 80 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand( |
87 int offset) { | 81 int offset) { |
88 return IsLoad( | 82 return IsLoad( |
89 MachineType::Uint8(), | 83 MachineType::Uint8(), |
90 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 84 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
91 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 85 IsIntPtrAdd( |
92 IsInt32Constant(offset))); | 86 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
| 87 IsInt32Constant(offset))); |
93 } | 88 } |
94 | 89 |
95 | |
96 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: | 90 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: |
97 IsBytecodeOperandSignExtended(int offset) { | 91 IsBytecodeOperandSignExtended(int offset) { |
98 Matcher<Node*> load_matcher = IsLoad( | 92 Matcher<Node*> load_matcher = IsLoad( |
99 MachineType::Int8(), | 93 MachineType::Int8(), |
100 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 94 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
101 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 95 IsIntPtrAdd( |
102 IsInt32Constant(offset))); | 96 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
| 97 IsInt32Constant(offset))); |
103 if (kPointerSize == 8) { | 98 if (kPointerSize == 8) { |
104 load_matcher = IsChangeInt32ToInt64(load_matcher); | 99 load_matcher = IsChangeInt32ToInt64(load_matcher); |
105 } | 100 } |
106 return load_matcher; | 101 return load_matcher; |
107 } | 102 } |
108 | 103 |
109 | |
110 Matcher<Node*> | 104 Matcher<Node*> |
111 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort( | 105 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort( |
112 int offset) { | 106 int offset) { |
113 if (TargetSupportsUnalignedAccess()) { | 107 if (TargetSupportsUnalignedAccess()) { |
114 return IsLoad( | 108 return IsLoad( |
115 MachineType::Uint16(), | 109 MachineType::Uint16(), |
116 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 110 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
117 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 111 IsIntPtrAdd( |
118 IsInt32Constant(offset))); | 112 IsParameter( |
| 113 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
| 114 IsInt32Constant(offset))); |
119 } else { | 115 } else { |
120 Matcher<Node*> first_byte = IsLoad( | 116 Matcher<Node*> first_byte = IsLoad( |
121 MachineType::Uint8(), | 117 MachineType::Uint8(), |
122 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 118 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
123 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 119 IsIntPtrAdd( |
124 IsInt32Constant(offset))); | 120 IsParameter( |
| 121 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
| 122 IsInt32Constant(offset))); |
125 Matcher<Node*> second_byte = IsLoad( | 123 Matcher<Node*> second_byte = IsLoad( |
126 MachineType::Uint8(), | 124 MachineType::Uint8(), |
127 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 125 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
128 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 126 IsIntPtrAdd( |
129 IsInt32Constant(offset + 1))); | 127 IsParameter( |
| 128 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
| 129 IsInt32Constant(offset + 1))); |
130 #if V8_TARGET_LITTLE_ENDIAN | 130 #if V8_TARGET_LITTLE_ENDIAN |
131 return IsWordOr(IsWordShl(second_byte, IsInt32Constant(kBitsPerByte)), | 131 return IsWordOr(IsWordShl(second_byte, IsInt32Constant(kBitsPerByte)), |
132 first_byte); | 132 first_byte); |
133 #elif V8_TARGET_BIG_ENDIAN | 133 #elif V8_TARGET_BIG_ENDIAN |
134 return IsWordOr(IsWordShl(first_byte, IsInt32Constant(kBitsPerByte)), | 134 return IsWordOr(IsWordShl(first_byte, IsInt32Constant(kBitsPerByte)), |
135 second_byte); | 135 second_byte); |
136 #else | 136 #else |
137 #error "Unknown Architecture" | 137 #error "Unknown Architecture" |
138 #endif | 138 #endif |
139 } | 139 } |
140 } | 140 } |
141 | 141 |
142 | |
143 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: | 142 Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: |
144 IsBytecodeOperandShortSignExtended(int offset) { | 143 IsBytecodeOperandShortSignExtended(int offset) { |
145 Matcher<Node*> load_matcher; | 144 Matcher<Node*> load_matcher; |
146 if (TargetSupportsUnalignedAccess()) { | 145 if (TargetSupportsUnalignedAccess()) { |
147 load_matcher = IsLoad( | 146 load_matcher = IsLoad( |
148 MachineType::Int16(), | 147 MachineType::Int16(), |
149 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 148 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
150 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 149 IsIntPtrAdd( |
151 IsInt32Constant(offset))); | 150 IsParameter( |
| 151 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
| 152 IsInt32Constant(offset))); |
152 } else { | 153 } else { |
153 #if V8_TARGET_LITTLE_ENDIAN | 154 #if V8_TARGET_LITTLE_ENDIAN |
154 int hi_byte_offset = offset + 1; | 155 int hi_byte_offset = offset + 1; |
155 int lo_byte_offset = offset; | 156 int lo_byte_offset = offset; |
156 | 157 |
157 #elif V8_TARGET_BIG_ENDIAN | 158 #elif V8_TARGET_BIG_ENDIAN |
158 int hi_byte_offset = offset; | 159 int hi_byte_offset = offset; |
159 int lo_byte_offset = offset + 1; | 160 int lo_byte_offset = offset + 1; |
160 #else | 161 #else |
161 #error "Unknown Architecture" | 162 #error "Unknown Architecture" |
162 #endif | 163 #endif |
163 Matcher<Node*> hi_byte = IsLoad( | 164 Matcher<Node*> hi_byte = IsLoad( |
164 MachineType::Int8(), | 165 MachineType::Int8(), |
165 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 166 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
166 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 167 IsIntPtrAdd( |
167 IsInt32Constant(hi_byte_offset))); | 168 IsParameter( |
| 169 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
| 170 IsInt32Constant(hi_byte_offset))); |
168 hi_byte = IsWord32Shl(hi_byte, IsInt32Constant(kBitsPerByte)); | 171 hi_byte = IsWord32Shl(hi_byte, IsInt32Constant(kBitsPerByte)); |
169 Matcher<Node*> lo_byte = IsLoad( | 172 Matcher<Node*> lo_byte = IsLoad( |
170 MachineType::Uint8(), | 173 MachineType::Uint8(), |
171 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 174 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
172 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 175 IsIntPtrAdd( |
173 IsInt32Constant(lo_byte_offset))); | 176 IsParameter( |
| 177 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
| 178 IsInt32Constant(lo_byte_offset))); |
174 load_matcher = IsWord32Or(hi_byte, lo_byte); | 179 load_matcher = IsWord32Or(hi_byte, lo_byte); |
175 } | 180 } |
176 | 181 |
177 if (kPointerSize == 8) { | 182 if (kPointerSize == 8) { |
178 load_matcher = IsChangeInt32ToInt64(load_matcher); | 183 load_matcher = IsChangeInt32ToInt64(load_matcher); |
179 } | 184 } |
180 return load_matcher; | 185 return load_matcher; |
181 } | 186 } |
182 | 187 |
183 | |
184 TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { | 188 TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { |
185 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 189 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
186 InterpreterAssemblerForTest m(this, bytecode); | 190 InterpreterAssemblerForTest m(this, bytecode); |
187 m.Dispatch(); | 191 m.Dispatch(); |
188 Graph* graph = m.graph(); | 192 Graph* graph = m.graph(); |
189 | 193 |
190 Node* end = graph->end(); | 194 Node* end = graph->end(); |
191 EXPECT_EQ(1, end->InputCount()); | 195 EXPECT_EQ(1, end->InputCount()); |
192 Node* tail_call_node = end->InputAt(0); | 196 Node* tail_call_node = end->InputAt(0); |
193 | 197 |
194 Matcher<Node*> next_bytecode_offset_matcher = | 198 Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd( |
195 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 199 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
196 IsInt32Constant(interpreter::Bytecodes::Size(bytecode))); | 200 IsInt32Constant(interpreter::Bytecodes::Size(bytecode))); |
197 Matcher<Node*> target_bytecode_matcher = | 201 Matcher<Node*> target_bytecode_matcher = m.IsLoad( |
198 m.IsLoad(MachineType::Uint8(), | 202 MachineType::Uint8(), |
199 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 203 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
200 next_bytecode_offset_matcher); | 204 next_bytecode_offset_matcher); |
201 Matcher<Node*> code_target_matcher = | 205 Matcher<Node*> code_target_matcher = m.IsLoad( |
202 m.IsLoad(MachineType::Pointer(), | 206 MachineType::Pointer(), |
203 IsParameter(Linkage::kInterpreterDispatchTableParameter), | 207 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), |
204 IsWord32Shl(target_bytecode_matcher, | 208 IsWord32Shl(target_bytecode_matcher, |
205 IsInt32Constant(kPointerSizeLog2))); | 209 IsInt32Constant(kPointerSizeLog2))); |
206 | 210 |
207 EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); | |
208 EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); | |
209 EXPECT_THAT( | 211 EXPECT_THAT( |
210 tail_call_node, | 212 tail_call_node, |
211 IsTailCall(m.call_descriptor(), code_target_matcher, | 213 IsTailCall( |
212 IsParameter(Linkage::kInterpreterAccumulatorParameter), | 214 _, code_target_matcher, |
213 IsParameter(Linkage::kInterpreterRegisterFileParameter), | 215 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), |
214 next_bytecode_offset_matcher, | 216 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), |
215 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 217 next_bytecode_offset_matcher, |
216 IsParameter(Linkage::kInterpreterDispatchTableParameter), | 218 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
217 IsParameter(Linkage::kInterpreterContextParameter), _, _)); | 219 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 220 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _, |
| 221 _)); |
218 } | 222 } |
219 } | 223 } |
220 | 224 |
221 | |
222 TARGET_TEST_F(InterpreterAssemblerTest, Jump) { | 225 TARGET_TEST_F(InterpreterAssemblerTest, Jump) { |
223 int jump_offsets[] = {-9710, -77, 0, +3, +97109}; | 226 int jump_offsets[] = {-9710, -77, 0, +3, +97109}; |
224 TRACED_FOREACH(int, jump_offset, jump_offsets) { | 227 TRACED_FOREACH(int, jump_offset, jump_offsets) { |
225 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 228 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
226 InterpreterAssemblerForTest m(this, bytecode); | 229 InterpreterAssemblerForTest m(this, bytecode); |
227 m.Jump(m.Int32Constant(jump_offset)); | 230 m.Jump(m.Int32Constant(jump_offset)); |
228 Graph* graph = m.graph(); | 231 Graph* graph = m.graph(); |
229 Node* end = graph->end(); | 232 Node* end = graph->end(); |
230 EXPECT_EQ(1, end->InputCount()); | 233 EXPECT_EQ(1, end->InputCount()); |
231 Node* tail_call_node = end->InputAt(0); | 234 Node* tail_call_node = end->InputAt(0); |
232 | 235 |
233 Matcher<Node*> next_bytecode_offset_matcher = | 236 Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd( |
234 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 237 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
235 IsInt32Constant(jump_offset)); | 238 IsInt32Constant(jump_offset)); |
236 Matcher<Node*> target_bytecode_matcher = | 239 Matcher<Node*> target_bytecode_matcher = m.IsLoad( |
237 m.IsLoad(MachineType::Uint8(), | 240 MachineType::Uint8(), |
238 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 241 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
239 next_bytecode_offset_matcher); | 242 next_bytecode_offset_matcher); |
240 Matcher<Node*> code_target_matcher = | 243 Matcher<Node*> code_target_matcher = m.IsLoad( |
241 m.IsLoad(MachineType::Pointer(), | 244 MachineType::Pointer(), |
242 IsParameter(Linkage::kInterpreterDispatchTableParameter), | 245 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), |
243 IsWord32Shl(target_bytecode_matcher, | 246 IsWord32Shl(target_bytecode_matcher, |
244 IsInt32Constant(kPointerSizeLog2))); | 247 IsInt32Constant(kPointerSizeLog2))); |
245 | 248 |
246 EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); | |
247 EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); | |
248 EXPECT_THAT( | 249 EXPECT_THAT( |
249 tail_call_node, | 250 tail_call_node, |
250 IsTailCall(m.call_descriptor(), code_target_matcher, | 251 IsTailCall( |
251 IsParameter(Linkage::kInterpreterAccumulatorParameter), | 252 _, code_target_matcher, |
252 IsParameter(Linkage::kInterpreterRegisterFileParameter), | 253 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), |
253 next_bytecode_offset_matcher, | 254 IsParameter( |
254 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 255 InterpreterDispatchDescriptor::kRegisterFileParameter), |
255 IsParameter(Linkage::kInterpreterDispatchTableParameter), | 256 next_bytecode_offset_matcher, |
256 IsParameter(Linkage::kInterpreterContextParameter), _, _)); | 257 IsParameter( |
| 258 InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
| 259 IsParameter( |
| 260 InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 261 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _, |
| 262 _)); |
257 } | 263 } |
258 } | 264 } |
259 } | 265 } |
260 | 266 |
261 | |
262 TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) { | 267 TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) { |
263 static const int kJumpIfTrueOffset = 73; | 268 static const int kJumpIfTrueOffset = 73; |
264 | 269 |
265 MachineOperatorBuilder machine(zone()); | 270 MachineOperatorBuilder machine(zone()); |
266 | 271 |
267 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 272 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
268 InterpreterAssemblerForTest m(this, bytecode); | 273 InterpreterAssemblerForTest m(this, bytecode); |
269 Node* lhs = m.IntPtrConstant(0); | 274 Node* lhs = m.IntPtrConstant(0); |
270 Node* rhs = m.IntPtrConstant(1); | 275 Node* rhs = m.IntPtrConstant(1); |
271 m.JumpIfWordEqual(lhs, rhs, m.Int32Constant(kJumpIfTrueOffset)); | 276 m.JumpIfWordEqual(lhs, rhs, m.Int32Constant(kJumpIfTrueOffset)); |
272 Graph* graph = m.graph(); | 277 Graph* graph = m.graph(); |
273 Node* end = graph->end(); | 278 Node* end = graph->end(); |
274 EXPECT_EQ(2, end->InputCount()); | 279 EXPECT_EQ(2, end->InputCount()); |
275 | 280 |
276 int jump_offsets[] = {kJumpIfTrueOffset, | 281 int jump_offsets[] = {kJumpIfTrueOffset, |
277 interpreter::Bytecodes::Size(bytecode)}; | 282 interpreter::Bytecodes::Size(bytecode)}; |
278 for (int i = 0; i < static_cast<int>(arraysize(jump_offsets)); i++) { | 283 for (int i = 0; i < static_cast<int>(arraysize(jump_offsets)); i++) { |
279 Matcher<Node*> next_bytecode_offset_matcher = | 284 Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd( |
280 IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 285 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
281 IsInt32Constant(jump_offsets[i])); | 286 IsInt32Constant(jump_offsets[i])); |
282 Matcher<Node*> target_bytecode_matcher = | 287 Matcher<Node*> target_bytecode_matcher = m.IsLoad( |
283 m.IsLoad(MachineType::Uint8(), | 288 MachineType::Uint8(), |
284 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 289 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
285 next_bytecode_offset_matcher); | 290 next_bytecode_offset_matcher); |
286 Matcher<Node*> code_target_matcher = | 291 Matcher<Node*> code_target_matcher = m.IsLoad( |
287 m.IsLoad(MachineType::Pointer(), | 292 MachineType::Pointer(), |
288 IsParameter(Linkage::kInterpreterDispatchTableParameter), | 293 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), |
289 IsWord32Shl(target_bytecode_matcher, | 294 IsWord32Shl(target_bytecode_matcher, |
290 IsInt32Constant(kPointerSizeLog2))); | 295 IsInt32Constant(kPointerSizeLog2))); |
291 EXPECT_THAT( | 296 EXPECT_THAT( |
292 end->InputAt(i), | 297 end->InputAt(i), |
293 IsTailCall(m.call_descriptor(), code_target_matcher, | 298 IsTailCall( |
294 IsParameter(Linkage::kInterpreterAccumulatorParameter), | 299 _, code_target_matcher, |
295 IsParameter(Linkage::kInterpreterRegisterFileParameter), | 300 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), |
296 next_bytecode_offset_matcher, | 301 IsParameter( |
297 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 302 InterpreterDispatchDescriptor::kRegisterFileParameter), |
298 IsParameter(Linkage::kInterpreterDispatchTableParameter), | 303 next_bytecode_offset_matcher, |
299 IsParameter(Linkage::kInterpreterContextParameter), _, _)); | 304 IsParameter( |
| 305 InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
| 306 IsParameter( |
| 307 InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 308 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _, |
| 309 _)); |
300 } | 310 } |
301 | 311 |
302 // TODO(oth): test control flow paths. | 312 // TODO(oth): test control flow paths. |
303 } | 313 } |
304 } | 314 } |
305 | 315 |
306 | 316 TARGET_TEST_F(InterpreterAssemblerTest, InterpreterReturn) { |
307 TARGET_TEST_F(InterpreterAssemblerTest, Return) { | |
308 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 317 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
309 InterpreterAssemblerForTest m(this, bytecode); | 318 InterpreterAssemblerForTest m(this, bytecode); |
310 m.Return(); | 319 m.InterpreterReturn(); |
311 Graph* graph = m.graph(); | 320 Graph* graph = m.graph(); |
312 | 321 |
313 Node* end = graph->end(); | 322 Node* end = graph->end(); |
314 EXPECT_EQ(1, end->InputCount()); | 323 EXPECT_EQ(1, end->InputCount()); |
315 Node* tail_call_node = end->InputAt(0); | 324 Node* tail_call_node = end->InputAt(0); |
316 | 325 |
317 EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); | |
318 EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); | |
319 Handle<HeapObject> exit_trampoline = | 326 Handle<HeapObject> exit_trampoline = |
320 isolate()->builtins()->InterpreterExitTrampoline(); | 327 isolate()->builtins()->InterpreterExitTrampoline(); |
321 EXPECT_THAT( | 328 EXPECT_THAT( |
322 tail_call_node, | 329 tail_call_node, |
323 IsTailCall(m.call_descriptor(), IsHeapConstant(exit_trampoline), | 330 IsTailCall( |
324 IsParameter(Linkage::kInterpreterAccumulatorParameter), | 331 _, IsHeapConstant(exit_trampoline), |
325 IsParameter(Linkage::kInterpreterRegisterFileParameter), | 332 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), |
326 IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), | 333 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), |
327 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 334 IsParameter( |
328 IsParameter(Linkage::kInterpreterDispatchTableParameter), | 335 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
329 IsParameter(Linkage::kInterpreterContextParameter), _, _)); | 336 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
| 337 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), |
| 338 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _, |
| 339 _)); |
330 } | 340 } |
331 } | 341 } |
332 | 342 |
333 | |
334 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { | 343 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { |
335 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 344 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
336 InterpreterAssemblerForTest m(this, bytecode); | 345 InterpreterAssemblerForTest m(this, bytecode); |
337 int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); | 346 int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); |
338 for (int i = 0; i < number_of_operands; i++) { | 347 for (int i = 0; i < number_of_operands; i++) { |
339 int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i); | 348 int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i); |
340 switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) { | 349 switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) { |
341 case interpreter::OperandType::kRegCount8: | 350 case interpreter::OperandType::kRegCount8: |
342 EXPECT_THAT(m.BytecodeOperandCount(i), m.IsBytecodeOperand(offset)); | 351 EXPECT_THAT(m.BytecodeOperandCount(i), m.IsBytecodeOperand(offset)); |
343 break; | 352 break; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 m.IsBytecodeOperandShortSignExtended(offset)); | 384 m.IsBytecodeOperandShortSignExtended(offset)); |
376 break; | 385 break; |
377 case interpreter::OperandType::kNone: | 386 case interpreter::OperandType::kNone: |
378 UNREACHABLE(); | 387 UNREACHABLE(); |
379 break; | 388 break; |
380 } | 389 } |
381 } | 390 } |
382 } | 391 } |
383 } | 392 } |
384 | 393 |
385 | |
386 TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { | 394 TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { |
387 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 395 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
388 InterpreterAssemblerForTest m(this, bytecode); | 396 InterpreterAssemblerForTest m(this, bytecode); |
389 // Should be incoming accumulator if not set. | 397 // Should be incoming accumulator if not set. |
390 EXPECT_THAT(m.GetAccumulator(), | 398 EXPECT_THAT( |
391 IsParameter(Linkage::kInterpreterAccumulatorParameter)); | 399 m.GetAccumulator(), |
| 400 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter)); |
392 | 401 |
393 // Should be set by SedtAccumulator. | 402 // Should be set by SetAccumulator. |
394 Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef); | 403 Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef); |
395 m.SetAccumulator(accumulator_value_1); | 404 m.SetAccumulator(accumulator_value_1); |
396 EXPECT_THAT(m.GetAccumulator(), accumulator_value_1); | 405 EXPECT_THAT(m.GetAccumulator(), accumulator_value_1); |
397 Node* accumulator_value_2 = m.Int32Constant(42); | 406 Node* accumulator_value_2 = m.Int32Constant(42); |
398 m.SetAccumulator(accumulator_value_2); | 407 m.SetAccumulator(accumulator_value_2); |
399 EXPECT_THAT(m.GetAccumulator(), accumulator_value_2); | 408 EXPECT_THAT(m.GetAccumulator(), accumulator_value_2); |
400 | 409 |
401 // Should be passed to next bytecode handler on dispatch. | 410 // Should be passed to next bytecode handler on dispatch. |
402 m.Dispatch(); | 411 m.Dispatch(); |
403 Graph* graph = m.graph(); | 412 Graph* graph = m.graph(); |
404 | 413 |
405 Node* end = graph->end(); | 414 Node* end = graph->end(); |
406 EXPECT_EQ(1, end->InputCount()); | 415 EXPECT_EQ(1, end->InputCount()); |
407 Node* tail_call_node = end->InputAt(0); | 416 Node* tail_call_node = end->InputAt(0); |
408 | 417 |
409 EXPECT_THAT(tail_call_node, | 418 EXPECT_THAT(tail_call_node, |
410 IsTailCall(m.call_descriptor(), _, accumulator_value_2, _, _, _, | 419 IsTailCall(_, _, accumulator_value_2, _, _, _, _, _, _)); |
411 _, _, _)); | |
412 } | 420 } |
413 } | 421 } |
414 | 422 |
415 | |
416 TARGET_TEST_F(InterpreterAssemblerTest, GetSetContext) { | 423 TARGET_TEST_F(InterpreterAssemblerTest, GetSetContext) { |
417 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 424 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
418 InterpreterAssemblerForTest m(this, bytecode); | 425 InterpreterAssemblerForTest m(this, bytecode); |
419 Node* context_node = m.Int32Constant(100); | 426 Node* context_node = m.Int32Constant(100); |
420 m.SetContext(context_node); | 427 m.SetContext(context_node); |
421 EXPECT_THAT(m.GetContext(), context_node); | 428 EXPECT_THAT(m.GetContext(), context_node); |
422 } | 429 } |
423 } | 430 } |
424 | 431 |
425 | |
426 TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) { | 432 TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) { |
427 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 433 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
428 InterpreterAssemblerForTest m(this, bytecode); | 434 InterpreterAssemblerForTest m(this, bytecode); |
429 Node* reg_index_node = m.Int32Constant(44); | 435 Node* reg_index_node = m.Int32Constant(44); |
430 Node* reg_location_node = m.RegisterLocation(reg_index_node); | 436 Node* reg_location_node = m.RegisterLocation(reg_index_node); |
431 EXPECT_THAT( | 437 EXPECT_THAT( |
432 reg_location_node, | 438 reg_location_node, |
433 IsIntPtrAdd( | 439 IsIntPtrAdd( |
434 IsParameter(Linkage::kInterpreterRegisterFileParameter), | 440 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), |
435 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)))); | 441 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)))); |
436 } | 442 } |
437 } | 443 } |
438 | 444 |
439 | |
440 TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) { | 445 TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) { |
441 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 446 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
442 InterpreterAssemblerForTest m(this, bytecode); | 447 InterpreterAssemblerForTest m(this, bytecode); |
443 Node* reg_index_node = m.Int32Constant(44); | 448 Node* reg_index_node = m.Int32Constant(44); |
444 Node* load_reg_node = m.LoadRegister(reg_index_node); | 449 Node* load_reg_node = m.LoadRegister(reg_index_node); |
445 EXPECT_THAT( | 450 EXPECT_THAT( |
446 load_reg_node, | 451 load_reg_node, |
447 m.IsLoad(MachineType::AnyTagged(), | 452 m.IsLoad( |
448 IsParameter(Linkage::kInterpreterRegisterFileParameter), | 453 MachineType::AnyTagged(), |
449 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)))); | 454 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), |
| 455 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)))); |
450 } | 456 } |
451 } | 457 } |
452 | 458 |
453 | |
454 TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) { | 459 TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) { |
455 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 460 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
456 InterpreterAssemblerForTest m(this, bytecode); | 461 InterpreterAssemblerForTest m(this, bytecode); |
457 Node* store_value = m.Int32Constant(0xdeadbeef); | 462 Node* store_value = m.Int32Constant(0xdeadbeef); |
458 Node* reg_index_node = m.Int32Constant(44); | 463 Node* reg_index_node = m.Int32Constant(44); |
459 Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); | 464 Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); |
460 EXPECT_THAT( | 465 EXPECT_THAT( |
461 store_reg_node, | 466 store_reg_node, |
462 m.IsStore(StoreRepresentation(MachineRepresentation::kTagged, | 467 m.IsStore( |
463 kNoWriteBarrier), | 468 StoreRepresentation(MachineRepresentation::kTagged, |
464 IsParameter(Linkage::kInterpreterRegisterFileParameter), | 469 kNoWriteBarrier), |
465 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)), | 470 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), |
466 store_value)); | 471 IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)), |
| 472 store_value)); |
467 } | 473 } |
468 } | 474 } |
469 | 475 |
470 | |
471 TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) { | 476 TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) { |
472 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 477 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
473 InterpreterAssemblerForTest m(this, bytecode); | 478 InterpreterAssemblerForTest m(this, bytecode); |
474 Node* value = m.Int32Constant(44); | 479 Node* value = m.Int32Constant(44); |
475 EXPECT_THAT(m.SmiTag(value), | 480 EXPECT_THAT(m.SmiTag(value), |
476 IsWordShl(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize))); | 481 IsWordShl(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize))); |
477 EXPECT_THAT(m.SmiUntag(value), | 482 EXPECT_THAT(m.SmiUntag(value), |
478 IsWordSar(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize))); | 483 IsWordSar(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize))); |
479 } | 484 } |
480 } | 485 } |
481 | 486 |
482 | |
483 TARGET_TEST_F(InterpreterAssemblerTest, IntPtrAdd) { | 487 TARGET_TEST_F(InterpreterAssemblerTest, IntPtrAdd) { |
484 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 488 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
485 InterpreterAssemblerForTest m(this, bytecode); | 489 InterpreterAssemblerForTest m(this, bytecode); |
486 Node* a = m.Int32Constant(0); | 490 Node* a = m.Int32Constant(0); |
487 Node* b = m.Int32Constant(1); | 491 Node* b = m.Int32Constant(1); |
488 Node* add = m.IntPtrAdd(a, b); | 492 Node* add = m.IntPtrAdd(a, b); |
489 EXPECT_THAT(add, IsIntPtrAdd(a, b)); | 493 EXPECT_THAT(add, IsIntPtrAdd(a, b)); |
490 } | 494 } |
491 } | 495 } |
492 | 496 |
493 | |
494 TARGET_TEST_F(InterpreterAssemblerTest, IntPtrSub) { | 497 TARGET_TEST_F(InterpreterAssemblerTest, IntPtrSub) { |
495 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 498 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
496 InterpreterAssemblerForTest m(this, bytecode); | 499 InterpreterAssemblerForTest m(this, bytecode); |
497 Node* a = m.Int32Constant(0); | 500 Node* a = m.Int32Constant(0); |
498 Node* b = m.Int32Constant(1); | 501 Node* b = m.Int32Constant(1); |
499 Node* add = m.IntPtrSub(a, b); | 502 Node* add = m.IntPtrSub(a, b); |
500 EXPECT_THAT(add, IsIntPtrSub(a, b)); | 503 EXPECT_THAT(add, IsIntPtrSub(a, b)); |
501 } | 504 } |
502 } | 505 } |
503 | 506 |
504 | |
505 TARGET_TEST_F(InterpreterAssemblerTest, WordShl) { | 507 TARGET_TEST_F(InterpreterAssemblerTest, WordShl) { |
506 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 508 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
507 InterpreterAssemblerForTest m(this, bytecode); | 509 InterpreterAssemblerForTest m(this, bytecode); |
508 Node* a = m.Int32Constant(0); | 510 Node* a = m.Int32Constant(0); |
509 Node* add = m.WordShl(a, 10); | 511 Node* add = m.WordShl(a, 10); |
510 EXPECT_THAT(add, IsWordShl(a, IsInt32Constant(10))); | 512 EXPECT_THAT(add, IsWordShl(a, IsInt32Constant(10))); |
511 } | 513 } |
512 } | 514 } |
513 | 515 |
514 | |
515 TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) { | 516 TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) { |
516 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 517 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
517 InterpreterAssemblerForTest m(this, bytecode); | 518 InterpreterAssemblerForTest m(this, bytecode); |
518 Node* index = m.Int32Constant(2); | 519 Node* index = m.Int32Constant(2); |
519 Node* load_constant = m.LoadConstantPoolEntry(index); | 520 Node* load_constant = m.LoadConstantPoolEntry(index); |
520 Matcher<Node*> constant_pool_matcher = m.IsLoad( | 521 Matcher<Node*> constant_pool_matcher = m.IsLoad( |
521 MachineType::AnyTagged(), | 522 MachineType::AnyTagged(), |
522 IsParameter(Linkage::kInterpreterBytecodeArrayParameter), | 523 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
523 IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - kHeapObjectTag)); | 524 IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - kHeapObjectTag)); |
524 EXPECT_THAT( | 525 EXPECT_THAT( |
525 load_constant, | 526 load_constant, |
526 m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher, | 527 m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher, |
527 IsIntPtrAdd( | 528 IsIntPtrAdd( |
528 IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), | 529 IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), |
529 IsWordShl(index, IsInt32Constant(kPointerSizeLog2))))); | 530 IsWordShl(index, IsInt32Constant(kPointerSizeLog2))))); |
530 } | 531 } |
531 } | 532 } |
532 | 533 |
533 | |
534 TARGET_TEST_F(InterpreterAssemblerTest, LoadFixedArrayElement) { | 534 TARGET_TEST_F(InterpreterAssemblerTest, LoadFixedArrayElement) { |
535 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 535 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
536 InterpreterAssemblerForTest m(this, bytecode); | 536 InterpreterAssemblerForTest m(this, bytecode); |
537 int index = 3; | 537 int index = 3; |
538 Node* fixed_array = m.IntPtrConstant(0xdeadbeef); | 538 Node* fixed_array = m.IntPtrConstant(0xdeadbeef); |
539 Node* load_element = m.LoadFixedArrayElement(fixed_array, index); | 539 Node* load_element = m.LoadFixedArrayElement(fixed_array, index); |
540 EXPECT_THAT( | 540 EXPECT_THAT( |
541 load_element, | 541 load_element, |
542 m.IsLoad(MachineType::AnyTagged(), fixed_array, | 542 m.IsLoad(MachineType::AnyTagged(), fixed_array, |
543 IsIntPtrAdd( | 543 IsIntPtrAdd( |
544 IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), | 544 IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), |
545 IsWordShl(IsInt32Constant(index), | 545 IsWordShl(IsInt32Constant(index), |
546 IsInt32Constant(kPointerSizeLog2))))); | 546 IsInt32Constant(kPointerSizeLog2))))); |
547 } | 547 } |
548 } | 548 } |
549 | 549 |
550 | |
551 TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) { | 550 TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) { |
552 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 551 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
553 InterpreterAssemblerForTest m(this, bytecode); | 552 InterpreterAssemblerForTest m(this, bytecode); |
554 Node* object = m.IntPtrConstant(0xdeadbeef); | 553 Node* object = m.IntPtrConstant(0xdeadbeef); |
555 int offset = 16; | 554 int offset = 16; |
556 Node* load_field = m.LoadObjectField(object, offset); | 555 Node* load_field = m.LoadObjectField(object, offset); |
557 EXPECT_THAT(load_field, | 556 EXPECT_THAT(load_field, |
558 m.IsLoad(MachineType::AnyTagged(), object, | 557 m.IsLoad(MachineType::AnyTagged(), object, |
559 IsIntPtrConstant(offset - kHeapObjectTag))); | 558 IsIntPtrConstant(offset - kHeapObjectTag))); |
560 } | 559 } |
561 } | 560 } |
562 | 561 |
563 | |
564 TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) { | 562 TARGET_TEST_F(InterpreterAssemblerTest, LoadContextSlot) { |
565 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 563 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
566 InterpreterAssemblerForTest m(this, bytecode); | 564 InterpreterAssemblerForTest m(this, bytecode); |
567 Node* context = m.Int32Constant(1); | 565 Node* context = m.Int32Constant(1); |
568 Node* slot_index = m.Int32Constant(22); | 566 Node* slot_index = m.Int32Constant(22); |
569 Node* load_context_slot = m.LoadContextSlot(context, slot_index); | 567 Node* load_context_slot = m.LoadContextSlot(context, slot_index); |
570 | 568 |
571 Matcher<Node*> offset = | 569 Matcher<Node*> offset = |
572 IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)), | 570 IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)), |
573 IsInt32Constant(Context::kHeaderSize - kHeapObjectTag)); | 571 IsInt32Constant(Context::kHeaderSize - kHeapObjectTag)); |
574 EXPECT_THAT(load_context_slot, | 572 EXPECT_THAT(load_context_slot, |
575 m.IsLoad(MachineType::AnyTagged(), context, offset)); | 573 m.IsLoad(MachineType::AnyTagged(), context, offset)); |
576 } | 574 } |
577 } | 575 } |
578 | 576 |
579 | |
580 TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) { | 577 TARGET_TEST_F(InterpreterAssemblerTest, StoreContextSlot) { |
581 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 578 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
582 InterpreterAssemblerForTest m(this, bytecode); | 579 InterpreterAssemblerForTest m(this, bytecode); |
583 Node* context = m.Int32Constant(1); | 580 Node* context = m.Int32Constant(1); |
584 Node* slot_index = m.Int32Constant(22); | 581 Node* slot_index = m.Int32Constant(22); |
585 Node* value = m.Int32Constant(100); | 582 Node* value = m.Int32Constant(100); |
586 Node* store_context_slot = m.StoreContextSlot(context, slot_index, value); | 583 Node* store_context_slot = m.StoreContextSlot(context, slot_index, value); |
587 | 584 |
588 Matcher<Node*> offset = | 585 Matcher<Node*> offset = |
589 IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)), | 586 IsIntPtrAdd(IsWordShl(slot_index, IsInt32Constant(kPointerSizeLog2)), |
590 IsInt32Constant(Context::kHeaderSize - kHeapObjectTag)); | 587 IsInt32Constant(Context::kHeaderSize - kHeapObjectTag)); |
591 EXPECT_THAT(store_context_slot, | 588 EXPECT_THAT(store_context_slot, |
592 m.IsStore(StoreRepresentation(MachineRepresentation::kTagged, | 589 m.IsStore(StoreRepresentation(MachineRepresentation::kTagged, |
593 kFullWriteBarrier), | 590 kFullWriteBarrier), |
594 context, offset, value)); | 591 context, offset, value)); |
595 } | 592 } |
596 } | 593 } |
597 | 594 |
598 | |
599 TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) { | 595 TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) { |
600 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 596 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
601 InterpreterAssemblerForTest m(this, bytecode); | 597 InterpreterAssemblerForTest m(this, bytecode); |
602 Node* arg1 = m.Int32Constant(2); | 598 Node* arg1 = m.Int32Constant(2); |
603 Node* arg2 = m.Int32Constant(3); | 599 Node* arg2 = m.Int32Constant(3); |
604 Node* call_runtime = m.CallRuntime(Runtime::kAdd, arg1, arg2); | 600 Node* context = |
| 601 m.Parameter(InterpreterDispatchDescriptor::kContextParameter); |
| 602 Node* call_runtime = m.CallRuntime(Runtime::kAdd, context, arg1, arg2); |
605 EXPECT_THAT( | 603 EXPECT_THAT( |
606 call_runtime, | 604 call_runtime, |
607 IsCall(_, _, arg1, arg2, _, IsInt32Constant(2), | 605 IsCall(_, _, arg1, arg2, _, IsInt32Constant(2), |
608 IsParameter(Linkage::kInterpreterContextParameter), _, _)); | 606 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _, |
| 607 _)); |
609 } | 608 } |
610 } | 609 } |
611 | 610 |
612 | |
613 TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { | 611 TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { |
614 const int kResultSizes[] = {1, 2}; | 612 const int kResultSizes[] = {1, 2}; |
615 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 613 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
616 TRACED_FOREACH(int, result_size, kResultSizes) { | 614 TRACED_FOREACH(int, result_size, kResultSizes) { |
617 InterpreterAssemblerForTest m(this, bytecode); | 615 InterpreterAssemblerForTest m(this, bytecode); |
618 Callable builtin = CodeFactory::InterpreterCEntry(isolate(), result_size); | 616 Callable builtin = CodeFactory::InterpreterCEntry(isolate(), result_size); |
619 | 617 |
620 Node* function_id = m.Int32Constant(0); | 618 Node* function_id = m.Int32Constant(0); |
621 Node* first_arg = m.Int32Constant(1); | 619 Node* first_arg = m.Int32Constant(1); |
622 Node* arg_count = m.Int32Constant(2); | 620 Node* arg_count = m.Int32Constant(2); |
| 621 Node* context = |
| 622 m.Parameter(InterpreterDispatchDescriptor::kContextParameter); |
623 | 623 |
624 Matcher<Node*> function_table = IsExternalConstant( | 624 Matcher<Node*> function_table = IsExternalConstant( |
625 ExternalReference::runtime_function_table_address(isolate())); | 625 ExternalReference::runtime_function_table_address(isolate())); |
626 Matcher<Node*> function = IsIntPtrAdd( | 626 Matcher<Node*> function = IsIntPtrAdd( |
627 function_table, | 627 function_table, |
628 IsInt32Mul(function_id, IsInt32Constant(sizeof(Runtime::Function)))); | 628 IsInt32Mul(function_id, IsInt32Constant(sizeof(Runtime::Function)))); |
629 Matcher<Node*> function_entry = | 629 Matcher<Node*> function_entry = |
630 m.IsLoad(MachineType::Pointer(), function, | 630 m.IsLoad(MachineType::Pointer(), function, |
631 IsInt32Constant(offsetof(Runtime::Function, entry))); | 631 IsInt32Constant(offsetof(Runtime::Function, entry))); |
632 | 632 |
633 Node* call_runtime = | 633 Node* call_runtime = m.CallRuntimeN(function_id, context, first_arg, |
634 m.CallRuntime(function_id, first_arg, arg_count, result_size); | 634 arg_count, result_size); |
635 EXPECT_THAT( | 635 EXPECT_THAT( |
636 call_runtime, | 636 call_runtime, |
637 IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg, | 637 IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg, |
638 function_entry, | 638 function_entry, |
639 IsParameter(Linkage::kInterpreterContextParameter), _, _)); | 639 IsParameter(InterpreterDispatchDescriptor::kContextParameter), |
| 640 _, _)); |
640 } | 641 } |
641 } | 642 } |
642 } | 643 } |
643 | 644 |
644 | |
645 TARGET_TEST_F(InterpreterAssemblerTest, CallIC) { | |
646 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | |
647 InterpreterAssemblerForTest m(this, bytecode); | |
648 LoadWithVectorDescriptor descriptor(isolate()); | |
649 Node* target = m.Int32Constant(1); | |
650 Node* arg1 = m.Int32Constant(2); | |
651 Node* arg2 = m.Int32Constant(3); | |
652 Node* arg3 = m.Int32Constant(4); | |
653 Node* arg4 = m.Int32Constant(5); | |
654 Node* call_ic = m.CallIC(descriptor, target, arg1, arg2, arg3, arg4); | |
655 EXPECT_THAT( | |
656 call_ic, | |
657 IsCall(_, target, arg1, arg2, arg3, arg4, | |
658 IsParameter(Linkage::kInterpreterContextParameter), _, _)); | |
659 } | |
660 } | |
661 | |
662 | |
663 TARGET_TEST_F(InterpreterAssemblerTest, CallJS) { | 645 TARGET_TEST_F(InterpreterAssemblerTest, CallJS) { |
664 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 646 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
665 InterpreterAssemblerForTest m(this, bytecode); | 647 InterpreterAssemblerForTest m(this, bytecode); |
666 Callable builtin = CodeFactory::InterpreterPushArgsAndCall(isolate()); | 648 Callable builtin = CodeFactory::InterpreterPushArgsAndCall(isolate()); |
667 Node* function = m.Int32Constant(0); | 649 Node* function = m.Int32Constant(0); |
668 Node* first_arg = m.Int32Constant(1); | 650 Node* first_arg = m.Int32Constant(1); |
669 Node* arg_count = m.Int32Constant(2); | 651 Node* arg_count = m.Int32Constant(2); |
670 Node* call_js = m.CallJS(function, first_arg, arg_count); | 652 Node* context = |
| 653 m.Parameter(InterpreterDispatchDescriptor::kContextParameter); |
| 654 Node* call_js = m.CallJS(function, context, first_arg, arg_count); |
671 EXPECT_THAT( | 655 EXPECT_THAT( |
672 call_js, | 656 call_js, |
673 IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg, | 657 IsCall(_, IsHeapConstant(builtin.code()), arg_count, first_arg, |
674 function, IsParameter(Linkage::kInterpreterContextParameter), _, | 658 function, |
| 659 IsParameter(InterpreterDispatchDescriptor::kContextParameter), _, |
675 _)); | 660 _)); |
676 } | 661 } |
677 } | 662 } |
678 | 663 |
679 | |
680 TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) { | 664 TARGET_TEST_F(InterpreterAssemblerTest, LoadTypeFeedbackVector) { |
681 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 665 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
682 InterpreterAssemblerForTest m(this, bytecode); | 666 InterpreterAssemblerForTest m(this, bytecode); |
683 Node* feedback_vector = m.LoadTypeFeedbackVector(); | 667 Node* feedback_vector = m.LoadTypeFeedbackVector(); |
684 | 668 |
685 Matcher<Node*> load_function_matcher = | 669 Matcher<Node*> load_function_matcher = m.IsLoad( |
686 m.IsLoad(MachineType::AnyTagged(), | 670 MachineType::AnyTagged(), |
687 IsParameter(Linkage::kInterpreterRegisterFileParameter), | 671 IsParameter(InterpreterDispatchDescriptor::kRegisterFileParameter), |
688 IsIntPtrConstant( | 672 IsIntPtrConstant( |
689 InterpreterFrameConstants::kFunctionFromRegisterPointer)); | 673 InterpreterFrameConstants::kFunctionFromRegisterPointer)); |
690 Matcher<Node*> load_shared_function_info_matcher = | 674 Matcher<Node*> load_shared_function_info_matcher = |
691 m.IsLoad(MachineType::AnyTagged(), load_function_matcher, | 675 m.IsLoad(MachineType::AnyTagged(), load_function_matcher, |
692 IsIntPtrConstant(JSFunction::kSharedFunctionInfoOffset - | 676 IsIntPtrConstant(JSFunction::kSharedFunctionInfoOffset - |
693 kHeapObjectTag)); | 677 kHeapObjectTag)); |
694 | 678 |
695 EXPECT_THAT( | 679 EXPECT_THAT( |
696 feedback_vector, | 680 feedback_vector, |
697 m.IsLoad(MachineType::AnyTagged(), load_shared_function_info_matcher, | 681 m.IsLoad(MachineType::AnyTagged(), load_shared_function_info_matcher, |
698 IsIntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset - | 682 IsIntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset - |
699 kHeapObjectTag))); | 683 kHeapObjectTag))); |
700 } | 684 } |
701 } | 685 } |
702 | 686 |
703 } // namespace compiler | 687 } // namespace interpreter |
704 } // namespace internal | 688 } // namespace internal |
705 } // namespace v8 | 689 } // namespace v8 |
OLD | NEW |