diff options
Diffstat (limited to 'deps/v8/src/interpreter/bytecodes.cc')
-rw-r--r-- | deps/v8/src/interpreter/bytecodes.cc | 532 |
1 files changed, 70 insertions, 462 deletions
diff --git a/deps/v8/src/interpreter/bytecodes.cc b/deps/v8/src/interpreter/bytecodes.cc index 09bcd22b92..c58f4685a2 100644 --- a/deps/v8/src/interpreter/bytecodes.cc +++ b/deps/v8/src/interpreter/bytecodes.cc @@ -7,14 +7,55 @@ #include <iomanip> #include "src/base/bits.h" -#include "src/globals.h" #include "src/interpreter/bytecode-traits.h" namespace v8 { namespace internal { namespace interpreter { -STATIC_CONST_MEMBER_DEFINITION const int Bytecodes::kMaxOperands; +// clang-format off +const OperandType* const Bytecodes::kOperandTypes[] = { +#define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandTypes, + BYTECODE_LIST(ENTRY) +#undef ENTRY +}; + +const OperandTypeInfo* const Bytecodes::kOperandTypeInfos[] = { +#define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandTypeInfos, + BYTECODE_LIST(ENTRY) +#undef ENTRY +}; + +const int Bytecodes::kOperandCount[] = { +#define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandCount, + BYTECODE_LIST(ENTRY) +#undef ENTRY +}; + +const AccumulatorUse Bytecodes::kAccumulatorUse[] = { +#define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kAccumulatorUse, + BYTECODE_LIST(ENTRY) +#undef ENTRY +}; + +const int Bytecodes::kBytecodeSizes[][3] = { +#define ENTRY(Name, ...) \ + { BytecodeTraits<__VA_ARGS__>::kSingleScaleSize, \ + BytecodeTraits<__VA_ARGS__>::kDoubleScaleSize, \ + BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleSize }, + BYTECODE_LIST(ENTRY) +#undef ENTRY +}; + +const OperandSize* const Bytecodes::kOperandSizes[][3] = { +#define ENTRY(Name, ...) \ + { BytecodeTraits<__VA_ARGS__>::kSingleScaleOperandSizes, \ + BytecodeTraits<__VA_ARGS__>::kDoubleScaleOperandSizes, \ + BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleOperandSizes }, + BYTECODE_LIST(ENTRY) +#undef ENTRY +}; +// clang-format on // static const char* Bytecodes::ToString(Bytecode bytecode) { @@ -44,77 +85,6 @@ std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale) { } // static -const char* Bytecodes::AccumulatorUseToString(AccumulatorUse accumulator_use) { - switch (accumulator_use) { - case AccumulatorUse::kNone: - return "None"; - case AccumulatorUse::kRead: - return "Read"; - case AccumulatorUse::kWrite: - return "Write"; - case AccumulatorUse::kReadWrite: - return "ReadWrite"; - } - UNREACHABLE(); - return ""; -} - -// static -const char* Bytecodes::OperandTypeToString(OperandType operand_type) { - switch (operand_type) { -#define CASE(Name, _) \ - case OperandType::k##Name: \ - return #Name; - OPERAND_TYPE_LIST(CASE) -#undef CASE - } - UNREACHABLE(); - return ""; -} - -// static -const char* Bytecodes::OperandScaleToString(OperandScale operand_scale) { - switch (operand_scale) { -#define CASE(Name, _) \ - case OperandScale::k##Name: \ - return #Name; - OPERAND_SCALE_LIST(CASE) -#undef CASE - } - UNREACHABLE(); - return ""; -} - -// static -const char* Bytecodes::OperandSizeToString(OperandSize operand_size) { - switch (operand_size) { - case OperandSize::kNone: - return "None"; - case OperandSize::kByte: - return "Byte"; - case OperandSize::kShort: - return "Short"; - case OperandSize::kQuad: - return "Quad"; - } - UNREACHABLE(); - return ""; -} - -// static -uint8_t Bytecodes::ToByte(Bytecode bytecode) { - DCHECK_LE(bytecode, Bytecode::kLast); - return static_cast<uint8_t>(bytecode); -} - -// static -Bytecode Bytecodes::FromByte(uint8_t value) { - Bytecode bytecode = static_cast<Bytecode>(value); - DCHECK(bytecode <= Bytecode::kLast); - return bytecode; -} - -// static Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) { DCHECK(!IsDebugBreak(bytecode)); if (bytecode == Bytecode::kWide) { @@ -124,7 +94,7 @@ Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) { return Bytecode::kDebugBreakExtraWide; } int bytecode_size = Size(bytecode, OperandScale::kSingle); -#define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name, ...) \ +#define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name) \ if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \ return Bytecode::k##Name; \ } @@ -135,224 +105,6 @@ Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) { } // static -int Bytecodes::Size(Bytecode bytecode, OperandScale operand_scale) { - int size = 1; - for (int i = 0; i < NumberOfOperands(bytecode); i++) { - OperandSize operand_size = GetOperandSize(bytecode, i, operand_scale); - int delta = static_cast<int>(operand_size); - DCHECK(base::bits::IsPowerOfTwo32(static_cast<uint32_t>(delta))); - size += delta; - } - return size; -} - -// static -size_t Bytecodes::ReturnCount(Bytecode bytecode) { - return bytecode == Bytecode::kReturn ? 1 : 0; -} - -// static -int Bytecodes::NumberOfOperands(Bytecode bytecode) { - DCHECK(bytecode <= Bytecode::kLast); - switch (bytecode) { -#define CASE(Name, ...) \ - case Bytecode::k##Name: \ - return BytecodeTraits<__VA_ARGS__>::kOperandCount; - BYTECODE_LIST(CASE) -#undef CASE - } - UNREACHABLE(); - return 0; -} - -// static -int Bytecodes::NumberOfRegisterOperands(Bytecode bytecode) { - DCHECK(bytecode <= Bytecode::kLast); - switch (bytecode) { -#define CASE(Name, ...) \ - case Bytecode::k##Name: \ - typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \ - return Name##Trait::kRegisterOperandCount; - BYTECODE_LIST(CASE) -#undef CASE - } - UNREACHABLE(); - return false; -} - -// static -Bytecode Bytecodes::OperandScaleToPrefixBytecode(OperandScale operand_scale) { - switch (operand_scale) { - case OperandScale::kQuadruple: - return Bytecode::kExtraWide; - case OperandScale::kDouble: - return Bytecode::kWide; - default: - UNREACHABLE(); - return Bytecode::kIllegal; - } -} - -// static -bool Bytecodes::OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) { - return operand_scale != OperandScale::kSingle; -} - -// static -OperandScale Bytecodes::PrefixBytecodeToOperandScale(Bytecode bytecode) { - switch (bytecode) { - case Bytecode::kExtraWide: - case Bytecode::kDebugBreakExtraWide: - return OperandScale::kQuadruple; - case Bytecode::kWide: - case Bytecode::kDebugBreakWide: - return OperandScale::kDouble; - default: - UNREACHABLE(); - return OperandScale::kSingle; - } -} - -// static -AccumulatorUse Bytecodes::GetAccumulatorUse(Bytecode bytecode) { - DCHECK(bytecode <= Bytecode::kLast); - switch (bytecode) { -#define CASE(Name, ...) \ - case Bytecode::k##Name: \ - return BytecodeTraits<__VA_ARGS__>::kAccumulatorUse; - BYTECODE_LIST(CASE) -#undef CASE - } - UNREACHABLE(); - return AccumulatorUse::kNone; -} - -// static -bool Bytecodes::ReadsAccumulator(Bytecode bytecode) { - return (GetAccumulatorUse(bytecode) & AccumulatorUse::kRead) == - AccumulatorUse::kRead; -} - -// static -bool Bytecodes::WritesAccumulator(Bytecode bytecode) { - return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) == - AccumulatorUse::kWrite; -} - -// static -bool Bytecodes::WritesBooleanToAccumulator(Bytecode bytecode) { - switch (bytecode) { - case Bytecode::kLdaTrue: - case Bytecode::kLdaFalse: - case Bytecode::kToBooleanLogicalNot: - case Bytecode::kLogicalNot: - case Bytecode::kTestEqual: - case Bytecode::kTestNotEqual: - case Bytecode::kTestEqualStrict: - case Bytecode::kTestLessThan: - case Bytecode::kTestLessThanOrEqual: - case Bytecode::kTestGreaterThan: - case Bytecode::kTestGreaterThanOrEqual: - case Bytecode::kTestInstanceOf: - case Bytecode::kTestIn: - case Bytecode::kForInDone: - return true; - default: - return false; - } -} - -// static -bool Bytecodes::IsAccumulatorLoadWithoutEffects(Bytecode bytecode) { - switch (bytecode) { - case Bytecode::kLdaZero: - case Bytecode::kLdaSmi: - case Bytecode::kLdaUndefined: - case Bytecode::kLdaNull: - case Bytecode::kLdaTheHole: - case Bytecode::kLdaTrue: - case Bytecode::kLdaFalse: - case Bytecode::kLdaConstant: - case Bytecode::kLdar: - return true; - default: - return false; - } -} - -// static -bool Bytecodes::IsJumpWithoutEffects(Bytecode bytecode) { - return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode); -} - -// static -bool Bytecodes::IsRegisterLoadWithoutEffects(Bytecode bytecode) { - switch (bytecode) { - case Bytecode::kMov: - case Bytecode::kPopContext: - case Bytecode::kPushContext: - case Bytecode::kStar: - case Bytecode::kLdrUndefined: - return true; - default: - return false; - } -} - -// static -bool Bytecodes::IsWithoutExternalSideEffects(Bytecode bytecode) { - // These bytecodes only manipulate interpreter frame state and will - // never throw. - return (IsAccumulatorLoadWithoutEffects(bytecode) || - IsRegisterLoadWithoutEffects(bytecode) || - bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode)); -} - -// static -OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { - DCHECK_LE(bytecode, Bytecode::kLast); - DCHECK_LT(i, NumberOfOperands(bytecode)); - DCHECK_GE(i, 0); - return GetOperandTypes(bytecode)[i]; -} - -// static -const OperandType* Bytecodes::GetOperandTypes(Bytecode bytecode) { - DCHECK(bytecode <= Bytecode::kLast); - switch (bytecode) { -#define CASE(Name, ...) \ - case Bytecode::k##Name: \ - return BytecodeTraits<__VA_ARGS__>::GetOperandTypes(); - BYTECODE_LIST(CASE) -#undef CASE - } - UNREACHABLE(); - return nullptr; -} - -// static -const OperandTypeInfo* Bytecodes::GetOperandTypeInfos(Bytecode bytecode) { - DCHECK(bytecode <= Bytecode::kLast); - switch (bytecode) { -#define CASE(Name, ...) \ - case Bytecode::k##Name: \ - return BytecodeTraits<__VA_ARGS__>::GetOperandTypeInfos(); - BYTECODE_LIST(CASE) -#undef CASE - } - UNREACHABLE(); - return nullptr; -} - -// static -OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i, - OperandScale operand_scale) { - DCHECK_LT(i, NumberOfOperands(bytecode)); - OperandType operand_type = GetOperandType(bytecode, i); - return SizeOfOperand(operand_type, operand_scale); -} - -// static int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, OperandScale operand_scale) { DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode)); @@ -367,67 +119,6 @@ int Bytecodes::GetOperandOffset(Bytecode bytecode, int i, } // static -OperandSize Bytecodes::SizeOfOperand(OperandType operand_type, - OperandScale operand_scale) { - return static_cast<OperandSize>( - ScaledOperandSize(operand_type, operand_scale)); -} - -// static -bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) { - return bytecode == Bytecode::kJumpIfTrue || - bytecode == Bytecode::kJumpIfFalse || - bytecode == Bytecode::kJumpIfToBooleanTrue || - bytecode == Bytecode::kJumpIfToBooleanFalse || - bytecode == Bytecode::kJumpIfNotHole || - bytecode == Bytecode::kJumpIfNull || - bytecode == Bytecode::kJumpIfUndefined; -} - -// static -bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) { - return bytecode == Bytecode::kJumpIfTrueConstant || - bytecode == Bytecode::kJumpIfFalseConstant || - bytecode == Bytecode::kJumpIfToBooleanTrueConstant || - bytecode == Bytecode::kJumpIfToBooleanFalseConstant || - bytecode == Bytecode::kJumpIfNotHoleConstant || - bytecode == Bytecode::kJumpIfNullConstant || - bytecode == Bytecode::kJumpIfUndefinedConstant; -} - -// static -bool Bytecodes::IsConditionalJump(Bytecode bytecode) { - return IsConditionalJumpImmediate(bytecode) || - IsConditionalJumpConstant(bytecode); -} - - -// static -bool Bytecodes::IsJumpImmediate(Bytecode bytecode) { - return bytecode == Bytecode::kJump || IsConditionalJumpImmediate(bytecode); -} - - -// static -bool Bytecodes::IsJumpConstant(Bytecode bytecode) { - return bytecode == Bytecode::kJumpConstant || - IsConditionalJumpConstant(bytecode); -} - -// static -bool Bytecodes::IsJump(Bytecode bytecode) { - return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); -} - -// static -bool Bytecodes::IsJumpIfToBoolean(Bytecode bytecode) { - return bytecode == Bytecode::kJumpIfToBooleanTrue || - bytecode == Bytecode::kJumpIfToBooleanFalse || - bytecode == Bytecode::kJumpIfToBooleanTrueConstant || - bytecode == Bytecode::kJumpIfToBooleanFalseConstant; -} - -// static Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) { switch (bytecode) { case Bytecode::kJumpIfToBooleanTrue: @@ -446,19 +137,6 @@ Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) { } // static -bool Bytecodes::IsCallOrNew(Bytecode bytecode) { - return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall || - bytecode == Bytecode::kNew; -} - -// static -bool Bytecodes::IsCallRuntime(Bytecode bytecode) { - return bytecode == Bytecode::kCallRuntime || - bytecode == Bytecode::kCallRuntimeForPair || - bytecode == Bytecode::kInvokeIntrinsic; -} - -// static bool Bytecodes::IsDebugBreak(Bytecode bytecode) { switch (bytecode) { #define CASE(Name, ...) case Bytecode::k##Name: @@ -472,53 +150,6 @@ bool Bytecodes::IsDebugBreak(Bytecode bytecode) { } // static -bool Bytecodes::IsLdarOrStar(Bytecode bytecode) { - return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar; -} - -// static -bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) { - switch (bytecode) { -#define CASE(Name, ...) \ - case Bytecode::k##Name: \ - typedef BytecodeTraits<__VA_ARGS__> Name##Trait; \ - return Name##Trait::IsScalable(); - BYTECODE_LIST(CASE) -#undef CASE - } - UNREACHABLE(); - return false; -} - -// static -bool Bytecodes::IsPrefixScalingBytecode(Bytecode bytecode) { - switch (bytecode) { - case Bytecode::kExtraWide: - case Bytecode::kDebugBreakExtraWide: - case Bytecode::kWide: - case Bytecode::kDebugBreakWide: - return true; - default: - return false; - } -} - -// static -bool Bytecodes::PutsNameInAccumulator(Bytecode bytecode) { - return bytecode == Bytecode::kTypeOf; -} - -// static -bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) { - return bytecode == Bytecode::kReturn || IsJump(bytecode); -} - -// static -bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) { - return operand_type == OperandType::kMaybeReg; -} - -// static bool Bytecodes::IsRegisterOperandType(OperandType operand_type) { switch (operand_type) { #define CASE(Name, _) \ @@ -599,21 +230,11 @@ bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) { } // static -int Bytecodes::GetNumberOfRegistersRepresentedBy(OperandType operand_type) { - switch (operand_type) { - case OperandType::kMaybeReg: - case OperandType::kReg: - case OperandType::kRegOut: - return 1; - case OperandType::kRegPair: - case OperandType::kRegOutPair: - return 2; - case OperandType::kRegOutTriple: - return 3; - default: - return 0; +bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) { + for (int i = 0; i < NumberOfOperands(bytecode); i++) { + if (OperandIsScalable(bytecode, i)) return true; } - return 0; + return false; } // static @@ -630,25 +251,28 @@ bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) { } // static -OperandSize Bytecodes::SizeForSignedOperand(int value) { - if (value >= kMinInt8 && value <= kMaxInt8) { - return OperandSize::kByte; - } else if (value >= kMinInt16 && value <= kMaxInt16) { - return OperandSize::kShort; - } else { - return OperandSize::kQuad; - } -} - -// static -OperandSize Bytecodes::SizeForUnsignedOperand(uint32_t value) { - if (value <= kMaxUInt8) { - return OperandSize::kByte; - } else if (value <= kMaxUInt16) { - return OperandSize::kShort; - } else { - return OperandSize::kQuad; - } +OperandSize Bytecodes::SizeOfOperand(OperandType operand_type, + OperandScale operand_scale) { + DCHECK_LE(operand_type, OperandType::kLast); + DCHECK_GE(operand_scale, OperandScale::kSingle); + DCHECK_LE(operand_scale, OperandScale::kLast); + STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 && + OperandScale::kLast == OperandScale::kQuadruple); + int scale_index = static_cast<int>(operand_scale) >> 1; + // clang-format off + static const OperandSize kOperandSizes[][3] = { +#define ENTRY(Name, ...) \ + { OperandScaler<OperandType::k##Name, \ + OperandScale::kSingle>::kOperandSize, \ + OperandScaler<OperandType::k##Name, \ + OperandScale::kDouble>::kOperandSize, \ + OperandScaler<OperandType::k##Name, \ + OperandScale::kQuadruple>::kOperandSize }, + OPERAND_TYPE_LIST(ENTRY) +#undef ENTRY + }; + // clang-format on + return kOperandSizes[static_cast<size_t>(operand_type)][scale_index]; } // static @@ -662,22 +286,6 @@ std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) { return os << Bytecodes::ToString(bytecode); } -std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use) { - return os << Bytecodes::AccumulatorUseToString(use); -} - -std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) { - return os << Bytecodes::OperandSizeToString(operand_size); -} - -std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale) { - return os << Bytecodes::OperandScaleToString(operand_scale); -} - -std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) { - return os << Bytecodes::OperandTypeToString(operand_type); -} - } // namespace interpreter } // namespace internal } // namespace v8 |