| 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/objects-inl.h" |   10 #include "src/objects-inl.h" | 
|   11 #include "src/objects.h" |   11 #include "src/objects.h" | 
|   12 #include "test/unittests/test-utils.h" |   12 #include "test/unittests/test-utils.h" | 
|   13  |   13  | 
|   14 namespace v8 { |   14 namespace v8 { | 
|   15 namespace internal { |   15 namespace internal { | 
|   16 namespace interpreter { |   16 namespace interpreter { | 
|   17  |   17  | 
|   18 class BytecodePeepholeOptimizerTest : public BytecodePipelineStage, |   18 class BytecodePeepholeOptimizerTest : public BytecodePipelineStage, | 
|   19                                       public TestWithIsolateAndZone { |   19                                       public TestWithIsolateAndZone { | 
|   20  public: |   20  public: | 
|   21   BytecodePeepholeOptimizerTest() |   21   BytecodePeepholeOptimizerTest() : peephole_optimizer_(this) {} | 
|   22       : peephole_optimizer_(this), last_written_(Bytecode::kIllegal) {} |  | 
|   23   ~BytecodePeepholeOptimizerTest() override {} |   22   ~BytecodePeepholeOptimizerTest() override {} | 
|   24  |   23  | 
|   25   void Reset() { |   24   void Reset() { | 
|   26     last_written_.set_bytecode(Bytecode::kIllegal); |   25     last_written_.set_bytecode(Bytecode::kIllegal); | 
|   27     write_count_ = 0; |   26     write_count_ = 0; | 
|   28   } |   27   } | 
|   29  |   28  | 
|   30   void Write(BytecodeNode* node) override { |   29   void Write(BytecodeNode* node) override { | 
|   31     write_count_++; |   30     write_count_++; | 
|   32     last_written_.Clone(node); |   31     last_written_.Clone(node); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   65 // Sanity tests. |   64 // Sanity tests. | 
|   66  |   65  | 
|   67 TEST_F(BytecodePeepholeOptimizerTest, FlushOnJump) { |   66 TEST_F(BytecodePeepholeOptimizerTest, FlushOnJump) { | 
|   68   CHECK_EQ(write_count(), 0); |   67   CHECK_EQ(write_count(), 0); | 
|   69  |   68  | 
|   70   BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); |   69   BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); | 
|   71   optimizer()->Write(&add); |   70   optimizer()->Write(&add); | 
|   72   CHECK_EQ(write_count(), 0); |   71   CHECK_EQ(write_count(), 0); | 
|   73  |   72  | 
|   74   BytecodeLabel target; |   73   BytecodeLabel target; | 
|   75   BytecodeNode jump(Bytecode::kJump, 0, nullptr); |   74   BytecodeNode jump(Bytecode::kJump, 0); | 
|   76   optimizer()->WriteJump(&jump, &target); |   75   optimizer()->WriteJump(&jump, &target); | 
|   77   CHECK_EQ(write_count(), 2); |   76   CHECK_EQ(write_count(), 2); | 
|   78   CHECK_EQ(jump, last_written()); |   77   CHECK_EQ(jump, last_written()); | 
|   79 } |   78 } | 
|   80  |   79  | 
|   81 TEST_F(BytecodePeepholeOptimizerTest, FlushOnBind) { |   80 TEST_F(BytecodePeepholeOptimizerTest, FlushOnBind) { | 
|   82   CHECK_EQ(write_count(), 0); |   81   CHECK_EQ(write_count(), 0); | 
|   83  |   82  | 
|   84   BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); |   83   BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); | 
|   85   optimizer()->Write(&add); |   84   optimizer()->Write(&add); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   97   BytecodeNode nop(Bytecode::kNop); |   96   BytecodeNode nop(Bytecode::kNop); | 
|   98   optimizer()->Write(&nop); |   97   optimizer()->Write(&nop); | 
|   99   BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); |   98   BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); | 
|  100   optimizer()->Write(&add); |   99   optimizer()->Write(&add); | 
|  101   Flush(); |  100   Flush(); | 
|  102   CHECK_EQ(write_count(), 1); |  101   CHECK_EQ(write_count(), 1); | 
|  103   CHECK_EQ(add, last_written()); |  102   CHECK_EQ(add, last_written()); | 
|  104 } |  103 } | 
|  105  |  104  | 
|  106 TEST_F(BytecodePeepholeOptimizerTest, ElideExpressionNop) { |  105 TEST_F(BytecodePeepholeOptimizerTest, ElideExpressionNop) { | 
|  107   BytecodeSourceInfo source_info(3, false); |  106   BytecodeNode nop(Bytecode::kNop); | 
|  108   BytecodeNode nop(Bytecode::kNop, &source_info); |  107   nop.source_info().MakeExpressionPosition(3); | 
|  109   optimizer()->Write(&nop); |  108   optimizer()->Write(&nop); | 
|  110   BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); |  109   BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); | 
|  111   optimizer()->Write(&add); |  110   optimizer()->Write(&add); | 
|  112   Flush(); |  111   Flush(); | 
|  113   CHECK_EQ(write_count(), 1); |  112   CHECK_EQ(write_count(), 1); | 
|  114   CHECK_EQ(add, last_written()); |  113   CHECK_EQ(add, last_written()); | 
|  115 } |  114 } | 
|  116  |  115  | 
|  117 TEST_F(BytecodePeepholeOptimizerTest, KeepStatementNop) { |  116 TEST_F(BytecodePeepholeOptimizerTest, KeepStatementNop) { | 
|  118   BytecodeSourceInfo source_info(3, true); |  117   BytecodeNode nop(Bytecode::kNop); | 
|  119   BytecodeNode nop(Bytecode::kNop, &source_info); |  118   nop.source_info().MakeStatementPosition(3); | 
|  120   optimizer()->Write(&nop); |  119   optimizer()->Write(&nop); | 
|  121   source_info.MakeExpressionPosition(3); |  120   BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); | 
|  122   BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1, &source_info); |  121   add.source_info().MakeExpressionPosition(3); | 
|  123   optimizer()->Write(&add); |  122   optimizer()->Write(&add); | 
|  124   Flush(); |  123   Flush(); | 
|  125   CHECK_EQ(write_count(), 2); |  124   CHECK_EQ(write_count(), 2); | 
|  126   CHECK_EQ(add, last_written()); |  125   CHECK_EQ(add, last_written()); | 
|  127 } |  126 } | 
|  128  |  127  | 
|  129 // Tests covering BytecodePeepholeOptimizer::UpdateCurrentBytecode(). |  128 // Tests covering BytecodePeepholeOptimizer::UpdateCurrentBytecode(). | 
|  130  |  129  | 
|  131 TEST_F(BytecodePeepholeOptimizerTest, KeepJumpIfToBooleanTrue) { |  130 TEST_F(BytecodePeepholeOptimizerTest, KeepJumpIfToBooleanTrue) { | 
|  132   BytecodeNode first(Bytecode::kLdaNull); |  131   BytecodeNode first(Bytecode::kLdaNull); | 
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  198   optimizer()->Write(&first); |  197   optimizer()->Write(&first); | 
|  199   optimizer()->Write(&second); |  198   optimizer()->Write(&second); | 
|  200   CHECK_EQ(write_count(), 0); |  199   CHECK_EQ(write_count(), 0); | 
|  201   Flush(); |  200   Flush(); | 
|  202   CHECK_EQ(write_count(), 1); |  201   CHECK_EQ(write_count(), 1); | 
|  203   CHECK_EQ(last_written(), first); |  202   CHECK_EQ(last_written(), first); | 
|  204 } |  203 } | 
|  205  |  204  | 
|  206 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatement) { |  205 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatement) { | 
|  207   BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); |  206   BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); | 
|  208   BytecodeSourceInfo source_info(3, true); |  207   BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand()); | 
|  209   BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand(), &source_info); |  208   second.source_info().MakeStatementPosition(0); | 
|  210   optimizer()->Write(&first); |  209   optimizer()->Write(&first); | 
|  211   CHECK_EQ(write_count(), 0); |  210   CHECK_EQ(write_count(), 0); | 
|  212   optimizer()->Write(&second); |  211   optimizer()->Write(&second); | 
|  213   CHECK_EQ(write_count(), 1); |  212   CHECK_EQ(write_count(), 1); | 
|  214   CHECK_EQ(last_written(), first); |  213   CHECK_EQ(last_written(), first); | 
|  215   Flush(); |  214   Flush(); | 
|  216   CHECK_EQ(write_count(), 2); |  215   CHECK_EQ(write_count(), 2); | 
|  217   CHECK_EQ(last_written().bytecode(), Bytecode::kNop); |  216   CHECK_EQ(last_written().bytecode(), Bytecode::kNop); | 
|  218   CHECK_EQ(last_written().source_info(), second.source_info()); |  217   CHECK_EQ(last_written().source_info(), second.source_info()); | 
|  219 } |  218 } | 
|  220  |  219  | 
|  221 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatementStarRy) { |  220 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatementStarRy) { | 
|  222   BytecodeLabel label; |  221   BytecodeLabel label; | 
|  223   BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); |  222   BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); | 
|  224   BytecodeSourceInfo source_info(0, true); |  223   BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand()); | 
|  225   BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand(), &source_info); |  | 
|  226   BytecodeNode third(Bytecode::kStar, Register(3).ToOperand()); |  224   BytecodeNode third(Bytecode::kStar, Register(3).ToOperand()); | 
 |  225   second.source_info().MakeStatementPosition(0); | 
|  227   optimizer()->Write(&first); |  226   optimizer()->Write(&first); | 
|  228   CHECK_EQ(write_count(), 0); |  227   CHECK_EQ(write_count(), 0); | 
|  229   optimizer()->Write(&second); |  228   optimizer()->Write(&second); | 
|  230   CHECK_EQ(write_count(), 1); |  229   CHECK_EQ(write_count(), 1); | 
|  231   CHECK_EQ(last_written(), first); |  230   CHECK_EQ(last_written(), first); | 
|  232   optimizer()->Write(&third); |  231   optimizer()->Write(&third); | 
|  233   CHECK_EQ(write_count(), 1); |  232   CHECK_EQ(write_count(), 1); | 
|  234   Flush(); |  233   Flush(); | 
|  235   CHECK_EQ(write_count(), 2); |  234   CHECK_EQ(write_count(), 2); | 
|  236   CHECK_EQ(last_written(), third); |  235   CHECK_EQ(last_written(), third); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  271   optimizer()->Write(&first); |  270   optimizer()->Write(&first); | 
|  272   CHECK_EQ(write_count(), 0); |  271   CHECK_EQ(write_count(), 0); | 
|  273   optimizer()->Write(&second); |  272   optimizer()->Write(&second); | 
|  274   CHECK_EQ(write_count(), 0); |  273   CHECK_EQ(write_count(), 0); | 
|  275   Flush(); |  274   Flush(); | 
|  276   CHECK_EQ(write_count(), 1); |  275   CHECK_EQ(write_count(), 1); | 
|  277   CHECK_EQ(last_written(), second); |  276   CHECK_EQ(last_written(), second); | 
|  278 } |  277 } | 
|  279  |  278  | 
|  280 TEST_F(BytecodePeepholeOptimizerTest, LdaTrueStatementLdaFalse) { |  279 TEST_F(BytecodePeepholeOptimizerTest, LdaTrueStatementLdaFalse) { | 
|  281   BytecodeSourceInfo source_info(3, true); |  280   BytecodeNode first(Bytecode::kLdaTrue); | 
|  282   BytecodeNode first(Bytecode::kLdaTrue, &source_info); |  281   first.source_info().MakeExpressionPosition(3); | 
|  283   BytecodeNode second(Bytecode::kLdaFalse); |  282   BytecodeNode second(Bytecode::kLdaFalse); | 
|  284   optimizer()->Write(&first); |  283   optimizer()->Write(&first); | 
|  285   CHECK_EQ(write_count(), 0); |  284   CHECK_EQ(write_count(), 0); | 
|  286   optimizer()->Write(&second); |  285   optimizer()->Write(&second); | 
|  287   CHECK_EQ(write_count(), 0); |  286   CHECK_EQ(write_count(), 0); | 
|  288   Flush(); |  287   Flush(); | 
|  289   CHECK_EQ(write_count(), 1); |  288   CHECK_EQ(write_count(), 1); | 
|  290   CHECK_EQ(last_written(), second); |  289   CHECK_EQ(last_written(), second); | 
|  291   CHECK(second.source_info().is_statement()); |  290   CHECK(second.source_info().is_expression()); | 
|  292   CHECK_EQ(second.source_info().source_position(), 3); |  291   CHECK_EQ(second.source_info().source_position(), 3); | 
|  293 } |  292 } | 
|  294  |  293  | 
|  295 TEST_F(BytecodePeepholeOptimizerTest, NopStackCheck) { |  294 TEST_F(BytecodePeepholeOptimizerTest, NopStackCheck) { | 
|  296   BytecodeNode first(Bytecode::kNop); |  295   BytecodeNode first(Bytecode::kNop); | 
|  297   BytecodeNode second(Bytecode::kStackCheck, nullptr); |  296   BytecodeNode second(Bytecode::kStackCheck); | 
|  298   optimizer()->Write(&first); |  297   optimizer()->Write(&first); | 
|  299   CHECK_EQ(write_count(), 0); |  298   CHECK_EQ(write_count(), 0); | 
|  300   optimizer()->Write(&second); |  299   optimizer()->Write(&second); | 
|  301   CHECK_EQ(write_count(), 0); |  300   CHECK_EQ(write_count(), 0); | 
|  302   Flush(); |  301   Flush(); | 
|  303   CHECK_EQ(write_count(), 1); |  302   CHECK_EQ(write_count(), 1); | 
|  304   CHECK_EQ(last_written(), second); |  303   CHECK_EQ(last_written(), second); | 
|  305 } |  304 } | 
|  306  |  305  | 
|  307 TEST_F(BytecodePeepholeOptimizerTest, NopStatementStackCheck) { |  306 TEST_F(BytecodePeepholeOptimizerTest, NopStatementStackCheck) { | 
|  308   BytecodeSourceInfo source_info(3, true); |  307   BytecodeNode first(Bytecode::kNop); | 
|  309   BytecodeNode first(Bytecode::kNop, &source_info); |  308   first.source_info().MakeExpressionPosition(3); | 
|  310   BytecodeNode second(Bytecode::kStackCheck); |  309   BytecodeNode second(Bytecode::kStackCheck); | 
|  311   optimizer()->Write(&first); |  310   optimizer()->Write(&first); | 
|  312   CHECK_EQ(write_count(), 0); |  311   CHECK_EQ(write_count(), 0); | 
|  313   optimizer()->Write(&second); |  312   optimizer()->Write(&second); | 
|  314   CHECK_EQ(write_count(), 0); |  313   CHECK_EQ(write_count(), 0); | 
|  315   Flush(); |  314   Flush(); | 
|  316   CHECK_EQ(write_count(), 1); |  315   CHECK_EQ(write_count(), 1); | 
|  317   BytecodeSourceInfo expected_source_info(3, true); |  316   second.source_info().MakeExpressionPosition( | 
|  318   BytecodeNode expected(Bytecode::kStackCheck, &expected_source_info); |  317       first.source_info().source_position()); | 
|  319   CHECK_EQ(last_written(), expected); |  318   CHECK_EQ(last_written(), second); | 
|  320 } |  319 } | 
|  321  |  320  | 
|  322 // Tests covering BytecodePeepholeOptimizer::UpdateLastAndCurrentBytecodes(). |  321 // Tests covering BytecodePeepholeOptimizer::UpdateLastAndCurrentBytecodes(). | 
|  323  |  322  | 
|  324 TEST_F(BytecodePeepholeOptimizerTest, MergeLoadICStar) { |  323 TEST_F(BytecodePeepholeOptimizerTest, MergeLoadICStar) { | 
|  325   const uint32_t operands[] = { |  324   const uint32_t operands[] = { | 
|  326       static_cast<uint32_t>(Register(31).ToOperand()), 32, 33, |  325       static_cast<uint32_t>(Register(31).ToOperand()), 32, 33, | 
|  327       static_cast<uint32_t>(Register(256).ToOperand())}; |  326       static_cast<uint32_t>(Register(256).ToOperand())}; | 
|  328   const int expected_operand_count = static_cast<int>(arraysize(operands)); |  327   const int expected_operand_count = static_cast<int>(arraysize(operands)); | 
|  329  |  328  | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  346   Flush(); |  345   Flush(); | 
|  347   CHECK_EQ(last_written().bytecode(), third.bytecode()); |  346   CHECK_EQ(last_written().bytecode(), third.bytecode()); | 
|  348 } |  347 } | 
|  349  |  348  | 
|  350 TEST_F(BytecodePeepholeOptimizerTest, MergeLdaKeyedPropertyStar) { |  349 TEST_F(BytecodePeepholeOptimizerTest, MergeLdaKeyedPropertyStar) { | 
|  351   const uint32_t operands[] = {static_cast<uint32_t>(Register(31).ToOperand()), |  350   const uint32_t operands[] = {static_cast<uint32_t>(Register(31).ToOperand()), | 
|  352                                9999997, |  351                                9999997, | 
|  353                                static_cast<uint32_t>(Register(1).ToOperand())}; |  352                                static_cast<uint32_t>(Register(1).ToOperand())}; | 
|  354   const int expected_operand_count = static_cast<int>(arraysize(operands)); |  353   const int expected_operand_count = static_cast<int>(arraysize(operands)); | 
|  355  |  354  | 
|  356   BytecodeNode first(Bytecode::kLdaKeyedProperty, operands[0], operands[1], |  355   BytecodeNode first(Bytecode::kLdaKeyedProperty, operands[0], operands[1]); | 
|  357                      nullptr); |  | 
|  358   BytecodeNode second(Bytecode::kStar, operands[2]); |  356   BytecodeNode second(Bytecode::kStar, operands[2]); | 
|  359   BytecodeNode third(Bytecode::kReturn); |  357   BytecodeNode third(Bytecode::kReturn); | 
|  360   optimizer()->Write(&first); |  358   optimizer()->Write(&first); | 
|  361   optimizer()->Write(&second); |  359   optimizer()->Write(&second); | 
|  362   CHECK_EQ(write_count(), 1); |  360   CHECK_EQ(write_count(), 1); | 
|  363   CHECK_EQ(last_written().bytecode(), Bytecode::kLdrKeyedProperty); |  361   CHECK_EQ(last_written().bytecode(), Bytecode::kLdrKeyedProperty); | 
|  364   CHECK_EQ(last_written().operand_count(), expected_operand_count); |  362   CHECK_EQ(last_written().operand_count(), expected_operand_count); | 
|  365   for (int i = 0; i < expected_operand_count; ++i) { |  363   for (int i = 0; i < expected_operand_count; ++i) { | 
|  366     CHECK_EQ(last_written().operand(i), operands[i]); |  364     CHECK_EQ(last_written().operand(i), operands[i]); | 
|  367   } |  365   } | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  452   Bytecode operator_replacement_pairs[][2] = { |  450   Bytecode operator_replacement_pairs[][2] = { | 
|  453       {Bytecode::kAdd, Bytecode::kAddSmi}, |  451       {Bytecode::kAdd, Bytecode::kAddSmi}, | 
|  454       {Bytecode::kSub, Bytecode::kSubSmi}, |  452       {Bytecode::kSub, Bytecode::kSubSmi}, | 
|  455       {Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi}, |  453       {Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi}, | 
|  456       {Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi}, |  454       {Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi}, | 
|  457       {Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi}, |  455       {Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi}, | 
|  458       {Bytecode::kShiftRight, Bytecode::kShiftRightSmi}}; |  456       {Bytecode::kShiftRight, Bytecode::kShiftRightSmi}}; | 
|  459  |  457  | 
|  460   for (auto operator_replacement : operator_replacement_pairs) { |  458   for (auto operator_replacement : operator_replacement_pairs) { | 
|  461     uint32_t imm_operand = 17; |  459     uint32_t imm_operand = 17; | 
|  462     BytecodeSourceInfo source_info(3, true); |  460     BytecodeNode first(Bytecode::kLdaSmi, imm_operand); | 
|  463     BytecodeNode first(Bytecode::kLdaSmi, imm_operand, &source_info); |  461     first.source_info().Clone({3, true}); | 
|  464     uint32_t reg_operand = Register(0).ToOperand(); |  462     uint32_t reg_operand = Register(0).ToOperand(); | 
|  465     uint32_t idx_operand = 1; |  463     uint32_t idx_operand = 1; | 
|  466     BytecodeNode second(operator_replacement[0], reg_operand, idx_operand); |  464     BytecodeNode second(operator_replacement[0], reg_operand, idx_operand); | 
|  467     optimizer()->Write(&first); |  465     optimizer()->Write(&first); | 
|  468     optimizer()->Write(&second); |  466     optimizer()->Write(&second); | 
|  469     Flush(); |  467     Flush(); | 
|  470     CHECK_EQ(write_count(), 1); |  468     CHECK_EQ(write_count(), 1); | 
|  471     CHECK_EQ(last_written().bytecode(), operator_replacement[1]); |  469     CHECK_EQ(last_written().bytecode(), operator_replacement[1]); | 
|  472     CHECK_EQ(last_written().operand_count(), 3); |  470     CHECK_EQ(last_written().operand_count(), 3); | 
|  473     CHECK_EQ(last_written().operand(0), imm_operand); |  471     CHECK_EQ(last_written().operand(0), imm_operand); | 
|  474     CHECK_EQ(last_written().operand(1), reg_operand); |  472     CHECK_EQ(last_written().operand(1), reg_operand); | 
|  475     CHECK_EQ(last_written().operand(2), idx_operand); |  473     CHECK_EQ(last_written().operand(2), idx_operand); | 
|  476     CHECK_EQ(last_written().source_info(), first.source_info()); |  474     CHECK_EQ(last_written().source_info(), first.source_info()); | 
|  477     Reset(); |  475     Reset(); | 
|  478   } |  476   } | 
|  479 } |  477 } | 
|  480  |  478  | 
|  481 TEST_F(BytecodePeepholeOptimizerTest, NotMergingLdaSmiWithBinaryOp) { |  479 TEST_F(BytecodePeepholeOptimizerTest, NotMergingLdaSmiWithBinaryOp) { | 
|  482   Bytecode operator_replacement_pairs[][2] = { |  480   Bytecode operator_replacement_pairs[][2] = { | 
|  483       {Bytecode::kAdd, Bytecode::kAddSmi}, |  481       {Bytecode::kAdd, Bytecode::kAddSmi}, | 
|  484       {Bytecode::kSub, Bytecode::kSubSmi}, |  482       {Bytecode::kSub, Bytecode::kSubSmi}, | 
|  485       {Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi}, |  483       {Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi}, | 
|  486       {Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi}, |  484       {Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi}, | 
|  487       {Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi}, |  485       {Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi}, | 
|  488       {Bytecode::kShiftRight, Bytecode::kShiftRightSmi}}; |  486       {Bytecode::kShiftRight, Bytecode::kShiftRightSmi}}; | 
|  489  |  487  | 
|  490   for (auto operator_replacement : operator_replacement_pairs) { |  488   for (auto operator_replacement : operator_replacement_pairs) { | 
|  491     uint32_t imm_operand = 17; |  489     uint32_t imm_operand = 17; | 
|  492     BytecodeSourceInfo source_info(3, true); |  490     BytecodeNode first(Bytecode::kLdaSmi, imm_operand); | 
|  493     BytecodeNode first(Bytecode::kLdaSmi, imm_operand, &source_info); |  491     first.source_info().Clone({3, true}); | 
|  494     uint32_t reg_operand = Register(0).ToOperand(); |  492     uint32_t reg_operand = Register(0).ToOperand(); | 
|  495     source_info.MakeStatementPosition(4); |  493     BytecodeNode second(operator_replacement[0], reg_operand, 1); | 
|  496     BytecodeNode second(operator_replacement[0], reg_operand, 1, &source_info); |  494     second.source_info().Clone({4, true}); | 
|  497     optimizer()->Write(&first); |  495     optimizer()->Write(&first); | 
|  498     optimizer()->Write(&second); |  496     optimizer()->Write(&second); | 
|  499     CHECK_EQ(last_written(), first); |  497     CHECK_EQ(last_written(), first); | 
|  500     Flush(); |  498     Flush(); | 
|  501     CHECK_EQ(last_written(), second); |  499     CHECK_EQ(last_written(), second); | 
|  502     Reset(); |  500     Reset(); | 
|  503   } |  501   } | 
|  504 } |  502 } | 
|  505  |  503  | 
|  506 TEST_F(BytecodePeepholeOptimizerTest, MergeLdaZeroWithBinaryOp) { |  504 TEST_F(BytecodePeepholeOptimizerTest, MergeLdaZeroWithBinaryOp) { | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  526     CHECK_EQ(last_written().operand(0), 0); |  524     CHECK_EQ(last_written().operand(0), 0); | 
|  527     CHECK_EQ(last_written().operand(1), reg_operand); |  525     CHECK_EQ(last_written().operand(1), reg_operand); | 
|  528     CHECK_EQ(last_written().operand(2), idx_operand); |  526     CHECK_EQ(last_written().operand(2), idx_operand); | 
|  529     Reset(); |  527     Reset(); | 
|  530   } |  528   } | 
|  531 } |  529 } | 
|  532  |  530  | 
|  533 }  // namespace interpreter |  531 }  // namespace interpreter | 
|  534 }  // namespace internal |  532 }  // namespace internal | 
|  535 }  // namespace v8 |  533 }  // namespace v8 | 
| OLD | NEW |