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 13 matching lines...) Expand all Loading... |
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 operand_scale_(operand_scale), | 33 operand_scale_(operand_scale), |
| 34 bytecode_offset_(this, MachineType::PointerRepresentation()), |
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 return DispatchTo(Advance(delta)); |
520 } | 532 } |
521 | 533 |
522 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { | 534 void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { |
523 Label match(this), no_match(this); | 535 Label match(this), no_match(this); |
524 | 536 |
525 BranchIf(condition, &match, &no_match); | 537 BranchIf(condition, &match, &no_match); |
526 Bind(&match); | 538 Bind(&match); |
527 Jump(delta); | 539 Jump(delta); |
528 Bind(&no_match); | 540 Bind(&no_match); |
529 Dispatch(); | 541 Dispatch(); |
530 } | 542 } |
531 | 543 |
532 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { | 544 void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { |
533 JumpConditional(WordEqual(lhs, rhs), delta); | 545 JumpConditional(WordEqual(lhs, rhs), delta); |
534 } | 546 } |
535 | 547 |
536 void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs, | 548 void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs, |
537 Node* delta) { | 549 Node* delta) { |
538 JumpConditional(WordNotEqual(lhs, rhs), delta); | 550 JumpConditional(WordNotEqual(lhs, rhs), delta); |
539 } | 551 } |
540 | 552 |
| 553 Node* InterpreterAssembler::LoadBytecode(compiler::Node* bytecode_offset) { |
| 554 Node* bytecode = |
| 555 Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), bytecode_offset); |
| 556 if (kPointerSize == 8) { |
| 557 bytecode = ChangeUint32ToUint64(bytecode); |
| 558 } |
| 559 return bytecode; |
| 560 } |
| 561 |
| 562 Node* InterpreterAssembler::StarDispatchLookahead(Node* target_bytecode) { |
| 563 Label do_inline_star(this), done(this); |
| 564 |
| 565 Variable var_bytecode(this, MachineRepresentation::kWord8); |
| 566 var_bytecode.Bind(target_bytecode); |
| 567 |
| 568 Node* star_bytecode = IntPtrConstant(static_cast<int>(Bytecode::kStar)); |
| 569 Node* is_star = WordEqual(target_bytecode, star_bytecode); |
| 570 BranchIf(is_star, &do_inline_star, &done); |
| 571 |
| 572 Bind(&do_inline_star); |
| 573 { |
| 574 InlineStar(); |
| 575 var_bytecode.Bind(LoadBytecode(BytecodeOffset())); |
| 576 Goto(&done); |
| 577 } |
| 578 Bind(&done); |
| 579 return var_bytecode.value(); |
| 580 } |
| 581 |
| 582 void InterpreterAssembler::InlineStar() { |
| 583 Bytecode previous_bytecode = bytecode_; |
| 584 AccumulatorUse previous_acc_use = accumulator_use_; |
| 585 |
| 586 bytecode_ = Bytecode::kStar; |
| 587 accumulator_use_ = AccumulatorUse::kNone; |
| 588 |
| 589 if (FLAG_trace_ignition) { |
| 590 TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry); |
| 591 } |
| 592 StoreRegister(GetAccumulator(), BytecodeOperandReg(0)); |
| 593 |
| 594 DCHECK_EQ(accumulator_use_, Bytecodes::GetAccumulatorUse(bytecode_)); |
| 595 |
| 596 Advance(); |
| 597 bytecode_ = previous_bytecode; |
| 598 accumulator_use_ = previous_acc_use; |
| 599 } |
| 600 |
541 Node* InterpreterAssembler::Dispatch() { | 601 Node* InterpreterAssembler::Dispatch() { |
542 return DispatchTo(Advance(Bytecodes::Size(bytecode_, operand_scale_))); | 602 Node* target_offset = Advance(); |
| 603 Node* target_bytecode = LoadBytecode(target_offset); |
| 604 |
| 605 if (Bytecodes::IsStarLookahead(bytecode_, operand_scale_)) { |
| 606 target_bytecode = StarDispatchLookahead(target_bytecode); |
| 607 } |
| 608 return DispatchToBytecode(target_bytecode, BytecodeOffset()); |
543 } | 609 } |
544 | 610 |
545 Node* InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { | 611 Node* InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { |
546 Node* target_bytecode = Load( | 612 DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_)); |
547 MachineType::Uint8(), BytecodeArrayTaggedPointer(), new_bytecode_offset); | 613 Node* target_bytecode = LoadBytecode(new_bytecode_offset); |
548 if (kPointerSize == 8) { | 614 return DispatchToBytecode(target_bytecode, new_bytecode_offset); |
549 target_bytecode = ChangeUint32ToUint64(target_bytecode); | 615 } |
550 } | |
551 | 616 |
| 617 Node* InterpreterAssembler::DispatchToBytecode(Node* target_bytecode, |
| 618 Node* new_bytecode_offset) { |
552 if (FLAG_trace_ignition_dispatches) { | 619 if (FLAG_trace_ignition_dispatches) { |
553 TraceBytecodeDispatch(target_bytecode); | 620 TraceBytecodeDispatch(target_bytecode); |
554 } | 621 } |
555 | 622 |
556 Node* target_code_entry = | 623 Node* target_code_entry = |
557 Load(MachineType::Pointer(), DispatchTableRawPointer(), | 624 Load(MachineType::Pointer(), DispatchTableRawPointer(), |
558 WordShl(target_bytecode, IntPtrConstant(kPointerSizeLog2))); | 625 WordShl(target_bytecode, IntPtrConstant(kPointerSizeLog2))); |
559 | 626 |
560 return DispatchToBytecodeHandlerEntry(target_code_entry, new_bytecode_offset); | 627 return DispatchToBytecodeHandlerEntry(target_code_entry, new_bytecode_offset); |
561 } | 628 } |
562 | 629 |
563 Node* InterpreterAssembler::DispatchToBytecodeHandler(Node* handler, | 630 Node* InterpreterAssembler::DispatchToBytecodeHandler(Node* handler, |
564 Node* bytecode_offset) { | 631 Node* bytecode_offset) { |
565 Node* handler_entry = | 632 Node* handler_entry = |
566 IntPtrAdd(handler, IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); | 633 IntPtrAdd(handler, IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); |
567 return DispatchToBytecodeHandlerEntry(handler_entry, bytecode_offset); | 634 return DispatchToBytecodeHandlerEntry(handler_entry, bytecode_offset); |
568 } | 635 } |
569 | 636 |
570 Node* InterpreterAssembler::DispatchToBytecodeHandlerEntry( | 637 Node* InterpreterAssembler::DispatchToBytecodeHandlerEntry( |
571 Node* handler_entry, Node* bytecode_offset) { | 638 Node* handler_entry, Node* bytecode_offset) { |
572 if (FLAG_trace_ignition) { | |
573 TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); | |
574 } | |
575 | |
576 InterpreterDispatchDescriptor descriptor(isolate()); | 639 InterpreterDispatchDescriptor descriptor(isolate()); |
577 Node* args[] = {GetAccumulatorUnchecked(), bytecode_offset, | 640 Node* args[] = {GetAccumulatorUnchecked(), bytecode_offset, |
578 BytecodeArrayTaggedPointer(), DispatchTableRawPointer()}; | 641 BytecodeArrayTaggedPointer(), DispatchTableRawPointer()}; |
579 return TailCallBytecodeDispatch(descriptor, handler_entry, args); | 642 return TailCallBytecodeDispatch(descriptor, handler_entry, args); |
580 } | 643 } |
581 | 644 |
582 void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { | 645 void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { |
583 // Dispatching a wide bytecode requires treating the prefix | 646 // Dispatching a wide bytecode requires treating the prefix |
584 // bytecode a base pointer into the dispatch table and dispatching | 647 // bytecode a base pointer into the dispatch table and dispatching |
585 // the bytecode that follows relative to this base. | 648 // the bytecode that follows relative to this base. |
586 // | 649 // |
587 // Indices 0-255 correspond to bytecodes with operand_scale == 0 | 650 // Indices 0-255 correspond to bytecodes with operand_scale == 0 |
588 // Indices 256-511 correspond to bytecodes with operand_scale == 1 | 651 // Indices 256-511 correspond to bytecodes with operand_scale == 1 |
589 // Indices 512-767 correspond to bytecodes with operand_scale == 2 | 652 // Indices 512-767 correspond to bytecodes with operand_scale == 2 |
590 Node* next_bytecode_offset = Advance(1); | 653 Node* next_bytecode_offset = Advance(1); |
591 Node* next_bytecode = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), | 654 Node* next_bytecode = LoadBytecode(next_bytecode_offset); |
592 next_bytecode_offset); | |
593 if (kPointerSize == 8) { | |
594 next_bytecode = ChangeUint32ToUint64(next_bytecode); | |
595 } | |
596 | 655 |
597 if (FLAG_trace_ignition_dispatches) { | 656 if (FLAG_trace_ignition_dispatches) { |
598 TraceBytecodeDispatch(next_bytecode); | 657 TraceBytecodeDispatch(next_bytecode); |
599 } | 658 } |
600 | 659 |
601 Node* base_index; | 660 Node* base_index; |
602 switch (operand_scale) { | 661 switch (operand_scale) { |
603 case OperandScale::kDouble: | 662 case OperandScale::kDouble: |
604 base_index = IntPtrConstant(1 << kBitsPerByte); | 663 base_index = IntPtrConstant(1 << kBitsPerByte); |
605 break; | 664 break; |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 Goto(&loop); | 838 Goto(&loop); |
780 } | 839 } |
781 Bind(&done_loop); | 840 Bind(&done_loop); |
782 | 841 |
783 return array; | 842 return array; |
784 } | 843 } |
785 | 844 |
786 } // namespace interpreter | 845 } // namespace interpreter |
787 } // namespace internal | 846 } // namespace internal |
788 } // namespace v8 | 847 } // namespace v8 |
OLD | NEW |