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