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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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_ |
OLD | NEW |