Home | History | Annotate | Download | only in interpreter
      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:
     21   explicit Register(int index = kInvalidIndex) : index_(index) {}
     22 
     23   int index() const { return index_; }
     24   bool is_parameter() const { return index() < 0; }
     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.
     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 
     60   int32_t ToOperand() const { return kRegisterFileStartOffset - index_; }
     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:
    104   RegisterList() : first_reg_index_(Register().index()), register_count_(0) {}
    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.
    109   void IncrementRegisterCount() { register_count_++; }
    110 
    111   // Returns a new RegisterList which is a truncated version of this list, with
    112   // |count| registers.
    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 
    124   const Register first_register() const {
    125     return (register_count() == 0) ? Register(0) : (*this)[0];
    126   }
    127 
    128   const Register last_register() const {
    129     return (register_count() == 0) ? Register(0) : (*this)[register_count_ - 1];
    130   }
    131 
    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