 Chromium Code Reviews
 Chromium Code Reviews Issue 2142273003:
  [interpreter] Inline Star on dispatch for some bytecodes  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 2142273003:
  [interpreter] Inline Star on dispatch for some bytecodes  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| OLD | NEW | 
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/interpreter-assembler.h" | 5 #include "src/interpreter/interpreter-assembler.h" | 
| 6 | 6 | 
| 7 #include <limits> | 7 #include <limits> | 
| 8 #include <ostream> | 8 #include <ostream> | 
| 9 | 9 | 
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 using compiler::Node; | 23 using compiler::Node; | 
| 24 | 24 | 
| 25 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, | 25 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, | 
| 26 Bytecode bytecode, | 26 Bytecode bytecode, | 
| 27 OperandScale operand_scale) | 27 OperandScale operand_scale) | 
| 28 : CodeStubAssembler(isolate, zone, InterpreterDispatchDescriptor(isolate), | 28 : CodeStubAssembler(isolate, zone, InterpreterDispatchDescriptor(isolate), | 
| 29 Code::ComputeFlags(Code::BYTECODE_HANDLER), | 29 Code::ComputeFlags(Code::BYTECODE_HANDLER), | 
| 30 Bytecodes::ToString(bytecode), | 30 Bytecodes::ToString(bytecode), | 
| 31 Bytecodes::ReturnCount(bytecode)), | 31 Bytecodes::ReturnCount(bytecode)), | 
| 32 bytecode_(bytecode), | 32 bytecode_(bytecode), | 
| 33 bytecode_offset_(this, MachineType::PointerRepresentation()), | |
| 33 operand_scale_(operand_scale), | 34 operand_scale_(operand_scale), | 
| 34 interpreted_frame_pointer_(this, MachineType::PointerRepresentation()), | 35 interpreted_frame_pointer_(this, MachineType::PointerRepresentation()), | 
| 35 accumulator_(this, MachineRepresentation::kTagged), | 36 accumulator_(this, MachineRepresentation::kTagged), | 
| 36 accumulator_use_(AccumulatorUse::kNone), | 37 accumulator_use_(AccumulatorUse::kNone), | 
| 37 made_call_(false), | 38 made_call_(false), | 
| 38 disable_stack_check_across_call_(false), | 39 disable_stack_check_across_call_(false), | 
| 39 stack_pointer_before_call_(nullptr) { | 40 stack_pointer_before_call_(nullptr) { | 
| 40 accumulator_.Bind( | 41 accumulator_.Bind( | 
| 41 Parameter(InterpreterDispatchDescriptor::kAccumulatorParameter)); | 42 Parameter(InterpreterDispatchDescriptor::kAccumulatorParameter)); | 
| 43 bytecode_offset_.Bind( | |
| 44 Parameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter)); | |
| 42 if (FLAG_trace_ignition) { | 45 if (FLAG_trace_ignition) { | 
| 43 TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry); | 46 TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry); | 
| 44 } | 47 } | 
| 45 } | 48 } | 
| 46 | 49 | 
| 47 InterpreterAssembler::~InterpreterAssembler() { | 50 InterpreterAssembler::~InterpreterAssembler() { | 
| 48 // If the following check fails the handler does not use the | 51 // If the following check fails the handler does not use the | 
| 49 // accumulator in the way described in the bytecode definitions in | 52 // accumulator in the way described in the bytecode definitions in | 
| 50 // bytecodes.h. | 53 // bytecodes.h. | 
| 51 DCHECK_EQ(accumulator_use_, Bytecodes::GetAccumulatorUse(bytecode_)); | 54 DCHECK_EQ(accumulator_use_, Bytecodes::GetAccumulatorUse(bytecode_)); | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 76 | 79 | 
| 77 Node* InterpreterAssembler::GetContext() { | 80 Node* InterpreterAssembler::GetContext() { | 
| 78 return LoadRegister(Register::current_context()); | 81 return LoadRegister(Register::current_context()); | 
| 79 } | 82 } | 
| 80 | 83 | 
| 81 void InterpreterAssembler::SetContext(Node* value) { | 84 void InterpreterAssembler::SetContext(Node* value) { | 
| 82 StoreRegister(value, Register::current_context()); | 85 StoreRegister(value, Register::current_context()); | 
| 83 } | 86 } | 
| 84 | 87 | 
| 85 Node* InterpreterAssembler::BytecodeOffset() { | 88 Node* InterpreterAssembler::BytecodeOffset() { | 
| 86 return Parameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter); | 89 return bytecode_offset_.value(); | 
| 87 } | 90 } | 
| 88 | 91 | 
| 89 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { | 92 Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { | 
| 90 if (made_call_) { | 93 if (made_call_) { | 
| 91 // If we have made a call, restore bytecode array from stack frame in case | 94 // If we have made a call, restore bytecode array from stack frame in case | 
| 92 // the debugger has swapped us to the patched debugger bytecode array. | 95 // the debugger has swapped us to the patched debugger bytecode array. | 
| 93 return LoadRegister(Register::bytecode_array()); | 96 return LoadRegister(Register::bytecode_array()); | 
| 94 } else { | 97 } else { | 
| 95 return Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter); | 98 return Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter); | 
| 96 } | 99 } | 
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 Goto(&ok); | 502 Goto(&ok); | 
| 500 } | 503 } | 
| 501 | 504 | 
| 502 // Update budget. | 505 // Update budget. | 
| 503 Bind(&ok); | 506 Bind(&ok); | 
| 504 StoreNoWriteBarrier(MachineRepresentation::kWord32, | 507 StoreNoWriteBarrier(MachineRepresentation::kWord32, | 
| 505 BytecodeArrayTaggedPointer(), budget_offset, | 508 BytecodeArrayTaggedPointer(), budget_offset, | 
| 506 new_budget.value()); | 509 new_budget.value()); | 
| 507 } | 510 } | 
| 508 | 511 | 
| 512 Node* InterpreterAssembler::Advance() { | |
| 513 return Advance(Bytecodes::Size(bytecode_, operand_scale_)); | |
| 514 } | |
| 515 | |
| 509 Node* InterpreterAssembler::Advance(int delta) { | 516 Node* InterpreterAssembler::Advance(int delta) { | 
| 510 return IntPtrAdd(BytecodeOffset(), IntPtrConstant(delta)); | 517 return Advance(IntPtrConstant(delta)); | 
| 511 } | 518 } | 
| 512 | 519 | 
| 513 Node* InterpreterAssembler::Advance(Node* delta) { | 520 Node* InterpreterAssembler::Advance(Node* delta) { | 
| 514 return IntPtrAdd(BytecodeOffset(), delta); | 521 if (FLAG_trace_ignition) { | 
| 522 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); | |
| 523 } | |
| 524 Node* next_offset = IntPtrAdd(BytecodeOffset(), delta); | |
| 525 bytecode_offset_.Bind(next_offset); | |
| 526 return next_offset; | |
| 515 } | 527 } | 
| 516 | 528 | 
| 517 Node* InterpreterAssembler::Jump(Node* delta) { | 529 Node* InterpreterAssembler::Jump(Node* delta) { | 
| 518 UpdateInterruptBudget(delta); | 530 UpdateInterruptBudget(delta); | 
| 519 return DispatchTo(Advance(delta)); | 531 Node* previous_offset = BytecodeOffset(); | 
| 532 Node* dispatch = DispatchTo(Advance(delta)); | |
| 533 bytecode_offset_.Bind(previous_offset); | |
| 
rmcilroy
2016/07/19 20:18:27
I don't think we need this line do we? We are be e
 
klaasb
2016/07/20 09:26:24
Done.
 | |
| 534 return dispatch; | |
| 520 } | 535 } | 
| 521 | 536 | 
| 522 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { | 537 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { | 
| 523 Label match(this), no_match(this); | 538 Label match(this), no_match(this); | 
| 524 | 539 | 
| 525 BranchIf(condition, &match, &no_match); | 540 BranchIf(condition, &match, &no_match); | 
| 526 Bind(&match); | 541 Bind(&match); | 
| 527 Jump(delta); | 542 Jump(delta); | 
| 528 Bind(&no_match); | 543 Bind(&no_match); | 
| 529 Dispatch(); | 544 Dispatch(); | 
| 530 } | 545 } | 
| 531 | 546 | 
| 532 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { | 547 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { | 
| 533 JumpConditional(WordEqual(lhs, rhs), delta); | 548 JumpConditional(WordEqual(lhs, rhs), delta); | 
| 534 } | 549 } | 
| 535 | 550 | 
| 536 void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs, | 551 void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs, | 
| 537 Node* delta) { | 552 Node* delta) { | 
| 538 JumpConditional(WordNotEqual(lhs, rhs), delta); | 553 JumpConditional(WordNotEqual(lhs, rhs), delta); | 
| 539 } | 554 } | 
| 540 | 555 | 
| 556 Node* InterpreterAssembler::LoadBytecode(compiler::Node* bytecode_offset) { | |
| 557 Node* bytecode = | |
| 558 Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), bytecode_offset); | |
| 559 if (kPointerSize == 8) { | |
| 560 bytecode = ChangeUint32ToUint64(bytecode); | |
| 561 } | |
| 562 return bytecode; | |
| 563 } | |
| 564 | |
| 565 void InterpreterAssembler::StarDispatchLookahead(Variable& target_bytecode) { | |
| 
rmcilroy
2016/07/19 20:18:27
no non-const references - https://google.github.io
 
klaasb
2016/07/20 09:26:24
Done.
 | |
| 566 Label do_inline_star(this), done(this); | |
| 567 | |
| 568 Node* star_bytecode = IntPtrConstant(static_cast<int>(Bytecode::kStar)); | |
| 569 Node* is_star = WordEqual(target_bytecode.value(), star_bytecode); | |
| 570 BranchIf(is_star, &do_inline_star, &done); | |
| 571 Bind(&do_inline_star); | |
| 
rmcilroy
2016/07/19 20:18:27
nit - newline above.
 
klaasb
2016/07/20 09:26:24
Done.
 | |
| 572 { | |
| 573 InlineStar(); | |
| 574 target_bytecode.Bind(LoadBytecode(BytecodeOffset())); | |
| 575 Goto(&done); | |
| 576 } | |
| 577 Bind(&done); | |
| 578 } | |
| 579 | |
| 580 void InterpreterAssembler::InlineStar() { | |
| 581 Bytecode previous_bytecode = bytecode_; | |
| 582 AccumulatorUse previous_acc_use = accumulator_use_; | |
| 583 | |
| 584 bytecode_ = Bytecode::kStar; | |
| 585 accumulator_use_ = AccumulatorUse::kNone; | |
| 586 | |
| 587 if (FLAG_trace_ignition) { | |
| 588 TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry); | |
| 589 } | |
| 590 StoreRegister(GetAccumulator(), BytecodeOperandReg(0)); | |
| 591 | |
| 592 DCHECK_EQ(accumulator_use_, Bytecodes::GetAccumulatorUse(bytecode_)); | |
| 593 | |
| 594 Advance(); | |
| 595 bytecode_ = previous_bytecode; | |
| 596 accumulator_use_ = previous_acc_use; | |
| 597 } | |
| 598 | |
| 541 Node* InterpreterAssembler::Dispatch() { | 599 Node* InterpreterAssembler::Dispatch() { | 
| 542 return DispatchTo(Advance(Bytecodes::Size(bytecode_, operand_scale_))); | 600 Node* previous_offset = BytecodeOffset(); | 
| 601 Node* target_offset = Advance(); | |
| 602 Node* target_bytecode = LoadBytecode(target_offset); | |
| 603 Variable var_bytecode(this, MachineRepresentation::kWord8); | |
| 604 var_bytecode.Bind(target_bytecode); | |
| 605 | |
| 606 if (Bytecodes::IsStarLookahead(bytecode_, operand_scale_)) { | |
| 607 StarDispatchLookahead(var_bytecode); | |
| 608 } | |
| 609 Node* dispatch = DispatchToBytecode(var_bytecode.value(), BytecodeOffset()); | |
| 610 bytecode_offset_.Bind(previous_offset); | |
| 
rmcilroy
2016/07/19 20:18:27
same comment as above.
 
klaasb
2016/07/20 09:26:24
Done.
 | |
| 611 return dispatch; | |
| 543 } | 612 } | 
| 544 | 613 | 
| 545 Node* InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { | 614 Node* InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { | 
| 546 Node* target_bytecode = Load( | 615 Node* target_bytecode = LoadBytecode(new_bytecode_offset); | 
| 
rmcilroy
2016/07/19 20:18:27
nit - DCHECK here that !Bytecodes::IsStarLookahead
 
klaasb
2016/07/20 09:26:24
Done.
 | |
| 547 MachineType::Uint8(), BytecodeArrayTaggedPointer(), new_bytecode_offset); | 616 return DispatchToBytecode(target_bytecode, new_bytecode_offset); | 
| 548 if (kPointerSize == 8) { | 617 } | 
| 549 target_bytecode = ChangeUint32ToUint64(target_bytecode); | |
| 550 } | |
| 551 | 618 | 
| 619 Node* InterpreterAssembler::DispatchToBytecode(Node* target_bytecode, | |
| 620 Node* new_bytecode_offset) { | |
| 552 if (FLAG_trace_ignition_dispatches) { | 621 if (FLAG_trace_ignition_dispatches) { | 
| 553 TraceBytecodeDispatch(target_bytecode); | 622 TraceBytecodeDispatch(target_bytecode); | 
| 554 } | 623 } | 
| 555 | 624 | 
| 556 Node* target_code_entry = | 625 Node* target_code_entry = | 
| 557 Load(MachineType::Pointer(), DispatchTableRawPointer(), | 626 Load(MachineType::Pointer(), DispatchTableRawPointer(), | 
| 558 WordShl(target_bytecode, IntPtrConstant(kPointerSizeLog2))); | 627 WordShl(target_bytecode, IntPtrConstant(kPointerSizeLog2))); | 
| 559 | 628 | 
| 560 return DispatchToBytecodeHandlerEntry(target_code_entry, new_bytecode_offset); | 629 return DispatchToBytecodeHandlerEntry(target_code_entry, new_bytecode_offset); | 
| 561 } | 630 } | 
| 562 | 631 | 
| 563 Node* InterpreterAssembler::DispatchToBytecodeHandler(Node* handler, | 632 Node* InterpreterAssembler::DispatchToBytecodeHandler(Node* handler, | 
| 564 Node* bytecode_offset) { | 633 Node* bytecode_offset) { | 
| 565 Node* handler_entry = | 634 Node* handler_entry = | 
| 566 IntPtrAdd(handler, IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); | 635 IntPtrAdd(handler, IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); | 
| 567 return DispatchToBytecodeHandlerEntry(handler_entry, bytecode_offset); | 636 return DispatchToBytecodeHandlerEntry(handler_entry, bytecode_offset); | 
| 568 } | 637 } | 
| 569 | 638 | 
| 570 Node* InterpreterAssembler::DispatchToBytecodeHandlerEntry( | 639 Node* InterpreterAssembler::DispatchToBytecodeHandlerEntry( | 
| 571 Node* handler_entry, Node* bytecode_offset) { | 640 Node* handler_entry, Node* bytecode_offset) { | 
| 572 if (FLAG_trace_ignition) { | |
| 573 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); | |
| 574 } | |
| 575 | |
| 576 InterpreterDispatchDescriptor descriptor(isolate()); | 641 InterpreterDispatchDescriptor descriptor(isolate()); | 
| 577 Node* args[] = {GetAccumulatorUnchecked(), bytecode_offset, | 642 Node* args[] = {GetAccumulatorUnchecked(), bytecode_offset, | 
| 578 BytecodeArrayTaggedPointer(), DispatchTableRawPointer()}; | 643 BytecodeArrayTaggedPointer(), DispatchTableRawPointer()}; | 
| 579 return TailCallBytecodeDispatch(descriptor, handler_entry, args); | 644 return TailCallBytecodeDispatch(descriptor, handler_entry, args); | 
| 580 } | 645 } | 
| 581 | 646 | 
| 582 void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { | 647 void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { | 
| 583 // Dispatching a wide bytecode requires treating the prefix | 648 // Dispatching a wide bytecode requires treating the prefix | 
| 584 // bytecode a base pointer into the dispatch table and dispatching | 649 // bytecode a base pointer into the dispatch table and dispatching | 
| 585 // the bytecode that follows relative to this base. | 650 // the bytecode that follows relative to this base. | 
| 586 // | 651 // | 
| 587 // Indices 0-255 correspond to bytecodes with operand_scale == 0 | 652 // Indices 0-255 correspond to bytecodes with operand_scale == 0 | 
| 588 // Indices 256-511 correspond to bytecodes with operand_scale == 1 | 653 // Indices 256-511 correspond to bytecodes with operand_scale == 1 | 
| 589 // Indices 512-767 correspond to bytecodes with operand_scale == 2 | 654 // Indices 512-767 correspond to bytecodes with operand_scale == 2 | 
| 590 Node* next_bytecode_offset = Advance(1); | 655 Node* next_bytecode_offset = Advance(1); | 
| 591 Node* next_bytecode = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), | 656 Node* next_bytecode = LoadBytecode(next_bytecode_offset); | 
| 592 next_bytecode_offset); | |
| 593 if (kPointerSize == 8) { | 657 if (kPointerSize == 8) { | 
| 594 next_bytecode = ChangeUint32ToUint64(next_bytecode); | 658 next_bytecode = ChangeUint32ToUint64(next_bytecode); | 
| 595 } | 659 } | 
| 
rmcilroy
2016/07/19 20:18:27
Remove extra ChangeUint32ToUint64 given it is alre
 
klaasb
2016/07/20 09:26:24
Done.
 | |
| 596 | 660 | 
| 597 if (FLAG_trace_ignition_dispatches) { | 661 if (FLAG_trace_ignition_dispatches) { | 
| 598 TraceBytecodeDispatch(next_bytecode); | 662 TraceBytecodeDispatch(next_bytecode); | 
| 599 } | 663 } | 
| 600 | 664 | 
| 601 Node* base_index; | 665 Node* base_index; | 
| 602 switch (operand_scale) { | 666 switch (operand_scale) { | 
| 603 case OperandScale::kDouble: | 667 case OperandScale::kDouble: | 
| 604 base_index = IntPtrConstant(1 << kBitsPerByte); | 668 base_index = IntPtrConstant(1 << kBitsPerByte); | 
| 605 break; | 669 break; | 
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 779 Goto(&loop); | 843 Goto(&loop); | 
| 780 } | 844 } | 
| 781 Bind(&done_loop); | 845 Bind(&done_loop); | 
| 782 | 846 | 
| 783 return array; | 847 return array; | 
| 784 } | 848 } | 
| 785 | 849 | 
| 786 } // namespace interpreter | 850 } // namespace interpreter | 
| 787 } // namespace internal | 851 } // namespace internal | 
| 788 } // namespace v8 | 852 } // namespace v8 | 
| OLD | NEW |