• 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 #include "src/interpreter/bytecode-register.h"
6 
7 namespace v8 {
8 namespace internal {
9 namespace interpreter {
10 
11 static const int kLastParamRegisterIndex =
12     (InterpreterFrameConstants::kRegisterFileFromFp -
13      InterpreterFrameConstants::kLastParamFromFp) /
14     kPointerSize;
15 static const int kFunctionClosureRegisterIndex =
16     (InterpreterFrameConstants::kRegisterFileFromFp -
17      StandardFrameConstants::kFunctionOffset) /
18     kPointerSize;
19 static const int kCurrentContextRegisterIndex =
20     (InterpreterFrameConstants::kRegisterFileFromFp -
21      StandardFrameConstants::kContextOffset) /
22     kPointerSize;
23 static const int kNewTargetRegisterIndex =
24     (InterpreterFrameConstants::kRegisterFileFromFp -
25      InterpreterFrameConstants::kNewTargetFromFp) /
26     kPointerSize;
27 static const int kBytecodeArrayRegisterIndex =
28     (InterpreterFrameConstants::kRegisterFileFromFp -
29      InterpreterFrameConstants::kBytecodeArrayFromFp) /
30     kPointerSize;
31 static const int kBytecodeOffsetRegisterIndex =
32     (InterpreterFrameConstants::kRegisterFileFromFp -
33      InterpreterFrameConstants::kBytecodeOffsetFromFp) /
34     kPointerSize;
35 static const int kCallerPCOffsetRegisterIndex =
36     (InterpreterFrameConstants::kRegisterFileFromFp -
37      InterpreterFrameConstants::kCallerPCOffsetFromFp) /
38     kPointerSize;
39 
FromParameterIndex(int index,int parameter_count)40 Register Register::FromParameterIndex(int index, int parameter_count) {
41   DCHECK_GE(index, 0);
42   DCHECK_LT(index, parameter_count);
43   int register_index = kLastParamRegisterIndex - parameter_count + index + 1;
44   DCHECK_LT(register_index, 0);
45   return Register(register_index);
46 }
47 
ToParameterIndex(int parameter_count) const48 int Register::ToParameterIndex(int parameter_count) const {
49   DCHECK(is_parameter());
50   return index() - kLastParamRegisterIndex + parameter_count - 1;
51 }
52 
function_closure()53 Register Register::function_closure() {
54   return Register(kFunctionClosureRegisterIndex);
55 }
56 
is_function_closure() const57 bool Register::is_function_closure() const {
58   return index() == kFunctionClosureRegisterIndex;
59 }
60 
current_context()61 Register Register::current_context() {
62   return Register(kCurrentContextRegisterIndex);
63 }
64 
is_current_context() const65 bool Register::is_current_context() const {
66   return index() == kCurrentContextRegisterIndex;
67 }
68 
new_target()69 Register Register::new_target() { return Register(kNewTargetRegisterIndex); }
70 
is_new_target() const71 bool Register::is_new_target() const {
72   return index() == kNewTargetRegisterIndex;
73 }
74 
bytecode_array()75 Register Register::bytecode_array() {
76   return Register(kBytecodeArrayRegisterIndex);
77 }
78 
is_bytecode_array() const79 bool Register::is_bytecode_array() const {
80   return index() == kBytecodeArrayRegisterIndex;
81 }
82 
bytecode_offset()83 Register Register::bytecode_offset() {
84   return Register(kBytecodeOffsetRegisterIndex);
85 }
86 
is_bytecode_offset() const87 bool Register::is_bytecode_offset() const {
88   return index() == kBytecodeOffsetRegisterIndex;
89 }
90 
91 // static
virtual_accumulator()92 Register Register::virtual_accumulator() {
93   return Register(kCallerPCOffsetRegisterIndex);
94 }
95 
SizeOfOperand() const96 OperandSize Register::SizeOfOperand() const {
97   int32_t operand = ToOperand();
98   if (operand >= kMinInt8 && operand <= kMaxInt8) {
99     return OperandSize::kByte;
100   } else if (operand >= kMinInt16 && operand <= kMaxInt16) {
101     return OperandSize::kShort;
102   } else {
103     return OperandSize::kQuad;
104   }
105 }
106 
AreContiguous(Register reg1,Register reg2,Register reg3,Register reg4,Register reg5)107 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3,
108                              Register reg4, Register reg5) {
109   if (reg1.index() + 1 != reg2.index()) {
110     return false;
111   }
112   if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) {
113     return false;
114   }
115   if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) {
116     return false;
117   }
118   if (reg5.is_valid() && reg4.index() + 1 != reg5.index()) {
119     return false;
120   }
121   return true;
122 }
123 
ToString(int parameter_count) const124 std::string Register::ToString(int parameter_count) const {
125   if (is_current_context()) {
126     return std::string("<context>");
127   } else if (is_function_closure()) {
128     return std::string("<closure>");
129   } else if (is_new_target()) {
130     return std::string("<new.target>");
131   } else if (is_parameter()) {
132     int parameter_index = ToParameterIndex(parameter_count);
133     if (parameter_index == 0) {
134       return std::string("<this>");
135     } else {
136       std::ostringstream s;
137       s << "a" << parameter_index - 1;
138       return s.str();
139     }
140   } else {
141     std::ostringstream s;
142     s << "r" << index();
143     return s.str();
144   }
145 }
146 
147 }  // namespace interpreter
148 }  // namespace internal
149 }  // namespace v8
150