Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: src/interpreter/bytecodes.cc

Issue 2360193003: Revert of [Interpreter] Optimize BytecodeArrayBuilder and BytecodeArrayWriter. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/bytecodes.h ('k') | src/v8.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/bytecodes.h" 5 #include "src/interpreter/bytecodes.h"
6 6
7 #include <iomanip> 7 #include <iomanip>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/globals.h"
10 #include "src/interpreter/bytecode-traits.h" 11 #include "src/interpreter/bytecode-traits.h"
11 12
12 namespace v8 { 13 namespace v8 {
13 namespace internal { 14 namespace internal {
14 namespace interpreter { 15 namespace interpreter {
15 16
16 // clang-format off 17 STATIC_CONST_MEMBER_DEFINITION const int Bytecodes::kMaxOperands;
17 STATIC_CONST_MEMBER_DEFINITION
18 const OperandType* const Bytecodes::kOperandTypes[] = {
19 #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandTypes,
20 BYTECODE_LIST(ENTRY)
21 #undef ENTRY
22 };
23
24 STATIC_CONST_MEMBER_DEFINITION
25 const OperandTypeInfo* const Bytecodes::kOperandTypeInfos[] = {
26 #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandTypeInfos,
27 BYTECODE_LIST(ENTRY)
28 #undef ENTRY
29 };
30
31 STATIC_CONST_MEMBER_DEFINITION const int Bytecodes::kOperandCount[] = {
32 #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandCount,
33 BYTECODE_LIST(ENTRY)
34 #undef ENTRY
35 };
36
37 STATIC_CONST_MEMBER_DEFINITION
38 const AccumulatorUse Bytecodes::kAccumulatorUse[] = {
39 #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kAccumulatorUse,
40 BYTECODE_LIST(ENTRY)
41 #undef ENTRY
42 };
43
44 STATIC_CONST_MEMBER_DEFINITION const int Bytecodes::kBytecodeSizes[][3] = {
45 #define ENTRY(Name, ...) \
46 { BytecodeTraits<__VA_ARGS__>::kSingleScaleSize, \
47 BytecodeTraits<__VA_ARGS__>::kDoubleScaleSize, \
48 BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleSize },
49 BYTECODE_LIST(ENTRY)
50 #undef ENTRY
51 };
52
53 STATIC_CONST_MEMBER_DEFINITION
54 const OperandSize* const Bytecodes::kOperandSizes[][3] = {
55 #define ENTRY(Name, ...) \
56 { BytecodeTraits<__VA_ARGS__>::kSingleScaleOperandSizes, \
57 BytecodeTraits<__VA_ARGS__>::kDoubleScaleOperandSizes, \
58 BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleOperandSizes },
59 BYTECODE_LIST(ENTRY)
60 #undef ENTRY
61 };
62 // clang-format on
63 18
64 // static 19 // static
65 const char* Bytecodes::ToString(Bytecode bytecode) { 20 const char* Bytecodes::ToString(Bytecode bytecode) {
66 switch (bytecode) { 21 switch (bytecode) {
67 #define CASE(Name, ...) \ 22 #define CASE(Name, ...) \
68 case Bytecode::k##Name: \ 23 case Bytecode::k##Name: \
69 return #Name; 24 return #Name;
70 BYTECODE_LIST(CASE) 25 BYTECODE_LIST(CASE)
71 #undef CASE 26 #undef CASE
72 } 27 }
73 UNREACHABLE(); 28 UNREACHABLE();
74 return ""; 29 return "";
75 } 30 }
76 31
77 // static 32 // static
78 std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale) { 33 std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale) {
79 static const char kSeparator = '.'; 34 static const char kSeparator = '.';
80 35
81 std::string value(ToString(bytecode)); 36 std::string value(ToString(bytecode));
82 if (operand_scale > OperandScale::kSingle) { 37 if (operand_scale > OperandScale::kSingle) {
83 Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale); 38 Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale);
84 std::string suffix = ToString(prefix_bytecode); 39 std::string suffix = ToString(prefix_bytecode);
85 return value.append(1, kSeparator).append(suffix); 40 return value.append(1, kSeparator).append(suffix);
86 } else { 41 } else {
87 return value; 42 return value;
88 } 43 }
89 } 44 }
90 45
91 // static 46 // static
47 const char* Bytecodes::AccumulatorUseToString(AccumulatorUse accumulator_use) {
48 switch (accumulator_use) {
49 case AccumulatorUse::kNone:
50 return "None";
51 case AccumulatorUse::kRead:
52 return "Read";
53 case AccumulatorUse::kWrite:
54 return "Write";
55 case AccumulatorUse::kReadWrite:
56 return "ReadWrite";
57 }
58 UNREACHABLE();
59 return "";
60 }
61
62 // static
63 const char* Bytecodes::OperandTypeToString(OperandType operand_type) {
64 switch (operand_type) {
65 #define CASE(Name, _) \
66 case OperandType::k##Name: \
67 return #Name;
68 OPERAND_TYPE_LIST(CASE)
69 #undef CASE
70 }
71 UNREACHABLE();
72 return "";
73 }
74
75 // static
76 const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) {
77 switch (operand_scale) {
78 #define CASE(Name, _) \
79 case OperandScale::k##Name: \
80 return #Name;
81 OPERAND_SCALE_LIST(CASE)
82 #undef CASE
83 }
84 UNREACHABLE();
85 return "";
86 }
87
88 // static
89 const char* Bytecodes::OperandSizeToString(OperandSize operand_size) {
90 switch (operand_size) {
91 case OperandSize::kNone:
92 return "None";
93 case OperandSize::kByte:
94 return "Byte";
95 case OperandSize::kShort:
96 return "Short";
97 case OperandSize::kQuad:
98 return "Quad";
99 }
100 UNREACHABLE();
101 return "";
102 }
103
104 // static
105 uint8_t Bytecodes::ToByte(Bytecode bytecode) {
106 DCHECK_LE(bytecode, Bytecode::kLast);
107 return static_cast<uint8_t>(bytecode);
108 }
109
110 // static
111 Bytecode Bytecodes::FromByte(uint8_t value) {
112 Bytecode bytecode = static_cast<Bytecode>(value);
113 DCHECK(bytecode <= Bytecode::kLast);
114 return bytecode;
115 }
116
117 // static
92 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) { 118 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
93 DCHECK(!IsDebugBreak(bytecode)); 119 DCHECK(!IsDebugBreak(bytecode));
94 if (bytecode == Bytecode::kWide) { 120 if (bytecode == Bytecode::kWide) {
95 return Bytecode::kDebugBreakWide; 121 return Bytecode::kDebugBreakWide;
96 } 122 }
97 if (bytecode == Bytecode::kExtraWide) { 123 if (bytecode == Bytecode::kExtraWide) {
98 return Bytecode::kDebugBreakExtraWide; 124 return Bytecode::kDebugBreakExtraWide;
99 } 125 }
100 int bytecode_size = Size(bytecode, OperandScale::kSingle); 126 int bytecode_size = Size(bytecode, OperandScale::kSingle);
101 #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name) \ 127 #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name, ...) \
102 if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \ 128 if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \
103 return Bytecode::k##Name; \ 129 return Bytecode::k##Name; \
104 } 130 }
105 DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES) 131 DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
106 #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES 132 #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
107 UNREACHABLE(); 133 UNREACHABLE();
108 return Bytecode::kIllegal; 134 return Bytecode::kIllegal;
109 } 135 }
110 136
111 // static 137 // static
138 int Bytecodes::Size(Bytecode bytecode, OperandScale operand_scale) {
139 int size = 1;
140 for (int i = 0; i < NumberOfOperands(bytecode); i++) {
141 OperandSize operand_size = GetOperandSize(bytecode, i, operand_scale);
142 int delta = static_cast<int>(operand_size);
143 DCHECK(base::bits::IsPowerOfTwo32(static_cast<uint32_t>(delta)));
144 size += delta;
145 }
146 return size;
147 }
148
149 // static
150 size_t Bytecodes::ReturnCount(Bytecode bytecode) {
151 return bytecode == Bytecode::kReturn ? 1 : 0;
152 }
153
154 // static
155 int Bytecodes::NumberOfOperands(Bytecode bytecode) {
156 DCHECK(bytecode <= Bytecode::kLast);
157 switch (bytecode) {
158 #define CASE(Name, ...) \
159 case Bytecode::k##Name: \
160 return BytecodeTraits<__VA_ARGS__>::kOperandCount;
161 BYTECODE_LIST(CASE)
162 #undef CASE
163 }
164 UNREACHABLE();
165 return 0;
166 }
167
168 // static
169 int Bytecodes::NumberOfRegisterOperands(Bytecode bytecode) {
170 DCHECK(bytecode <= Bytecode::kLast);
171 switch (bytecode) {
172 #define CASE(Name, ...) \
173 case Bytecode::k##Name: \
174 typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \
175 return Name##Trait::kRegisterOperandCount;
176 BYTECODE_LIST(CASE)
177 #undef CASE
178 }
179 UNREACHABLE();
180 return false;
181 }
182
183 // static
184 Bytecode Bytecodes::OperandScaleToPrefixBytecode(OperandScale operand_scale) {
185 switch (operand_scale) {
186 case OperandScale::kQuadruple:
187 return Bytecode::kExtraWide;
188 case OperandScale::kDouble:
189 return Bytecode::kWide;
190 default:
191 UNREACHABLE();
192 return Bytecode::kIllegal;
193 }
194 }
195
196 // static
197 bool Bytecodes::OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) {
198 return operand_scale != OperandScale::kSingle;
199 }
200
201 // static
202 OperandScale Bytecodes::PrefixBytecodeToOperandScale(Bytecode bytecode) {
203 switch (bytecode) {
204 case Bytecode::kExtraWide:
205 case Bytecode::kDebugBreakExtraWide:
206 return OperandScale::kQuadruple;
207 case Bytecode::kWide:
208 case Bytecode::kDebugBreakWide:
209 return OperandScale::kDouble;
210 default:
211 UNREACHABLE();
212 return OperandScale::kSingle;
213 }
214 }
215
216 // static
217 AccumulatorUse Bytecodes::GetAccumulatorUse(Bytecode bytecode) {
218 DCHECK(bytecode <= Bytecode::kLast);
219 switch (bytecode) {
220 #define CASE(Name, ...) \
221 case Bytecode::k##Name: \
222 return BytecodeTraits<__VA_ARGS__>::kAccumulatorUse;
223 BYTECODE_LIST(CASE)
224 #undef CASE
225 }
226 UNREACHABLE();
227 return AccumulatorUse::kNone;
228 }
229
230 // static
231 bool Bytecodes::ReadsAccumulator(Bytecode bytecode) {
232 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kRead) ==
233 AccumulatorUse::kRead;
234 }
235
236 // static
237 bool Bytecodes::WritesAccumulator(Bytecode bytecode) {
238 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) ==
239 AccumulatorUse::kWrite;
240 }
241
242 // static
243 bool Bytecodes::WritesBooleanToAccumulator(Bytecode bytecode) {
244 switch (bytecode) {
245 case Bytecode::kLdaTrue:
246 case Bytecode::kLdaFalse:
247 case Bytecode::kToBooleanLogicalNot:
248 case Bytecode::kLogicalNot:
249 case Bytecode::kTestEqual:
250 case Bytecode::kTestNotEqual:
251 case Bytecode::kTestEqualStrict:
252 case Bytecode::kTestLessThan:
253 case Bytecode::kTestLessThanOrEqual:
254 case Bytecode::kTestGreaterThan:
255 case Bytecode::kTestGreaterThanOrEqual:
256 case Bytecode::kTestInstanceOf:
257 case Bytecode::kTestIn:
258 case Bytecode::kForInContinue:
259 return true;
260 default:
261 return false;
262 }
263 }
264
265 // static
266 bool Bytecodes::IsAccumulatorLoadWithoutEffects(Bytecode bytecode) {
267 switch (bytecode) {
268 case Bytecode::kLdaZero:
269 case Bytecode::kLdaSmi:
270 case Bytecode::kLdaUndefined:
271 case Bytecode::kLdaNull:
272 case Bytecode::kLdaTheHole:
273 case Bytecode::kLdaTrue:
274 case Bytecode::kLdaFalse:
275 case Bytecode::kLdaConstant:
276 case Bytecode::kLdar:
277 return true;
278 default:
279 return false;
280 }
281 }
282
283 // static
284 bool Bytecodes::IsJumpWithoutEffects(Bytecode bytecode) {
285 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
286 }
287
288 // static
289 bool Bytecodes::IsRegisterLoadWithoutEffects(Bytecode bytecode) {
290 switch (bytecode) {
291 case Bytecode::kMov:
292 case Bytecode::kPopContext:
293 case Bytecode::kPushContext:
294 case Bytecode::kStar:
295 case Bytecode::kLdrUndefined:
296 return true;
297 default:
298 return false;
299 }
300 }
301
302 // static
303 bool Bytecodes::IsWithoutExternalSideEffects(Bytecode bytecode) {
304 // These bytecodes only manipulate interpreter frame state and will
305 // never throw.
306 return (IsAccumulatorLoadWithoutEffects(bytecode) ||
307 IsRegisterLoadWithoutEffects(bytecode) ||
308 bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode));
309 }
310
311 // static
312 OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
313 DCHECK_LE(bytecode, Bytecode::kLast);
314 DCHECK_LT(i, NumberOfOperands(bytecode));
315 DCHECK_GE(i, 0);
316 return GetOperandTypes(bytecode)[i];
317 }
318
319 // static
320 const OperandType* Bytecodes::GetOperandTypes(Bytecode bytecode) {
321 DCHECK_LE(bytecode, Bytecode::kLast);
322 switch (bytecode) {
323 #define CASE(Name, ...) \
324 case Bytecode::k##Name: \
325 return BytecodeTraits<__VA_ARGS__>::GetOperandTypes();
326 BYTECODE_LIST(CASE)
327 #undef CASE
328 }
329 UNREACHABLE();
330 return nullptr;
331 }
332
333 // static
334 const OperandTypeInfo* Bytecodes::GetOperandTypeInfos(Bytecode bytecode) {
335 DCHECK(bytecode <= Bytecode::kLast);
336 switch (bytecode) {
337 #define CASE(Name, ...) \
338 case Bytecode::k##Name: \
339 return BytecodeTraits<__VA_ARGS__>::GetOperandTypeInfos();
340 BYTECODE_LIST(CASE)
341 #undef CASE
342 }
343 UNREACHABLE();
344 return nullptr;
345 }
346
347 // static
348 OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i,
349 OperandScale operand_scale) {
350 DCHECK_LT(i, NumberOfOperands(bytecode));
351 OperandType operand_type = GetOperandType(bytecode, i);
352 return SizeOfOperand(operand_type, operand_scale);
353 }
354
355 // static
112 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, 356 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
113 OperandScale operand_scale) { 357 OperandScale operand_scale) {
114 DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode)); 358 DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
115 // TODO(oth): restore this to a statically determined constant. 359 // TODO(oth): restore this to a statically determined constant.
116 int offset = 1; 360 int offset = 1;
117 for (int operand_index = 0; operand_index < i; ++operand_index) { 361 for (int operand_index = 0; operand_index < i; ++operand_index) {
118 OperandSize operand_size = 362 OperandSize operand_size =
119 GetOperandSize(bytecode, operand_index, operand_scale); 363 GetOperandSize(bytecode, operand_index, operand_scale);
120 offset += static_cast<int>(operand_size); 364 offset += static_cast<int>(operand_size);
121 } 365 }
122 return offset; 366 return offset;
123 } 367 }
124 368
125 // static 369 // static
370 OperandSize Bytecodes::SizeOfOperand(OperandType operand_type,
371 OperandScale operand_scale) {
372 DCHECK_LE(operand_type, OperandType::kLast);
373 DCHECK_GE(operand_scale, OperandScale::kSingle);
374 DCHECK_LE(operand_scale, OperandScale::kLast);
375 return static_cast<OperandSize>(
376 ScaledOperandSize(operand_type, operand_scale));
377 }
378
379 // static
380 bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) {
381 return bytecode == Bytecode::kJumpIfTrue ||
382 bytecode == Bytecode::kJumpIfFalse ||
383 bytecode == Bytecode::kJumpIfToBooleanTrue ||
384 bytecode == Bytecode::kJumpIfToBooleanFalse ||
385 bytecode == Bytecode::kJumpIfNotHole ||
386 bytecode == Bytecode::kJumpIfNull ||
387 bytecode == Bytecode::kJumpIfUndefined;
388 }
389
390 // static
391 bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) {
392 return bytecode == Bytecode::kJumpIfTrueConstant ||
393 bytecode == Bytecode::kJumpIfFalseConstant ||
394 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
395 bytecode == Bytecode::kJumpIfToBooleanFalseConstant ||
396 bytecode == Bytecode::kJumpIfNotHoleConstant ||
397 bytecode == Bytecode::kJumpIfNullConstant ||
398 bytecode == Bytecode::kJumpIfUndefinedConstant;
399 }
400
401 // static
402 bool Bytecodes::IsConditionalJump(Bytecode bytecode) {
403 return IsConditionalJumpImmediate(bytecode) ||
404 IsConditionalJumpConstant(bytecode);
405 }
406
407
408 // static
409 bool Bytecodes::IsJumpImmediate(Bytecode bytecode) {
410 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop ||
411 IsConditionalJumpImmediate(bytecode);
412 }
413
414
415 // static
416 bool Bytecodes::IsJumpConstant(Bytecode bytecode) {
417 return bytecode == Bytecode::kJumpConstant ||
418 IsConditionalJumpConstant(bytecode);
419 }
420
421 // static
422 bool Bytecodes::IsJump(Bytecode bytecode) {
423 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
424 }
425
426 // static
427 bool Bytecodes::IsJumpIfToBoolean(Bytecode bytecode) {
428 return bytecode == Bytecode::kJumpIfToBooleanTrue ||
429 bytecode == Bytecode::kJumpIfToBooleanFalse ||
430 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
431 bytecode == Bytecode::kJumpIfToBooleanFalseConstant;
432 }
433
434 // static
126 Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) { 435 Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) {
127 switch (bytecode) { 436 switch (bytecode) {
128 case Bytecode::kJumpIfToBooleanTrue: 437 case Bytecode::kJumpIfToBooleanTrue:
129 return Bytecode::kJumpIfTrue; 438 return Bytecode::kJumpIfTrue;
130 case Bytecode::kJumpIfToBooleanFalse: 439 case Bytecode::kJumpIfToBooleanFalse:
131 return Bytecode::kJumpIfFalse; 440 return Bytecode::kJumpIfFalse;
132 case Bytecode::kJumpIfToBooleanTrueConstant: 441 case Bytecode::kJumpIfToBooleanTrueConstant:
133 return Bytecode::kJumpIfTrueConstant; 442 return Bytecode::kJumpIfTrueConstant;
134 case Bytecode::kJumpIfToBooleanFalseConstant: 443 case Bytecode::kJumpIfToBooleanFalseConstant:
135 return Bytecode::kJumpIfFalseConstant; 444 return Bytecode::kJumpIfFalseConstant;
136 default: 445 default:
137 break; 446 break;
138 } 447 }
139 UNREACHABLE(); 448 UNREACHABLE();
140 return Bytecode::kIllegal; 449 return Bytecode::kIllegal;
141 } 450 }
142 451
143 // static 452 // static
453 bool Bytecodes::IsCallOrNew(Bytecode bytecode) {
454 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall ||
455 bytecode == Bytecode::kNew;
456 }
457
458 // static
459 bool Bytecodes::IsCallRuntime(Bytecode bytecode) {
460 return bytecode == Bytecode::kCallRuntime ||
461 bytecode == Bytecode::kCallRuntimeForPair ||
462 bytecode == Bytecode::kInvokeIntrinsic;
463 }
464
465 // static
144 bool Bytecodes::IsDebugBreak(Bytecode bytecode) { 466 bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
145 switch (bytecode) { 467 switch (bytecode) {
146 #define CASE(Name, ...) case Bytecode::k##Name: 468 #define CASE(Name, ...) case Bytecode::k##Name:
147 DEBUG_BREAK_BYTECODE_LIST(CASE); 469 DEBUG_BREAK_BYTECODE_LIST(CASE);
148 #undef CASE 470 #undef CASE
149 return true; 471 return true;
150 default: 472 default:
151 break; 473 break;
152 } 474 }
153 return false; 475 return false;
154 } 476 }
155 477
156 // static 478 // static
479 bool Bytecodes::IsLdarOrStar(Bytecode bytecode) {
480 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
481 }
482
483 // static
484 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
485 switch (bytecode) {
486 #define CASE(Name, ...) \
487 case Bytecode::k##Name: \
488 typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \
489 return Name##Trait::IsScalable();
490 BYTECODE_LIST(CASE)
491 #undef CASE
492 }
493 UNREACHABLE();
494 return false;
495 }
496
497 // static
498 bool Bytecodes::IsPrefixScalingBytecode(Bytecode bytecode) {
499 switch (bytecode) {
500 case Bytecode::kExtraWide:
501 case Bytecode::kDebugBreakExtraWide:
502 case Bytecode::kWide:
503 case Bytecode::kDebugBreakWide:
504 return true;
505 default:
506 return false;
507 }
508 }
509
510 // static
511 bool Bytecodes::PutsNameInAccumulator(Bytecode bytecode) {
512 return bytecode == Bytecode::kTypeOf;
513 }
514
515 // static
516 bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) {
517 return bytecode == Bytecode::kReturn || IsJump(bytecode);
518 }
519
520 // static
521 bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) {
522 return operand_type == OperandType::kMaybeReg;
523 }
524
525 // static
157 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) { 526 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
158 switch (operand_type) { 527 switch (operand_type) {
159 #define CASE(Name, _) \ 528 #define CASE(Name, _) \
160 case OperandType::k##Name: \ 529 case OperandType::k##Name: \
161 return true; 530 return true;
162 REGISTER_OPERAND_TYPE_LIST(CASE) 531 REGISTER_OPERAND_TYPE_LIST(CASE)
163 #undef CASE 532 #undef CASE
164 #define CASE(Name, _) \ 533 #define CASE(Name, _) \
165 case OperandType::k##Name: \ 534 case OperandType::k##Name: \
166 break; 535 break;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 case Bytecode::kNew: 596 case Bytecode::kNew:
228 return true; 597 return true;
229 default: 598 default:
230 return false; 599 return false;
231 } 600 }
232 } 601 }
233 return false; 602 return false;
234 } 603 }
235 604
236 // static 605 // static
237 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) { 606 int Bytecodes::GetNumberOfRegistersRepresentedBy(OperandType operand_type) {
238 for (int i = 0; i < NumberOfOperands(bytecode); i++) { 607 switch (operand_type) {
239 if (OperandIsScalable(bytecode, i)) return true; 608 case OperandType::kMaybeReg:
609 case OperandType::kReg:
610 case OperandType::kRegOut:
611 return 1;
612 case OperandType::kRegPair:
613 case OperandType::kRegOutPair:
614 return 2;
615 case OperandType::kRegOutTriple:
616 return 3;
617 default:
618 return 0;
240 } 619 }
241 return false; 620 return 0;
242 } 621 }
243 622
244 // static 623 // static
245 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) { 624 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
246 switch (operand_type) { 625 switch (operand_type) {
247 #define CASE(Name, _) \ 626 #define CASE(Name, _) \
248 case OperandType::k##Name: \ 627 case OperandType::k##Name: \
249 return OperandTraits<OperandType::k##Name>::TypeInfoTraits::kIsUnsigned; 628 return OperandTraits<OperandType::k##Name>::TypeInfoTraits::kIsUnsigned;
250 OPERAND_TYPE_LIST(CASE) 629 OPERAND_TYPE_LIST(CASE)
251 #undef CASE 630 #undef CASE
252 } 631 }
253 UNREACHABLE(); 632 UNREACHABLE();
254 return false; 633 return false;
255 } 634 }
256 635
257 // static 636 // static
258 OperandSize Bytecodes::SizeOfOperand(OperandType operand_type, 637 OperandSize Bytecodes::SizeForSignedOperand(int value) {
259 OperandScale operand_scale) { 638 if (value >= kMinInt8 && value <= kMaxInt8) {
260 DCHECK_LE(operand_type, OperandType::kLast); 639 return OperandSize::kByte;
261 DCHECK_GE(operand_scale, OperandScale::kSingle); 640 } else if (value >= kMinInt16 && value <= kMaxInt16) {
262 DCHECK_LE(operand_scale, OperandScale::kLast); 641 return OperandSize::kShort;
263 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 && 642 } else {
264 OperandScale::kLast == OperandScale::kQuadruple); 643 return OperandSize::kQuad;
265 int scale_index = static_cast<int>(operand_scale) >> 1; 644 }
266 // clang-format off
267 static const OperandSize kOperandSizes[][3] = {
268 #define ENTRY(Name, ...) \
269 { OperandScaler<OperandType::k##Name, \
270 OperandScale::kSingle>::kOperandSize, \
271 OperandScaler<OperandType::k##Name, \
272 OperandScale::kDouble>::kOperandSize, \
273 OperandScaler<OperandType::k##Name, \
274 OperandScale::kQuadruple>::kOperandSize },
275 OPERAND_TYPE_LIST(ENTRY)
276 #undef ENTRY
277 };
278 // clang-format on
279 return kOperandSizes[static_cast<size_t>(operand_type)][scale_index];
280 } 645 }
281 646
282 // static 647 // static
648 OperandSize Bytecodes::SizeForUnsignedOperand(uint32_t value) {
649 if (value <= kMaxUInt8) {
650 return OperandSize::kByte;
651 } else if (value <= kMaxUInt16) {
652 return OperandSize::kShort;
653 } else {
654 return OperandSize::kQuad;
655 }
656 }
657
658 // static
283 bool Bytecodes::BytecodeHasHandler(Bytecode bytecode, 659 bool Bytecodes::BytecodeHasHandler(Bytecode bytecode,
284 OperandScale operand_scale) { 660 OperandScale operand_scale) {
285 return operand_scale == OperandScale::kSingle || 661 return operand_scale == OperandScale::kSingle ||
286 Bytecodes::IsBytecodeWithScalableOperands(bytecode); 662 Bytecodes::IsBytecodeWithScalableOperands(bytecode);
287 } 663 }
288 664
289 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) { 665 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
290 return os << Bytecodes::ToString(bytecode); 666 return os << Bytecodes::ToString(bytecode);
291 } 667 }
292 668
669 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use) {
670 return os << Bytecodes::AccumulatorUseToString(use);
671 }
672
673 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) {
674 return os << Bytecodes::OperandSizeToString(operand_size);
675 }
676
677 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale) {
678 return os << Bytecodes::OperandScaleToString(operand_scale);
679 }
680
681 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) {
682 return os << Bytecodes::OperandTypeToString(operand_type);
683 }
684
293 } // namespace interpreter 685 } // namespace interpreter
294 } // namespace internal 686 } // namespace internal
295 } // namespace v8 687 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecodes.h ('k') | src/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698