| 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 |