| 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 |