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 147368 : const char* Bytecodes::ToString(Bytecode bytecode) {
99 147368 : switch (bytecode) {
100 : #define CASE(Name, ...) \
101 : case Bytecode::k##Name: \
102 : return #Name;
103 8535 : BYTECODE_LIST(CASE)
104 : #undef CASE
105 : }
106 0 : UNREACHABLE();
107 : }
108 :
109 : // static
110 27095 : std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale,
111 : const char* separator) {
112 27095 : std::string value(ToString(bytecode));
113 27095 : if (operand_scale > OperandScale::kSingle) {
114 : Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale);
115 16766 : std::string suffix = ToString(prefix_bytecode);
116 16766 : return value.append(separator).append(suffix);
117 : } else {
118 : return value;
119 : }
120 : }
121 :
122 : // static
123 3776688 : Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
124 : DCHECK(!IsDebugBreak(bytecode));
125 3776688 : if (bytecode == Bytecode::kWide) {
126 : return Bytecode::kDebugBreakWide;
127 : }
128 2914237 : if (bytecode == Bytecode::kExtraWide) {
129 : return Bytecode::kDebugBreakExtraWide;
130 : }
131 : int bytecode_size = Size(bytecode, OperandScale::kSingle);
132 : #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name) \
133 : if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \
134 : return Bytecode::k##Name; \
135 : }
136 2903796 : DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
137 : #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
138 0 : UNREACHABLE();
139 : }
140 :
141 : // static
142 30999034 : int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
143 : OperandScale operand_scale) {
144 : DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
145 : // TODO(oth): restore this to a statically determined constant.
146 : int offset = 1;
147 57757244 : for (int operand_index = 0; operand_index < i; ++operand_index) {
148 : OperandSize operand_size =
149 : GetOperandSize(bytecode, operand_index, operand_scale);
150 13379105 : offset += static_cast<int>(operand_size);
151 : }
152 30999034 : return offset;
153 : }
154 :
155 : // static
156 0 : Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) {
157 0 : switch (bytecode) {
158 : case Bytecode::kJumpIfToBooleanTrue:
159 : return Bytecode::kJumpIfTrue;
160 : case Bytecode::kJumpIfToBooleanFalse:
161 0 : return Bytecode::kJumpIfFalse;
162 : case Bytecode::kJumpIfToBooleanTrueConstant:
163 0 : return Bytecode::kJumpIfTrueConstant;
164 : case Bytecode::kJumpIfToBooleanFalseConstant:
165 0 : return Bytecode::kJumpIfFalseConstant;
166 : default:
167 : break;
168 : }
169 0 : UNREACHABLE();
170 : }
171 :
172 : // static
173 3807859 : bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
174 3807859 : switch (bytecode) {
175 : #define CASE(Name, ...) case Bytecode::k##Name:
176 : DEBUG_BREAK_BYTECODE_LIST(CASE);
177 : #undef CASE
178 : return true;
179 : default:
180 : break;
181 : }
182 3776936 : return false;
183 : }
184 :
185 : // static
186 82587 : bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
187 82587 : switch (operand_type) {
188 : #define CASE(Name, _) \
189 : case OperandType::k##Name: \
190 : return true;
191 : REGISTER_OPERAND_TYPE_LIST(CASE)
192 : #undef CASE
193 : #define CASE(Name, _) \
194 : case OperandType::k##Name: \
195 : break;
196 : NON_REGISTER_OPERAND_TYPE_LIST(CASE)
197 : #undef CASE
198 : }
199 40695 : return false;
200 : }
201 :
202 : // static
203 0 : bool Bytecodes::IsRegisterListOperandType(OperandType operand_type) {
204 0 : switch (operand_type) {
205 : case OperandType::kRegList:
206 : case OperandType::kRegOutList:
207 : return true;
208 : default:
209 0 : return false;
210 : }
211 : }
212 :
213 522381 : bool Bytecodes::MakesCallAlongCriticalPath(Bytecode bytecode) {
214 1017345 : if (IsCallOrConstruct(bytecode) || IsCallRuntime(bytecode)) return true;
215 : switch (bytecode) {
216 : case Bytecode::kCreateWithContext:
217 : case Bytecode::kCreateBlockContext:
218 : case Bytecode::kCreateCatchContext:
219 : case Bytecode::kCreateRegExpLiteral:
220 : return true;
221 : default:
222 474455 : return false;
223 : }
224 : }
225 :
226 : // static
227 4 : bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) {
228 4 : switch (operand_type) {
229 : #define CASE(Name, _) \
230 : case OperandType::k##Name: \
231 : return true;
232 : REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
233 : #undef CASE
234 : #define CASE(Name, _) \
235 : case OperandType::k##Name: \
236 : break;
237 : NON_REGISTER_OPERAND_TYPE_LIST(CASE)
238 : REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
239 : #undef CASE
240 : }
241 1 : return false;
242 : }
243 :
244 : // static
245 3 : bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
246 3 : switch (operand_type) {
247 : #define CASE(Name, _) \
248 : case OperandType::k##Name: \
249 : return true;
250 : REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
251 : #undef CASE
252 : #define CASE(Name, _) \
253 : case OperandType::k##Name: \
254 : break;
255 : NON_REGISTER_OPERAND_TYPE_LIST(CASE)
256 : REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
257 : #undef CASE
258 : }
259 1 : return false;
260 : }
261 :
262 : // static
263 38360 : bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
264 38360 : if (operand_scale == OperandScale::kSingle) {
265 13720 : switch (bytecode) {
266 : case Bytecode::kLdaZero:
267 : case Bytecode::kLdaSmi:
268 : case Bytecode::kLdaNull:
269 : case Bytecode::kLdaTheHole:
270 : case Bytecode::kLdaConstant:
271 : case Bytecode::kLdaUndefined:
272 : case Bytecode::kLdaGlobal:
273 : case Bytecode::kLdaNamedProperty:
274 : case Bytecode::kLdaKeyedProperty:
275 : case Bytecode::kLdaContextSlot:
276 : case Bytecode::kLdaCurrentContextSlot:
277 : case Bytecode::kAdd:
278 : case Bytecode::kSub:
279 : case Bytecode::kMul:
280 : case Bytecode::kAddSmi:
281 : case Bytecode::kSubSmi:
282 : case Bytecode::kInc:
283 : case Bytecode::kDec:
284 : case Bytecode::kTypeOf:
285 : case Bytecode::kCallAnyReceiver:
286 : case Bytecode::kCallNoFeedback:
287 : case Bytecode::kCallProperty:
288 : case Bytecode::kCallProperty0:
289 : case Bytecode::kCallProperty1:
290 : case Bytecode::kCallProperty2:
291 : case Bytecode::kCallUndefinedReceiver:
292 : case Bytecode::kCallUndefinedReceiver0:
293 : case Bytecode::kCallUndefinedReceiver1:
294 : case Bytecode::kCallUndefinedReceiver2:
295 : case Bytecode::kConstruct:
296 : case Bytecode::kConstructWithSpread:
297 : return true;
298 : default:
299 11480 : return false;
300 : }
301 : }
302 : return false;
303 : }
304 :
305 : // static
306 0 : bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
307 23977601 : for (int i = 0; i < NumberOfOperands(bytecode); i++) {
308 19107193 : if (OperandIsScalable(bytecode, i)) return true;
309 : }
310 : return false;
311 : }
312 :
313 : // static
314 0 : bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
315 0 : switch (operand_type) {
316 : #define CASE(Name, _) \
317 : case OperandType::k##Name: \
318 : return OperandTraits<OperandType::k##Name>::TypeInfoTraits::kIsUnsigned;
319 0 : OPERAND_TYPE_LIST(CASE)
320 : #undef CASE
321 : }
322 0 : UNREACHABLE();
323 : }
324 :
325 : // static
326 33718178 : bool Bytecodes::BytecodeHasHandler(Bytecode bytecode,
327 : OperandScale operand_scale) {
328 56197149 : return operand_scale == OperandScale::kSingle ||
329 33718178 : Bytecodes::IsBytecodeWithScalableOperands(bytecode);
330 : }
331 :
332 1263 : std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
333 1263 : return os << Bytecodes::ToString(bytecode);
334 : }
335 :
336 : } // namespace interpreter
337 : } // namespace internal
338 122038 : } // namespace v8
|