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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 | 349 |
349 // Perform an operation that returns boolean value to | 350 // Perform an operation that returns boolean value to |
350 // generate JumpIfTrue/False | 351 // generate JumpIfTrue/False |
351 builder.CompareOperation(Token::Value::EQ, reg) | 352 builder.CompareOperation(Token::Value::EQ, reg) |
352 .JumpIfTrue(&start) | 353 .JumpIfTrue(&start) |
353 .CompareOperation(Token::Value::EQ, reg) | 354 .CompareOperation(Token::Value::EQ, reg) |
354 .JumpIfFalse(&start); | 355 .JumpIfFalse(&start); |
355 | 356 |
356 // Perform an operation that returns a non-boolean operation to | 357 // Perform an operation that returns a non-boolean operation to |
357 // generate JumpIfToBooleanTrue/False. | 358 // generate JumpIfToBooleanTrue/False. |
358 builder.BinaryOperation(Token::Value::ADD, reg) | 359 builder.BinaryOperation(Token::Value::ADD, reg, 1) |
359 .JumpIfTrue(&start) | 360 .JumpIfTrue(&start) |
360 .BinaryOperation(Token::Value::ADD, reg) | 361 .BinaryOperation(Token::Value::ADD, reg, 2) |
361 .JumpIfFalse(&start); | 362 .JumpIfFalse(&start); |
362 | 363 |
363 // Emit generator operations | 364 // Emit generator operations |
364 builder.SuspendGenerator(reg) | 365 builder.SuspendGenerator(reg) |
365 .ResumeGenerator(reg); | 366 .ResumeGenerator(reg); |
366 | 367 |
367 // Intrinsics handled by the interpreter. | 368 // Intrinsics handled by the interpreter. |
368 builder.CallRuntime(Runtime::kInlineIsArray, reg, 1) | 369 builder.CallRuntime(Runtime::kInlineIsArray, reg, 1) |
369 .CallRuntime(Runtime::kInlineIsArray, wide, 1); | 370 .CallRuntime(Runtime::kInlineIsArray, wide, 1); |
370 | 371 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 BytecodeLabel far0, far1, far2, far3, far4; | 553 BytecodeLabel far0, far1, far2, far3, far4; |
553 BytecodeLabel near0, near1, near2, near3, near4; | 554 BytecodeLabel near0, near1, near2, near3, near4; |
554 BytecodeLabel after_jump0, after_jump1; | 555 BytecodeLabel after_jump0, after_jump1; |
555 | 556 |
556 builder.Jump(&near0) | 557 builder.Jump(&near0) |
557 .Bind(&after_jump0) | 558 .Bind(&after_jump0) |
558 .CompareOperation(Token::Value::EQ, reg) | 559 .CompareOperation(Token::Value::EQ, reg) |
559 .JumpIfTrue(&near1) | 560 .JumpIfTrue(&near1) |
560 .CompareOperation(Token::Value::EQ, reg) | 561 .CompareOperation(Token::Value::EQ, reg) |
561 .JumpIfFalse(&near2) | 562 .JumpIfFalse(&near2) |
562 .BinaryOperation(Token::Value::ADD, reg) | 563 .BinaryOperation(Token::Value::ADD, reg, 1) |
563 .JumpIfTrue(&near3) | 564 .JumpIfTrue(&near3) |
564 .BinaryOperation(Token::Value::ADD, reg) | 565 .BinaryOperation(Token::Value::ADD, reg, 2) |
565 .JumpIfFalse(&near4) | 566 .JumpIfFalse(&near4) |
566 .Bind(&near0) | 567 .Bind(&near0) |
567 .Bind(&near1) | 568 .Bind(&near1) |
568 .Bind(&near2) | 569 .Bind(&near2) |
569 .Bind(&near3) | 570 .Bind(&near3) |
570 .Bind(&near4) | 571 .Bind(&near4) |
571 .Jump(&far0) | 572 .Jump(&far0) |
572 .Bind(&after_jump1) | 573 .Bind(&after_jump1) |
573 .CompareOperation(Token::Value::EQ, reg) | 574 .CompareOperation(Token::Value::EQ, reg) |
574 .JumpIfTrue(&far1) | 575 .JumpIfTrue(&far1) |
575 .CompareOperation(Token::Value::EQ, reg) | 576 .CompareOperation(Token::Value::EQ, reg) |
576 .JumpIfFalse(&far2) | 577 .JumpIfFalse(&far2) |
577 .BinaryOperation(Token::Value::ADD, reg) | 578 .BinaryOperation(Token::Value::ADD, reg, 3) |
578 .JumpIfTrue(&far3) | 579 .JumpIfTrue(&far3) |
579 .BinaryOperation(Token::Value::ADD, reg) | 580 .BinaryOperation(Token::Value::ADD, reg, 4) |
580 .JumpIfFalse(&far4); | 581 .JumpIfFalse(&far4); |
581 for (int i = 0; i < kFarJumpDistance - 18; i++) { | 582 for (int i = 0; i < kFarJumpDistance - 20; i++) { |
582 builder.Debugger(); | 583 builder.Debugger(); |
583 } | 584 } |
584 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); | 585 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); |
585 builder.Return(); | 586 builder.Return(); |
586 | 587 |
587 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 588 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
588 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1); | 589 DCHECK_EQ(array->length(), 40 + kFarJumpDistance - 20 + 1); |
589 | 590 |
590 BytecodeArrayIterator iterator(array); | 591 BytecodeArrayIterator iterator(array); |
591 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 592 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
592 CHECK_EQ(iterator.GetImmediateOperand(0), 18); | 593 CHECK_EQ(iterator.GetImmediateOperand(0), 20); |
593 iterator.Advance(); | 594 iterator.Advance(); |
594 | 595 |
595 // Ignore compare operation. | 596 // Ignore compare operation. |
596 iterator.Advance(); | 597 iterator.Advance(); |
597 | 598 |
598 CHECK_EQ(iterator.current_bytecode(), | 599 CHECK_EQ(iterator.current_bytecode(), |
599 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | 600 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); |
600 CHECK_EQ(iterator.GetImmediateOperand(0), 14); | 601 CHECK_EQ(iterator.GetImmediateOperand(0), 16); |
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::kJumpIfToBooleanFalse)); | 608 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); |
608 CHECK_EQ(iterator.GetImmediateOperand(0), 10); | 609 CHECK_EQ(iterator.GetImmediateOperand(0), 12); |
609 iterator.Advance(); | 610 iterator.Advance(); |
610 | 611 |
611 // Ignore add operation. | 612 // Ignore add operation. |
612 iterator.Advance(); | 613 iterator.Advance(); |
613 | 614 |
614 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 615 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
615 CHECK_EQ(iterator.GetImmediateOperand(0), 6); | 616 CHECK_EQ(iterator.GetImmediateOperand(0), 7); |
616 iterator.Advance(); | 617 iterator.Advance(); |
617 | 618 |
618 // Ignore add operation. | 619 // Ignore add operation. |
619 iterator.Advance(); | 620 iterator.Advance(); |
620 | 621 |
621 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); | 622 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
622 CHECK_EQ(iterator.GetImmediateOperand(0), 2); | 623 CHECK_EQ(iterator.GetImmediateOperand(0), 2); |
623 iterator.Advance(); | 624 iterator.Advance(); |
624 | 625 |
625 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); | 626 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); |
(...skipping 17 matching lines...) Expand all Loading... | |
643 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalseConstant)); | 644 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalseConstant)); |
644 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 645 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
645 Smi::FromInt(kFarJumpDistance - 8)); | 646 Smi::FromInt(kFarJumpDistance - 8)); |
646 iterator.Advance(); | 647 iterator.Advance(); |
647 | 648 |
648 // Ignore add operation. | 649 // Ignore add operation. |
649 iterator.Advance(); | 650 iterator.Advance(); |
650 | 651 |
651 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); | 652 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); |
652 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 653 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
653 Smi::FromInt(kFarJumpDistance - 12)); | 654 Smi::FromInt(kFarJumpDistance - 13)); |
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(), | 660 CHECK_EQ(iterator.current_bytecode(), |
660 Bytecode::kJumpIfToBooleanFalseConstant); | 661 Bytecode::kJumpIfToBooleanFalseConstant); |
661 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 662 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
662 Smi::FromInt(kFarJumpDistance - 16)); | 663 Smi::FromInt(kFarJumpDistance - 18)); |
663 iterator.Advance(); | 664 iterator.Advance(); |
664 } | 665 } |
665 | 666 |
666 | 667 |
667 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { | 668 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { |
668 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); | 669 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); |
669 | 670 |
670 Register reg(0); | 671 Register reg(0); |
671 | 672 |
672 BytecodeLabel label0, label1, label2, label3, label4; | 673 BytecodeLabel label0, label1, label2, label3, label4; |
673 builder.Bind(&label0) | 674 builder.Bind(&label0) |
674 .Jump(&label0) | 675 .Jump(&label0) |
675 .Bind(&label1) | 676 .Bind(&label1) |
676 .CompareOperation(Token::Value::EQ, reg) | 677 .CompareOperation(Token::Value::EQ, reg) |
677 .JumpIfTrue(&label1) | 678 .JumpIfTrue(&label1) |
678 .Bind(&label2) | 679 .Bind(&label2) |
679 .CompareOperation(Token::Value::EQ, reg) | 680 .CompareOperation(Token::Value::EQ, reg) |
680 .JumpIfFalse(&label2) | 681 .JumpIfFalse(&label2) |
681 .Bind(&label3) | 682 .Bind(&label3) |
682 .BinaryOperation(Token::Value::ADD, reg) | 683 .BinaryOperation(Token::Value::ADD, reg, 1) |
683 .JumpIfTrue(&label3) | 684 .JumpIfTrue(&label3) |
684 .Bind(&label4) | 685 .Bind(&label4) |
685 .BinaryOperation(Token::Value::ADD, reg) | 686 .BinaryOperation(Token::Value::ADD, reg, 2) |
686 .JumpIfFalse(&label4); | 687 .JumpIfFalse(&label4); |
687 for (int i = 0; i < 63; i++) { | 688 for (int i = 0; i < 63; i++) { |
688 BytecodeLabel after_jump; | 689 BytecodeLabel after_jump; |
689 builder.Jump(&label4).Bind(&after_jump); | 690 builder.Jump(&label4).Bind(&after_jump); |
690 } | 691 } |
691 | 692 |
692 // Add padding to force wide backwards jumps. | 693 // Add padding to force wide backwards jumps. |
693 for (int i = 0; i < 256; i++) { | 694 for (int i = 0; i < 256; i++) { |
694 builder.Debugger(); | 695 builder.Debugger(); |
695 } | 696 } |
696 | 697 |
697 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfFalse(&label4); | 698 builder.BinaryOperation(Token::Value::ADD, reg, 1).JumpIfFalse(&label4); |
698 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfTrue(&label3); | 699 builder.BinaryOperation(Token::Value::ADD, reg, 2).JumpIfTrue(&label3); |
699 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2); | 700 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2); |
700 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1); | 701 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1); |
701 builder.Jump(&label0); | 702 builder.Jump(&label0); |
702 BytecodeLabel end; | 703 BytecodeLabel end; |
703 builder.Bind(&end); | 704 builder.Bind(&end); |
704 builder.Return(); | 705 builder.Return(); |
705 | 706 |
706 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 707 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
707 BytecodeArrayIterator iterator(array); | 708 BytecodeArrayIterator iterator(array); |
708 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 709 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
(...skipping 10 matching lines...) Expand all Loading... | |
719 iterator.Advance(); | 720 iterator.Advance(); |
720 CHECK_EQ(iterator.current_bytecode(), | 721 CHECK_EQ(iterator.current_bytecode(), |
721 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | 722 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); |
722 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 723 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
723 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 724 CHECK_EQ(iterator.GetImmediateOperand(0), -2); |
724 iterator.Advance(); | 725 iterator.Advance(); |
725 // Ignore binary operation. | 726 // Ignore binary operation. |
726 iterator.Advance(); | 727 iterator.Advance(); |
727 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 728 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
728 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 729 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
729 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 730 CHECK_EQ(iterator.GetImmediateOperand(0), -3); |
730 iterator.Advance(); | 731 iterator.Advance(); |
731 // Ignore binary operation. | 732 // Ignore binary operation. |
732 iterator.Advance(); | 733 iterator.Advance(); |
733 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); | 734 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
734 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 735 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
735 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 736 CHECK_EQ(iterator.GetImmediateOperand(0), -3); |
736 iterator.Advance(); | 737 iterator.Advance(); |
737 for (int i = 0; i < 63; i++) { | 738 for (int i = 0; i < 63; i++) { |
738 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 739 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
739 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 740 if (i == 62) { |
740 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 4); | 741 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
741 iterator.Advance(); | 742 // offset of 5 (3 for binary operation and 2 for jump) |
743 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 5 - 1); | |
rmcilroy
2016/08/03 16:04:30
Why is the last one special? Could you update the
mythria
2016/08/05 07:08:15
Done. I removed the special case.
| |
744 iterator.Advance(); | |
745 } else { | |
746 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
747 // offset of 5 (3 for binary operation and 2 for jump) | |
748 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 5); | |
749 iterator.Advance(); | |
750 } | |
742 } | 751 } |
743 // Check padding to force wide backwards jumps. | 752 // Check padding to force wide backwards jumps. |
744 for (int i = 0; i < 256; i++) { | 753 for (int i = 0; i < 256; i++) { |
745 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger); | 754 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger); |
746 iterator.Advance(); | 755 iterator.Advance(); |
747 } | 756 } |
748 // Ignore binary operation. | 757 // Ignore binary operation. |
749 iterator.Advance(); | 758 iterator.Advance(); |
750 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); | 759 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
751 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 760 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
752 CHECK_EQ(iterator.GetImmediateOperand(0), -389); | 761 CHECK_EQ(iterator.GetImmediateOperand(0), -393); |
753 iterator.Advance(); | 762 iterator.Advance(); |
754 // Ignore binary operation. | 763 // Ignore binary operation. |
755 iterator.Advance(); | 764 iterator.Advance(); |
756 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 765 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
757 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 766 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
758 CHECK_EQ(iterator.GetImmediateOperand(0), -399); | 767 CHECK_EQ(iterator.GetImmediateOperand(0), -405); |
759 iterator.Advance(); | 768 iterator.Advance(); |
760 // Ignore compare operation. | 769 // Ignore compare operation. |
761 iterator.Advance(); | 770 iterator.Advance(); |
762 CHECK_EQ(iterator.current_bytecode(), | 771 CHECK_EQ(iterator.current_bytecode(), |
763 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | 772 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); |
764 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 773 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
765 CHECK_EQ(iterator.GetImmediateOperand(0), -409); | 774 CHECK_EQ(iterator.GetImmediateOperand(0), -415); |
766 iterator.Advance(); | 775 iterator.Advance(); |
767 // Ignore compare operation. | 776 // Ignore compare operation. |
768 iterator.Advance(); | 777 iterator.Advance(); |
769 CHECK_EQ(iterator.current_bytecode(), | 778 CHECK_EQ(iterator.current_bytecode(), |
770 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | 779 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); |
771 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 780 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
772 CHECK_EQ(iterator.GetImmediateOperand(0), -419); | 781 CHECK_EQ(iterator.GetImmediateOperand(0), -425); |
773 iterator.Advance(); | 782 iterator.Advance(); |
774 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 783 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
775 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 784 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
776 CHECK_EQ(iterator.GetImmediateOperand(0), -425); | 785 CHECK_EQ(iterator.GetImmediateOperand(0), -431); |
777 iterator.Advance(); | 786 iterator.Advance(); |
778 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 787 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
779 iterator.Advance(); | 788 iterator.Advance(); |
780 CHECK(iterator.done()); | 789 CHECK(iterator.done()); |
781 } | 790 } |
782 | 791 |
783 | 792 |
784 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { | 793 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { |
785 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); | 794 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); |
786 | 795 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
842 iterator.Advance(); | 851 iterator.Advance(); |
843 } | 852 } |
844 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 853 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
845 iterator.Advance(); | 854 iterator.Advance(); |
846 CHECK(iterator.done()); | 855 CHECK(iterator.done()); |
847 } | 856 } |
848 | 857 |
849 } // namespace interpreter | 858 } // namespace interpreter |
850 } // namespace internal | 859 } // namespace internal |
851 } // namespace v8 | 860 } // namespace v8 |
OLD | NEW |