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