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