OLD | NEW |
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 Loading... |
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_ |
OLD | NEW |