Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: src/interpreter/bytecode-array-builder.cc

Issue 2369873002: [Interpreter] Replace BytecodeRegisterAllocator with a simple bump pointer. (Closed)
Patch Set: Add dcheck Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/bytecode-array-builder.h" 5 #include "src/interpreter/bytecode-array-builder.h"
6 6
7 #include "src/globals.h" 7 #include "src/globals.h"
8 #include "src/interpreter/bytecode-array-writer.h" 8 #include "src/interpreter/bytecode-array-writer.h"
9 #include "src/interpreter/bytecode-dead-code-optimizer.h" 9 #include "src/interpreter/bytecode-dead-code-optimizer.h"
10 #include "src/interpreter/bytecode-label.h" 10 #include "src/interpreter/bytecode-label.h"
(...skipping 10 matching lines...) Expand all
21 int locals_count, FunctionLiteral* literal, 21 int locals_count, FunctionLiteral* literal,
22 SourcePositionTableBuilder::RecordingMode source_position_mode) 22 SourcePositionTableBuilder::RecordingMode source_position_mode)
23 : zone_(zone), 23 : zone_(zone),
24 bytecode_generated_(false), 24 bytecode_generated_(false),
25 constant_array_builder_(zone, isolate->factory()->the_hole_value()), 25 constant_array_builder_(zone, isolate->factory()->the_hole_value()),
26 handler_table_builder_(zone), 26 handler_table_builder_(zone),
27 return_seen_in_block_(false), 27 return_seen_in_block_(false),
28 parameter_count_(parameter_count), 28 parameter_count_(parameter_count),
29 local_register_count_(locals_count), 29 local_register_count_(locals_count),
30 context_register_count_(context_count), 30 context_register_count_(context_count),
31 temporary_allocator_(zone, fixed_register_count()), 31 register_allocator_(fixed_register_count()),
32 bytecode_array_writer_(zone, &constant_array_builder_, 32 bytecode_array_writer_(zone, &constant_array_builder_,
33 source_position_mode), 33 source_position_mode),
34 pipeline_(&bytecode_array_writer_) { 34 pipeline_(&bytecode_array_writer_) {
35 DCHECK_GE(parameter_count_, 0); 35 DCHECK_GE(parameter_count_, 0);
36 DCHECK_GE(context_register_count_, 0); 36 DCHECK_GE(context_register_count_, 0);
37 DCHECK_GE(local_register_count_, 0); 37 DCHECK_GE(local_register_count_, 0);
38 38
39 if (FLAG_ignition_deadcode) { 39 if (FLAG_ignition_deadcode) {
40 pipeline_ = new (zone) BytecodeDeadCodeOptimizer(pipeline_); 40 pipeline_ = new (zone) BytecodeDeadCodeOptimizer(pipeline_);
41 } 41 }
42 42
43 if (FLAG_ignition_peephole) { 43 if (FLAG_ignition_peephole) {
44 pipeline_ = new (zone) BytecodePeepholeOptimizer(pipeline_); 44 pipeline_ = new (zone) BytecodePeepholeOptimizer(pipeline_);
45 } 45 }
46 46
47 if (FLAG_ignition_reo) { 47 if (FLAG_ignition_reo) {
48 pipeline_ = new (zone) BytecodeRegisterOptimizer( 48 pipeline_ = new (zone) BytecodeRegisterOptimizer(
49 zone, &temporary_allocator_, parameter_count, pipeline_); 49 zone, &register_allocator_, fixed_register_count(), parameter_count,
50 pipeline_);
50 } 51 }
51 52
52 return_position_ = 53 return_position_ =
53 literal ? std::max(literal->start_position(), literal->end_position() - 1) 54 literal ? std::max(literal->start_position(), literal->end_position() - 1)
54 : kNoSourcePosition; 55 : kNoSourcePosition;
55 } 56 }
56 57
57 Register BytecodeArrayBuilder::first_context_register() const { 58 Register BytecodeArrayBuilder::first_context_register() const {
58 DCHECK_GT(context_register_count_, 0); 59 DCHECK_GT(context_register_count_, 0);
59 return Register(local_register_count_); 60 return Register(local_register_count_);
60 } 61 }
61 62
62 Register BytecodeArrayBuilder::last_context_register() const { 63 Register BytecodeArrayBuilder::last_context_register() const {
63 DCHECK_GT(context_register_count_, 0); 64 DCHECK_GT(context_register_count_, 0);
64 return Register(local_register_count_ + context_register_count_ - 1); 65 return Register(local_register_count_ + context_register_count_ - 1);
65 } 66 }
66 67
67 Register BytecodeArrayBuilder::Parameter(int parameter_index) const { 68 Register BytecodeArrayBuilder::Parameter(int parameter_index) const {
68 DCHECK_GE(parameter_index, 0); 69 DCHECK_GE(parameter_index, 0);
69 return Register::FromParameterIndex(parameter_index, parameter_count()); 70 return Register::FromParameterIndex(parameter_index, parameter_count());
70 } 71 }
71 72
72 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const {
73 return reg.is_parameter() || reg.index() < locals_count();
74 }
75
76 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) { 73 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray(Isolate* isolate) {
77 DCHECK(return_seen_in_block_); 74 DCHECK(return_seen_in_block_);
78 DCHECK(!bytecode_generated_); 75 DCHECK(!bytecode_generated_);
79 bytecode_generated_ = true; 76 bytecode_generated_ = true;
80 77
81 Handle<FixedArray> handler_table = 78 Handle<FixedArray> handler_table =
82 handler_table_builder()->ToHandlerTable(isolate); 79 handler_table_builder()->ToHandlerTable(isolate);
83 return pipeline_->ToBytecodeArray(isolate, 80 return pipeline_->ToBytecodeArray(isolate, total_register_count(),
84 fixed_and_temporary_register_count(),
85 parameter_count(), handler_table); 81 parameter_count(), handler_table);
86 } 82 }
87 83
88 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, 84 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
89 uint32_t operand1, uint32_t operand2, 85 uint32_t operand1, uint32_t operand2,
90 uint32_t operand3) { 86 uint32_t operand3) {
91 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3)); 87 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3));
92 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3, 88 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3,
93 &latest_source_info_); 89 &latest_source_info_);
94 pipeline()->Write(&node); 90 pipeline()->Write(&node);
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 718
723 void BytecodeArrayBuilder::EnsureReturn() { 719 void BytecodeArrayBuilder::EnsureReturn() {
724 if (!return_seen_in_block_) { 720 if (!return_seen_in_block_) {
725 LoadUndefined(); 721 LoadUndefined();
726 Return(); 722 Return();
727 } 723 }
728 DCHECK(return_seen_in_block_); 724 DCHECK(return_seen_in_block_);
729 } 725 }
730 726
731 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, 727 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
732 Register receiver_args, 728 RegisterList args,
733 size_t receiver_args_count,
734 int feedback_slot, 729 int feedback_slot,
735 TailCallMode tail_call_mode) { 730 TailCallMode tail_call_mode) {
736 if (tail_call_mode == TailCallMode::kDisallow) { 731 if (tail_call_mode == TailCallMode::kDisallow) {
737 Output(Bytecode::kCall, RegisterOperand(callable), 732 Output(Bytecode::kCall, RegisterOperand(callable),
738 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count), 733 RegisterOperand(args.first_register()),
734 UnsignedOperand(args.register_count()),
739 UnsignedOperand(feedback_slot)); 735 UnsignedOperand(feedback_slot));
740 } else { 736 } else {
741 DCHECK(tail_call_mode == TailCallMode::kAllow); 737 DCHECK(tail_call_mode == TailCallMode::kAllow);
742 Output(Bytecode::kTailCall, RegisterOperand(callable), 738 Output(Bytecode::kTailCall, RegisterOperand(callable),
743 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count), 739 RegisterOperand(args.first_register()),
740 UnsignedOperand(args.register_count()),
744 UnsignedOperand(feedback_slot)); 741 UnsignedOperand(feedback_slot));
745 } 742 }
746 return *this; 743 return *this;
747 } 744 }
748 745
749 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, 746 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
750 Register first_arg, 747 RegisterList args,
751 size_t arg_count,
752 int feedback_slot_id) { 748 int feedback_slot_id) {
753 if (!first_arg.is_valid()) {
754 DCHECK_EQ(0u, arg_count);
755 first_arg = Register(0);
756 }
757 Output(Bytecode::kNew, RegisterOperand(constructor), 749 Output(Bytecode::kNew, RegisterOperand(constructor),
758 RegisterOperand(first_arg), UnsignedOperand(arg_count), 750 RegisterOperand(args.first_register()),
751 UnsignedOperand(args.register_count()),
759 UnsignedOperand(feedback_slot_id)); 752 UnsignedOperand(feedback_slot_id));
760 return *this; 753 return *this;
761 } 754 }
762 755
763 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( 756 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
764 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { 757 Runtime::FunctionId function_id, RegisterList args) {
765 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); 758 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size);
766 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); 759 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
767 if (!first_arg.is_valid()) {
768 DCHECK_EQ(0u, arg_count);
769 first_arg = Register(0);
770 }
771 Bytecode bytecode; 760 Bytecode bytecode;
772 uint32_t id; 761 uint32_t id;
773 if (IntrinsicsHelper::IsSupported(function_id)) { 762 if (IntrinsicsHelper::IsSupported(function_id)) {
774 bytecode = Bytecode::kInvokeIntrinsic; 763 bytecode = Bytecode::kInvokeIntrinsic;
775 id = static_cast<uint32_t>(IntrinsicsHelper::FromRuntimeId(function_id)); 764 id = static_cast<uint32_t>(IntrinsicsHelper::FromRuntimeId(function_id));
776 } else { 765 } else {
777 bytecode = Bytecode::kCallRuntime; 766 bytecode = Bytecode::kCallRuntime;
778 id = static_cast<uint32_t>(function_id); 767 id = static_cast<uint32_t>(function_id);
779 } 768 }
780 Output(bytecode, id, RegisterOperand(first_arg), UnsignedOperand(arg_count)); 769 Output(bytecode, id, RegisterOperand(args.first_register()),
770 UnsignedOperand(args.register_count()));
771 return *this;
772 }
773
774 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
775 Runtime::FunctionId function_id, Register arg) {
776 return CallRuntime(function_id, RegisterList(arg.index(), 1));
777 }
778
779 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
780 Runtime::FunctionId function_id) {
781 return CallRuntime(function_id, RegisterList());
782 }
783
784 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
785 Runtime::FunctionId function_id, RegisterList args, Register first_return) {
786 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size);
787 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
788 Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id),
789 RegisterOperand(args.first_register()),
790 UnsignedOperand(args.register_count()), RegisterOperand(first_return));
781 return *this; 791 return *this;
782 } 792 }
783 793
784 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( 794 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
785 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, 795 Runtime::FunctionId function_id, Register arg, Register first_return) {
786 Register first_return) { 796 return CallRuntimeForPair(function_id, RegisterList(arg.index(), 1),
787 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); 797 first_return);
788 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); 798 }
789 if (!first_arg.is_valid()) { 799
790 DCHECK_EQ(0u, arg_count); 800 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index,
791 first_arg = Register(0); 801 RegisterList args) {
792 } 802 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index),
793 Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id), 803 RegisterOperand(args.first_register()),
794 RegisterOperand(first_arg), UnsignedOperand(arg_count), 804 UnsignedOperand(args.register_count()));
795 RegisterOperand(first_return));
796 return *this; 805 return *this;
797 } 806 }
798 807
799 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(
800 int context_index, Register receiver_args, size_t receiver_args_count) {
801 Output(Bytecode::kCallJSRuntime, UnsignedOperand(context_index),
802 RegisterOperand(receiver_args), UnsignedOperand(receiver_args_count));
803 return *this;
804 }
805
806 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, 808 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
807 LanguageMode language_mode) { 809 LanguageMode language_mode) {
808 if (language_mode == SLOPPY) { 810 if (language_mode == SLOPPY) {
809 Output(Bytecode::kDeletePropertySloppy, RegisterOperand(object)); 811 Output(Bytecode::kDeletePropertySloppy, RegisterOperand(object));
810 } else { 812 } else {
811 DCHECK_EQ(language_mode, STRICT); 813 DCHECK_EQ(language_mode, STRICT);
812 Output(Bytecode::kDeletePropertyStrict, RegisterOperand(object)); 814 Output(Bytecode::kDeletePropertyStrict, RegisterOperand(object));
813 } 815 }
814 return *this; 816 return *this;
815 } 817 }
816 818
817 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { 819 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
818 return constant_array_builder()->Insert(object); 820 return constant_array_builder()->Insert(object);
819 } 821 }
820 822
821 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() { 823 size_t BytecodeArrayBuilder::AllocateConstantPoolEntry() {
822 return constant_array_builder()->AllocateEntry(); 824 return constant_array_builder()->AllocateEntry();
823 } 825 }
824 826
825 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry, 827 void BytecodeArrayBuilder::InsertConstantPoolEntryAt(size_t entry,
826 Handle<Object> object) { 828 Handle<Object> object) {
827 constant_array_builder()->InsertAllocatedEntry(entry, object); 829 constant_array_builder()->InsertAllocatedEntry(entry, object);
828 } 830 }
829 831
830 void BytecodeArrayBuilder::SetReturnPosition() { 832 void BytecodeArrayBuilder::SetReturnPosition() {
831 if (return_position_ == kNoSourcePosition) return; 833 if (return_position_ == kNoSourcePosition) return;
832 latest_source_info_.MakeStatementPosition(return_position_); 834 latest_source_info_.MakeStatementPosition(return_position_);
833 } 835 }
834 836
835 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
836 return temporary_register_allocator()->RegisterIsLive(reg);
837 }
838
839 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { 837 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const {
840 if (!reg.is_valid()) { 838 if (!reg.is_valid()) {
841 return false; 839 return false;
842 } 840 }
843 841
844 if (reg.is_current_context() || reg.is_function_closure() || 842 if (reg.is_current_context() || reg.is_function_closure() ||
845 reg.is_new_target()) { 843 reg.is_new_target()) {
846 return true; 844 return true;
847 } else if (reg.is_parameter()) { 845 } else if (reg.is_parameter()) {
848 int parameter_index = reg.ToParameterIndex(parameter_count()); 846 int parameter_index = reg.ToParameterIndex(parameter_count());
849 return parameter_index >= 0 && parameter_index < parameter_count(); 847 return parameter_index >= 0 && parameter_index < parameter_count();
850 } else if (reg.index() < fixed_register_count()) { 848 } else if (reg.index() < fixed_register_count()) {
851 return true; 849 return true;
852 } else { 850 } else {
853 return TemporaryRegisterIsLive(reg); 851 return register_allocator()->RegisterIsLive(reg);
854 } 852 }
855 } 853 }
856 854
857 bool BytecodeArrayBuilder::OperandsAreValid( 855 bool BytecodeArrayBuilder::OperandsAreValid(
858 Bytecode bytecode, int operand_count, uint32_t operand0, uint32_t operand1, 856 Bytecode bytecode, int operand_count, uint32_t operand0, uint32_t operand1,
859 uint32_t operand2, uint32_t operand3) const { 857 uint32_t operand2, uint32_t operand3) const {
860 if (Bytecodes::NumberOfOperands(bytecode) != operand_count) { 858 if (Bytecodes::NumberOfOperands(bytecode) != operand_count) {
861 return false; 859 return false;
862 } 860 }
863 861
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 } 932 }
935 } 933 }
936 } 934 }
937 935
938 return true; 936 return true;
939 } 937 }
940 938
941 } // namespace interpreter 939 } // namespace interpreter
942 } // namespace internal 940 } // namespace internal
943 } // namespace v8 941 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698