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

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

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/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
12 // This interface and it's implementation are independent of the 15 // This interface and it's implementation are independent of the
13 // libv8_base library as they are used by the interpreter and the 16 // libv8_base library as they are used by the interpreter and the
14 // standalone mkpeephole table generator program. 17 // standalone mkpeephole table generator program.
15 18
16 namespace v8 { 19 namespace v8 {
17 namespace internal { 20 namespace internal {
18 namespace interpreter { 21 namespace interpreter {
19 22
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
78 // The list of bytecodes which are interpreted by the interpreter. 23 // The list of bytecodes which are interpreted by the interpreter.
24 // Format is V(<bytecode>, <accumulator_use>, <operands>).
79 #define BYTECODE_LIST(V) \ 25 #define BYTECODE_LIST(V) \
80 /* Extended width operands */ \ 26 /* Extended width operands */ \
81 V(Wide, AccumulatorUse::kNone) \ 27 V(Wide, AccumulatorUse::kNone) \
82 V(ExtraWide, AccumulatorUse::kNone) \ 28 V(ExtraWide, AccumulatorUse::kNone) \
83 \ 29 \
84 /* Loading the accumulator */ \ 30 /* Loading the accumulator */ \
85 V(LdaZero, AccumulatorUse::kWrite) \ 31 V(LdaZero, AccumulatorUse::kWrite) \
86 V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \ 32 V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \
87 V(LdaUndefined, AccumulatorUse::kWrite) \ 33 V(LdaUndefined, AccumulatorUse::kWrite) \
88 V(LdaNull, AccumulatorUse::kWrite) \ 34 V(LdaNull, AccumulatorUse::kWrite) \
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 V(Throw, AccumulatorUse::kRead) \ 245 V(Throw, AccumulatorUse::kRead) \
300 V(ReThrow, AccumulatorUse::kRead) \ 246 V(ReThrow, AccumulatorUse::kRead) \
301 V(Return, AccumulatorUse::kRead) \ 247 V(Return, AccumulatorUse::kRead) \
302 \ 248 \
303 /* Generators */ \ 249 /* Generators */ \
304 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \ 250 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \
305 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg) \ 251 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg) \
306 \ 252 \
307 /* Debugger */ \ 253 /* Debugger */ \
308 V(Debugger, AccumulatorUse::kNone) \ 254 V(Debugger, AccumulatorUse::kNone) \
309 DEBUG_BREAK_BYTECODE_LIST(V) \ 255 \
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) \
310 \ 271 \
311 /* Illegal bytecode (terminates execution) */ \ 272 /* Illegal bytecode (terminates execution) */ \
312 V(Illegal, AccumulatorUse::kNone) \ 273 V(Illegal, AccumulatorUse::kNone) \
313 \ 274 \
314 /* No operation (used to maintain source positions for peephole */ \ 275 /* No operation (used to maintain source positions for peephole */ \
315 /* eliminated bytecodes). */ \ 276 /* eliminated bytecodes). */ \
316 V(Nop, AccumulatorUse::kNone) 277 V(Nop, AccumulatorUse::kNone)
317 278
318 enum class AccumulatorUse : uint8_t { 279 // List of debug break bytecodes.
319 kNone = 0, 280 #define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
320 kRead = 1 << 0, 281 V(DebugBreak0) \
321 kWrite = 1 << 1, 282 V(DebugBreak1) \
322 kReadWrite = kRead | kWrite 283 V(DebugBreak2) \
323 }; 284 V(DebugBreak3) \
285 V(DebugBreak4) \
286 V(DebugBreak5) \
287 V(DebugBreak6)
324 288
325 inline AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) { 289 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \
326 int result = static_cast<int>(lhs) & static_cast<int>(rhs); 290 V(DebugBreakWide) \
327 return static_cast<AccumulatorUse>(result); 291 V(DebugBreakExtraWide)
328 }
329 292
330 inline AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) { 293 #define DEBUG_BREAK_BYTECODE_LIST(V) \
331 int result = static_cast<int>(lhs) | static_cast<int>(rhs); 294 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
332 return static_cast<AccumulatorUse>(result); 295 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V)
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 };
386 296
387 // Enumeration of interpreter bytecodes. 297 // Enumeration of interpreter bytecodes.
388 enum class Bytecode : uint8_t { 298 enum class Bytecode : uint8_t {
389 #define DECLARE_BYTECODE(Name, ...) k##Name, 299 #define DECLARE_BYTECODE(Name, ...) k##Name,
390 BYTECODE_LIST(DECLARE_BYTECODE) 300 BYTECODE_LIST(DECLARE_BYTECODE)
391 #undef DECLARE_BYTECODE 301 #undef DECLARE_BYTECODE
392 #define COUNT_BYTECODE(x, ...) +1 302 #define COUNT_BYTECODE(x, ...) +1
393 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will 303 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
394 // evaluate to the same value as the last real bytecode. 304 // evaluate to the same value as the last real bytecode.
395 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) 305 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
396 #undef COUNT_BYTECODE 306 #undef COUNT_BYTECODE
397 }; 307 };
398 308
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
399 class Bytecodes final { 317 class Bytecodes final {
400 public: 318 public:
401 // The maximum number of operands a bytecode may have. 319 // The maximum number of operands a bytecode may have.
402 static const int kMaxOperands = 4; 320 static const int kMaxOperands = 4;
403 321
404 // Returns string representation of |bytecode|. 322 // Returns string representation of |bytecode|.
405 static const char* ToString(Bytecode bytecode); 323 static const char* ToString(Bytecode bytecode);
406 324
407 // Returns string representation of |bytecode|. 325 // Returns string representation of |bytecode|.
408 static std::string ToString(Bytecode bytecode, OperandScale operand_scale); 326 static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
409 327
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
422 // Returns byte value of bytecode. 328 // Returns byte value of bytecode.
423 static uint8_t ToByte(Bytecode bytecode); 329 static uint8_t ToByte(Bytecode bytecode) {
330 DCHECK_LE(bytecode, Bytecode::kLast);
331 return static_cast<uint8_t>(bytecode);
332 }
424 333
425 // Returns bytecode for |value|. 334 // Returns bytecode for |value|.
426 static Bytecode FromByte(uint8_t value); 335 static Bytecode FromByte(uint8_t value) {
427 336 Bytecode bytecode = static_cast<Bytecode>(value);
428 // Returns the number of operands expected by |bytecode|. 337 DCHECK(bytecode <= Bytecode::kLast);
429 static int NumberOfOperands(Bytecode bytecode); 338 return bytecode;
430 339 }
431 // Returns the number of register operands expected by |bytecode|.
432 static int NumberOfRegisterOperands(Bytecode bytecode);
433 340
434 // Returns the prefix bytecode representing an operand scale to be 341 // Returns the prefix bytecode representing an operand scale to be
435 // applied to a a bytecode. 342 // applied to a a bytecode.
436 static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale); 343 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 }
437 354
438 // Returns true if the operand scale requires a prefix bytecode. 355 // Returns true if the operand scale requires a prefix bytecode.
439 static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale); 356 static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) {
357 return operand_scale != OperandScale::kSingle;
358 }
440 359
441 // Returns the scaling applied to scalable operands if bytecode is 360 // Returns the scaling applied to scalable operands if bytecode is
442 // is a scaling prefix. 361 // is a scaling prefix.
443 static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode); 362 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 }
444 375
445 // Returns how accumulator is used by |bytecode|. 376 // Returns how accumulator is used by |bytecode|.
446 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode); 377 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) {
378 DCHECK(bytecode <= Bytecode::kLast);
379 return kAccumulatorUse[static_cast<size_t>(bytecode)];
380 }
447 381
448 // Returns true if |bytecode| reads the accumulator. 382 // Returns true if |bytecode| reads the accumulator.
449 static bool ReadsAccumulator(Bytecode bytecode); 383 static bool ReadsAccumulator(Bytecode bytecode) {
384 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kRead) ==
385 AccumulatorUse::kRead;
386 }
450 387
451 // Returns true if |bytecode| writes the accumulator. 388 // Returns true if |bytecode| writes the accumulator.
452 static bool WritesAccumulator(Bytecode bytecode); 389 static bool WritesAccumulator(Bytecode bytecode) {
390 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) ==
391 AccumulatorUse::kWrite;
392 }
453 393
454 // Return true if |bytecode| writes the accumulator with a boolean value. 394 // Return true if |bytecode| writes the accumulator with a boolean value.
455 static bool WritesBooleanToAccumulator(Bytecode bytecode); 395 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 }
456 416
457 // Return true if |bytecode| is an accumulator load without effects, 417 // Return true if |bytecode| is an accumulator load without effects,
458 // e.g. LdaConstant, LdaTrue, Ldar. 418 // e.g. LdaConstant, LdaTrue, Ldar.
459 static bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode); 419 static CONSTEXPR 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 }
460 500
461 // Return true if |bytecode| is a jump without effects, 501 // Return true if |bytecode| is a jump without effects,
462 // e.g. any jump excluding those that include type coercion like 502 // e.g. any jump excluding those that include type coercion like
463 // JumpIfTrueToBoolean. 503 // JumpIfTrueToBoolean.
464 static bool IsJumpWithoutEffects(Bytecode bytecode); 504 static CONSTEXPR bool IsJumpWithoutEffects(Bytecode bytecode) {
465 505 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
466 // Return true if |bytecode| is a register load without effects, 506 }
467 // e.g. Mov, Star, LdrUndefined. 507
468 static bool IsRegisterLoadWithoutEffects(Bytecode bytecode); 508 // Returns true if |bytecode| has no effects. These bytecodes only manipulate
469 509 // interpreter frame state and will never throw.
470 // Returns true if |bytecode| has no effects. 510 static CONSTEXPR bool IsWithoutExternalSideEffects(Bytecode bytecode) {
471 static bool IsWithoutExternalSideEffects(Bytecode bytecode); 511 return (IsAccumulatorLoadWithoutEffects(bytecode) ||
512 IsRegisterLoadWithoutEffects(bytecode) ||
513 bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode));
514 }
515
516 // Returns true if the bytecode is Ldar or Star.
517 static CONSTEXPR bool IsLdarOrStar(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 }
472 556
473 // Returns the i-th operand of |bytecode|. 557 // Returns the i-th operand of |bytecode|.
474 static OperandType GetOperandType(Bytecode bytecode, int i); 558 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 }
475 564
476 // Returns a pointer to an array of operand types terminated in 565 // Returns a pointer to an array of operand types terminated in
477 // OperandType::kNone. 566 // OperandType::kNone.
478 static const OperandType* GetOperandTypes(Bytecode bytecode); 567 static const OperandType* GetOperandTypes(Bytecode bytecode) {
479 568 DCHECK(bytecode <= Bytecode::kLast);
480 // Returns a pointer to an array of operand type info terminated in 569 return kOperandTypes[static_cast<size_t>(bytecode)];
481 // OperandTypeInfo::kNone. 570 }
482 static const OperandTypeInfo* GetOperandTypeInfos(Bytecode bytecode); 571
572 static bool OperandIsScalableSignedByte(Bytecode bytecode,
573 int operand_index) {
574 DCHECK(bytecode <= Bytecode::kLast);
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);
483 593
484 // Returns the size of the i-th operand of |bytecode|. 594 // Returns the size of the i-th operand of |bytecode|.
485 static OperandSize GetOperandSize(Bytecode bytecode, int i, 595 static OperandSize GetOperandSize(Bytecode bytecode, int i,
486 OperandScale operand_scale); 596 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 }
487 612
488 // Returns the offset of the i-th operand of |bytecode| relative to the start 613 // Returns the offset of the i-th operand of |bytecode| relative to the start
489 // of the bytecode. 614 // of the bytecode.
490 static int GetOperandOffset(Bytecode bytecode, int i, 615 static int GetOperandOffset(Bytecode bytecode, int i,
491 OperandScale operand_scale); 616 OperandScale operand_scale);
492 617
618 // Returns the size of the bytecode including its operands for the
619 // given |operand_scale|.
620 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
493 // Returns a debug break bytecode to replace |bytecode|. 628 // Returns a debug break bytecode to replace |bytecode|.
494 static Bytecode GetDebugBreak(Bytecode bytecode); 629 static Bytecode GetDebugBreak(Bytecode bytecode);
495 630
496 // Returns the size of the bytecode including its operands for the
497 // given |operand_scale|.
498 static int Size(Bytecode bytecode, OperandScale operand_scale);
499
500 // Returns the size of |operand|.
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);
533
534 // Returns the equivalent jump bytecode without the accumulator coercion. 631 // Returns the equivalent jump bytecode without the accumulator coercion.
535 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode); 632 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode);
536 633
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
546 // Returns true if the bytecode is a debug break. 634 // Returns true if the bytecode is a debug break.
547 static bool IsDebugBreak(Bytecode bytecode); 635 static bool IsDebugBreak(Bytecode bytecode);
548 636
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
561 // Returns true if |operand_type| is any type of register operand. 637 // Returns true if |operand_type| is any type of register operand.
562 static bool IsRegisterOperandType(OperandType operand_type); 638 static bool IsRegisterOperandType(OperandType operand_type);
563 639
564 // Returns true if |operand_type| represents a register used as an input. 640 // Returns true if |operand_type| represents a register used as an input.
565 static bool IsRegisterInputOperandType(OperandType operand_type); 641 static bool IsRegisterInputOperandType(OperandType operand_type);
566 642
567 // Returns true if |operand_type| represents a register used as an output. 643 // Returns true if |operand_type| represents a register used as an output.
568 static bool IsRegisterOutputOperandType(OperandType operand_type); 644 static bool IsRegisterOutputOperandType(OperandType operand_type);
569 645
570 // Returns true if the handler for |bytecode| should look ahead and inline a 646 // Returns true if the handler for |bytecode| should look ahead and inline a
571 // dispatch to a Star bytecode. 647 // dispatch to a Star bytecode.
572 static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale); 648 static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale);
573 649
574 // Returns the number of registers represented by a register operand. For 650 // Returns the number of registers represented by a register operand. For
575 // instance, a RegPair represents two registers. 651 // instance, a RegPair represents two registers.
576 static int GetNumberOfRegistersRepresentedBy(OperandType operand_type); 652 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 }
577 668
578 // Returns true if |operand_type| is a maybe register operand 669 // Returns the size of |operand| for |operand_scale|.
579 // (kMaybeReg). 670 static OperandSize SizeOfOperand(OperandType operand, OperandScale scale);
580 static bool IsMaybeRegisterOperandType(OperandType operand_type);
581 671
582 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId). 672 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId).
583 static bool IsRuntimeIdOperandType(OperandType operand_type); 673 static bool IsRuntimeIdOperandType(OperandType operand_type);
584 674
585 // Returns true if |operand_type| is unsigned, false if signed. 675 // Returns true if |operand_type| is unsigned, false if signed.
586 static bool IsUnsignedOperandType(OperandType operand_type); 676 static bool IsUnsignedOperandType(OperandType operand_type);
587 677
588 // Returns true if a handler is generated for a bytecode at a given 678 // Returns true if a handler is generated for a bytecode at a given
589 // operand scale. All bytecodes have handlers at OperandScale::kSingle, 679 // operand scale. All bytecodes have handlers at OperandScale::kSingle,
590 // but only bytecodes with scalable operands have handlers with larger 680 // but only bytecodes with scalable operands have handlers with larger
591 // OperandScale values. 681 // OperandScale values.
592 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale); 682 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
593 683
594 // Return the operand size required to hold a signed operand. 684 // Return the operand scale required to hold a signed operand with |value|.
595 static OperandSize SizeForSignedOperand(int value); 685 static OperandScale ScaleForSignedOperand(int32_t 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 }
596 694
597 // Return the operand size required to hold an unsigned operand. 695 // Return the operand scale required to hold an unsigned operand with |value|.
598 static OperandSize SizeForUnsignedOperand(uint32_t value); 696 static OperandScale ScaleForUnsignedOperand(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];
599 }; 726 };
600 727
728 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr.
729 // See crbug.com/603131.
730 #undef CONSTEXPR
731
601 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode); 732 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);
606 733
607 } // namespace interpreter 734 } // namespace interpreter
608 } // namespace internal 735 } // namespace internal
609 } // namespace v8 736 } // namespace v8
610 737
611 #endif // V8_INTERPRETER_BYTECODES_H_ 738 #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