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