Chromium Code Reviews| 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 |