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

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

Issue 2360193003: Revert of [Interpreter] Optimize BytecodeArrayBuilder and BytecodeArrayWriter. (Closed)
Patch Set: 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/bytecode-traits.h ('k') | src/interpreter/bytecodes.cc » ('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 #ifndef V8_INTERPRETER_BYTECODES_H_ 5 #ifndef V8_INTERPRETER_BYTECODES_H_
6 #define V8_INTERPRETER_BYTECODES_H_ 6 #define V8_INTERPRETER_BYTECODES_H_
7 7
8 #include <cstdint> 8 #include <cstdint>
9 #include <iosfwd> 9 #include <iosfwd>
10 #include <string> 10 #include <string>
11 11
12 #include "src/globals.h"
13 #include "src/interpreter/bytecode-operands.h"
14
15 // This interface and it's implementation are independent of the 12 // This interface and it's implementation are independent of the
16 // libv8_base library as they are used by the interpreter and the 13 // libv8_base library as they are used by the interpreter and the
17 // standalone mkpeephole table generator program. 14 // standalone mkpeephole table generator program.
18 15
19 namespace v8 { 16 namespace v8 {
20 namespace internal { 17 namespace internal {
21 namespace interpreter { 18 namespace interpreter {
22 19
20 #define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone)
21
22 #define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
23 V(MaybeReg, OperandTypeInfo::kScalableSignedByte) \
24 V(Reg, OperandTypeInfo::kScalableSignedByte) \
25 V(RegPair, OperandTypeInfo::kScalableSignedByte)
26
27 #define REGISTER_OUTPUT_OPERAND_TYPE_LIST(V) \
28 V(RegOut, OperandTypeInfo::kScalableSignedByte) \
29 V(RegOutPair, OperandTypeInfo::kScalableSignedByte) \
30 V(RegOutTriple, OperandTypeInfo::kScalableSignedByte)
31
32 #define SCALAR_OPERAND_TYPE_LIST(V) \
33 V(Flag8, OperandTypeInfo::kFixedUnsignedByte) \
34 V(IntrinsicId, OperandTypeInfo::kFixedUnsignedByte) \
35 V(Idx, OperandTypeInfo::kScalableUnsignedByte) \
36 V(UImm, OperandTypeInfo::kScalableUnsignedByte) \
37 V(Imm, OperandTypeInfo::kScalableSignedByte) \
38 V(RegCount, OperandTypeInfo::kScalableUnsignedByte) \
39 V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort)
40
41 #define REGISTER_OPERAND_TYPE_LIST(V) \
42 REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
43 REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)
44
45 #define NON_REGISTER_OPERAND_TYPE_LIST(V) \
46 INVALID_OPERAND_TYPE_LIST(V) \
47 SCALAR_OPERAND_TYPE_LIST(V)
48
49 // The list of operand types used by bytecodes.
50 #define OPERAND_TYPE_LIST(V) \
51 NON_REGISTER_OPERAND_TYPE_LIST(V) \
52 REGISTER_OPERAND_TYPE_LIST(V)
53
54 // Define one debug break bytecode for each possible size of unscaled
55 // bytecodes. Format is V(<bytecode>, <accumulator_use>, <operands>).
56 #define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
57 V(DebugBreak0, AccumulatorUse::kRead) \
58 V(DebugBreak1, AccumulatorUse::kRead, OperandType::kReg) \
59 V(DebugBreak2, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg) \
60 V(DebugBreak3, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
61 OperandType::kReg) \
62 V(DebugBreak4, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
63 OperandType::kReg, OperandType::kReg) \
64 V(DebugBreak5, AccumulatorUse::kRead, OperandType::kRuntimeId, \
65 OperandType::kReg, OperandType::kReg) \
66 V(DebugBreak6, AccumulatorUse::kRead, OperandType::kRuntimeId, \
67 OperandType::kReg, OperandType::kReg, OperandType::kReg)
68
69 // Define one debug break for each widening prefix.
70 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \
71 V(DebugBreakWide, AccumulatorUse::kRead) \
72 V(DebugBreakExtraWide, AccumulatorUse::kRead)
73
74 #define DEBUG_BREAK_BYTECODE_LIST(V) \
75 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
76 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V)
77
23 // The list of bytecodes which are interpreted by the interpreter. 78 // The list of bytecodes which are interpreted by the interpreter.
24 // Format is V(<bytecode>, <accumulator_use>, <operands>).
25 #define BYTECODE_LIST(V) \ 79 #define BYTECODE_LIST(V) \
26 /* Extended width operands */ \ 80 /* Extended width operands */ \
27 V(Wide, AccumulatorUse::kNone) \ 81 V(Wide, AccumulatorUse::kNone) \
28 V(ExtraWide, AccumulatorUse::kNone) \ 82 V(ExtraWide, AccumulatorUse::kNone) \
29 \ 83 \
30 /* Loading the accumulator */ \ 84 /* Loading the accumulator */ \
31 V(LdaZero, AccumulatorUse::kWrite) \ 85 V(LdaZero, AccumulatorUse::kWrite) \
32 V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \ 86 V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \
33 V(LdaUndefined, AccumulatorUse::kWrite) \ 87 V(LdaUndefined, AccumulatorUse::kWrite) \
34 V(LdaNull, AccumulatorUse::kWrite) \ 88 V(LdaNull, AccumulatorUse::kWrite) \
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 V(Throw, AccumulatorUse::kRead) \ 299 V(Throw, AccumulatorUse::kRead) \
246 V(ReThrow, AccumulatorUse::kRead) \ 300 V(ReThrow, AccumulatorUse::kRead) \
247 V(Return, AccumulatorUse::kRead) \ 301 V(Return, AccumulatorUse::kRead) \
248 \ 302 \
249 /* Generators */ \ 303 /* Generators */ \
250 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \ 304 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \
251 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg) \ 305 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg) \
252 \ 306 \
253 /* Debugger */ \ 307 /* Debugger */ \
254 V(Debugger, AccumulatorUse::kNone) \ 308 V(Debugger, AccumulatorUse::kNone) \
255 \ 309 DEBUG_BREAK_BYTECODE_LIST(V) \
256 /* Debug Breakpoints - one for each possible size of unscaled bytecodes */ \
257 /* and one for each operand widening prefix bytecode */ \
258 V(DebugBreak0, AccumulatorUse::kRead) \
259 V(DebugBreak1, AccumulatorUse::kRead, OperandType::kReg) \
260 V(DebugBreak2, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg) \
261 V(DebugBreak3, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
262 OperandType::kReg) \
263 V(DebugBreak4, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
264 OperandType::kReg, OperandType::kReg) \
265 V(DebugBreak5, AccumulatorUse::kRead, OperandType::kRuntimeId, \
266 OperandType::kReg, OperandType::kReg) \
267 V(DebugBreak6, AccumulatorUse::kRead, OperandType::kRuntimeId, \
268 OperandType::kReg, OperandType::kReg, OperandType::kReg) \
269 V(DebugBreakWide, AccumulatorUse::kRead) \
270 V(DebugBreakExtraWide, AccumulatorUse::kRead) \
271 \ 310 \
272 /* Illegal bytecode (terminates execution) */ \ 311 /* Illegal bytecode (terminates execution) */ \
273 V(Illegal, AccumulatorUse::kNone) \ 312 V(Illegal, AccumulatorUse::kNone) \
274 \ 313 \
275 /* No operation (used to maintain source positions for peephole */ \ 314 /* No operation (used to maintain source positions for peephole */ \
276 /* eliminated bytecodes). */ \ 315 /* eliminated bytecodes). */ \
277 V(Nop, AccumulatorUse::kNone) 316 V(Nop, AccumulatorUse::kNone)
278 317
279 // List of debug break bytecodes. 318 enum class AccumulatorUse : uint8_t {
280 #define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ 319 kNone = 0,
281 V(DebugBreak0) \ 320 kRead = 1 << 0,
282 V(DebugBreak1) \ 321 kWrite = 1 << 1,
283 V(DebugBreak2) \ 322 kReadWrite = kRead | kWrite
284 V(DebugBreak3) \ 323 };
285 V(DebugBreak4) \
286 V(DebugBreak5) \
287 V(DebugBreak6)
288 324
289 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \ 325 inline AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) {
290 V(DebugBreakWide) \ 326 int result = static_cast<int>(lhs) & static_cast<int>(rhs);
291 V(DebugBreakExtraWide) 327 return static_cast<AccumulatorUse>(result);
328 }
292 329
293 #define DEBUG_BREAK_BYTECODE_LIST(V) \ 330 inline AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) {
294 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ 331 int result = static_cast<int>(lhs) | static_cast<int>(rhs);
295 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) 332 return static_cast<AccumulatorUse>(result);
333 }
334
335 // Enumeration of scaling factors applicable to scalable operands. Code
336 // relies on being able to cast values to integer scaling values.
337 #define OPERAND_SCALE_LIST(V) \
338 V(Single, 1) \
339 V(Double, 2) \
340 V(Quadruple, 4)
341
342 enum class OperandScale : uint8_t {
343 #define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale,
344 OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE)
345 #undef DECLARE_OPERAND_SCALE
346 kLast = kQuadruple
347 };
348
349 // Enumeration of the size classes of operand types used by
350 // bytecodes. Code relies on being able to cast values to integer
351 // types to get the size in bytes.
352 enum class OperandSize : uint8_t {
353 kNone = 0,
354 kByte = 1,
355 kShort = 2,
356 kQuad = 4,
357 kLast = kQuad
358 };
359
360 // Primitive operand info used that summarize properties of operands.
361 // Columns are Name, IsScalable, IsUnsigned, UnscaledSize.
362 #define OPERAND_TYPE_INFO_LIST(V) \
363 V(None, false, false, OperandSize::kNone) \
364 V(ScalableSignedByte, true, false, OperandSize::kByte) \
365 V(ScalableUnsignedByte, true, true, OperandSize::kByte) \
366 V(FixedUnsignedByte, false, true, OperandSize::kByte) \
367 V(FixedUnsignedShort, false, true, OperandSize::kShort)
368
369 enum class OperandTypeInfo : uint8_t {
370 #define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name,
371 OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
372 #undef DECLARE_OPERAND_TYPE_INFO
373 };
374
375 // Enumeration of operand types used by bytecodes.
376 enum class OperandType : uint8_t {
377 #define DECLARE_OPERAND_TYPE(Name, _) k##Name,
378 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE)
379 #undef DECLARE_OPERAND_TYPE
380 #define COUNT_OPERAND_TYPES(x, _) +1
381 // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will
382 // evaluate to the same value as the last operand.
383 kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES)
384 #undef COUNT_OPERAND_TYPES
385 };
296 386
297 // Enumeration of interpreter bytecodes. 387 // Enumeration of interpreter bytecodes.
298 enum class Bytecode : uint8_t { 388 enum class Bytecode : uint8_t {
299 #define DECLARE_BYTECODE(Name, ...) k##Name, 389 #define DECLARE_BYTECODE(Name, ...) k##Name,
300 BYTECODE_LIST(DECLARE_BYTECODE) 390 BYTECODE_LIST(DECLARE_BYTECODE)
301 #undef DECLARE_BYTECODE 391 #undef DECLARE_BYTECODE
302 #define COUNT_BYTECODE(x, ...) +1 392 #define COUNT_BYTECODE(x, ...) +1
303 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will 393 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
304 // evaluate to the same value as the last real bytecode. 394 // evaluate to the same value as the last real bytecode.
305 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) 395 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
306 #undef COUNT_BYTECODE 396 #undef COUNT_BYTECODE
307 }; 397 };
308 398
309 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr.
310 // See crbug.com/603131.
311 #if V8_CC_MSVC
312 #define CONSTEXPR const
313 #else
314 #define CONSTEXPR constexpr
315 #endif
316
317 class Bytecodes final { 399 class Bytecodes final {
318 public: 400 public:
319 // The maximum number of operands a bytecode may have. 401 // The maximum number of operands a bytecode may have.
320 static const int kMaxOperands = 4; 402 static const int kMaxOperands = 4;
321 403
322 // Returns string representation of |bytecode|. 404 // Returns string representation of |bytecode|.
323 static const char* ToString(Bytecode bytecode); 405 static const char* ToString(Bytecode bytecode);
324 406
325 // Returns string representation of |bytecode|. 407 // Returns string representation of |bytecode|.
326 static std::string ToString(Bytecode bytecode, OperandScale operand_scale); 408 static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
327 409
410 // Returns string representation of |accumulator_use|.
411 static const char* AccumulatorUseToString(AccumulatorUse accumulator_use);
412
413 // Returns string representation of |operand_type|.
414 static const char* OperandTypeToString(OperandType operand_type);
415
416 // Returns string representation of |operand_scale|.
417 static const char* OperandScaleToString(OperandScale operand_scale);
418
419 // Returns string representation of |operand_size|.
420 static const char* OperandSizeToString(OperandSize operand_size);
421
328 // Returns byte value of bytecode. 422 // Returns byte value of bytecode.
329 static uint8_t ToByte(Bytecode bytecode) { 423 static uint8_t ToByte(Bytecode bytecode);
330 DCHECK_LE(bytecode, Bytecode::kLast);
331 return static_cast<uint8_t>(bytecode);
332 }
333 424
334 // Returns bytecode for |value|. 425 // Returns bytecode for |value|.
335 static Bytecode FromByte(uint8_t value) { 426 static Bytecode FromByte(uint8_t value);
336 Bytecode bytecode = static_cast<Bytecode>(value); 427
337 DCHECK(bytecode <= Bytecode::kLast); 428 // Returns the number of operands expected by |bytecode|.
338 return bytecode; 429 static int NumberOfOperands(Bytecode bytecode);
339 } 430
431 // Returns the number of register operands expected by |bytecode|.
432 static int NumberOfRegisterOperands(Bytecode bytecode);
340 433
341 // Returns the prefix bytecode representing an operand scale to be 434 // Returns the prefix bytecode representing an operand scale to be
342 // applied to a a bytecode. 435 // applied to a a bytecode.
343 static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale) { 436 static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale);
344 switch (operand_scale) {
345 case OperandScale::kQuadruple:
346 return Bytecode::kExtraWide;
347 case OperandScale::kDouble:
348 return Bytecode::kWide;
349 default:
350 UNREACHABLE();
351 return Bytecode::kIllegal;
352 }
353 }
354 437
355 // Returns true if the operand scale requires a prefix bytecode. 438 // Returns true if the operand scale requires a prefix bytecode.
356 static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) { 439 static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale);
357 return operand_scale != OperandScale::kSingle;
358 }
359 440
360 // Returns the scaling applied to scalable operands if bytecode is 441 // Returns the scaling applied to scalable operands if bytecode is
361 // is a scaling prefix. 442 // is a scaling prefix.
362 static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode) { 443 static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode);
363 switch (bytecode) {
364 case Bytecode::kExtraWide:
365 case Bytecode::kDebugBreakExtraWide:
366 return OperandScale::kQuadruple;
367 case Bytecode::kWide:
368 case Bytecode::kDebugBreakWide:
369 return OperandScale::kDouble;
370 default:
371 UNREACHABLE();
372 return OperandScale::kSingle;
373 }
374 }
375 444
376 // Returns how accumulator is used by |bytecode|. 445 // Returns how accumulator is used by |bytecode|.
377 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) { 446 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode);
378 DCHECK(bytecode <= Bytecode::kLast);
379 return kAccumulatorUse[static_cast<size_t>(bytecode)];
380 }
381 447
382 // Returns true if |bytecode| reads the accumulator. 448 // Returns true if |bytecode| reads the accumulator.
383 static bool ReadsAccumulator(Bytecode bytecode) { 449 static bool ReadsAccumulator(Bytecode bytecode);
384 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kRead) ==
385 AccumulatorUse::kRead;
386 }
387 450
388 // Returns true if |bytecode| writes the accumulator. 451 // Returns true if |bytecode| writes the accumulator.
389 static bool WritesAccumulator(Bytecode bytecode) { 452 static bool WritesAccumulator(Bytecode bytecode);
390 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) ==
391 AccumulatorUse::kWrite;
392 }
393 453
394 // Return true if |bytecode| writes the accumulator with a boolean value. 454 // Return true if |bytecode| writes the accumulator with a boolean value.
395 static bool WritesBooleanToAccumulator(Bytecode bytecode) { 455 static bool WritesBooleanToAccumulator(Bytecode bytecode);
396 switch (bytecode) {
397 case Bytecode::kLdaTrue:
398 case Bytecode::kLdaFalse:
399 case Bytecode::kToBooleanLogicalNot:
400 case Bytecode::kLogicalNot:
401 case Bytecode::kTestEqual:
402 case Bytecode::kTestNotEqual:
403 case Bytecode::kTestEqualStrict:
404 case Bytecode::kTestLessThan:
405 case Bytecode::kTestLessThanOrEqual:
406 case Bytecode::kTestGreaterThan:
407 case Bytecode::kTestGreaterThanOrEqual:
408 case Bytecode::kTestInstanceOf:
409 case Bytecode::kTestIn:
410 case Bytecode::kForInContinue:
411 return true;
412 default:
413 return false;
414 }
415 }
416 456
417 // Return true if |bytecode| is an accumulator load without effects, 457 // Return true if |bytecode| is an accumulator load without effects,
418 // e.g. LdaConstant, LdaTrue, Ldar. 458 // e.g. LdaConstant, LdaTrue, Ldar.
419 static CONSTEXPR bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode) { 459 static bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode);
420 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kLdaZero ||
421 bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaNull ||
422 bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse ||
423 bytecode == Bytecode::kLdaUndefined ||
424 bytecode == Bytecode::kLdaTheHole ||
425 bytecode == Bytecode::kLdaConstant;
426 }
427
428 // Return true if |bytecode| is a register load without effects,
429 // e.g. Mov, Star, LdrUndefined.
430 static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) {
431 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext ||
432 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar ||
433 bytecode == Bytecode::kLdrUndefined;
434 }
435
436 // Returns true if the bytecode is a conditional jump taking
437 // an immediate byte operand (OperandType::kImm).
438 static CONSTEXPR bool IsConditionalJumpImmediate(Bytecode bytecode) {
439 return bytecode == Bytecode::kJumpIfTrue ||
440 bytecode == Bytecode::kJumpIfFalse ||
441 bytecode == Bytecode::kJumpIfToBooleanTrue ||
442 bytecode == Bytecode::kJumpIfToBooleanFalse ||
443 bytecode == Bytecode::kJumpIfNotHole ||
444 bytecode == Bytecode::kJumpIfNull ||
445 bytecode == Bytecode::kJumpIfUndefined;
446 }
447
448 // Returns true if the bytecode is a conditional jump taking
449 // a constant pool entry (OperandType::kIdx).
450 static CONSTEXPR bool IsConditionalJumpConstant(Bytecode bytecode) {
451 return bytecode == Bytecode::kJumpIfTrueConstant ||
452 bytecode == Bytecode::kJumpIfFalseConstant ||
453 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
454 bytecode == Bytecode::kJumpIfToBooleanFalseConstant ||
455 bytecode == Bytecode::kJumpIfNotHoleConstant ||
456 bytecode == Bytecode::kJumpIfNullConstant ||
457 bytecode == Bytecode::kJumpIfUndefinedConstant;
458 }
459
460 // Returns true if the bytecode is a conditional jump taking
461 // any kind of operand.
462 static CONSTEXPR bool IsConditionalJump(Bytecode bytecode) {
463 return IsConditionalJumpImmediate(bytecode) ||
464 IsConditionalJumpConstant(bytecode);
465 }
466
467 // Returns true if the bytecode is a jump or a conditional jump taking
468 // an immediate byte operand (OperandType::kImm).
469 static CONSTEXPR bool IsJumpImmediate(Bytecode bytecode) {
470 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop ||
471 IsConditionalJumpImmediate(bytecode);
472 }
473
474 // Returns true if the bytecode is a jump or conditional jump taking a
475 // constant pool entry (OperandType::kIdx).
476 static CONSTEXPR bool IsJumpConstant(Bytecode bytecode) {
477 return bytecode == Bytecode::kJumpConstant ||
478 IsConditionalJumpConstant(bytecode);
479 }
480
481 // Returns true if the bytecode is a jump that internally coerces the
482 // accumulator to a boolean.
483 static CONSTEXPR bool IsJumpIfToBoolean(Bytecode bytecode) {
484 return bytecode == Bytecode::kJumpIfToBooleanTrue ||
485 bytecode == Bytecode::kJumpIfToBooleanFalse ||
486 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
487 bytecode == Bytecode::kJumpIfToBooleanFalseConstant;
488 }
489
490 // Returns true if the bytecode is a jump or conditional jump taking
491 // any kind of operand.
492 static CONSTEXPR bool IsJump(Bytecode bytecode) {
493 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
494 }
495
496 // Returns true if the bytecode is a conditional jump, a jump, or a return.
497 static CONSTEXPR bool IsJumpOrReturn(Bytecode bytecode) {
498 return bytecode == Bytecode::kReturn || IsJump(bytecode);
499 }
500 460
501 // Return true if |bytecode| is a jump without effects, 461 // Return true if |bytecode| is a jump without effects,
502 // e.g. any jump excluding those that include type coercion like 462 // e.g. any jump excluding those that include type coercion like
503 // JumpIfTrueToBoolean. 463 // JumpIfTrueToBoolean.
504 static CONSTEXPR bool IsJumpWithoutEffects(Bytecode bytecode) { 464 static bool IsJumpWithoutEffects(Bytecode bytecode);
505 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
506 }
507 465
508 // Returns true if |bytecode| has no effects. These bytecodes only manipulate 466 // Return true if |bytecode| is a register load without effects,
509 // interpreter frame state and will never throw. 467 // e.g. Mov, Star, LdrUndefined.
510 static CONSTEXPR bool IsWithoutExternalSideEffects(Bytecode bytecode) { 468 static bool IsRegisterLoadWithoutEffects(Bytecode bytecode);
511 return (IsAccumulatorLoadWithoutEffects(bytecode) ||
512 IsRegisterLoadWithoutEffects(bytecode) ||
513 bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode));
514 }
515 469
516 // Returns true if the bytecode is Ldar or Star. 470 // Returns true if |bytecode| has no effects.
517 static CONSTEXPR bool IsLdarOrStar(Bytecode bytecode) { 471 static bool IsWithoutExternalSideEffects(Bytecode bytecode);
518 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
519 }
520
521 // Returns true if |bytecode| puts a name in the accumulator.
522 static CONSTEXPR bool PutsNameInAccumulator(Bytecode bytecode) {
523 return bytecode == Bytecode::kTypeOf;
524 }
525
526 // Returns true if the bytecode is a call or a constructor call.
527 static CONSTEXPR bool IsCallOrNew(Bytecode bytecode) {
528 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall ||
529 bytecode == Bytecode::kNew;
530 }
531
532 // Returns true if the bytecode is a call to the runtime.
533 static CONSTEXPR bool IsCallRuntime(Bytecode bytecode) {
534 return bytecode == Bytecode::kCallRuntime ||
535 bytecode == Bytecode::kCallRuntimeForPair ||
536 bytecode == Bytecode::kInvokeIntrinsic;
537 }
538
539 // Returns true if the bytecode is a scaling prefix bytecode.
540 static CONSTEXPR bool IsPrefixScalingBytecode(Bytecode bytecode) {
541 return bytecode == Bytecode::kExtraWide || bytecode == Bytecode::kWide ||
542 bytecode == Bytecode::kDebugBreakExtraWide ||
543 bytecode == Bytecode::kDebugBreakWide;
544 }
545
546 // Returns the number of values which |bytecode| returns.
547 static CONSTEXPR size_t ReturnCount(Bytecode bytecode) {
548 return bytecode == Bytecode::kReturn ? 1 : 0;
549 }
550
551 // Returns the number of operands expected by |bytecode|.
552 static int NumberOfOperands(Bytecode bytecode) {
553 DCHECK(bytecode <= Bytecode::kLast);
554 return kOperandCount[static_cast<size_t>(bytecode)];
555 }
556 472
557 // Returns the i-th operand of |bytecode|. 473 // Returns the i-th operand of |bytecode|.
558 static OperandType GetOperandType(Bytecode bytecode, int i) { 474 static OperandType GetOperandType(Bytecode bytecode, int i);
559 DCHECK_LE(bytecode, Bytecode::kLast);
560 DCHECK_LT(i, NumberOfOperands(bytecode));
561 DCHECK_GE(i, 0);
562 return GetOperandTypes(bytecode)[i];
563 }
564 475
565 // Returns a pointer to an array of operand types terminated in 476 // Returns a pointer to an array of operand types terminated in
566 // OperandType::kNone. 477 // OperandType::kNone.
567 static const OperandType* GetOperandTypes(Bytecode bytecode) { 478 static const OperandType* GetOperandTypes(Bytecode bytecode);
568 DCHECK(bytecode <= Bytecode::kLast);
569 return kOperandTypes[static_cast<size_t>(bytecode)];
570 }
571 479
572 static bool OperandIsScalableSignedByte(Bytecode bytecode, 480 // Returns a pointer to an array of operand type info terminated in
573 int operand_index) { 481 // OperandTypeInfo::kNone.
574 DCHECK(bytecode <= Bytecode::kLast); 482 static const OperandTypeInfo* GetOperandTypeInfos(Bytecode bytecode);
575 return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] ==
576 OperandTypeInfo::kScalableSignedByte;
577 }
578
579 static bool OperandIsScalableUnsignedByte(Bytecode bytecode,
580 int operand_index) {
581 DCHECK(bytecode <= Bytecode::kLast);
582 return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] ==
583 OperandTypeInfo::kScalableUnsignedByte;
584 }
585
586 static bool OperandIsScalable(Bytecode bytecode, int operand_index) {
587 return OperandIsScalableSignedByte(bytecode, operand_index) ||
588 OperandIsScalableUnsignedByte(bytecode, operand_index);
589 }
590
591 // Returns true if the bytecode has wider operand forms.
592 static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
593 483
594 // Returns the size of the i-th operand of |bytecode|. 484 // Returns the size of the i-th operand of |bytecode|.
595 static OperandSize GetOperandSize(Bytecode bytecode, int i, 485 static OperandSize GetOperandSize(Bytecode bytecode, int i,
596 OperandScale operand_scale) { 486 OperandScale operand_scale);
597 CHECK_LT(i, NumberOfOperands(bytecode));
598 return GetOperandSizes(bytecode, operand_scale)[i];
599 }
600
601 // Returns the operand sizes of |bytecode| with scale |operand_scale|.
602 static const OperandSize* GetOperandSizes(Bytecode bytecode,
603 OperandScale operand_scale) {
604 DCHECK(bytecode <= Bytecode::kLast);
605 DCHECK_GE(operand_scale, OperandScale::kSingle);
606 DCHECK_LE(operand_scale, OperandScale::kLast);
607 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
608 OperandScale::kLast == OperandScale::kQuadruple);
609 int scale_index = static_cast<int>(operand_scale) >> 1;
610 return kOperandSizes[static_cast<size_t>(bytecode)][scale_index];
611 }
612 487
613 // Returns the offset of the i-th operand of |bytecode| relative to the start 488 // Returns the offset of the i-th operand of |bytecode| relative to the start
614 // of the bytecode. 489 // of the bytecode.
615 static int GetOperandOffset(Bytecode bytecode, int i, 490 static int GetOperandOffset(Bytecode bytecode, int i,
616 OperandScale operand_scale); 491 OperandScale operand_scale);
617 492
493 // Returns a debug break bytecode to replace |bytecode|.
494 static Bytecode GetDebugBreak(Bytecode bytecode);
495
618 // Returns the size of the bytecode including its operands for the 496 // Returns the size of the bytecode including its operands for the
619 // given |operand_scale|. 497 // given |operand_scale|.
620 static int Size(Bytecode bytecode, OperandScale operand_scale) { 498 static int Size(Bytecode bytecode, OperandScale operand_scale);
621 DCHECK(bytecode <= Bytecode::kLast);
622 STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
623 OperandScale::kLast == OperandScale::kQuadruple);
624 int scale_index = static_cast<int>(operand_scale) >> 1;
625 return kBytecodeSizes[static_cast<size_t>(bytecode)][scale_index];
626 }
627 499
628 // Returns a debug break bytecode to replace |bytecode|. 500 // Returns the size of |operand|.
629 static Bytecode GetDebugBreak(Bytecode bytecode); 501 static OperandSize SizeOfOperand(OperandType operand, OperandScale scale);
502
503 // Returns the number of values which |bytecode| returns.
504 static size_t ReturnCount(Bytecode bytecode);
505
506 // Returns true if the bytecode is a conditional jump taking
507 // an immediate byte operand (OperandType::kImm).
508 static bool IsConditionalJumpImmediate(Bytecode bytecode);
509
510 // Returns true if the bytecode is a conditional jump taking
511 // a constant pool entry (OperandType::kIdx).
512 static bool IsConditionalJumpConstant(Bytecode bytecode);
513
514 // Returns true if the bytecode is a conditional jump taking
515 // any kind of operand.
516 static bool IsConditionalJump(Bytecode bytecode);
517
518 // Returns true if the bytecode is a jump or a conditional jump taking
519 // an immediate byte operand (OperandType::kImm).
520 static bool IsJumpImmediate(Bytecode bytecode);
521
522 // Returns true if the bytecode is a jump or conditional jump taking a
523 // constant pool entry (OperandType::kIdx).
524 static bool IsJumpConstant(Bytecode bytecode);
525
526 // Returns true if the bytecode is a jump or conditional jump taking
527 // any kind of operand.
528 static bool IsJump(Bytecode bytecode);
529
530 // Returns true if the bytecode is a jump that internally coerces the
531 // accumulator to a boolean.
532 static bool IsJumpIfToBoolean(Bytecode bytecode);
630 533
631 // Returns the equivalent jump bytecode without the accumulator coercion. 534 // Returns the equivalent jump bytecode without the accumulator coercion.
632 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode); 535 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode);
633 536
537 // Returns true if the bytecode is a conditional jump, a jump, or a return.
538 static bool IsJumpOrReturn(Bytecode bytecode);
539
540 // Returns true if the bytecode is a call or a constructor call.
541 static bool IsCallOrNew(Bytecode bytecode);
542
543 // Returns true if the bytecode is a call to the runtime.
544 static bool IsCallRuntime(Bytecode bytecode);
545
634 // Returns true if the bytecode is a debug break. 546 // Returns true if the bytecode is a debug break.
635 static bool IsDebugBreak(Bytecode bytecode); 547 static bool IsDebugBreak(Bytecode bytecode);
636 548
549 // Returns true if the bytecode is Ldar or Star.
550 static bool IsLdarOrStar(Bytecode bytecode);
551
552 // Returns true if the bytecode has wider operand forms.
553 static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
554
555 // Returns true if the bytecode is a scaling prefix bytecode.
556 static bool IsPrefixScalingBytecode(Bytecode bytecode);
557
558 // Returns true if |bytecode| puts a name in the accumulator.
559 static bool PutsNameInAccumulator(Bytecode bytecode);
560
637 // Returns true if |operand_type| is any type of register operand. 561 // Returns true if |operand_type| is any type of register operand.
638 static bool IsRegisterOperandType(OperandType operand_type); 562 static bool IsRegisterOperandType(OperandType operand_type);
639 563
640 // Returns true if |operand_type| represents a register used as an input. 564 // Returns true if |operand_type| represents a register used as an input.
641 static bool IsRegisterInputOperandType(OperandType operand_type); 565 static bool IsRegisterInputOperandType(OperandType operand_type);
642 566
643 // Returns true if |operand_type| represents a register used as an output. 567 // Returns true if |operand_type| represents a register used as an output.
644 static bool IsRegisterOutputOperandType(OperandType operand_type); 568 static bool IsRegisterOutputOperandType(OperandType operand_type);
645 569
646 // Returns true if the handler for |bytecode| should look ahead and inline a 570 // Returns true if the handler for |bytecode| should look ahead and inline a
647 // dispatch to a Star bytecode. 571 // dispatch to a Star bytecode.
648 static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale); 572 static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale);
649 573
650 // Returns the number of registers represented by a register operand. For 574 // Returns the number of registers represented by a register operand. For
651 // instance, a RegPair represents two registers. 575 // instance, a RegPair represents two registers.
652 static int GetNumberOfRegistersRepresentedBy(OperandType operand_type) { 576 static int GetNumberOfRegistersRepresentedBy(OperandType operand_type);
653 switch (operand_type) {
654 case OperandType::kMaybeReg:
655 case OperandType::kReg:
656 case OperandType::kRegOut:
657 return 1;
658 case OperandType::kRegPair:
659 case OperandType::kRegOutPair:
660 return 2;
661 case OperandType::kRegOutTriple:
662 return 3;
663 default:
664 return 0;
665 }
666 return 0;
667 }
668 577
669 // Returns the size of |operand| for |operand_scale|. 578 // Returns true if |operand_type| is a maybe register operand
670 static OperandSize SizeOfOperand(OperandType operand, OperandScale scale); 579 // (kMaybeReg).
580 static bool IsMaybeRegisterOperandType(OperandType operand_type);
671 581
672 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId). 582 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId).
673 static bool IsRuntimeIdOperandType(OperandType operand_type); 583 static bool IsRuntimeIdOperandType(OperandType operand_type);
674 584
675 // Returns true if |operand_type| is unsigned, false if signed. 585 // Returns true if |operand_type| is unsigned, false if signed.
676 static bool IsUnsignedOperandType(OperandType operand_type); 586 static bool IsUnsignedOperandType(OperandType operand_type);
677 587
678 // Returns true if a handler is generated for a bytecode at a given 588 // Returns true if a handler is generated for a bytecode at a given
679 // operand scale. All bytecodes have handlers at OperandScale::kSingle, 589 // operand scale. All bytecodes have handlers at OperandScale::kSingle,
680 // but only bytecodes with scalable operands have handlers with larger 590 // but only bytecodes with scalable operands have handlers with larger
681 // OperandScale values. 591 // OperandScale values.
682 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale); 592 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
683 593
684 // Return the operand scale required to hold a signed operand with |value|. 594 // Return the operand size required to hold a signed operand.
685 static OperandScale ScaleForSignedOperand(int32_t value) { 595 static OperandSize SizeForSignedOperand(int value);
686 if (value >= kMinInt8 && value <= kMaxInt8) {
687 return OperandScale::kSingle;
688 } else if (value >= kMinInt16 && value <= kMaxInt16) {
689 return OperandScale::kDouble;
690 } else {
691 return OperandScale::kQuadruple;
692 }
693 }
694 596
695 // Return the operand scale required to hold an unsigned operand with |value|. 597 // Return the operand size required to hold an unsigned operand.
696 static OperandScale ScaleForUnsignedOperand(uint32_t value) { 598 static OperandSize SizeForUnsignedOperand(uint32_t value);
697 if (value <= kMaxUInt8) {
698 return OperandScale::kSingle;
699 } else if (value <= kMaxUInt16) {
700 return OperandScale::kDouble;
701 } else {
702 return OperandScale::kQuadruple;
703 }
704 }
705
706 // Return the operand size required to hold an unsigned operand with |value|.
707 static OperandSize SizeForUnsignedOperand(uint32_t value) {
708 if (value <= kMaxUInt8) {
709 return OperandSize::kByte;
710 } else if (value <= kMaxUInt16) {
711 return OperandSize::kShort;
712 } else {
713 return OperandSize::kQuad;
714 }
715 }
716
717 private:
718 static const OperandType* const kOperandTypes[];
719 static const OperandTypeInfo* const kOperandTypeInfos[];
720 static const int kOperandCount[];
721 static const int kNumberOfRegisterOperands[];
722 static const AccumulatorUse kAccumulatorUse[];
723 static const bool kIsScalable[];
724 static const int kBytecodeSizes[][3];
725 static const OperandSize* const kOperandSizes[][3];
726 }; 599 };
727 600
728 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr.
729 // See crbug.com/603131.
730 #undef CONSTEXPR
731
732 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode); 601 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode);
602 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use);
603 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale);
604 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size);
605 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type);
733 606
734 } // namespace interpreter 607 } // namespace interpreter
735 } // namespace internal 608 } // namespace internal
736 } // namespace v8 609 } // namespace v8
737 610
738 #endif // V8_INTERPRETER_BYTECODES_H_ 611 #endif // V8_INTERPRETER_BYTECODES_H_
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-traits.h ('k') | src/interpreter/bytecodes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698