Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: test/unittests/interpreter/bytecode-array-builder-unittest.cc

Issue 1947403002: [interpreter] Introduce bytecode generation pipeline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/interpreter/bytecode-array-builder.h" 7 #include "src/interpreter/bytecode-array-builder.h"
8 #include "src/interpreter/bytecode-array-iterator.h" 8 #include "src/interpreter/bytecode-array-iterator.h"
9 #include "src/interpreter/bytecode-register-allocator.h" 9 #include "src/interpreter/bytecode-register-allocator.h"
10 #include "test/unittests/test-utils.h" 10 #include "test/unittests/test-utils.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 namespace interpreter { 14 namespace interpreter {
15 15
16 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { 16 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone {
17 public: 17 public:
18 BytecodeArrayBuilderTest() {} 18 BytecodeArrayBuilderTest() {}
19 ~BytecodeArrayBuilderTest() override {} 19 ~BytecodeArrayBuilderTest() override {}
20 }; 20 };
21 21
22 22
23 TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { 23 TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
24 BytecodeArrayBuilder builder(isolate(), zone(), 0, 1, 131); 24 BytecodeArrayBuilder builder(isolate(), zone(), 0, 1, 131);
25 Factory* factory = isolate()->factory();
25 26
26 CHECK_EQ(builder.locals_count(), 131); 27 CHECK_EQ(builder.locals_count(), 131);
27 CHECK_EQ(builder.context_count(), 1); 28 CHECK_EQ(builder.context_count(), 1);
28 CHECK_EQ(builder.fixed_register_count(), 132); 29 CHECK_EQ(builder.fixed_register_count(), 132);
29 30
31 Register reg(0);
32 Register other(reg.index() + 1);
33 Register wide(128);
34
30 // Emit argument creation operations. 35 // Emit argument creation operations.
31 builder.CreateArguments(CreateArgumentsType::kMappedArguments) 36 builder.CreateArguments(CreateArgumentsType::kMappedArguments)
32 .CreateArguments(CreateArgumentsType::kUnmappedArguments) 37 .CreateArguments(CreateArgumentsType::kUnmappedArguments)
33 .CreateArguments(CreateArgumentsType::kRestParameter); 38 .CreateArguments(CreateArgumentsType::kRestParameter);
34 39
35 // Emit constant loads. 40 // Emit constant loads.
36 builder.LoadLiteral(Smi::FromInt(0)) 41 builder.LoadLiteral(Smi::FromInt(0))
42 .StoreAccumulatorInRegister(reg)
37 .LoadLiteral(Smi::FromInt(8)) 43 .LoadLiteral(Smi::FromInt(8))
44 .StoreAccumulatorInRegister(reg)
38 .LoadLiteral(Smi::FromInt(10000000)) 45 .LoadLiteral(Smi::FromInt(10000000))
46 .StoreAccumulatorInRegister(reg)
47 .LoadLiteral(factory->NewStringFromStaticChars("A constant"))
48 .StoreAccumulatorInRegister(reg)
39 .LoadUndefined() 49 .LoadUndefined()
50 .StoreAccumulatorInRegister(reg)
40 .LoadNull() 51 .LoadNull()
52 .StoreAccumulatorInRegister(reg)
41 .LoadTheHole() 53 .LoadTheHole()
54 .StoreAccumulatorInRegister(reg)
42 .LoadTrue() 55 .LoadTrue()
43 .LoadFalse(); 56 .StoreAccumulatorInRegister(reg)
57 .LoadFalse()
58 .StoreAccumulatorInRegister(wide);
44 59
45 Register reg(0); 60 builder.StackCheck(0)
46 Register other(reg.index() + 1); 61 .LoadAccumulatorWithRegister(other)
47 Register wide(128); 62 .StoreAccumulatorInRegister(reg)
48
49 builder.LoadAccumulatorWithRegister(reg)
50 .LoadNull() 63 .LoadNull()
51 .StoreAccumulatorInRegister(reg); 64 .StoreAccumulatorInRegister(reg);
52 65
53 // Emit register-register transfer. 66 // Emit register-register transfer.
54 builder.MoveRegister(reg, other); 67 builder.MoveRegister(reg, other);
55 builder.MoveRegister(reg, wide); 68 builder.MoveRegister(reg, wide);
56 69
57 // Emit global load / store operations. 70 // Emit global load / store operations.
58 Factory* factory = isolate()->factory();
59 Handle<String> name = factory->NewStringFromStaticChars("var_name"); 71 Handle<String> name = factory->NewStringFromStaticChars("var_name");
60 builder.LoadGlobal(name, 1, TypeofMode::NOT_INSIDE_TYPEOF) 72 builder.LoadGlobal(name, 1, TypeofMode::NOT_INSIDE_TYPEOF)
61 .LoadGlobal(name, 1, TypeofMode::INSIDE_TYPEOF) 73 .LoadGlobal(name, 1, TypeofMode::INSIDE_TYPEOF)
62 .StoreGlobal(name, 1, LanguageMode::SLOPPY) 74 .StoreGlobal(name, 1, LanguageMode::SLOPPY)
63 .StoreGlobal(name, 1, LanguageMode::STRICT); 75 .StoreGlobal(name, 1, LanguageMode::STRICT);
64 76
65 // Emit context operations. 77 // Emit context operations.
66 builder.PushContext(reg) 78 builder.PushContext(reg)
67 .PopContext(reg) 79 .PopContext(reg)
68 .LoadContextSlot(reg, 1) 80 .LoadContextSlot(reg, 1)
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 prefix_offset = 1; 336 prefix_offset = 1;
325 code = the_array->get(i + 1); 337 code = the_array->get(i + 1);
326 final_bytecode = Bytecodes::FromByte(code); 338 final_bytecode = Bytecodes::FromByte(code);
327 } 339 }
328 i += prefix_offset + Bytecodes::Size(final_bytecode, operand_scale); 340 i += prefix_offset + Bytecodes::Size(final_bytecode, operand_scale);
329 } 341 }
330 342
331 // Insert entry for illegal bytecode as this is never willingly emitted. 343 // Insert entry for illegal bytecode as this is never willingly emitted.
332 scorecard[Bytecodes::ToByte(Bytecode::kIllegal)] = 1; 344 scorecard[Bytecodes::ToByte(Bytecode::kIllegal)] = 1;
333 345
346 // Insert entry for nop bytecode as this often gets optimized out.
347 scorecard[Bytecodes::ToByte(Bytecode::kNop)] = 1;
348
334 // Check return occurs at the end and only once in the BytecodeArray. 349 // Check return occurs at the end and only once in the BytecodeArray.
335 CHECK_EQ(final_bytecode, Bytecode::kReturn); 350 CHECK_EQ(final_bytecode, Bytecode::kReturn);
336 CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1); 351 CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1);
337 352
338 #define CHECK_BYTECODE_PRESENT(Name, ...) \ 353 #define CHECK_BYTECODE_PRESENT(Name, ...) \
339 /* Check Bytecode is marked in scorecard, unless it's a debug break */ \ 354 /* Check Bytecode is marked in scorecard, unless it's a debug break */ \
340 if (!Bytecodes::IsDebugBreak(Bytecode::k##Name)) { \ 355 if (!Bytecodes::IsDebugBreak(Bytecode::k##Name)) { \
341 CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1); \ 356 CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1); \
342 } 357 }
343 BYTECODE_LIST(CHECK_BYTECODE_PRESENT) 358 BYTECODE_LIST(CHECK_BYTECODE_PRESENT)
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 .Jump(&far0) 470 .Jump(&far0)
456 .CompareOperation(Token::Value::EQ, reg) 471 .CompareOperation(Token::Value::EQ, reg)
457 .JumpIfTrue(&far1) 472 .JumpIfTrue(&far1)
458 .CompareOperation(Token::Value::EQ, reg) 473 .CompareOperation(Token::Value::EQ, reg)
459 .JumpIfFalse(&far2) 474 .JumpIfFalse(&far2)
460 .BinaryOperation(Token::Value::ADD, reg) 475 .BinaryOperation(Token::Value::ADD, reg)
461 .JumpIfTrue(&far3) 476 .JumpIfTrue(&far3)
462 .BinaryOperation(Token::Value::ADD, reg) 477 .BinaryOperation(Token::Value::ADD, reg)
463 .JumpIfFalse(&far4); 478 .JumpIfFalse(&far4);
464 for (int i = 0; i < kFarJumpDistance - 18; i++) { 479 for (int i = 0; i < kFarJumpDistance - 18; i++) {
465 builder.LoadUndefined(); 480 builder.Debugger();
466 } 481 }
467 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); 482 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4);
468 builder.Return(); 483 builder.Return();
469 484
470 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 485 Handle<BytecodeArray> array = builder.ToBytecodeArray();
471 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1); 486 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1);
472 487
473 BytecodeArrayIterator iterator(array); 488 BytecodeArrayIterator iterator(array);
474 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 489 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
475 CHECK_EQ(iterator.GetImmediateOperand(0), 18); 490 CHECK_EQ(iterator.GetImmediateOperand(0), 18);
(...skipping 20 matching lines...) Expand all
496 CHECK_EQ(iterator.GetImmediateOperand(0), 6); 511 CHECK_EQ(iterator.GetImmediateOperand(0), 6);
497 iterator.Advance(); 512 iterator.Advance();
498 513
499 // Ignore add operation. 514 // Ignore add operation.
500 iterator.Advance(); 515 iterator.Advance();
501 516
502 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); 517 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
503 CHECK_EQ(iterator.GetImmediateOperand(0), 2); 518 CHECK_EQ(iterator.GetImmediateOperand(0), 2);
504 iterator.Advance(); 519 iterator.Advance();
505 520
506
507 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); 521 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
508 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), 522 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
509 Smi::FromInt(kFarJumpDistance)); 523 Smi::FromInt(kFarJumpDistance));
510 iterator.Advance(); 524 iterator.Advance();
511 525
512 // Ignore compare operation. 526 // Ignore compare operation.
513 iterator.Advance(); 527 iterator.Advance();
514 528
515 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); 529 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
516 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), 530 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 .JumpIfTrue(&label3) 576 .JumpIfTrue(&label3)
563 .Bind(&label4) 577 .Bind(&label4)
564 .BinaryOperation(Token::Value::ADD, reg) 578 .BinaryOperation(Token::Value::ADD, reg)
565 .JumpIfFalse(&label4); 579 .JumpIfFalse(&label4);
566 for (int i = 0; i < 63; i++) { 580 for (int i = 0; i < 63; i++) {
567 builder.Jump(&label4); 581 builder.Jump(&label4);
568 } 582 }
569 583
570 // Add padding to force wide backwards jumps. 584 // Add padding to force wide backwards jumps.
571 for (int i = 0; i < 256; i++) { 585 for (int i = 0; i < 256; i++) {
572 builder.LoadTrue(); 586 builder.Debugger();
573 } 587 }
574 588
575 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfFalse(&label4); 589 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfFalse(&label4);
576 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfTrue(&label3); 590 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfTrue(&label3);
577 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2); 591 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2);
578 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1); 592 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1);
579 builder.Jump(&label0); 593 builder.Jump(&label0);
580 builder.Return(); 594 builder.Return();
581 595
582 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 596 Handle<BytecodeArray> array = builder.ToBytecodeArray();
(...skipping 26 matching lines...) Expand all
609 CHECK_EQ(iterator.GetImmediateOperand(0), -2); 623 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
610 iterator.Advance(); 624 iterator.Advance();
611 for (int i = 0; i < 63; i++) { 625 for (int i = 0; i < 63; i++) {
612 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 626 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
613 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); 627 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
614 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 4); 628 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 4);
615 iterator.Advance(); 629 iterator.Advance();
616 } 630 }
617 // Check padding to force wide backwards jumps. 631 // Check padding to force wide backwards jumps.
618 for (int i = 0; i < 256; i++) { 632 for (int i = 0; i < 256; i++) {
619 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaTrue); 633 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
620 iterator.Advance(); 634 iterator.Advance();
621 } 635 }
622 // Ignore binary operation. 636 // Ignore binary operation.
623 iterator.Advance(); 637 iterator.Advance();
624 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); 638 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
625 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); 639 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble);
626 CHECK_EQ(iterator.GetImmediateOperand(0), -389); 640 CHECK_EQ(iterator.GetImmediateOperand(0), -389);
627 iterator.Advance(); 641 iterator.Advance();
628 // Ignore binary operation. 642 // Ignore binary operation.
629 iterator.Advance(); 643 iterator.Advance();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 iterator.Advance(); 714 iterator.Advance();
701 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 715 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
702 CHECK_EQ(iterator.GetImmediateOperand(0), -2); 716 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
703 iterator.Advance(); 717 iterator.Advance();
704 } 718 }
705 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 719 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
706 iterator.Advance(); 720 iterator.Advance();
707 CHECK(iterator.done()); 721 CHECK(iterator.done());
708 } 722 }
709 723
710 TEST_F(BytecodeArrayBuilderTest, OperandScales) {
711 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(OperandSize::kByte),
712 OperandScale::kSingle);
713 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(OperandSize::kShort),
714 OperandScale::kDouble);
715 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(OperandSize::kQuad),
716 OperandScale::kQuadruple);
717 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(
718 OperandSize::kShort, OperandSize::kShort, OperandSize::kShort,
719 OperandSize::kShort),
720 OperandScale::kDouble);
721 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(
722 OperandSize::kQuad, OperandSize::kShort, OperandSize::kShort,
723 OperandSize::kShort),
724 OperandScale::kQuadruple);
725 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(
726 OperandSize::kShort, OperandSize::kQuad, OperandSize::kShort,
727 OperandSize::kShort),
728 OperandScale::kQuadruple);
729 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(
730 OperandSize::kShort, OperandSize::kShort, OperandSize::kQuad,
731 OperandSize::kShort),
732 OperandScale::kQuadruple);
733 CHECK_EQ(BytecodeArrayBuilder::OperandSizesToScale(
734 OperandSize::kShort, OperandSize::kShort, OperandSize::kShort,
735 OperandSize::kQuad),
736 OperandScale::kQuadruple);
737 }
738
739 TEST_F(BytecodeArrayBuilderTest, SizesForSignOperands) {
740 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(0) == OperandSize::kByte);
741 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMaxInt8) ==
742 OperandSize::kByte);
743 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMinInt8) ==
744 OperandSize::kByte);
745 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMaxInt8 + 1) ==
746 OperandSize::kShort);
747 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMinInt8 - 1) ==
748 OperandSize::kShort);
749 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMaxInt16) ==
750 OperandSize::kShort);
751 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMinInt16) ==
752 OperandSize::kShort);
753 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMaxInt16 + 1) ==
754 OperandSize::kQuad);
755 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMinInt16 - 1) ==
756 OperandSize::kQuad);
757 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMaxInt) ==
758 OperandSize::kQuad);
759 CHECK(BytecodeArrayBuilder::SizeForSignedOperand(kMinInt) ==
760 OperandSize::kQuad);
761 }
762
763 TEST_F(BytecodeArrayBuilderTest, SizesForUnsignOperands) {
764 // int overloads
765 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(0) == OperandSize::kByte);
766 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(kMaxUInt8) ==
767 OperandSize::kByte);
768 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(kMaxUInt8 + 1) ==
769 OperandSize::kShort);
770 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(kMaxUInt16) ==
771 OperandSize::kShort);
772 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(kMaxUInt16 + 1) ==
773 OperandSize::kQuad);
774 // size_t overloads
775 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(static_cast<size_t>(0)) ==
776 OperandSize::kByte);
777 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(
778 static_cast<size_t>(kMaxUInt8)) == OperandSize::kByte);
779 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(
780 static_cast<size_t>(kMaxUInt8 + 1)) == OperandSize::kShort);
781 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(
782 static_cast<size_t>(kMaxUInt16)) == OperandSize::kShort);
783 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(
784 static_cast<size_t>(kMaxUInt16 + 1)) == OperandSize::kQuad);
785 CHECK(BytecodeArrayBuilder::SizeForUnsignedOperand(
786 static_cast<size_t>(kMaxUInt32)) == OperandSize::kQuad);
787 }
788
789 } // namespace interpreter 724 } // namespace interpreter
790 } // namespace internal 725 } // namespace internal
791 } // namespace v8 726 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698