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/bytecode-array-builder.h" | 5 #include "src/interpreter/bytecode-array-builder.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace interpreter { | 9 namespace interpreter { |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... |
25 temporary_register_next_(0) {} | 25 temporary_register_next_(0) {} |
26 | 26 |
27 | 27 |
28 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { | 28 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { |
29 local_register_count_ = number_of_locals; | 29 local_register_count_ = number_of_locals; |
30 DCHECK_LE(context_register_count_, 0); | 30 DCHECK_LE(context_register_count_, 0); |
31 temporary_register_next_ = local_register_count_; | 31 temporary_register_next_ = local_register_count_; |
32 } | 32 } |
33 | 33 |
34 | 34 |
35 int BytecodeArrayBuilder::locals_count() const { return local_register_count_; } | |
36 | |
37 | |
38 void BytecodeArrayBuilder::set_parameter_count(int number_of_parameters) { | 35 void BytecodeArrayBuilder::set_parameter_count(int number_of_parameters) { |
39 parameter_count_ = number_of_parameters; | 36 parameter_count_ = number_of_parameters; |
40 } | 37 } |
41 | 38 |
42 | 39 |
43 int BytecodeArrayBuilder::parameter_count() const { return parameter_count_; } | |
44 | |
45 | |
46 void BytecodeArrayBuilder::set_context_count(int number_of_contexts) { | 40 void BytecodeArrayBuilder::set_context_count(int number_of_contexts) { |
47 context_register_count_ = number_of_contexts; | 41 context_register_count_ = number_of_contexts; |
48 DCHECK_GE(local_register_count_, 0); | 42 DCHECK_GE(local_register_count_, 0); |
49 temporary_register_next_ = local_register_count_ + context_register_count_; | 43 temporary_register_next_ = local_register_count_ + context_register_count_; |
50 } | 44 } |
51 | 45 |
52 | 46 |
53 Register BytecodeArrayBuilder::first_context_register() const { | 47 Register BytecodeArrayBuilder::first_context_register() const { |
54 DCHECK_GT(context_register_count_, 0); | 48 DCHECK_GT(context_register_count_, 0); |
55 return Register(local_register_count_); | 49 return Register(local_register_count_); |
56 } | 50 } |
57 | 51 |
58 | 52 |
59 Register BytecodeArrayBuilder::last_context_register() const { | 53 Register BytecodeArrayBuilder::last_context_register() const { |
60 DCHECK_GT(context_register_count_, 0); | 54 DCHECK_GT(context_register_count_, 0); |
61 return Register(local_register_count_ + context_register_count_ - 1); | 55 return Register(local_register_count_ + context_register_count_ - 1); |
62 } | 56 } |
63 | 57 |
64 | 58 |
65 Register BytecodeArrayBuilder::Parameter(int parameter_index) const { | 59 Register BytecodeArrayBuilder::Parameter(int parameter_index) const { |
66 DCHECK_GE(parameter_index, 0); | 60 DCHECK_GE(parameter_index, 0); |
67 DCHECK_LT(parameter_index, parameter_count_); | 61 return Register::FromParameterIndex(parameter_index, parameter_count()); |
68 return Register::FromParameterIndex(parameter_index, parameter_count_); | |
69 } | 62 } |
70 | 63 |
71 | 64 |
72 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { | 65 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { |
73 DCHECK_EQ(bytecode_generated_, false); | 66 DCHECK_EQ(bytecode_generated_, false); |
74 DCHECK_GE(parameter_count_, 0); | |
75 DCHECK_GE(local_register_count_, 0); | |
76 | 67 |
77 EnsureReturn(); | 68 EnsureReturn(); |
78 | 69 |
79 int bytecode_size = static_cast<int>(bytecodes_.size()); | 70 int bytecode_size = static_cast<int>(bytecodes_.size()); |
80 int register_count = local_register_count_ + temporary_register_count_; | 71 int register_count = fixed_register_count() + temporary_register_count_; |
81 int frame_size = register_count * kPointerSize; | 72 int frame_size = register_count * kPointerSize; |
82 | 73 |
83 Factory* factory = isolate_->factory(); | 74 Factory* factory = isolate_->factory(); |
84 int constants_count = static_cast<int>(constants_.size()); | 75 int constants_count = static_cast<int>(constants_.size()); |
85 Handle<FixedArray> constant_pool = | 76 Handle<FixedArray> constant_pool = |
86 factory->NewFixedArray(constants_count, TENURED); | 77 factory->NewFixedArray(constants_count, TENURED); |
87 for (int i = 0; i < constants_count; i++) { | 78 for (int i = 0; i < constants_count; i++) { |
88 constant_pool->set(i, *constants_[i]); | 79 constant_pool->set(i, *constants_[i]); |
89 } | 80 } |
90 | 81 |
91 Handle<BytecodeArray> output = | 82 Handle<BytecodeArray> output = |
92 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, | 83 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, |
93 parameter_count_, constant_pool); | 84 parameter_count(), constant_pool); |
94 bytecode_generated_ = true; | 85 bytecode_generated_ = true; |
95 return output; | 86 return output; |
96 } | 87 } |
97 | 88 |
98 | 89 |
99 template <size_t N> | 90 template <size_t N> |
100 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { | 91 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { |
101 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N)); | 92 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N)); |
102 last_bytecode_start_ = bytecodes()->size(); | 93 last_bytecode_start_ = bytecodes()->size(); |
103 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 94 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 if (FitsInIdx8Operand(slot_index)) { | 275 if (FitsInIdx8Operand(slot_index)) { |
285 Output(Bytecode::kLdaContextSlot, context.ToOperand(), | 276 Output(Bytecode::kLdaContextSlot, context.ToOperand(), |
286 static_cast<uint8_t>(slot_index)); | 277 static_cast<uint8_t>(slot_index)); |
287 } else { | 278 } else { |
288 UNIMPLEMENTED(); | 279 UNIMPLEMENTED(); |
289 } | 280 } |
290 return *this; | 281 return *this; |
291 } | 282 } |
292 | 283 |
293 | 284 |
| 285 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, |
| 286 int slot_index) { |
| 287 DCHECK(slot_index >= 0); |
| 288 if (FitsInIdx8Operand(slot_index)) { |
| 289 Output(Bytecode::kStaContextSlot, context.ToOperand(), |
| 290 static_cast<uint8_t>(slot_index)); |
| 291 } else { |
| 292 UNIMPLEMENTED(); |
| 293 } |
| 294 return *this; |
| 295 } |
| 296 |
| 297 |
294 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 298 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( |
295 Register object, int feedback_slot, LanguageMode language_mode) { | 299 Register object, int feedback_slot, LanguageMode language_mode) { |
296 Bytecode bytecode = BytecodeForLoadIC(language_mode); | 300 Bytecode bytecode = BytecodeForLoadIC(language_mode); |
297 if (FitsInIdx8Operand(feedback_slot)) { | 301 if (FitsInIdx8Operand(feedback_slot)) { |
298 Output(bytecode, object.ToOperand(), static_cast<uint8_t>(feedback_slot)); | 302 Output(bytecode, object.ToOperand(), static_cast<uint8_t>(feedback_slot)); |
299 } else { | 303 } else { |
300 UNIMPLEMENTED(); | 304 UNIMPLEMENTED(); |
301 } | 305 } |
302 return *this; | 306 return *this; |
303 } | 307 } |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 entry = constants_map_.Get(object); | 627 entry = constants_map_.Get(object); |
624 *entry = constants_.size(); | 628 *entry = constants_.size(); |
625 constants_.push_back(object); | 629 constants_.push_back(object); |
626 } | 630 } |
627 DCHECK(constants_[*entry].is_identical_to(object)); | 631 DCHECK(constants_[*entry].is_identical_to(object)); |
628 return *entry; | 632 return *entry; |
629 } | 633 } |
630 | 634 |
631 | 635 |
632 int BytecodeArrayBuilder::BorrowTemporaryRegister() { | 636 int BytecodeArrayBuilder::BorrowTemporaryRegister() { |
633 DCHECK_GE(local_register_count_, 0); | |
634 int temporary_reg_index = temporary_register_next_++; | 637 int temporary_reg_index = temporary_register_next_++; |
635 int count = temporary_register_next_ - local_register_count_; | 638 int count = temporary_register_next_ - fixed_register_count(); |
636 if (count > temporary_register_count_) { | 639 if (count > temporary_register_count_) { |
637 temporary_register_count_ = count; | 640 temporary_register_count_ = count; |
638 } | 641 } |
639 return temporary_reg_index; | 642 return temporary_reg_index; |
640 } | 643 } |
641 | 644 |
642 | 645 |
643 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) { | 646 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) { |
644 DCHECK_EQ(reg_index, temporary_register_next_ - 1); | 647 DCHECK_EQ(reg_index, temporary_register_next_ - 1); |
645 temporary_register_next_ = reg_index; | 648 temporary_register_next_ = reg_index; |
(...skipping 10 matching lines...) Expand all Loading... |
656 return static_cast<uint16_t>(operand_value) == operand_value; | 659 return static_cast<uint16_t>(operand_value) == operand_value; |
657 case OperandType::kCount8: | 660 case OperandType::kCount8: |
658 case OperandType::kImm8: | 661 case OperandType::kImm8: |
659 case OperandType::kIdx8: | 662 case OperandType::kIdx8: |
660 return static_cast<uint8_t>(operand_value) == operand_value; | 663 return static_cast<uint8_t>(operand_value) == operand_value; |
661 case OperandType::kReg8: { | 664 case OperandType::kReg8: { |
662 Register reg = Register::FromOperand(static_cast<uint8_t>(operand_value)); | 665 Register reg = Register::FromOperand(static_cast<uint8_t>(operand_value)); |
663 if (reg.is_function_context() || reg.is_function_closure()) { | 666 if (reg.is_function_context() || reg.is_function_closure()) { |
664 return true; | 667 return true; |
665 } else if (reg.is_parameter()) { | 668 } else if (reg.is_parameter()) { |
666 int parameter_index = reg.ToParameterIndex(parameter_count_); | 669 int parameter_index = reg.ToParameterIndex(parameter_count()); |
667 return parameter_index >= 0 && parameter_index < parameter_count_; | 670 return parameter_index >= 0 && parameter_index < parameter_count(); |
668 } else { | 671 } else { |
669 return (reg.index() >= 0 && reg.index() < temporary_register_next_); | 672 return (reg.index() >= 0 && reg.index() < temporary_register_next_); |
670 } | 673 } |
671 } | 674 } |
672 } | 675 } |
673 UNREACHABLE(); | 676 UNREACHABLE(); |
674 return false; | 677 return false; |
675 } | 678 } |
676 | 679 |
677 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { | 680 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 | 848 |
846 Register TemporaryRegisterScope::NewRegister() { | 849 Register TemporaryRegisterScope::NewRegister() { |
847 count_++; | 850 count_++; |
848 last_register_index_ = builder_->BorrowTemporaryRegister(); | 851 last_register_index_ = builder_->BorrowTemporaryRegister(); |
849 return Register(last_register_index_); | 852 return Register(last_register_index_); |
850 } | 853 } |
851 | 854 |
852 } // namespace interpreter | 855 } // namespace interpreter |
853 } // namespace internal | 856 } // namespace internal |
854 } // namespace v8 | 857 } // namespace v8 |
OLD | NEW |