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

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

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

Powered by Google App Engine
This is Rietveld 408576698