| 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" | |
| 11 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
| 12 #include "src/objects.h" | 11 #include "src/objects.h" |
| 13 #include "test/unittests/test-utils.h" | 12 #include "test/unittests/test-utils.h" |
| 14 | 13 |
| 15 namespace v8 { | 14 namespace v8 { |
| 16 namespace internal { | 15 namespace internal { |
| 17 namespace interpreter { | 16 namespace interpreter { |
| 18 | 17 |
| 19 class BytecodePeepholeOptimizerTest : public BytecodePipelineStage, | 18 class BytecodePeepholeOptimizerTest : public BytecodePipelineStage, |
| 20 public TestWithIsolateAndZone { | 19 public TestWithIsolateAndZone { |
| 21 public: | 20 public: |
| 22 BytecodePeepholeOptimizerTest() | 21 BytecodePeepholeOptimizerTest() : peephole_optimizer_(this) {} |
| 23 : constant_array_builder_(isolate(), zone()), | |
| 24 peephole_optimizer_(&constant_array_builder_, this) {} | |
| 25 ~BytecodePeepholeOptimizerTest() override {} | 22 ~BytecodePeepholeOptimizerTest() override {} |
| 26 | 23 |
| 27 void Reset() { | 24 void Reset() { |
| 28 last_written_.set_bytecode(Bytecode::kIllegal); | 25 last_written_.set_bytecode(Bytecode::kIllegal); |
| 29 write_count_ = 0; | 26 write_count_ = 0; |
| 30 } | 27 } |
| 31 | 28 |
| 32 void Write(BytecodeNode* node) override { | 29 void Write(BytecodeNode* node) override { |
| 33 write_count_++; | 30 write_count_++; |
| 34 last_written_.Clone(node); | 31 last_written_.Clone(node); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 45 int fixed_register_count, int parameter_count, | 42 int fixed_register_count, int parameter_count, |
| 46 Handle<FixedArray> handle_table) override { | 43 Handle<FixedArray> handle_table) override { |
| 47 return Handle<BytecodeArray>(); | 44 return Handle<BytecodeArray>(); |
| 48 } | 45 } |
| 49 | 46 |
| 50 void Flush() { | 47 void Flush() { |
| 51 optimizer()->ToBytecodeArray(0, 0, factory()->empty_fixed_array()); | 48 optimizer()->ToBytecodeArray(0, 0, factory()->empty_fixed_array()); |
| 52 } | 49 } |
| 53 | 50 |
| 54 BytecodePeepholeOptimizer* optimizer() { return &peephole_optimizer_; } | 51 BytecodePeepholeOptimizer* optimizer() { return &peephole_optimizer_; } |
| 55 ConstantArrayBuilder* constant_array() { return &constant_array_builder_; } | |
| 56 | 52 |
| 57 int write_count() const { return write_count_; } | 53 int write_count() const { return write_count_; } |
| 58 const BytecodeNode& last_written() const { return last_written_; } | 54 const BytecodeNode& last_written() const { return last_written_; } |
| 59 | 55 |
| 60 private: | 56 private: |
| 61 ConstantArrayBuilder constant_array_builder_; | |
| 62 BytecodePeepholeOptimizer peephole_optimizer_; | 57 BytecodePeepholeOptimizer peephole_optimizer_; |
| 63 | 58 |
| 64 int write_count_ = 0; | 59 int write_count_ = 0; |
| 65 BytecodeNode last_written_; | 60 BytecodeNode last_written_; |
| 66 }; | 61 }; |
| 67 | 62 |
| 68 // Sanity tests. | 63 // Sanity tests. |
| 69 | 64 |
| 70 TEST_F(BytecodePeepholeOptimizerTest, FlushOnJump) { | 65 TEST_F(BytecodePeepholeOptimizerTest, FlushOnJump) { |
| 71 CHECK_EQ(write_count(), 0); | 66 CHECK_EQ(write_count(), 0); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 CHECK_EQ(write_count(), 0); | 254 CHECK_EQ(write_count(), 0); |
| 260 optimizer()->Write(&second); | 255 optimizer()->Write(&second); |
| 261 CHECK_EQ(write_count(), 1); | 256 CHECK_EQ(write_count(), 1); |
| 262 CHECK_EQ(last_written(), first); | 257 CHECK_EQ(last_written(), first); |
| 263 Flush(); | 258 Flush(); |
| 264 CHECK_EQ(write_count(), 2); | 259 CHECK_EQ(write_count(), 2); |
| 265 CHECK_EQ(last_written(), second); | 260 CHECK_EQ(last_written(), second); |
| 266 CHECK_EQ(last_written().bytecode(), Bytecode::kStar); | 261 CHECK_EQ(last_written().bytecode(), Bytecode::kStar); |
| 267 } | 262 } |
| 268 | 263 |
| 269 TEST_F(BytecodePeepholeOptimizerTest, LdaConstantStringToName) { | |
| 270 Handle<Object> word = | |
| 271 isolate()->factory()->NewStringFromStaticChars("optimizing"); | |
| 272 size_t index = constant_array()->Insert(word); | |
| 273 BytecodeNode first(Bytecode::kLdaConstant, static_cast<uint32_t>(index)); | |
| 274 BytecodeNode second(Bytecode::kToName, Register(0).ToOperand()); | |
| 275 optimizer()->Write(&first); | |
| 276 CHECK_EQ(write_count(), 0); | |
| 277 optimizer()->Write(&second); | |
| 278 CHECK_EQ(write_count(), 1); | |
| 279 CHECK_EQ(last_written(), first); | |
| 280 Flush(); | |
| 281 CHECK_EQ(write_count(), 2); | |
| 282 CHECK_EQ(last_written(), second); | |
| 283 CHECK_EQ(last_written().bytecode(), Bytecode::kStar); | |
| 284 } | |
| 285 | |
| 286 TEST_F(BytecodePeepholeOptimizerTest, LdaConstantNumberToName) { | |
| 287 Handle<Object> word = isolate()->factory()->NewNumber(0.380); | |
| 288 size_t index = constant_array()->Insert(word); | |
| 289 BytecodeNode first(Bytecode::kLdaConstant, static_cast<uint32_t>(index)); | |
| 290 BytecodeNode second(Bytecode::kToName, Register(0).ToOperand()); | |
| 291 optimizer()->Write(&first); | |
| 292 CHECK_EQ(write_count(), 0); | |
| 293 optimizer()->Write(&second); | |
| 294 CHECK_EQ(write_count(), 1); | |
| 295 CHECK_EQ(last_written(), first); | |
| 296 Flush(); | |
| 297 CHECK_EQ(write_count(), 2); | |
| 298 CHECK_EQ(last_written(), second); | |
| 299 } | |
| 300 | |
| 301 // Tests covering BytecodePeepholeOptimizer::CanElideLast(). | 264 // Tests covering BytecodePeepholeOptimizer::CanElideLast(). |
| 302 | 265 |
| 303 TEST_F(BytecodePeepholeOptimizerTest, LdaTrueLdaFalse) { | 266 TEST_F(BytecodePeepholeOptimizerTest, LdaTrueLdaFalse) { |
| 304 BytecodeNode first(Bytecode::kLdaTrue); | 267 BytecodeNode first(Bytecode::kLdaTrue); |
| 305 BytecodeNode second(Bytecode::kLdaFalse); | 268 BytecodeNode second(Bytecode::kLdaFalse); |
| 306 optimizer()->Write(&first); | 269 optimizer()->Write(&first); |
| 307 CHECK_EQ(write_count(), 0); | 270 CHECK_EQ(write_count(), 0); |
| 308 optimizer()->Write(&second); | 271 optimizer()->Write(&second); |
| 309 CHECK_EQ(write_count(), 0); | 272 CHECK_EQ(write_count(), 0); |
| 310 Flush(); | 273 Flush(); |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 CHECK_EQ(last_written().operand_count(), 2); | 517 CHECK_EQ(last_written().operand_count(), 2); |
| 555 CHECK_EQ(last_written().operand(0), 0); | 518 CHECK_EQ(last_written().operand(0), 0); |
| 556 CHECK_EQ(last_written().operand(1), reg_operand); | 519 CHECK_EQ(last_written().operand(1), reg_operand); |
| 557 Reset(); | 520 Reset(); |
| 558 } | 521 } |
| 559 } | 522 } |
| 560 | 523 |
| 561 } // namespace interpreter | 524 } // namespace interpreter |
| 562 } // namespace internal | 525 } // namespace internal |
| 563 } // namespace v8 | 526 } // namespace v8 |
| OLD | NEW |