| 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 | 
|---|