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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 .LoadTheHole() | 57 .LoadTheHole() |
58 .StoreAccumulatorInRegister(reg) | 58 .StoreAccumulatorInRegister(reg) |
59 .LoadTrue() | 59 .LoadTrue() |
60 .StoreAccumulatorInRegister(reg) | 60 .StoreAccumulatorInRegister(reg) |
61 .LoadFalse() | 61 .LoadFalse() |
62 .StoreAccumulatorInRegister(wide); | 62 .StoreAccumulatorInRegister(wide); |
63 | 63 |
64 // Emit Ldar and Star taking care to foil the register optimizer. | 64 // Emit Ldar and Star taking care to foil the register optimizer. |
65 builder.StackCheck(0) | 65 builder.StackCheck(0) |
66 .LoadAccumulatorWithRegister(other) | 66 .LoadAccumulatorWithRegister(other) |
67 .BinaryOperation(Token::ADD, reg) | 67 .BinaryOperation(Token::ADD, reg, 1) |
68 .StoreAccumulatorInRegister(reg) | 68 .StoreAccumulatorInRegister(reg) |
69 .LoadNull(); | 69 .LoadNull(); |
70 | 70 |
71 // Emit register-register transfer. | 71 // Emit register-register transfer. |
72 builder.MoveRegister(reg, other); | 72 builder.MoveRegister(reg, other); |
73 builder.MoveRegister(reg, wide); | 73 builder.MoveRegister(reg, wide); |
74 | 74 |
75 // Emit global load / store operations. | 75 // Emit global load / store operations. |
76 Handle<String> name = factory->NewStringFromStaticChars("var_name"); | 76 Handle<String> name = factory->NewStringFromStaticChars("var_name"); |
77 builder.LoadGlobal(1, TypeofMode::NOT_INSIDE_TYPEOF) | 77 builder.LoadGlobal(1, TypeofMode::NOT_INSIDE_TYPEOF) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 .TailCall(reg, other, 0, 1) | 116 .TailCall(reg, other, 0, 1) |
117 .TailCall(reg, wide, 0, 1) | 117 .TailCall(reg, wide, 0, 1) |
118 .CallRuntime(Runtime::kIsArray, reg, 1) | 118 .CallRuntime(Runtime::kIsArray, reg, 1) |
119 .CallRuntime(Runtime::kIsArray, wide, 1) | 119 .CallRuntime(Runtime::kIsArray, wide, 1) |
120 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg, 1, other) | 120 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg, 1, other) |
121 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, wide, 1, other) | 121 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, wide, 1, other) |
122 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg, 1) | 122 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg, 1) |
123 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, wide, 1); | 123 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, wide, 1); |
124 | 124 |
125 // Emit binary operator invocations. | 125 // Emit binary operator invocations. |
126 builder.BinaryOperation(Token::Value::ADD, reg) | 126 builder.BinaryOperation(Token::Value::ADD, reg, 1) |
127 .BinaryOperation(Token::Value::SUB, reg) | 127 .BinaryOperation(Token::Value::SUB, reg, 2) |
128 .BinaryOperation(Token::Value::MUL, reg) | 128 .BinaryOperation(Token::Value::MUL, reg, 3) |
129 .BinaryOperation(Token::Value::DIV, reg) | 129 .BinaryOperation(Token::Value::DIV, reg, 4) |
130 .BinaryOperation(Token::Value::MOD, reg); | 130 .BinaryOperation(Token::Value::MOD, reg, 5); |
131 | 131 |
132 // Emit bitwise operator invocations | 132 // Emit bitwise operator invocations |
133 builder.BinaryOperation(Token::Value::BIT_OR, reg) | 133 builder.BinaryOperation(Token::Value::BIT_OR, reg, 6) |
134 .BinaryOperation(Token::Value::BIT_XOR, reg) | 134 .BinaryOperation(Token::Value::BIT_XOR, reg, 7) |
135 .BinaryOperation(Token::Value::BIT_AND, reg); | 135 .BinaryOperation(Token::Value::BIT_AND, reg, 8); |
136 | 136 |
137 // Emit shift operator invocations | 137 // Emit shift operator invocations |
138 builder.BinaryOperation(Token::Value::SHL, reg) | 138 builder.BinaryOperation(Token::Value::SHL, reg, 9) |
139 .BinaryOperation(Token::Value::SAR, reg) | 139 .BinaryOperation(Token::Value::SAR, reg, 10) |
140 .BinaryOperation(Token::Value::SHR, reg); | 140 .BinaryOperation(Token::Value::SHR, reg, 11); |
141 | 141 |
142 // Emit peephole optimizations of LdaSmi followed by binary operation. | 142 // Emit peephole optimizations of LdaSmi followed by binary operation. |
143 builder.LoadLiteral(Smi::FromInt(1)) | 143 builder.LoadLiteral(Smi::FromInt(1)) |
144 .BinaryOperation(Token::Value::ADD, reg) | 144 .BinaryOperation(Token::Value::ADD, reg, 1) |
145 .LoadLiteral(Smi::FromInt(2)) | 145 .LoadLiteral(Smi::FromInt(2)) |
146 .BinaryOperation(Token::Value::SUB, reg) | 146 .BinaryOperation(Token::Value::SUB, reg, 2) |
147 .LoadLiteral(Smi::FromInt(3)) | 147 .LoadLiteral(Smi::FromInt(3)) |
148 .BinaryOperation(Token::Value::BIT_AND, reg) | 148 .BinaryOperation(Token::Value::BIT_AND, reg, 3) |
149 .LoadLiteral(Smi::FromInt(4)) | 149 .LoadLiteral(Smi::FromInt(4)) |
150 .BinaryOperation(Token::Value::BIT_OR, reg) | 150 .BinaryOperation(Token::Value::BIT_OR, reg, 4) |
151 .LoadLiteral(Smi::FromInt(5)) | 151 .LoadLiteral(Smi::FromInt(5)) |
152 .BinaryOperation(Token::Value::SHL, reg) | 152 .BinaryOperation(Token::Value::SHL, reg, 5) |
153 .LoadLiteral(Smi::FromInt(6)) | 153 .LoadLiteral(Smi::FromInt(6)) |
154 .BinaryOperation(Token::Value::SAR, reg); | 154 .BinaryOperation(Token::Value::SAR, reg, 6); |
155 | 155 |
156 // Emit count operatior invocations | 156 // Emit count operatior invocations |
157 builder.CountOperation(Token::Value::ADD).CountOperation(Token::Value::SUB); | 157 builder.CountOperation(Token::Value::ADD, 1) |
| 158 .CountOperation(Token::Value::SUB, 1); |
158 | 159 |
159 // Emit unary operator invocations. | 160 // Emit unary operator invocations. |
160 builder | 161 builder |
161 .LogicalNot() // ToBooleanLogicalNot | 162 .LogicalNot() // ToBooleanLogicalNot |
162 .LogicalNot() // non-ToBoolean LogicalNot | 163 .LogicalNot() // non-ToBoolean LogicalNot |
163 .TypeOf(); | 164 .TypeOf(); |
164 | 165 |
165 // Emit delete | 166 // Emit delete |
166 builder.Delete(reg, LanguageMode::SLOPPY).Delete(reg, LanguageMode::STRICT); | 167 builder.Delete(reg, LanguageMode::SLOPPY).Delete(reg, LanguageMode::STRICT); |
167 | 168 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 } | 219 } |
219 | 220 |
220 // Perform an operation that returns boolean value to | 221 // Perform an operation that returns boolean value to |
221 // generate JumpIfTrue/False | 222 // generate JumpIfTrue/False |
222 builder.CompareOperation(Token::Value::EQ, reg) | 223 builder.CompareOperation(Token::Value::EQ, reg) |
223 .JumpIfTrue(&start) | 224 .JumpIfTrue(&start) |
224 .CompareOperation(Token::Value::EQ, reg) | 225 .CompareOperation(Token::Value::EQ, reg) |
225 .JumpIfFalse(&start); | 226 .JumpIfFalse(&start); |
226 // Perform an operation that returns a non-boolean operation to | 227 // Perform an operation that returns a non-boolean operation to |
227 // generate JumpIfToBooleanTrue/False. | 228 // generate JumpIfToBooleanTrue/False. |
228 builder.BinaryOperation(Token::Value::ADD, reg) | 229 builder.BinaryOperation(Token::Value::ADD, reg, 1) |
229 .JumpIfTrue(&start) | 230 .JumpIfTrue(&start) |
230 .BinaryOperation(Token::Value::ADD, reg) | 231 .BinaryOperation(Token::Value::ADD, reg, 2) |
231 .JumpIfFalse(&start); | 232 .JumpIfFalse(&start); |
232 // Insert dummy ops to force longer jumps | 233 // Insert dummy ops to force longer jumps |
233 for (int i = 0; i < 128; i++) { | 234 for (int i = 0; i < 128; i++) { |
234 builder.LoadTrue(); | 235 builder.LoadTrue(); |
235 } | 236 } |
236 // Longer jumps requiring Constant operand | 237 // Longer jumps requiring Constant operand |
237 { | 238 { |
238 BytecodeLabel after_jump; | 239 BytecodeLabel after_jump; |
239 builder.Jump(&start) | 240 builder.Jump(&start) |
240 .Bind(&after_jump) | 241 .Bind(&after_jump) |
241 .JumpIfNull(&start) | 242 .JumpIfNull(&start) |
242 .JumpIfUndefined(&start) | 243 .JumpIfUndefined(&start) |
243 .JumpIfNotHole(&start); | 244 .JumpIfNotHole(&start); |
244 // Perform an operation that returns boolean value to | 245 // Perform an operation that returns boolean value to |
245 // generate JumpIfTrue/False | 246 // generate JumpIfTrue/False |
246 builder.CompareOperation(Token::Value::EQ, reg) | 247 builder.CompareOperation(Token::Value::EQ, reg) |
247 .JumpIfTrue(&start) | 248 .JumpIfTrue(&start) |
248 .CompareOperation(Token::Value::EQ, reg) | 249 .CompareOperation(Token::Value::EQ, reg) |
249 .JumpIfFalse(&start); | 250 .JumpIfFalse(&start); |
250 // Perform an operation that returns a non-boolean operation to | 251 // Perform an operation that returns a non-boolean operation to |
251 // generate JumpIfToBooleanTrue/False. | 252 // generate JumpIfToBooleanTrue/False. |
252 builder.BinaryOperation(Token::Value::ADD, reg) | 253 builder.BinaryOperation(Token::Value::ADD, reg, 1) |
253 .JumpIfTrue(&start) | 254 .JumpIfTrue(&start) |
254 .BinaryOperation(Token::Value::ADD, reg) | 255 .BinaryOperation(Token::Value::ADD, reg, 2) |
255 .JumpIfFalse(&start); | 256 .JumpIfFalse(&start); |
256 } | 257 } |
257 | 258 |
258 // Emit stack check bytecode. | 259 // Emit stack check bytecode. |
259 builder.StackCheck(0); | 260 builder.StackCheck(0); |
260 | 261 |
261 // Emit an OSR poll bytecode. | 262 // Emit an OSR poll bytecode. |
262 builder.OsrPoll(1); | 263 builder.OsrPoll(1); |
263 | 264 |
264 // Emit throw and re-throw in it's own basic block so that the rest of the | 265 // Emit throw and re-throw in it's own basic block so that the rest of the |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 | 347 |
347 // Perform an operation that returns boolean value to | 348 // Perform an operation that returns boolean value to |
348 // generate JumpIfTrue/False | 349 // generate JumpIfTrue/False |
349 builder.CompareOperation(Token::Value::EQ, reg) | 350 builder.CompareOperation(Token::Value::EQ, reg) |
350 .JumpIfTrue(&start) | 351 .JumpIfTrue(&start) |
351 .CompareOperation(Token::Value::EQ, reg) | 352 .CompareOperation(Token::Value::EQ, reg) |
352 .JumpIfFalse(&start); | 353 .JumpIfFalse(&start); |
353 | 354 |
354 // Perform an operation that returns a non-boolean operation to | 355 // Perform an operation that returns a non-boolean operation to |
355 // generate JumpIfToBooleanTrue/False. | 356 // generate JumpIfToBooleanTrue/False. |
356 builder.BinaryOperation(Token::Value::ADD, reg) | 357 builder.BinaryOperation(Token::Value::ADD, reg, 1) |
357 .JumpIfTrue(&start) | 358 .JumpIfTrue(&start) |
358 .BinaryOperation(Token::Value::ADD, reg) | 359 .BinaryOperation(Token::Value::ADD, reg, 2) |
359 .JumpIfFalse(&start); | 360 .JumpIfFalse(&start); |
360 | 361 |
361 // Emit generator operations | 362 // Emit generator operations |
362 builder.SuspendGenerator(reg) | 363 builder.SuspendGenerator(reg) |
363 .ResumeGenerator(reg); | 364 .ResumeGenerator(reg); |
364 | 365 |
365 // Intrinsics handled by the interpreter. | 366 // Intrinsics handled by the interpreter. |
366 builder.CallRuntime(Runtime::kInlineIsArray, reg, 1) | 367 builder.CallRuntime(Runtime::kInlineIsArray, reg, 1) |
367 .CallRuntime(Runtime::kInlineIsArray, wide, 1); | 368 .CallRuntime(Runtime::kInlineIsArray, wide, 1); |
368 | 369 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 BytecodeLabel far0, far1, far2, far3, far4; | 557 BytecodeLabel far0, far1, far2, far3, far4; |
557 BytecodeLabel near0, near1, near2, near3, near4; | 558 BytecodeLabel near0, near1, near2, near3, near4; |
558 BytecodeLabel after_jump0, after_jump1; | 559 BytecodeLabel after_jump0, after_jump1; |
559 | 560 |
560 builder.Jump(&near0) | 561 builder.Jump(&near0) |
561 .Bind(&after_jump0) | 562 .Bind(&after_jump0) |
562 .CompareOperation(Token::Value::EQ, reg) | 563 .CompareOperation(Token::Value::EQ, reg) |
563 .JumpIfTrue(&near1) | 564 .JumpIfTrue(&near1) |
564 .CompareOperation(Token::Value::EQ, reg) | 565 .CompareOperation(Token::Value::EQ, reg) |
565 .JumpIfFalse(&near2) | 566 .JumpIfFalse(&near2) |
566 .BinaryOperation(Token::Value::ADD, reg) | 567 .BinaryOperation(Token::Value::ADD, reg, 1) |
567 .JumpIfTrue(&near3) | 568 .JumpIfTrue(&near3) |
568 .BinaryOperation(Token::Value::ADD, reg) | 569 .BinaryOperation(Token::Value::ADD, reg, 2) |
569 .JumpIfFalse(&near4) | 570 .JumpIfFalse(&near4) |
570 .Bind(&near0) | 571 .Bind(&near0) |
571 .Bind(&near1) | 572 .Bind(&near1) |
572 .Bind(&near2) | 573 .Bind(&near2) |
573 .Bind(&near3) | 574 .Bind(&near3) |
574 .Bind(&near4) | 575 .Bind(&near4) |
575 .Jump(&far0) | 576 .Jump(&far0) |
576 .Bind(&after_jump1) | 577 .Bind(&after_jump1) |
577 .CompareOperation(Token::Value::EQ, reg) | 578 .CompareOperation(Token::Value::EQ, reg) |
578 .JumpIfTrue(&far1) | 579 .JumpIfTrue(&far1) |
579 .CompareOperation(Token::Value::EQ, reg) | 580 .CompareOperation(Token::Value::EQ, reg) |
580 .JumpIfFalse(&far2) | 581 .JumpIfFalse(&far2) |
581 .BinaryOperation(Token::Value::ADD, reg) | 582 .BinaryOperation(Token::Value::ADD, reg, 3) |
582 .JumpIfTrue(&far3) | 583 .JumpIfTrue(&far3) |
583 .BinaryOperation(Token::Value::ADD, reg) | 584 .BinaryOperation(Token::Value::ADD, reg, 4) |
584 .JumpIfFalse(&far4); | 585 .JumpIfFalse(&far4); |
585 for (int i = 0; i < kFarJumpDistance - 18; i++) { | 586 for (int i = 0; i < kFarJumpDistance - 20; i++) { |
586 builder.Debugger(); | 587 builder.Debugger(); |
587 } | 588 } |
588 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); | 589 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); |
589 builder.Return(); | 590 builder.Return(); |
590 | 591 |
591 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 592 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
592 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1); | 593 DCHECK_EQ(array->length(), 40 + kFarJumpDistance - 20 + 1); |
593 | 594 |
594 BytecodeArrayIterator iterator(array); | 595 BytecodeArrayIterator iterator(array); |
595 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 596 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
596 CHECK_EQ(iterator.GetImmediateOperand(0), 18); | 597 CHECK_EQ(iterator.GetImmediateOperand(0), 20); |
597 iterator.Advance(); | 598 iterator.Advance(); |
598 | 599 |
599 // Ignore compare operation. | 600 // Ignore compare operation. |
600 iterator.Advance(); | 601 iterator.Advance(); |
601 | 602 |
602 CHECK_EQ(iterator.current_bytecode(), | 603 CHECK_EQ(iterator.current_bytecode(), |
603 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | 604 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); |
604 CHECK_EQ(iterator.GetImmediateOperand(0), 14); | 605 CHECK_EQ(iterator.GetImmediateOperand(0), 16); |
605 iterator.Advance(); | 606 iterator.Advance(); |
606 | 607 |
607 // Ignore compare operation. | 608 // Ignore compare operation. |
608 iterator.Advance(); | 609 iterator.Advance(); |
609 | 610 |
610 CHECK_EQ(iterator.current_bytecode(), | 611 CHECK_EQ(iterator.current_bytecode(), |
611 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | 612 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); |
612 CHECK_EQ(iterator.GetImmediateOperand(0), 10); | 613 CHECK_EQ(iterator.GetImmediateOperand(0), 12); |
613 iterator.Advance(); | 614 iterator.Advance(); |
614 | 615 |
615 // Ignore add operation. | 616 // Ignore add operation. |
616 iterator.Advance(); | 617 iterator.Advance(); |
617 | 618 |
618 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 619 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
619 CHECK_EQ(iterator.GetImmediateOperand(0), 6); | 620 CHECK_EQ(iterator.GetImmediateOperand(0), 7); |
620 iterator.Advance(); | 621 iterator.Advance(); |
621 | 622 |
622 // Ignore add operation. | 623 // Ignore add operation. |
623 iterator.Advance(); | 624 iterator.Advance(); |
624 | 625 |
625 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); | 626 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
626 CHECK_EQ(iterator.GetImmediateOperand(0), 2); | 627 CHECK_EQ(iterator.GetImmediateOperand(0), 2); |
627 iterator.Advance(); | 628 iterator.Advance(); |
628 | 629 |
629 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); | 630 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); |
(...skipping 17 matching lines...) Expand all Loading... |
647 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalseConstant)); | 648 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalseConstant)); |
648 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 649 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
649 Smi::FromInt(kFarJumpDistance - 8)); | 650 Smi::FromInt(kFarJumpDistance - 8)); |
650 iterator.Advance(); | 651 iterator.Advance(); |
651 | 652 |
652 // Ignore add operation. | 653 // Ignore add operation. |
653 iterator.Advance(); | 654 iterator.Advance(); |
654 | 655 |
655 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); | 656 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); |
656 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 657 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
657 Smi::FromInt(kFarJumpDistance - 12)); | 658 Smi::FromInt(kFarJumpDistance - 13)); |
658 iterator.Advance(); | 659 iterator.Advance(); |
659 | 660 |
660 // Ignore add operation. | 661 // Ignore add operation. |
661 iterator.Advance(); | 662 iterator.Advance(); |
662 | 663 |
663 CHECK_EQ(iterator.current_bytecode(), | 664 CHECK_EQ(iterator.current_bytecode(), |
664 Bytecode::kJumpIfToBooleanFalseConstant); | 665 Bytecode::kJumpIfToBooleanFalseConstant); |
665 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 666 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
666 Smi::FromInt(kFarJumpDistance - 16)); | 667 Smi::FromInt(kFarJumpDistance - 18)); |
667 iterator.Advance(); | 668 iterator.Advance(); |
668 } | 669 } |
669 | 670 |
670 | 671 |
671 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { | 672 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { |
672 CanonicalHandleScope canonical(isolate()); | 673 CanonicalHandleScope canonical(isolate()); |
673 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); | 674 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); |
674 | 675 |
675 Register reg(0); | 676 Register reg(0); |
676 | 677 |
677 BytecodeLabel label0, label1, label2, label3, label4; | 678 BytecodeLabel label0, label1, label2, label3, label4; |
678 builder.Bind(&label0) | 679 builder.Bind(&label0) |
679 .Jump(&label0) | 680 .Jump(&label0) |
680 .Bind(&label1) | 681 .Bind(&label1) |
681 .CompareOperation(Token::Value::EQ, reg) | 682 .CompareOperation(Token::Value::EQ, reg) |
682 .JumpIfTrue(&label1) | 683 .JumpIfTrue(&label1) |
683 .Bind(&label2) | 684 .Bind(&label2) |
684 .CompareOperation(Token::Value::EQ, reg) | 685 .CompareOperation(Token::Value::EQ, reg) |
685 .JumpIfFalse(&label2) | 686 .JumpIfFalse(&label2) |
686 .Bind(&label3) | 687 .Bind(&label3) |
687 .BinaryOperation(Token::Value::ADD, reg) | 688 .BinaryOperation(Token::Value::ADD, reg, 1) |
688 .JumpIfTrue(&label3) | 689 .JumpIfTrue(&label3) |
689 .Bind(&label4) | 690 .Bind(&label4) |
690 .BinaryOperation(Token::Value::ADD, reg) | 691 .BinaryOperation(Token::Value::ADD, reg, 2) |
691 .JumpIfFalse(&label4); | 692 .JumpIfFalse(&label4); |
692 for (int i = 0; i < 63; i++) { | 693 for (int i = 0; i < 62; i++) { |
693 BytecodeLabel after_jump; | 694 BytecodeLabel after_jump; |
694 builder.Jump(&label4).Bind(&after_jump); | 695 builder.Jump(&label4).Bind(&after_jump); |
695 } | 696 } |
696 | 697 |
697 // Add padding to force wide backwards jumps. | 698 // Add padding to force wide backwards jumps. |
698 for (int i = 0; i < 256; i++) { | 699 for (int i = 0; i < 256; i++) { |
699 builder.Debugger(); | 700 builder.Debugger(); |
700 } | 701 } |
701 | 702 |
702 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfFalse(&label4); | 703 builder.BinaryOperation(Token::Value::ADD, reg, 1).JumpIfFalse(&label4); |
703 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfTrue(&label3); | 704 builder.BinaryOperation(Token::Value::ADD, reg, 2).JumpIfTrue(&label3); |
704 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2); | 705 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2); |
705 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1); | 706 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1); |
706 builder.Jump(&label0); | 707 builder.Jump(&label0); |
707 BytecodeLabel end; | 708 BytecodeLabel end; |
708 builder.Bind(&end); | 709 builder.Bind(&end); |
709 builder.Return(); | 710 builder.Return(); |
710 | 711 |
711 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 712 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
712 BytecodeArrayIterator iterator(array); | 713 BytecodeArrayIterator iterator(array); |
713 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 714 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
(...skipping 10 matching lines...) Expand all Loading... |
724 iterator.Advance(); | 725 iterator.Advance(); |
725 CHECK_EQ(iterator.current_bytecode(), | 726 CHECK_EQ(iterator.current_bytecode(), |
726 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | 727 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); |
727 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 728 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
728 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 729 CHECK_EQ(iterator.GetImmediateOperand(0), -2); |
729 iterator.Advance(); | 730 iterator.Advance(); |
730 // Ignore binary operation. | 731 // Ignore binary operation. |
731 iterator.Advance(); | 732 iterator.Advance(); |
732 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 733 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
733 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 734 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
734 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 735 CHECK_EQ(iterator.GetImmediateOperand(0), -3); |
735 iterator.Advance(); | 736 iterator.Advance(); |
736 // Ignore binary operation. | 737 // Ignore binary operation. |
737 iterator.Advance(); | 738 iterator.Advance(); |
738 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); | 739 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
739 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 740 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
740 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 741 CHECK_EQ(iterator.GetImmediateOperand(0), -3); |
741 iterator.Advance(); | 742 iterator.Advance(); |
742 for (int i = 0; i < 63; i++) { | 743 for (int i = 0; i < 62; i++) { |
743 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 744 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
744 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 745 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
745 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 4); | 746 // offset of 5 (3 for binary operation and 2 for jump) |
| 747 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 5); |
746 iterator.Advance(); | 748 iterator.Advance(); |
747 } | 749 } |
748 // Check padding to force wide backwards jumps. | 750 // Check padding to force wide backwards jumps. |
749 for (int i = 0; i < 256; i++) { | 751 for (int i = 0; i < 256; i++) { |
750 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger); | 752 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger); |
751 iterator.Advance(); | 753 iterator.Advance(); |
752 } | 754 } |
753 // Ignore binary operation. | 755 // Ignore binary operation. |
754 iterator.Advance(); | 756 iterator.Advance(); |
755 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); | 757 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
756 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 758 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
757 CHECK_EQ(iterator.GetImmediateOperand(0), -389); | 759 CHECK_EQ(iterator.GetImmediateOperand(0), -389); |
758 iterator.Advance(); | 760 iterator.Advance(); |
759 // Ignore binary operation. | 761 // Ignore binary operation. |
760 iterator.Advance(); | 762 iterator.Advance(); |
761 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 763 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
762 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 764 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
763 CHECK_EQ(iterator.GetImmediateOperand(0), -399); | 765 CHECK_EQ(iterator.GetImmediateOperand(0), -401); |
764 iterator.Advance(); | 766 iterator.Advance(); |
765 // Ignore compare operation. | 767 // Ignore compare operation. |
766 iterator.Advance(); | 768 iterator.Advance(); |
767 CHECK_EQ(iterator.current_bytecode(), | 769 CHECK_EQ(iterator.current_bytecode(), |
768 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | 770 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); |
769 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 771 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
770 CHECK_EQ(iterator.GetImmediateOperand(0), -409); | 772 CHECK_EQ(iterator.GetImmediateOperand(0), -411); |
771 iterator.Advance(); | 773 iterator.Advance(); |
772 // Ignore compare operation. | 774 // Ignore compare operation. |
773 iterator.Advance(); | 775 iterator.Advance(); |
774 CHECK_EQ(iterator.current_bytecode(), | 776 CHECK_EQ(iterator.current_bytecode(), |
775 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | 777 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); |
776 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 778 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
777 CHECK_EQ(iterator.GetImmediateOperand(0), -419); | 779 CHECK_EQ(iterator.GetImmediateOperand(0), -421); |
778 iterator.Advance(); | 780 iterator.Advance(); |
779 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 781 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
780 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 782 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
781 CHECK_EQ(iterator.GetImmediateOperand(0), -425); | 783 CHECK_EQ(iterator.GetImmediateOperand(0), -427); |
782 iterator.Advance(); | 784 iterator.Advance(); |
783 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 785 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
784 iterator.Advance(); | 786 iterator.Advance(); |
785 CHECK(iterator.done()); | 787 CHECK(iterator.done()); |
786 } | 788 } |
787 | 789 |
788 | 790 |
789 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { | 791 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { |
790 CanonicalHandleScope canonical(isolate()); | 792 CanonicalHandleScope canonical(isolate()); |
791 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); | 793 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 iterator.Advance(); | 851 iterator.Advance(); |
850 } | 852 } |
851 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 853 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
852 iterator.Advance(); | 854 iterator.Advance(); |
853 CHECK(iterator.done()); | 855 CHECK(iterator.done()); |
854 } | 856 } |
855 | 857 |
856 } // namespace interpreter | 858 } // namespace interpreter |
857 } // namespace internal | 859 } // namespace internal |
858 } // namespace v8 | 860 } // namespace v8 |
OLD | NEW |