• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/common/globals.h"
13 #include "src/execution/frame-constants.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   constexpr 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);
30   int ToParameterIndex() 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 the register for the argument count.
52   static Register argument_count();
53 
54   // Returns a register that can be used to represent the accumulator
55   // within code in the interpreter, but should never be emitted in
56   // bytecode.
57   static Register virtual_accumulator();
58 
59   OperandSize SizeOfOperand() const;
60 
ToOperand()61   constexpr int32_t ToOperand() const {
62     return kRegisterFileStartOffset - index_;
63   }
FromOperand(int32_t operand)64   static Register FromOperand(int32_t operand) {
65     return Register(kRegisterFileStartOffset - operand);
66   }
67 
FromShortStar(Bytecode bytecode)68   static constexpr Register FromShortStar(Bytecode bytecode) {
69     DCHECK(Bytecodes::IsShortStar(bytecode));
70     return Register(static_cast<int>(Bytecode::kStar0) -
71                     static_cast<int>(bytecode));
72   }
73 
TryToShortStar()74   const base::Optional<Bytecode> TryToShortStar() const {
75     if (index() >= 0 && index() < Bytecodes::kShortStarCount) {
76       Bytecode bytecode =
77           static_cast<Bytecode>(static_cast<int>(Bytecode::kStar0) - index());
78       DCHECK_GE(bytecode, Bytecode::kFirstShortStar);
79       DCHECK_LE(bytecode, Bytecode::kLastShortStar);
80       return bytecode;
81     }
82     return {};
83   }
84 
85   static bool AreContiguous(Register reg1, Register reg2,
86                             Register reg3 = invalid_value(),
87                             Register reg4 = invalid_value(),
88                             Register reg5 = invalid_value());
89 
90   std::string ToString() const;
91 
92   bool operator==(const Register& other) const {
93     return index() == other.index();
94   }
95   bool operator!=(const Register& other) const {
96     return index() != other.index();
97   }
98   bool operator<(const Register& other) const {
99     return index() < other.index();
100   }
101   bool operator<=(const Register& other) const {
102     return index() <= other.index();
103   }
104   bool operator>(const Register& other) const {
105     return index() > other.index();
106   }
107   bool operator>=(const Register& other) const {
108     return index() >= other.index();
109   }
110 
111  private:
112   DISALLOW_NEW_AND_DELETE()
113 
114   static const int kInvalidIndex = kMaxInt;
115   static const int kRegisterFileStartOffset =
116       InterpreterFrameConstants::kRegisterFileFromFp / kSystemPointerSize;
117 
118   int index_;
119 };
120 
121 class RegisterList {
122  public:
RegisterList()123   RegisterList()
124       : first_reg_index_(Register::invalid_value().index()),
125         register_count_(0) {}
RegisterList(Register r)126   explicit RegisterList(Register r) : RegisterList(r.index(), 1) {}
127 
128   // Returns a new RegisterList which is a truncated version of this list, with
129   // |count| registers.
Truncate(int new_count)130   const RegisterList Truncate(int new_count) {
131     DCHECK_GE(new_count, 0);
132     DCHECK_LT(new_count, register_count_);
133     return RegisterList(first_reg_index_, new_count);
134   }
PopLeft()135   const RegisterList PopLeft() {
136     DCHECK_GE(register_count_, 0);
137     return RegisterList(first_reg_index_ + 1, register_count_ - 1);
138   }
139 
140   const Register operator[](size_t i) const {
141     DCHECK_LT(static_cast<int>(i), register_count_);
142     return Register(first_reg_index_ + static_cast<int>(i));
143   }
144 
first_register()145   const Register first_register() const {
146     return (register_count() == 0) ? Register(0) : (*this)[0];
147   }
148 
last_register()149   const Register last_register() const {
150     return (register_count() == 0) ? Register(0) : (*this)[register_count_ - 1];
151   }
152 
register_count()153   int register_count() const { return register_count_; }
154 
155  private:
156   friend class BytecodeRegisterAllocator;
157   friend class BytecodeDecoder;
158   friend class InterpreterTester;
159   friend class BytecodeUtils;
160   friend class BytecodeArrayIterator;
161 
RegisterList(int first_reg_index,int register_count)162   RegisterList(int first_reg_index, int register_count)
163       : first_reg_index_(first_reg_index), register_count_(register_count) {}
164 
165   // Increases the size of the register list by one.
IncrementRegisterCount()166   void IncrementRegisterCount() { register_count_++; }
167 
168   int first_reg_index_;
169   int register_count_;
170 };
171 
172 }  // namespace interpreter
173 }  // namespace internal
174 }  // namespace v8
175 
176 #endif  // V8_INTERPRETER_BYTECODE_REGISTER_H_
177