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/bytecodes.h"
6 :
7 : #include <iomanip>
8 :
9 : #include "src/base/bits.h"
10 : #include "src/interpreter/bytecode-traits.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 : namespace interpreter {
15 :
16 : // clang-format off
17 : const OperandType* const Bytecodes::kOperandTypes[] = {
18 : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandTypes,
19 : BYTECODE_LIST(ENTRY)
20 : #undef ENTRY
21 : };
22 :
23 : const OperandTypeInfo* const Bytecodes::kOperandTypeInfos[] = {
24 : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandTypeInfos,
25 : BYTECODE_LIST(ENTRY)
26 : #undef ENTRY
27 : };
28 :
29 : const int Bytecodes::kOperandCount[] = {
30 : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandCount,
31 : BYTECODE_LIST(ENTRY)
32 : #undef ENTRY
33 : };
34 :
35 : const AccumulatorUse Bytecodes::kAccumulatorUse[] = {
36 : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kAccumulatorUse,
37 : BYTECODE_LIST(ENTRY)
38 : #undef ENTRY
39 : };
40 :
41 : const int Bytecodes::kBytecodeSizes[3][kBytecodeCount] = {
42 : {
43 : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kSingleScaleSize,
44 : BYTECODE_LIST(ENTRY)
45 : #undef ENTRY
46 : }, {
47 : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kDoubleScaleSize,
48 : BYTECODE_LIST(ENTRY)
49 : #undef ENTRY
50 : }, {
51 : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleSize,
52 : BYTECODE_LIST(ENTRY)
53 : #undef ENTRY
54 : }
55 : };
56 :
57 : const OperandSize* const Bytecodes::kOperandSizes[3][kBytecodeCount] = {
58 : {
59 : #define ENTRY(Name, ...) \
60 : BytecodeTraits<__VA_ARGS__>::kSingleScaleOperandSizes,
61 : BYTECODE_LIST(ENTRY)
62 : #undef ENTRY
63 : }, {
64 : #define ENTRY(Name, ...) \
65 : BytecodeTraits<__VA_ARGS__>::kDoubleScaleOperandSizes,
66 : BYTECODE_LIST(ENTRY)
67 : #undef ENTRY
68 : }, {
69 : #define ENTRY(Name, ...) \
70 : BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleOperandSizes,
71 : BYTECODE_LIST(ENTRY)
72 : #undef ENTRY
73 : }
74 : };
75 :
76 : const OperandSize
77 : Bytecodes::kOperandKindSizes[3][BytecodeOperands::kOperandTypeCount] = {
78 : {
79 : #define ENTRY(Name, ...) \
80 : OperandScaler<OperandType::k##Name, OperandScale::kSingle>::kOperandSize,
81 : OPERAND_TYPE_LIST(ENTRY)
82 : #undef ENTRY
83 : }, {
84 : #define ENTRY(Name, ...) \
85 : OperandScaler<OperandType::k##Name, OperandScale::kDouble>::kOperandSize,
86 : OPERAND_TYPE_LIST(ENTRY)
87 : #undef ENTRY
88 : }, {
89 : #define ENTRY(Name, ...) \
90 : OperandScaler<OperandType::k##Name, OperandScale::kQuadruple>::kOperandSize,
91 : OPERAND_TYPE_LIST(ENTRY)
92 : #undef ENTRY
93 : }
94 : };
95 : // clang-format on
96 :
97 : // static
98 158886 : const char* Bytecodes::ToString(Bytecode bytecode) {
99 158886 : switch (bytecode) {
100 : #define CASE(Name, ...) \
101 : case Bytecode::k##Name: \
102 : return #Name;
103 7402 : BYTECODE_LIST(CASE)
104 : #undef CASE
105 : }
106 0 : UNREACHABLE();
107 : }
108 :
109 : // static
110 23491 : std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale) {
111 : static const char kSeparator = '.';
112 :
113 23491 : std::string value(ToString(bytecode));
114 23491 : if (operand_scale > OperandScale::kSingle) {
115 14548 : Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale);
116 14548 : std::string suffix = ToString(prefix_bytecode);
117 14548 : return value.append(1, kSeparator).append(suffix);
118 : } else {
119 : return value;
120 : }
121 : }
122 :
123 : // static
124 3677185 : Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
125 : DCHECK(!IsDebugBreak(bytecode));
126 3677185 : if (bytecode == Bytecode::kWide) {
127 : return Bytecode::kDebugBreakWide;
128 : }
129 2831007 : if (bytecode == Bytecode::kExtraWide) {
130 : return Bytecode::kDebugBreakExtraWide;
131 : }
132 : int bytecode_size = Size(bytecode, OperandScale::kSingle);
133 : #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name) \
134 : if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \
135 : return Bytecode::k##Name; \
136 : }
137 2820566 : DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
138 : #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
139 0 : UNREACHABLE();
140 : }
141 :
142 : // static
143 34017338 : int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
144 : OperandScale operand_scale) {
145 : DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
146 : // TODO(oth): restore this to a statically determined constant.
147 : int offset = 1;
148 49324722 : for (int operand_index = 0; operand_index < i; ++operand_index) {
149 : OperandSize operand_size =
150 15307400 : GetOperandSize(bytecode, operand_index, operand_scale);
151 15307384 : offset += static_cast<int>(operand_size);
152 : }
153 34017322 : return offset;
154 : }
155 :
156 : // static
157 0 : Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) {
158 0 : switch (bytecode) {
159 : case Bytecode::kJumpIfToBooleanTrue:
160 : return Bytecode::kJumpIfTrue;
161 : case Bytecode::kJumpIfToBooleanFalse:
162 0 : return Bytecode::kJumpIfFalse;
163 : case Bytecode::kJumpIfToBooleanTrueConstant:
164 0 : return Bytecode::kJumpIfTrueConstant;
165 : case Bytecode::kJumpIfToBooleanFalseConstant:
166 0 : return Bytecode::kJumpIfFalseConstant;
167 : default:
168 : break;
169 : }
170 0 : UNREACHABLE();
171 : }
172 :
173 : // static
174 3704745 : bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
175 3704745 : switch (bytecode) {
176 : #define CASE(Name, ...) case Bytecode::k##Name:
177 : DEBUG_BREAK_BYTECODE_LIST(CASE);
178 : #undef CASE
179 : return true;
180 : default:
181 : break;
182 : }
183 3677417 : return false;
184 : }
185 :
186 : // static
187 121256 : bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
188 121256 : switch (operand_type) {
189 : #define CASE(Name, _) \
190 : case OperandType::k##Name: \
191 : return true;
192 : REGISTER_OPERAND_TYPE_LIST(CASE)
193 : #undef CASE
194 : #define CASE(Name, _) \
195 : case OperandType::k##Name: \
196 : break;
197 : NON_REGISTER_OPERAND_TYPE_LIST(CASE)
198 : #undef CASE
199 : }
200 63504 : return false;
201 : }
202 :
203 261131 : bool Bytecodes::MakesCallAlongCriticalPath(Bytecode bytecode) {
204 505515 : if (IsCallOrConstruct(bytecode) || IsCallRuntime(bytecode)) return true;
205 : switch (bytecode) {
206 : case Bytecode::kCreateWithContext:
207 : case Bytecode::kCreateBlockContext:
208 : case Bytecode::kCreateCatchContext:
209 : case Bytecode::kCreateRegExpLiteral:
210 : return true;
211 : default:
212 229994 : return false;
213 : }
214 : }
215 :
216 : // static
217 4 : bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) {
218 4 : switch (operand_type) {
219 : #define CASE(Name, _) \
220 : case OperandType::k##Name: \
221 : return true;
222 : REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
223 : #undef CASE
224 : #define CASE(Name, _) \
225 : case OperandType::k##Name: \
226 : break;
227 : NON_REGISTER_OPERAND_TYPE_LIST(CASE)
228 : REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
229 : #undef CASE
230 : }
231 1 : return false;
232 : }
233 :
234 : // static
235 3 : bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
236 3 : switch (operand_type) {
237 : #define CASE(Name, _) \
238 : case OperandType::k##Name: \
239 : return true;
240 : REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
241 : #undef CASE
242 : #define CASE(Name, _) \
243 : case OperandType::k##Name: \
244 : break;
245 : NON_REGISTER_OPERAND_TYPE_LIST(CASE)
246 : REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
247 : #undef CASE
248 : }
249 1 : return false;
250 : }
251 :
252 : // static
253 13764 : bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
254 13764 : if (operand_scale == OperandScale::kSingle) {
255 5084 : switch (bytecode) {
256 : case Bytecode::kLdaZero:
257 : case Bytecode::kLdaSmi:
258 : case Bytecode::kLdaNull:
259 : case Bytecode::kLdaTheHole:
260 : case Bytecode::kLdaConstant:
261 : case Bytecode::kLdaUndefined:
262 : case Bytecode::kLdaGlobal:
263 : case Bytecode::kLdaNamedProperty:
264 : case Bytecode::kLdaKeyedProperty:
265 : case Bytecode::kLdaContextSlot:
266 : case Bytecode::kLdaCurrentContextSlot:
267 : case Bytecode::kAdd:
268 : case Bytecode::kSub:
269 : case Bytecode::kMul:
270 : case Bytecode::kAddSmi:
271 : case Bytecode::kSubSmi:
272 : case Bytecode::kInc:
273 : case Bytecode::kDec:
274 : case Bytecode::kTypeOf:
275 : case Bytecode::kCallAnyReceiver:
276 : case Bytecode::kCallProperty:
277 : case Bytecode::kCallProperty0:
278 : case Bytecode::kCallProperty1:
279 : case Bytecode::kCallProperty2:
280 : case Bytecode::kCallUndefinedReceiver:
281 : case Bytecode::kCallUndefinedReceiver0:
282 : case Bytecode::kCallUndefinedReceiver1:
283 : case Bytecode::kCallUndefinedReceiver2:
284 : case Bytecode::kConstruct:
285 : case Bytecode::kConstructWithSpread:
286 : return true;
287 : default:
288 4402 : return false;
289 : }
290 : }
291 : return false;
292 : }
293 :
294 : // static
295 0 : bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
296 19136 : for (int i = 0; i < NumberOfOperands(bytecode); i++) {
297 15288 : if (OperandIsScalable(bytecode, i)) return true;
298 : }
299 : return false;
300 : }
301 :
302 : // static
303 0 : bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
304 0 : switch (operand_type) {
305 : #define CASE(Name, _) \
306 : case OperandType::k##Name: \
307 : return OperandTraits<OperandType::k##Name>::TypeInfoTraits::kIsUnsigned;
308 0 : OPERAND_TYPE_LIST(CASE)
309 : #undef CASE
310 : }
311 0 : UNREACHABLE();
312 : }
313 :
314 : // static
315 26832 : bool Bytecodes::BytecodeHasHandler(Bytecode bytecode,
316 : OperandScale operand_scale) {
317 44720 : return operand_scale == OperandScale::kSingle ||
318 26832 : Bytecodes::IsBytecodeWithScalableOperands(bytecode);
319 : }
320 :
321 1723 : std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
322 1723 : return os << Bytecodes::ToString(bytecode);
323 : }
324 :
325 : } // namespace interpreter
326 : } // namespace internal
327 : } // namespace v8
|