OLD | NEW |
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-label.h" | 9 #include "src/interpreter/bytecode-label.h" |
10 #include "src/interpreter/bytecode-register-allocator.h" | 10 #include "src/interpreter/bytecode-register-allocator.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 | 36 |
37 // Emit argument creation operations. | 37 // Emit argument creation operations. |
38 builder.CreateArguments(CreateArgumentsType::kMappedArguments) | 38 builder.CreateArguments(CreateArgumentsType::kMappedArguments) |
39 .CreateArguments(CreateArgumentsType::kUnmappedArguments) | 39 .CreateArguments(CreateArgumentsType::kUnmappedArguments) |
40 .CreateArguments(CreateArgumentsType::kRestParameter); | 40 .CreateArguments(CreateArgumentsType::kRestParameter); |
41 | 41 |
42 // Emit constant loads. | 42 // Emit constant loads. |
43 builder.LoadLiteral(Smi::FromInt(0)) | 43 builder.LoadLiteral(Smi::FromInt(0)) |
44 .StoreAccumulatorInRegister(reg) | 44 .StoreAccumulatorInRegister(reg) |
45 .LoadLiteral(Smi::FromInt(8)) | 45 .LoadLiteral(Smi::FromInt(8)) |
46 .CompareOperation(Token::Value::NE, reg) // Prevent peephole optimization | 46 .CompareOperation(Token::Value::NE, reg, |
47 // LdaSmi, Star -> LdrSmi. | 47 1) // Prevent peephole optimization |
| 48 // LdaSmi, Star -> LdrSmi. |
48 .StoreAccumulatorInRegister(reg) | 49 .StoreAccumulatorInRegister(reg) |
49 .LoadLiteral(Smi::FromInt(10000000)) | 50 .LoadLiteral(Smi::FromInt(10000000)) |
50 .StoreAccumulatorInRegister(reg) | 51 .StoreAccumulatorInRegister(reg) |
51 .LoadLiteral(factory->NewStringFromStaticChars("A constant")) | 52 .LoadLiteral(factory->NewStringFromStaticChars("A constant")) |
52 .StoreAccumulatorInRegister(reg) | 53 .StoreAccumulatorInRegister(reg) |
53 .LoadUndefined() | 54 .LoadUndefined() |
54 .Debugger() // Prevent peephole optimization LdaNull, Star -> LdrNull. | 55 .Debugger() // Prevent peephole optimization LdaNull, Star -> LdrNull. |
55 .LoadNull() | 56 .LoadNull() |
56 .StoreAccumulatorInRegister(reg) | 57 .StoreAccumulatorInRegister(reg) |
57 .LoadTheHole() | 58 .LoadTheHole() |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 .TypeOf(); | 168 .TypeOf(); |
168 | 169 |
169 // Emit delete | 170 // Emit delete |
170 builder.Delete(reg, LanguageMode::SLOPPY).Delete(reg, LanguageMode::STRICT); | 171 builder.Delete(reg, LanguageMode::SLOPPY).Delete(reg, LanguageMode::STRICT); |
171 | 172 |
172 // Emit new. | 173 // Emit new. |
173 builder.New(reg, reg, 0); | 174 builder.New(reg, reg, 0); |
174 builder.New(wide, wide, 0); | 175 builder.New(wide, wide, 0); |
175 | 176 |
176 // Emit test operator invocations. | 177 // Emit test operator invocations. |
177 builder.CompareOperation(Token::Value::EQ, reg) | 178 builder.CompareOperation(Token::Value::EQ, reg, 1) |
178 .CompareOperation(Token::Value::NE, reg) | 179 .CompareOperation(Token::Value::NE, reg, 2) |
179 .CompareOperation(Token::Value::EQ_STRICT, reg) | 180 .CompareOperation(Token::Value::EQ_STRICT, reg, 3) |
180 .CompareOperation(Token::Value::LT, reg) | 181 .CompareOperation(Token::Value::LT, reg, 4) |
181 .CompareOperation(Token::Value::GT, reg) | 182 .CompareOperation(Token::Value::GT, reg, 5) |
182 .CompareOperation(Token::Value::LTE, reg) | 183 .CompareOperation(Token::Value::LTE, reg, 6) |
183 .CompareOperation(Token::Value::GTE, reg) | 184 .CompareOperation(Token::Value::GTE, reg, 7) |
184 .CompareOperation(Token::Value::INSTANCEOF, reg) | 185 .CompareOperation(Token::Value::INSTANCEOF, reg, 8) |
185 .CompareOperation(Token::Value::IN, reg); | 186 .CompareOperation(Token::Value::IN, reg, 9); |
186 | 187 |
187 // Emit cast operator invocations. | 188 // Emit cast operator invocations. |
188 builder.CastAccumulatorToNumber(reg) | 189 builder.CastAccumulatorToNumber(reg) |
189 .CastAccumulatorToJSObject(reg) | 190 .CastAccumulatorToJSObject(reg) |
190 .CastAccumulatorToName(reg); | 191 .CastAccumulatorToName(reg); |
191 | 192 |
192 // Emit control flow. Return must be the last instruction. | 193 // Emit control flow. Return must be the last instruction. |
193 BytecodeLabel start; | 194 BytecodeLabel start; |
194 builder.Bind(&start); | 195 builder.Bind(&start); |
195 { | 196 { |
(...skipping 20 matching lines...) Expand all Loading... |
216 .JumpIfTrue(&end[3]) | 217 .JumpIfTrue(&end[3]) |
217 .LoadLiteral(Smi::FromInt(0)) | 218 .LoadLiteral(Smi::FromInt(0)) |
218 .JumpIfFalse(&end[4]) | 219 .JumpIfFalse(&end[4]) |
219 .JumpIfNull(&end[5]) | 220 .JumpIfNull(&end[5]) |
220 .JumpIfUndefined(&end[6]) | 221 .JumpIfUndefined(&end[6]) |
221 .JumpIfNotHole(&end[7]); | 222 .JumpIfNotHole(&end[7]); |
222 } | 223 } |
223 | 224 |
224 // Perform an operation that returns boolean value to | 225 // Perform an operation that returns boolean value to |
225 // generate JumpIfTrue/False | 226 // generate JumpIfTrue/False |
226 builder.CompareOperation(Token::Value::EQ, reg) | 227 builder.CompareOperation(Token::Value::EQ, reg, 1) |
227 .JumpIfTrue(&start) | 228 .JumpIfTrue(&start) |
228 .CompareOperation(Token::Value::EQ, reg) | 229 .CompareOperation(Token::Value::EQ, reg, 2) |
229 .JumpIfFalse(&start); | 230 .JumpIfFalse(&start); |
230 // Perform an operation that returns a non-boolean operation to | 231 // Perform an operation that returns a non-boolean operation to |
231 // generate JumpIfToBooleanTrue/False. | 232 // generate JumpIfToBooleanTrue/False. |
232 builder.BinaryOperation(Token::Value::ADD, reg, 1) | 233 builder.BinaryOperation(Token::Value::ADD, reg, 1) |
233 .JumpIfTrue(&start) | 234 .JumpIfTrue(&start) |
234 .BinaryOperation(Token::Value::ADD, reg, 2) | 235 .BinaryOperation(Token::Value::ADD, reg, 2) |
235 .JumpIfFalse(&start); | 236 .JumpIfFalse(&start); |
236 // Insert dummy ops to force longer jumps | 237 // Insert dummy ops to force longer jumps |
237 for (int i = 0; i < 128; i++) { | 238 for (int i = 0; i < 128; i++) { |
238 builder.LoadTrue(); | 239 builder.LoadTrue(); |
239 } | 240 } |
240 // Longer jumps requiring Constant operand | 241 // Longer jumps requiring Constant operand |
241 { | 242 { |
242 BytecodeLabel after_jump; | 243 BytecodeLabel after_jump; |
243 builder.Jump(&start) | 244 builder.Jump(&start) |
244 .Bind(&after_jump) | 245 .Bind(&after_jump) |
245 .JumpIfNull(&start) | 246 .JumpIfNull(&start) |
246 .JumpIfUndefined(&start) | 247 .JumpIfUndefined(&start) |
247 .JumpIfNotHole(&start); | 248 .JumpIfNotHole(&start); |
248 // Perform an operation that returns boolean value to | 249 // Perform an operation that returns boolean value to |
249 // generate JumpIfTrue/False | 250 // generate JumpIfTrue/False |
250 builder.CompareOperation(Token::Value::EQ, reg) | 251 builder.CompareOperation(Token::Value::EQ, reg, 1) |
251 .JumpIfTrue(&start) | 252 .JumpIfTrue(&start) |
252 .CompareOperation(Token::Value::EQ, reg) | 253 .CompareOperation(Token::Value::EQ, reg, 2) |
253 .JumpIfFalse(&start); | 254 .JumpIfFalse(&start); |
254 // Perform an operation that returns a non-boolean operation to | 255 // Perform an operation that returns a non-boolean operation to |
255 // generate JumpIfToBooleanTrue/False. | 256 // generate JumpIfToBooleanTrue/False. |
256 builder.BinaryOperation(Token::Value::ADD, reg, 1) | 257 builder.BinaryOperation(Token::Value::ADD, reg, 1) |
257 .JumpIfTrue(&start) | 258 .JumpIfTrue(&start) |
258 .BinaryOperation(Token::Value::ADD, reg, 2) | 259 .BinaryOperation(Token::Value::ADD, reg, 2) |
259 .JumpIfFalse(&start); | 260 .JumpIfFalse(&start); |
260 } | 261 } |
261 | 262 |
262 // Emit stack check bytecode. | 263 // Emit stack check bytecode. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 BytecodeLabel after_jump; | 344 BytecodeLabel after_jump; |
344 builder.Jump(&start) | 345 builder.Jump(&start) |
345 .Bind(&after_jump) | 346 .Bind(&after_jump) |
346 .JumpIfNull(&start) | 347 .JumpIfNull(&start) |
347 .JumpIfUndefined(&start) | 348 .JumpIfUndefined(&start) |
348 .JumpIfNotHole(&start); | 349 .JumpIfNotHole(&start); |
349 } | 350 } |
350 | 351 |
351 // Perform an operation that returns boolean value to | 352 // Perform an operation that returns boolean value to |
352 // generate JumpIfTrue/False | 353 // generate JumpIfTrue/False |
353 builder.CompareOperation(Token::Value::EQ, reg) | 354 builder.CompareOperation(Token::Value::EQ, reg, 1) |
354 .JumpIfTrue(&start) | 355 .JumpIfTrue(&start) |
355 .CompareOperation(Token::Value::EQ, reg) | 356 .CompareOperation(Token::Value::EQ, reg, 2) |
356 .JumpIfFalse(&start); | 357 .JumpIfFalse(&start); |
357 | 358 |
358 // Perform an operation that returns a non-boolean operation to | 359 // Perform an operation that returns a non-boolean operation to |
359 // generate JumpIfToBooleanTrue/False. | 360 // generate JumpIfToBooleanTrue/False. |
360 builder.BinaryOperation(Token::Value::ADD, reg, 1) | 361 builder.BinaryOperation(Token::Value::ADD, reg, 1) |
361 .JumpIfTrue(&start) | 362 .JumpIfTrue(&start) |
362 .BinaryOperation(Token::Value::ADD, reg, 2) | 363 .BinaryOperation(Token::Value::ADD, reg, 2) |
363 .JumpIfFalse(&start); | 364 .JumpIfFalse(&start); |
364 | 365 |
365 // Emit generator operations | 366 // Emit generator operations |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 | 557 |
557 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); | 558 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); |
558 | 559 |
559 Register reg(0); | 560 Register reg(0); |
560 BytecodeLabel far0, far1, far2, far3, far4; | 561 BytecodeLabel far0, far1, far2, far3, far4; |
561 BytecodeLabel near0, near1, near2, near3, near4; | 562 BytecodeLabel near0, near1, near2, near3, near4; |
562 BytecodeLabel after_jump0, after_jump1; | 563 BytecodeLabel after_jump0, after_jump1; |
563 | 564 |
564 builder.Jump(&near0) | 565 builder.Jump(&near0) |
565 .Bind(&after_jump0) | 566 .Bind(&after_jump0) |
566 .CompareOperation(Token::Value::EQ, reg) | 567 .CompareOperation(Token::Value::EQ, reg, 1) |
567 .JumpIfTrue(&near1) | 568 .JumpIfTrue(&near1) |
568 .CompareOperation(Token::Value::EQ, reg) | 569 .CompareOperation(Token::Value::EQ, reg, 2) |
569 .JumpIfFalse(&near2) | 570 .JumpIfFalse(&near2) |
570 .BinaryOperation(Token::Value::ADD, reg, 1) | 571 .BinaryOperation(Token::Value::ADD, reg, 1) |
571 .JumpIfTrue(&near3) | 572 .JumpIfTrue(&near3) |
572 .BinaryOperation(Token::Value::ADD, reg, 2) | 573 .BinaryOperation(Token::Value::ADD, reg, 2) |
573 .JumpIfFalse(&near4) | 574 .JumpIfFalse(&near4) |
574 .Bind(&near0) | 575 .Bind(&near0) |
575 .Bind(&near1) | 576 .Bind(&near1) |
576 .Bind(&near2) | 577 .Bind(&near2) |
577 .Bind(&near3) | 578 .Bind(&near3) |
578 .Bind(&near4) | 579 .Bind(&near4) |
579 .Jump(&far0) | 580 .Jump(&far0) |
580 .Bind(&after_jump1) | 581 .Bind(&after_jump1) |
581 .CompareOperation(Token::Value::EQ, reg) | 582 .CompareOperation(Token::Value::EQ, reg, 3) |
582 .JumpIfTrue(&far1) | 583 .JumpIfTrue(&far1) |
583 .CompareOperation(Token::Value::EQ, reg) | 584 .CompareOperation(Token::Value::EQ, reg, 4) |
584 .JumpIfFalse(&far2) | 585 .JumpIfFalse(&far2) |
585 .BinaryOperation(Token::Value::ADD, reg, 3) | 586 .BinaryOperation(Token::Value::ADD, reg, 3) |
586 .JumpIfTrue(&far3) | 587 .JumpIfTrue(&far3) |
587 .BinaryOperation(Token::Value::ADD, reg, 4) | 588 .BinaryOperation(Token::Value::ADD, reg, 4) |
588 .JumpIfFalse(&far4); | 589 .JumpIfFalse(&far4); |
589 for (int i = 0; i < kFarJumpDistance - 20; i++) { | 590 for (int i = 0; i < kFarJumpDistance - 22; i++) { |
590 builder.Debugger(); | 591 builder.Debugger(); |
591 } | 592 } |
592 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); | 593 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); |
593 builder.Return(); | 594 builder.Return(); |
594 | 595 |
595 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); | 596 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); |
596 DCHECK_EQ(array->length(), 40 + kFarJumpDistance - 20 + 1); | 597 DCHECK_EQ(array->length(), 44 + kFarJumpDistance - 22 + 1); |
597 | 598 |
598 BytecodeArrayIterator iterator(array); | 599 BytecodeArrayIterator iterator(array); |
599 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 600 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
600 CHECK_EQ(iterator.GetImmediateOperand(0), 20); | 601 CHECK_EQ(iterator.GetImmediateOperand(0), 22); |
601 iterator.Advance(); | 602 iterator.Advance(); |
602 | 603 |
603 // Ignore compare operation. | 604 // Ignore compare operation. |
604 iterator.Advance(); | 605 iterator.Advance(); |
605 | 606 |
606 CHECK_EQ(iterator.current_bytecode(), | 607 CHECK_EQ(iterator.current_bytecode(), |
607 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | 608 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); |
608 CHECK_EQ(iterator.GetImmediateOperand(0), 16); | 609 CHECK_EQ(iterator.GetImmediateOperand(0), 17); |
609 iterator.Advance(); | 610 iterator.Advance(); |
610 | 611 |
611 // Ignore compare operation. | 612 // Ignore compare operation. |
612 iterator.Advance(); | 613 iterator.Advance(); |
613 | 614 |
614 CHECK_EQ(iterator.current_bytecode(), | 615 CHECK_EQ(iterator.current_bytecode(), |
615 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | 616 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); |
616 CHECK_EQ(iterator.GetImmediateOperand(0), 12); | 617 CHECK_EQ(iterator.GetImmediateOperand(0), 12); |
617 iterator.Advance(); | 618 iterator.Advance(); |
618 | 619 |
(...skipping 15 matching lines...) Expand all Loading... |
634 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 635 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
635 Smi::FromInt(kFarJumpDistance)); | 636 Smi::FromInt(kFarJumpDistance)); |
636 iterator.Advance(); | 637 iterator.Advance(); |
637 | 638 |
638 // Ignore compare operation. | 639 // Ignore compare operation. |
639 iterator.Advance(); | 640 iterator.Advance(); |
640 | 641 |
641 CHECK_EQ(iterator.current_bytecode(), | 642 CHECK_EQ(iterator.current_bytecode(), |
642 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrueConstant)); | 643 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrueConstant)); |
643 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 644 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
644 Smi::FromInt(kFarJumpDistance - 4)); | 645 Smi::FromInt(kFarJumpDistance - 5)); |
645 iterator.Advance(); | 646 iterator.Advance(); |
646 | 647 |
647 // Ignore compare operation. | 648 // Ignore compare operation. |
648 iterator.Advance(); | 649 iterator.Advance(); |
649 | 650 |
650 CHECK_EQ(iterator.current_bytecode(), | 651 CHECK_EQ(iterator.current_bytecode(), |
651 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalseConstant)); | 652 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalseConstant)); |
652 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 653 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
653 Smi::FromInt(kFarJumpDistance - 8)); | 654 Smi::FromInt(kFarJumpDistance - 10)); |
654 iterator.Advance(); | 655 iterator.Advance(); |
655 | 656 |
656 // Ignore add operation. | 657 // Ignore add operation. |
657 iterator.Advance(); | 658 iterator.Advance(); |
658 | 659 |
659 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); | 660 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); |
660 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 661 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
661 Smi::FromInt(kFarJumpDistance - 13)); | 662 Smi::FromInt(kFarJumpDistance - 15)); |
662 iterator.Advance(); | 663 iterator.Advance(); |
663 | 664 |
664 // Ignore add operation. | 665 // Ignore add operation. |
665 iterator.Advance(); | 666 iterator.Advance(); |
666 | 667 |
667 CHECK_EQ(iterator.current_bytecode(), | 668 CHECK_EQ(iterator.current_bytecode(), |
668 Bytecode::kJumpIfToBooleanFalseConstant); | 669 Bytecode::kJumpIfToBooleanFalseConstant); |
669 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 670 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
670 Smi::FromInt(kFarJumpDistance - 18)); | 671 Smi::FromInt(kFarJumpDistance - 20)); |
671 iterator.Advance(); | 672 iterator.Advance(); |
672 } | 673 } |
673 | 674 |
674 | 675 |
675 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { | 676 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { |
676 CanonicalHandleScope canonical(isolate()); | 677 CanonicalHandleScope canonical(isolate()); |
677 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); | 678 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); |
678 | 679 |
679 Register reg(0); | 680 Register reg(0); |
680 | 681 |
681 BytecodeLabel label0, label1, label2, label3, label4; | 682 BytecodeLabel label0, label1, label2, label3, label4; |
682 builder.Bind(&label0) | 683 builder.Bind(&label0) |
683 .Jump(&label0) | 684 .Jump(&label0) |
684 .Bind(&label1) | 685 .Bind(&label1) |
685 .CompareOperation(Token::Value::EQ, reg) | 686 .CompareOperation(Token::Value::EQ, reg, 1) |
686 .JumpIfTrue(&label1) | 687 .JumpIfTrue(&label1) |
687 .Bind(&label2) | 688 .Bind(&label2) |
688 .CompareOperation(Token::Value::EQ, reg) | 689 .CompareOperation(Token::Value::EQ, reg, 2) |
689 .JumpIfFalse(&label2) | 690 .JumpIfFalse(&label2) |
690 .Bind(&label3) | 691 .Bind(&label3) |
691 .BinaryOperation(Token::Value::ADD, reg, 1) | 692 .BinaryOperation(Token::Value::ADD, reg, 1) |
692 .JumpIfTrue(&label3) | 693 .JumpIfTrue(&label3) |
693 .Bind(&label4) | 694 .Bind(&label4) |
694 .BinaryOperation(Token::Value::ADD, reg, 2) | 695 .BinaryOperation(Token::Value::ADD, reg, 2) |
695 .JumpIfFalse(&label4); | 696 .JumpIfFalse(&label4); |
696 for (int i = 0; i < 62; i++) { | 697 for (int i = 0; i < 62; i++) { |
697 BytecodeLabel after_jump; | 698 BytecodeLabel after_jump; |
698 builder.Jump(&label4).Bind(&after_jump); | 699 builder.Jump(&label4).Bind(&after_jump); |
699 } | 700 } |
700 | 701 |
701 // Add padding to force wide backwards jumps. | 702 // Add padding to force wide backwards jumps. |
702 for (int i = 0; i < 256; i++) { | 703 for (int i = 0; i < 256; i++) { |
703 builder.Debugger(); | 704 builder.Debugger(); |
704 } | 705 } |
705 | 706 |
706 builder.BinaryOperation(Token::Value::ADD, reg, 1).JumpIfFalse(&label4); | 707 builder.BinaryOperation(Token::Value::ADD, reg, 1).JumpIfFalse(&label4); |
707 builder.BinaryOperation(Token::Value::ADD, reg, 2).JumpIfTrue(&label3); | 708 builder.BinaryOperation(Token::Value::ADD, reg, 2).JumpIfTrue(&label3); |
708 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2); | 709 builder.CompareOperation(Token::Value::EQ, reg, 1).JumpIfFalse(&label2); |
709 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1); | 710 builder.CompareOperation(Token::Value::EQ, reg, 2).JumpIfTrue(&label1); |
710 builder.Jump(&label0); | 711 builder.Jump(&label0); |
711 BytecodeLabel end; | 712 BytecodeLabel end; |
712 builder.Bind(&end); | 713 builder.Bind(&end); |
713 builder.Return(); | 714 builder.Return(); |
714 | 715 |
715 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); | 716 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); |
716 BytecodeArrayIterator iterator(array); | 717 BytecodeArrayIterator iterator(array); |
717 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 718 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
718 CHECK_EQ(iterator.GetImmediateOperand(0), 0); | 719 CHECK_EQ(iterator.GetImmediateOperand(0), 0); |
719 iterator.Advance(); | 720 iterator.Advance(); |
720 // Ignore compare operation. | 721 // Ignore compare operation. |
721 iterator.Advance(); | 722 iterator.Advance(); |
722 CHECK_EQ(iterator.current_bytecode(), | 723 CHECK_EQ(iterator.current_bytecode(), |
723 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | 724 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); |
724 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 725 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
725 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 726 CHECK_EQ(iterator.GetImmediateOperand(0), -3); |
726 iterator.Advance(); | 727 iterator.Advance(); |
727 // Ignore compare operation. | 728 // Ignore compare operation. |
728 iterator.Advance(); | 729 iterator.Advance(); |
729 CHECK_EQ(iterator.current_bytecode(), | 730 CHECK_EQ(iterator.current_bytecode(), |
730 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | 731 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); |
731 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 732 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
732 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 733 CHECK_EQ(iterator.GetImmediateOperand(0), -3); |
733 iterator.Advance(); | 734 iterator.Advance(); |
734 // Ignore binary operation. | 735 // Ignore binary operation. |
735 iterator.Advance(); | 736 iterator.Advance(); |
736 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 737 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
737 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 738 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
738 CHECK_EQ(iterator.GetImmediateOperand(0), -3); | 739 CHECK_EQ(iterator.GetImmediateOperand(0), -3); |
739 iterator.Advance(); | 740 iterator.Advance(); |
740 // Ignore binary operation. | 741 // Ignore binary operation. |
741 iterator.Advance(); | 742 iterator.Advance(); |
742 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); | 743 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
(...skipping 22 matching lines...) Expand all Loading... |
765 iterator.Advance(); | 766 iterator.Advance(); |
766 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 767 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
767 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 768 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
768 CHECK_EQ(iterator.GetImmediateOperand(0), -401); | 769 CHECK_EQ(iterator.GetImmediateOperand(0), -401); |
769 iterator.Advance(); | 770 iterator.Advance(); |
770 // Ignore compare operation. | 771 // Ignore compare operation. |
771 iterator.Advance(); | 772 iterator.Advance(); |
772 CHECK_EQ(iterator.current_bytecode(), | 773 CHECK_EQ(iterator.current_bytecode(), |
773 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | 774 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); |
774 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 775 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
775 CHECK_EQ(iterator.GetImmediateOperand(0), -411); | 776 CHECK_EQ(iterator.GetImmediateOperand(0), -413); |
776 iterator.Advance(); | 777 iterator.Advance(); |
777 // Ignore compare operation. | 778 // Ignore compare operation. |
778 iterator.Advance(); | 779 iterator.Advance(); |
779 CHECK_EQ(iterator.current_bytecode(), | 780 CHECK_EQ(iterator.current_bytecode(), |
780 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | 781 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); |
781 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 782 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
782 CHECK_EQ(iterator.GetImmediateOperand(0), -421); | 783 CHECK_EQ(iterator.GetImmediateOperand(0), -425); |
783 iterator.Advance(); | 784 iterator.Advance(); |
784 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 785 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
785 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 786 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
786 CHECK_EQ(iterator.GetImmediateOperand(0), -427); | 787 CHECK_EQ(iterator.GetImmediateOperand(0), -431); |
787 iterator.Advance(); | 788 iterator.Advance(); |
788 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 789 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
789 iterator.Advance(); | 790 iterator.Advance(); |
790 CHECK(iterator.done()); | 791 CHECK(iterator.done()); |
791 } | 792 } |
792 | 793 |
793 | 794 |
794 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { | 795 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { |
795 CanonicalHandleScope canonical(isolate()); | 796 CanonicalHandleScope canonical(isolate()); |
796 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); | 797 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 iterator.Advance(); | 855 iterator.Advance(); |
855 } | 856 } |
856 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 857 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
857 iterator.Advance(); | 858 iterator.Advance(); |
858 CHECK(iterator.done()); | 859 CHECK(iterator.done()); |
859 } | 860 } |
860 | 861 |
861 } // namespace interpreter | 862 } // namespace interpreter |
862 } // namespace internal | 863 } // namespace internal |
863 } // namespace v8 | 864 } // namespace v8 |
OLD | NEW |