OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/factory.h" | 7 #include "src/factory.h" |
8 #include "src/interpreter/bytecode-label.h" | 8 #include "src/interpreter/bytecode-label.h" |
9 #include "src/interpreter/bytecode-peephole-optimizer.h" | 9 #include "src/interpreter/bytecode-peephole-optimizer.h" |
10 #include "src/interpreter/constant-array-builder.h" | 10 #include "src/interpreter/constant-array-builder.h" |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 optimizer()->Write(&nop); | 96 optimizer()->Write(&nop); |
97 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand()); | 97 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand()); |
98 optimizer()->Write(&add); | 98 optimizer()->Write(&add); |
99 Flush(); | 99 Flush(); |
100 CHECK_EQ(write_count(), 1); | 100 CHECK_EQ(write_count(), 1); |
101 CHECK_EQ(add, last_written()); | 101 CHECK_EQ(add, last_written()); |
102 } | 102 } |
103 | 103 |
104 TEST_F(BytecodePeepholeOptimizerTest, ElideExpressionNop) { | 104 TEST_F(BytecodePeepholeOptimizerTest, ElideExpressionNop) { |
105 BytecodeNode nop(Bytecode::kNop); | 105 BytecodeNode nop(Bytecode::kNop); |
106 nop.source_info().Update({3, false}); | 106 nop.source_info().MakeExpressionPosition(3); |
107 optimizer()->Write(&nop); | 107 optimizer()->Write(&nop); |
108 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand()); | 108 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand()); |
109 optimizer()->Write(&add); | 109 optimizer()->Write(&add); |
110 Flush(); | 110 Flush(); |
111 CHECK_EQ(write_count(), 1); | 111 CHECK_EQ(write_count(), 1); |
112 CHECK_EQ(add, last_written()); | 112 CHECK_EQ(add, last_written()); |
113 } | 113 } |
114 | 114 |
115 TEST_F(BytecodePeepholeOptimizerTest, KeepStatementNop) { | 115 TEST_F(BytecodePeepholeOptimizerTest, KeepStatementNop) { |
116 BytecodeNode nop(Bytecode::kNop); | 116 BytecodeNode nop(Bytecode::kNop); |
117 nop.source_info().Update({3, true}); | 117 nop.source_info().MakeStatementPosition(3); |
118 optimizer()->Write(&nop); | 118 optimizer()->Write(&nop); |
119 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand()); | 119 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand()); |
120 add.source_info().Update({3, false}); | 120 add.source_info().MakeExpressionPosition(3); |
121 optimizer()->Write(&add); | 121 optimizer()->Write(&add); |
122 Flush(); | 122 Flush(); |
123 CHECK_EQ(write_count(), 2); | 123 CHECK_EQ(write_count(), 2); |
124 CHECK_EQ(add, last_written()); | 124 CHECK_EQ(add, last_written()); |
125 } | 125 } |
126 | 126 |
127 // Tests covering BytecodePeepholeOptimizer::UpdateCurrentBytecode(). | 127 // Tests covering BytecodePeepholeOptimizer::UpdateCurrentBytecode(). |
128 | 128 |
129 TEST_F(BytecodePeepholeOptimizerTest, KeepJumpIfToBooleanTrue) { | 129 TEST_F(BytecodePeepholeOptimizerTest, KeepJumpIfToBooleanTrue) { |
130 BytecodeNode first(Bytecode::kLdaNull); | 130 BytecodeNode first(Bytecode::kLdaNull); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 optimizer()->Write(&second); | 203 optimizer()->Write(&second); |
204 CHECK_EQ(write_count(), 1); | 204 CHECK_EQ(write_count(), 1); |
205 CHECK_EQ(last_written(), first); | 205 CHECK_EQ(last_written(), first); |
206 Flush(); | 206 Flush(); |
207 CHECK_EQ(write_count(), 1); | 207 CHECK_EQ(write_count(), 1); |
208 } | 208 } |
209 | 209 |
210 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatement) { | 210 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatement) { |
211 BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); | 211 BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); |
212 BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand()); | 212 BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand()); |
213 second.source_info().Update({0, true}); | 213 second.source_info().MakeStatementPosition(0); |
214 optimizer()->Write(&first); | 214 optimizer()->Write(&first); |
215 CHECK_EQ(write_count(), 0); | 215 CHECK_EQ(write_count(), 0); |
216 optimizer()->Write(&second); | 216 optimizer()->Write(&second); |
217 CHECK_EQ(write_count(), 1); | 217 CHECK_EQ(write_count(), 1); |
218 CHECK_EQ(last_written(), first); | 218 CHECK_EQ(last_written(), first); |
219 Flush(); | 219 Flush(); |
220 CHECK_EQ(write_count(), 2); | 220 CHECK_EQ(write_count(), 2); |
221 CHECK_EQ(last_written().bytecode(), Bytecode::kNop); | 221 CHECK_EQ(last_written().bytecode(), Bytecode::kNop); |
222 CHECK_EQ(last_written().source_info(), second.source_info()); | 222 CHECK_EQ(last_written().source_info(), second.source_info()); |
223 } | 223 } |
224 | 224 |
225 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatementStarRy) { | 225 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatementStarRy) { |
226 BytecodeLabel label; | 226 BytecodeLabel label; |
227 BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); | 227 BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); |
228 BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand()); | 228 BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand()); |
229 BytecodeNode third(Bytecode::kStar, Register(3).ToOperand()); | 229 BytecodeNode third(Bytecode::kStar, Register(3).ToOperand()); |
230 second.source_info().Update({0, true}); | 230 second.source_info().MakeStatementPosition(0); |
231 optimizer()->Write(&first); | 231 optimizer()->Write(&first); |
232 CHECK_EQ(write_count(), 0); | 232 CHECK_EQ(write_count(), 0); |
233 optimizer()->Write(&second); | 233 optimizer()->Write(&second); |
234 CHECK_EQ(write_count(), 1); | 234 CHECK_EQ(write_count(), 1); |
235 CHECK_EQ(last_written(), first); | 235 CHECK_EQ(last_written(), first); |
236 optimizer()->Write(&third); | 236 optimizer()->Write(&third); |
237 CHECK_EQ(write_count(), 1); | 237 CHECK_EQ(write_count(), 1); |
238 Flush(); | 238 Flush(); |
239 CHECK_EQ(write_count(), 2); | 239 CHECK_EQ(write_count(), 2); |
240 // Source position should move |second| to |third| when |second| is elided. | |
241 third.source_info().Update(second.source_info()); | |
242 CHECK_EQ(last_written(), third); | 240 CHECK_EQ(last_written(), third); |
243 } | 241 } |
244 | 242 |
245 TEST_F(BytecodePeepholeOptimizerTest, LdarToName) { | 243 TEST_F(BytecodePeepholeOptimizerTest, LdarToName) { |
246 BytecodeNode first(Bytecode::kLdar, Register(0).ToOperand()); | 244 BytecodeNode first(Bytecode::kLdar, Register(0).ToOperand()); |
247 BytecodeNode second(Bytecode::kToName); | 245 BytecodeNode second(Bytecode::kToName); |
248 optimizer()->Write(&first); | 246 optimizer()->Write(&first); |
249 CHECK_EQ(write_count(), 0); | 247 CHECK_EQ(write_count(), 0); |
250 optimizer()->Write(&second); | 248 optimizer()->Write(&second); |
251 CHECK_EQ(write_count(), 1); | 249 CHECK_EQ(write_count(), 1); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 CHECK_EQ(write_count(), 0); | 316 CHECK_EQ(write_count(), 0); |
319 optimizer()->Write(&second); | 317 optimizer()->Write(&second); |
320 CHECK_EQ(write_count(), 0); | 318 CHECK_EQ(write_count(), 0); |
321 Flush(); | 319 Flush(); |
322 CHECK_EQ(write_count(), 1); | 320 CHECK_EQ(write_count(), 1); |
323 CHECK_EQ(last_written(), second); | 321 CHECK_EQ(last_written(), second); |
324 } | 322 } |
325 | 323 |
326 TEST_F(BytecodePeepholeOptimizerTest, LdaTrueStatementLdaFalse) { | 324 TEST_F(BytecodePeepholeOptimizerTest, LdaTrueStatementLdaFalse) { |
327 BytecodeNode first(Bytecode::kLdaTrue); | 325 BytecodeNode first(Bytecode::kLdaTrue); |
328 first.source_info().Update({3, false}); | 326 first.source_info().MakeExpressionPosition(3); |
329 BytecodeNode second(Bytecode::kLdaFalse); | 327 BytecodeNode second(Bytecode::kLdaFalse); |
330 optimizer()->Write(&first); | 328 optimizer()->Write(&first); |
331 CHECK_EQ(write_count(), 0); | 329 CHECK_EQ(write_count(), 0); |
332 optimizer()->Write(&second); | 330 optimizer()->Write(&second); |
333 CHECK_EQ(write_count(), 0); | 331 CHECK_EQ(write_count(), 0); |
334 Flush(); | 332 Flush(); |
335 CHECK_EQ(write_count(), 1); | 333 CHECK_EQ(write_count(), 1); |
336 second.source_info().Update(first.source_info()); | |
337 CHECK_EQ(last_written(), second); | 334 CHECK_EQ(last_written(), second); |
| 335 CHECK(second.source_info().is_expression()); |
| 336 CHECK_EQ(second.source_info().source_position(), 3); |
338 } | 337 } |
339 | 338 |
340 TEST_F(BytecodePeepholeOptimizerTest, NopStackCheck) { | 339 TEST_F(BytecodePeepholeOptimizerTest, NopStackCheck) { |
341 BytecodeNode first(Bytecode::kNop); | 340 BytecodeNode first(Bytecode::kNop); |
342 BytecodeNode second(Bytecode::kStackCheck); | 341 BytecodeNode second(Bytecode::kStackCheck); |
343 optimizer()->Write(&first); | 342 optimizer()->Write(&first); |
344 CHECK_EQ(write_count(), 0); | 343 CHECK_EQ(write_count(), 0); |
345 optimizer()->Write(&second); | 344 optimizer()->Write(&second); |
346 CHECK_EQ(write_count(), 0); | 345 CHECK_EQ(write_count(), 0); |
347 Flush(); | 346 Flush(); |
348 CHECK_EQ(write_count(), 1); | 347 CHECK_EQ(write_count(), 1); |
349 CHECK_EQ(last_written(), second); | 348 CHECK_EQ(last_written(), second); |
350 } | 349 } |
351 | 350 |
352 TEST_F(BytecodePeepholeOptimizerTest, NopStatementStackCheck) { | 351 TEST_F(BytecodePeepholeOptimizerTest, NopStatementStackCheck) { |
353 BytecodeNode first(Bytecode::kNop); | 352 BytecodeNode first(Bytecode::kNop); |
354 first.source_info().Update({3, false}); | 353 first.source_info().MakeExpressionPosition(3); |
355 BytecodeNode second(Bytecode::kStackCheck); | 354 BytecodeNode second(Bytecode::kStackCheck); |
356 optimizer()->Write(&first); | 355 optimizer()->Write(&first); |
357 CHECK_EQ(write_count(), 0); | 356 CHECK_EQ(write_count(), 0); |
358 optimizer()->Write(&second); | 357 optimizer()->Write(&second); |
359 CHECK_EQ(write_count(), 0); | 358 CHECK_EQ(write_count(), 0); |
360 Flush(); | 359 Flush(); |
361 CHECK_EQ(write_count(), 1); | 360 CHECK_EQ(write_count(), 1); |
362 second.source_info().Update(first.source_info()); | 361 second.source_info().MakeExpressionPosition( |
| 362 first.source_info().source_position()); |
363 CHECK_EQ(last_written(), second); | 363 CHECK_EQ(last_written(), second); |
364 } | 364 } |
365 | 365 |
366 // Tests covering BytecodePeepholeOptimizer::UpdateLastAndCurrentBytecodes(). | 366 // Tests covering BytecodePeepholeOptimizer::UpdateLastAndCurrentBytecodes(). |
367 | 367 |
368 TEST_F(BytecodePeepholeOptimizerTest, MergeLoadICStar) { | 368 TEST_F(BytecodePeepholeOptimizerTest, MergeLoadICStar) { |
369 const uint32_t operands[] = { | 369 const uint32_t operands[] = { |
370 static_cast<uint32_t>(Register(31).ToOperand()), 32, 33, | 370 static_cast<uint32_t>(Register(31).ToOperand()), 32, 33, |
371 static_cast<uint32_t>(Register(256).ToOperand())}; | 371 static_cast<uint32_t>(Register(256).ToOperand())}; |
372 const int expected_operand_count = static_cast<int>(arraysize(operands)); | 372 const int expected_operand_count = static_cast<int>(arraysize(operands)); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 CHECK_EQ(write_count(), 2); | 485 CHECK_EQ(write_count(), 2); |
486 CHECK_EQ(last_written().bytecode(), Bytecode::kLdar); | 486 CHECK_EQ(last_written().bytecode(), Bytecode::kLdar); |
487 CHECK_EQ(last_written().operand(0), operands[expected_operand_count - 1]); | 487 CHECK_EQ(last_written().operand(0), operands[expected_operand_count - 1]); |
488 Flush(); | 488 Flush(); |
489 CHECK_EQ(last_written().bytecode(), third.bytecode()); | 489 CHECK_EQ(last_written().bytecode(), third.bytecode()); |
490 } | 490 } |
491 | 491 |
492 } // namespace interpreter | 492 } // namespace interpreter |
493 } // namespace internal | 493 } // namespace internal |
494 } // namespace v8 | 494 } // namespace v8 |
OLD | NEW |