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

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

Issue 2351763002: [Interpreter] Optimize BytecodeArrayBuilder and BytecodeArrayWriter. (Closed)
Patch Set: Fix Chromium Windows bots. Created 4 years, 2 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"
11 #include "src/interpreter/bytecode-traits.h" 10 #include "src/interpreter/bytecode-traits.h"
12 11
13 namespace v8 { 12 namespace v8 {
14 namespace internal { 13 namespace internal {
15 namespace interpreter { 14 namespace interpreter {
16 15
17 STATIC_CONST_MEMBER_DEFINITION const int Bytecodes::kMaxOperands; 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] = {
42 #define ENTRY(Name, ...) \
43 { BytecodeTraits<__VA_ARGS__>::kSingleScaleSize, \
44 BytecodeTraits<__VA_ARGS__>::kDoubleScaleSize, \
45 BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleSize },
46 BYTECODE_LIST(ENTRY)
47 #undef ENTRY
48 };
49
50 const OperandSize* const Bytecodes::kOperandSizes[][3] = {
51 #define ENTRY(Name, ...) \
52 { BytecodeTraits<__VA_ARGS__>::kSingleScaleOperandSizes, \
53 BytecodeTraits<__VA_ARGS__>::kDoubleScaleOperandSizes, \
54 BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleOperandSizes },
55 BYTECODE_LIST(ENTRY)
56 #undef ENTRY
57 };
58 // clang-format on
18 59
19 // static 60 // static
20 const char* Bytecodes::ToString(Bytecode bytecode) { 61 const char* Bytecodes::ToString(Bytecode bytecode) {
21 switch (bytecode) { 62 switch (bytecode) {
22 #define CASE(Name, ...) \ 63 #define CASE(Name, ...) \
23 case Bytecode::k##Name: \ 64 case Bytecode::k##Name: \
24 return #Name; 65 return #Name;
25 BYTECODE_LIST(CASE) 66 BYTECODE_LIST(CASE)
26 #undef CASE 67 #undef CASE
27 } 68 }
28 UNREACHABLE(); 69 UNREACHABLE();
29 return ""; 70 return "";
30 } 71 }
31 72
32 // static 73 // static
33 std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale) { 74 std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale) {
34 static const char kSeparator = '.'; 75 static const char kSeparator = '.';
35 76
36 std::string value(ToString(bytecode)); 77 std::string value(ToString(bytecode));
37 if (operand_scale > OperandScale::kSingle) { 78 if (operand_scale > OperandScale::kSingle) {
38 Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale); 79 Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale);
39 std::string suffix = ToString(prefix_bytecode); 80 std::string suffix = ToString(prefix_bytecode);
40 return value.append(1, kSeparator).append(suffix); 81 return value.append(1, kSeparator).append(suffix);
41 } else { 82 } else {
42 return value; 83 return value;
43 } 84 }
44 } 85 }
45 86
46 // static 87 // 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
118 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) { 88 Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
119 DCHECK(!IsDebugBreak(bytecode)); 89 DCHECK(!IsDebugBreak(bytecode));
120 if (bytecode == Bytecode::kWide) { 90 if (bytecode == Bytecode::kWide) {
121 return Bytecode::kDebugBreakWide; 91 return Bytecode::kDebugBreakWide;
122 } 92 }
123 if (bytecode == Bytecode::kExtraWide) { 93 if (bytecode == Bytecode::kExtraWide) {
124 return Bytecode::kDebugBreakExtraWide; 94 return Bytecode::kDebugBreakExtraWide;
125 } 95 }
126 int bytecode_size = Size(bytecode, OperandScale::kSingle); 96 int bytecode_size = Size(bytecode, OperandScale::kSingle);
127 #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name, ...) \ 97 #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name) \
128 if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \ 98 if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \
129 return Bytecode::k##Name; \ 99 return Bytecode::k##Name; \
130 } 100 }
131 DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES) 101 DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
132 #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES 102 #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
133 UNREACHABLE(); 103 UNREACHABLE();
134 return Bytecode::kIllegal; 104 return Bytecode::kIllegal;
135 } 105 }
136 106
137 // static 107 // 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
356 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, 108 int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
357 OperandScale operand_scale) { 109 OperandScale operand_scale) {
358 DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode)); 110 DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
359 // TODO(oth): restore this to a statically determined constant. 111 // TODO(oth): restore this to a statically determined constant.
360 int offset = 1; 112 int offset = 1;
361 for (int operand_index = 0; operand_index < i; ++operand_index) { 113 for (int operand_index = 0; operand_index < i; ++operand_index) {
362 OperandSize operand_size = 114 OperandSize operand_size =
363 GetOperandSize(bytecode, operand_index, operand_scale); 115 GetOperandSize(bytecode, operand_index, operand_scale);
364 offset += static_cast<int>(operand_size); 116 offset += static_cast<int>(operand_size);
365 } 117 }
366 return offset; 118 return offset;
367 } 119 }
368 120
369 // static 121 // 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
435 Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) { 122 Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) {
436 switch (bytecode) { 123 switch (bytecode) {
437 case Bytecode::kJumpIfToBooleanTrue: 124 case Bytecode::kJumpIfToBooleanTrue:
438 return Bytecode::kJumpIfTrue; 125 return Bytecode::kJumpIfTrue;
439 case Bytecode::kJumpIfToBooleanFalse: 126 case Bytecode::kJumpIfToBooleanFalse:
440 return Bytecode::kJumpIfFalse; 127 return Bytecode::kJumpIfFalse;
441 case Bytecode::kJumpIfToBooleanTrueConstant: 128 case Bytecode::kJumpIfToBooleanTrueConstant:
442 return Bytecode::kJumpIfTrueConstant; 129 return Bytecode::kJumpIfTrueConstant;
443 case Bytecode::kJumpIfToBooleanFalseConstant: 130 case Bytecode::kJumpIfToBooleanFalseConstant:
444 return Bytecode::kJumpIfFalseConstant; 131 return Bytecode::kJumpIfFalseConstant;
445 default: 132 default:
446 break; 133 break;
447 } 134 }
448 UNREACHABLE(); 135 UNREACHABLE();
449 return Bytecode::kIllegal; 136 return Bytecode::kIllegal;
450 } 137 }
451 138
452 // static 139 // 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
466 bool Bytecodes::IsDebugBreak(Bytecode bytecode) { 140 bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
467 switch (bytecode) { 141 switch (bytecode) {
468 #define CASE(Name, ...) case Bytecode::k##Name: 142 #define CASE(Name, ...) case Bytecode::k##Name:
469 DEBUG_BREAK_BYTECODE_LIST(CASE); 143 DEBUG_BREAK_BYTECODE_LIST(CASE);
470 #undef CASE 144 #undef CASE
471 return true; 145 return true;
472 default: 146 default:
473 break; 147 break;
474 } 148 }
475 return false; 149 return false;
476 } 150 }
477 151
478 // static 152 // 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
526 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) { 153 bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
527 switch (operand_type) { 154 switch (operand_type) {
528 #define CASE(Name, _) \ 155 #define CASE(Name, _) \
529 case OperandType::k##Name: \ 156 case OperandType::k##Name: \
530 return true; 157 return true;
531 REGISTER_OPERAND_TYPE_LIST(CASE) 158 REGISTER_OPERAND_TYPE_LIST(CASE)
532 #undef CASE 159 #undef CASE
533 #define CASE(Name, _) \ 160 #define CASE(Name, _) \
534 case OperandType::k##Name: \ 161 case OperandType::k##Name: \
535 break; 162 break;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 case Bytecode::kNew: 223 case Bytecode::kNew:
597 return true; 224 return true;
598 default: 225 default:
599 return false; 226 return false;
600 } 227 }
601 } 228 }
602 return false; 229 return false;
603 } 230 }
604 231
605 // static 232 // static
606 int Bytecodes::GetNumberOfRegistersRepresentedBy(OperandType operand_type) { 233 bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
607 switch (operand_type) { 234 for (int i = 0; i < NumberOfOperands(bytecode); i++) {
608 case OperandType::kMaybeReg: 235 if (OperandIsScalable(bytecode, i)) return true;
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;
619 } 236 }
620 return 0; 237 return false;
621 } 238 }
622 239
623 // static 240 // static
624 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) { 241 bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
625 switch (operand_type) { 242 switch (operand_type) {
626 #define CASE(Name, _) \ 243 #define CASE(Name, _) \
627 case OperandType::k##Name: \ 244 case OperandType::k##Name: \
628 return OperandTraits<OperandType::k##Name>::TypeInfoTraits::kIsUnsigned; 245 return OperandTraits<OperandType::k##Name>::TypeInfoTraits::kIsUnsigned;
629 OPERAND_TYPE_LIST(CASE) 246 OPERAND_TYPE_LIST(CASE)
630 #undef CASE 247 #undef CASE
631 } 248 }
632 UNREACHABLE(); 249 UNREACHABLE();
633 return false; 250 return false;
634 } 251 }
635 252
636 // static 253 // static
637 OperandSize Bytecodes::SizeForSignedOperand(int value) { 254 OperandSize Bytecodes::SizeOfOperand(OperandType operand_type,
638 if (value >= kMinInt8 && value <= kMaxInt8) { 255 OperandScale operand_scale) {
639 return OperandSize::kByte; 256 DCHECK_LE(operand_type, OperandType::kLast);
640 } else if (value >= kMinInt16 && value <= kMaxInt16) { 257 DCHECK_GE(operand_scale, OperandScale::kSingle);
641 return OperandSize::kShort; 258 DCHECK_LE(operand_scale, OperandScale::kLast);
642 } else { 259 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
643 return OperandSize::kQuad; 260 OperandScale::kLast == OperandScale::kQuadruple);
644 } 261 int scale_index = static_cast<int>(operand_scale) >> 1;
262 // clang-format off
263 static const OperandSize kOperandSizes[][3] = {
264 #define ENTRY(Name, ...) \
265 { OperandScaler<OperandType::k##Name, \
266 OperandScale::kSingle>::kOperandSize, \
267 OperandScaler<OperandType::k##Name, \
268 OperandScale::kDouble>::kOperandSize, \
269 OperandScaler<OperandType::k##Name, \
270 OperandScale::kQuadruple>::kOperandSize },
271 OPERAND_TYPE_LIST(ENTRY)
272 #undef ENTRY
273 };
274 // clang-format on
275 return kOperandSizes[static_cast<size_t>(operand_type)][scale_index];
645 } 276 }
646 277
647 // static 278 // 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
659 bool Bytecodes::BytecodeHasHandler(Bytecode bytecode, 279 bool Bytecodes::BytecodeHasHandler(Bytecode bytecode,
660 OperandScale operand_scale) { 280 OperandScale operand_scale) {
661 return operand_scale == OperandScale::kSingle || 281 return operand_scale == OperandScale::kSingle ||
662 Bytecodes::IsBytecodeWithScalableOperands(bytecode); 282 Bytecodes::IsBytecodeWithScalableOperands(bytecode);
663 } 283 }
664 284
665 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) { 285 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
666 return os << Bytecodes::ToString(bytecode); 286 return os << Bytecodes::ToString(bytecode);
667 } 287 }
668 288
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
685 } // namespace interpreter 289 } // namespace interpreter
686 } // namespace internal 290 } // namespace internal
687 } // namespace v8 291 } // 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