Line data Source code
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 :
40 5282934 : Register Register::FromParameterIndex(int index, int parameter_count) {
41 : DCHECK_GE(index, 0);
42 : DCHECK_LT(index, parameter_count);
43 5282934 : int register_index = kLastParamRegisterIndex - parameter_count + index + 1;
44 : DCHECK_LT(register_index, 0);
45 5282934 : return Register(register_index);
46 : }
47 :
48 968550 : int Register::ToParameterIndex(int parameter_count) const {
49 : DCHECK(is_parameter());
50 968551 : return index() - kLastParamRegisterIndex + parameter_count - 1;
51 : }
52 :
53 426682 : Register Register::function_closure() {
54 426682 : return Register(kFunctionClosureRegisterIndex);
55 : }
56 :
57 6116016 : bool Register::is_function_closure() const {
58 6116016 : return index() == kFunctionClosureRegisterIndex;
59 : }
60 :
61 2650574 : Register Register::current_context() {
62 2650574 : return Register(kCurrentContextRegisterIndex);
63 : }
64 :
65 11509513 : bool Register::is_current_context() const {
66 11509513 : return index() == kCurrentContextRegisterIndex;
67 : }
68 :
69 145298 : Register Register::new_target() { return Register(kNewTargetRegisterIndex); }
70 :
71 6027984 : bool Register::is_new_target() const {
72 6027984 : return index() == kNewTargetRegisterIndex;
73 : }
74 :
75 19178 : Register Register::bytecode_array() {
76 19178 : return Register(kBytecodeArrayRegisterIndex);
77 : }
78 :
79 0 : bool Register::is_bytecode_array() const {
80 0 : return index() == kBytecodeArrayRegisterIndex;
81 : }
82 :
83 40168 : Register Register::bytecode_offset() {
84 40168 : return Register(kBytecodeOffsetRegisterIndex);
85 : }
86 :
87 0 : bool Register::is_bytecode_offset() const {
88 0 : return index() == kBytecodeOffsetRegisterIndex;
89 : }
90 :
91 : // static
92 2104165 : Register Register::virtual_accumulator() {
93 2104165 : return Register(kCallerPCOffsetRegisterIndex);
94 : }
95 :
96 0 : OperandSize Register::SizeOfOperand() const {
97 : int32_t operand = ToOperand();
98 0 : if (operand >= kMinInt8 && operand <= kMaxInt8) {
99 : return OperandSize::kByte;
100 0 : } else if (operand >= kMinInt16 && operand <= kMaxInt16) {
101 : return OperandSize::kShort;
102 : } else {
103 0 : return OperandSize::kQuad;
104 : }
105 : }
106 :
107 0 : bool Register::AreContiguous(Register reg1, Register reg2, Register reg3,
108 : Register reg4, Register reg5) {
109 0 : if (reg1.index() + 1 != reg2.index()) {
110 : return false;
111 : }
112 0 : if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) {
113 : return false;
114 : }
115 0 : if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) {
116 : return false;
117 : }
118 0 : if (reg5.is_valid() && reg4.index() + 1 != reg5.index()) {
119 : return false;
120 : }
121 0 : return true;
122 : }
123 :
124 40 : std::string Register::ToString(int parameter_count) const {
125 40 : if (is_current_context()) {
126 0 : return std::string("<context>");
127 40 : } else if (is_function_closure()) {
128 0 : return std::string("<closure>");
129 40 : } else if (is_new_target()) {
130 0 : return std::string("<new.target>");
131 40 : } else if (is_parameter()) {
132 : int parameter_index = ToParameterIndex(parameter_count);
133 1 : if (parameter_index == 0) {
134 0 : return std::string("<this>");
135 : } else {
136 1 : std::ostringstream s;
137 1 : s << "a" << parameter_index - 1;
138 1 : return s.str();
139 : }
140 : } else {
141 39 : std::ostringstream s;
142 39 : s << "r" << index();
143 39 : return s.str();
144 : }
145 : }
146 :
147 : } // namespace interpreter
148 : } // namespace internal
149 : } // namespace v8
|