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 3 // found in the LICENSE file. 4 5 #ifndef V8_INTERPRETER_BYTECODE_REGISTER_H_ 6 #define V8_INTERPRETER_BYTECODE_REGISTER_H_ 7 8 #include "src/interpreter/bytecodes.h" 9 10 #include "src/frames.h" 11 #include "src/globals.h" 12 13 namespace v8 { 14 namespace internal { 15 namespace interpreter { 16 17 // An interpreter Register which is located in the function's Register file 18 // in its stack-frame. Register hold parameters, this, and expression values. 19 class V8_EXPORT_PRIVATE Register final { 20 public: index_(index)21 explicit Register(int index = kInvalidIndex) : index_(index) {} 22 index()23 int index() const { return index_; } is_parameter()24 bool is_parameter() const { return index() < 0; } is_valid()25 bool is_valid() const { return index_ != kInvalidIndex; } 26 27 static Register FromParameterIndex(int index, int parameter_count); 28 int ToParameterIndex(int parameter_count) const; 29 30 // Returns an invalid register. invalid_value()31 static Register invalid_value() { return Register(); } 32 33 // Returns the register for the function's closure object. 34 static Register function_closure(); 35 bool is_function_closure() const; 36 37 // Returns the register which holds the current context object. 38 static Register current_context(); 39 bool is_current_context() const; 40 41 // Returns the register for the incoming new target value. 42 static Register new_target(); 43 bool is_new_target() const; 44 45 // Returns the register for the bytecode array. 46 static Register bytecode_array(); 47 bool is_bytecode_array() const; 48 49 // Returns the register for the saved bytecode offset. 50 static Register bytecode_offset(); 51 bool is_bytecode_offset() const; 52 53 // Returns a register that can be used to represent the accumulator 54 // within code in the interpreter, but should never be emitted in 55 // bytecode. 56 static Register virtual_accumulator(); 57 58 OperandSize SizeOfOperand() const; 59 ToOperand()60 int32_t ToOperand() const { return kRegisterFileStartOffset - index_; } FromOperand(int32_t operand)61 static Register FromOperand(int32_t operand) { 62 return Register(kRegisterFileStartOffset - operand); 63 } 64 65 static bool AreContiguous(Register reg1, Register reg2, 66 Register reg3 = Register(), 67 Register reg4 = Register(), 68 Register reg5 = Register()); 69 70 std::string ToString(int parameter_count) const; 71 72 bool operator==(const Register& other) const { 73 return index() == other.index(); 74 } 75 bool operator!=(const Register& other) const { 76 return index() != other.index(); 77 } 78 bool operator<(const Register& other) const { 79 return index() < other.index(); 80 } 81 bool operator<=(const Register& other) const { 82 return index() <= other.index(); 83 } 84 bool operator>(const Register& other) const { 85 return index() > other.index(); 86 } 87 bool operator>=(const Register& other) const { 88 return index() >= other.index(); 89 } 90 91 private: 92 static const int kInvalidIndex = kMaxInt; 93 static const int kRegisterFileStartOffset = 94 InterpreterFrameConstants::kRegisterFileFromFp / kPointerSize; 95 96 void* operator new(size_t size) = delete; 97 void operator delete(void* p) = delete; 98 99 int index_; 100 }; 101 102 class RegisterList { 103 public: RegisterList()104 RegisterList() : first_reg_index_(Register().index()), register_count_(0) {} RegisterList(int first_reg_index,int register_count)105 RegisterList(int first_reg_index, int register_count) 106 : first_reg_index_(first_reg_index), register_count_(register_count) {} 107 108 // Increases the size of the register list by one. IncrementRegisterCount()109 void IncrementRegisterCount() { register_count_++; } 110 111 // Returns a new RegisterList which is a truncated version of this list, with 112 // |count| registers. Truncate(int new_count)113 const RegisterList Truncate(int new_count) { 114 DCHECK_GE(new_count, 0); 115 DCHECK_LT(new_count, register_count_); 116 return RegisterList(first_reg_index_, new_count); 117 } 118 119 const Register operator[](size_t i) const { 120 DCHECK_LT(static_cast<int>(i), register_count_); 121 return Register(first_reg_index_ + static_cast<int>(i)); 122 } 123 first_register()124 const Register first_register() const { 125 return (register_count() == 0) ? Register(0) : (*this)[0]; 126 } 127 last_register()128 const Register last_register() const { 129 return (register_count() == 0) ? Register(0) : (*this)[register_count_ - 1]; 130 } 131 register_count()132 int register_count() const { return register_count_; } 133 134 private: 135 int first_reg_index_; 136 int register_count_; 137 }; 138 139 } // namespace interpreter 140 } // namespace internal 141 } // namespace v8 142 143 #endif // V8_INTERPRETER_BYTECODE_REGISTER_H_ 144