| Index: src/interpreter/bytecodes.cc
|
| diff --git a/src/interpreter/bytecodes.cc b/src/interpreter/bytecodes.cc
|
| index 0c600843aebc6219dc04885895033191d1cacab6..8b78ee2e4929036f0acd5e54af2e27e9654d88eb 100644
|
| --- a/src/interpreter/bytecodes.cc
|
| +++ b/src/interpreter/bytecodes.cc
|
| @@ -7,59 +7,14 @@
|
| #include <iomanip>
|
|
|
| #include "src/base/bits.h"
|
| +#include "src/globals.h"
|
| #include "src/interpreter/bytecode-traits.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| namespace interpreter {
|
|
|
| -// clang-format off
|
| -STATIC_CONST_MEMBER_DEFINITION
|
| -const OperandType* const Bytecodes::kOperandTypes[] = {
|
| -#define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandTypes,
|
| - BYTECODE_LIST(ENTRY)
|
| -#undef ENTRY
|
| -};
|
| -
|
| -STATIC_CONST_MEMBER_DEFINITION
|
| -const OperandTypeInfo* const Bytecodes::kOperandTypeInfos[] = {
|
| -#define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandTypeInfos,
|
| - BYTECODE_LIST(ENTRY)
|
| -#undef ENTRY
|
| -};
|
| -
|
| -STATIC_CONST_MEMBER_DEFINITION const int Bytecodes::kOperandCount[] = {
|
| -#define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandCount,
|
| - BYTECODE_LIST(ENTRY)
|
| -#undef ENTRY
|
| -};
|
| -
|
| -STATIC_CONST_MEMBER_DEFINITION
|
| -const AccumulatorUse Bytecodes::kAccumulatorUse[] = {
|
| -#define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kAccumulatorUse,
|
| - BYTECODE_LIST(ENTRY)
|
| -#undef ENTRY
|
| -};
|
| -
|
| -STATIC_CONST_MEMBER_DEFINITION 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
|
| -};
|
| -
|
| -STATIC_CONST_MEMBER_DEFINITION
|
| -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_MEMBER_DEFINITION const int Bytecodes::kMaxOperands;
|
|
|
| // static
|
| const char* Bytecodes::ToString(Bytecode bytecode) {
|
| @@ -89,6 +44,77 @@
|
| }
|
|
|
| // 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) {
|
| @@ -98,7 +124,7 @@
|
| 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; \
|
| }
|
| @@ -106,6 +132,224 @@
|
| #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
|
| UNREACHABLE();
|
| return Bytecode::kIllegal;
|
| +}
|
| +
|
| +// 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::kForInContinue:
|
| + 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_LE(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
|
| @@ -123,6 +367,71 @@
|
| }
|
|
|
| // static
|
| +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);
|
| + 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 || bytecode == Bytecode::kJumpLoop ||
|
| + 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:
|
| @@ -141,6 +450,19 @@
|
| }
|
|
|
| // 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:
|
| @@ -151,6 +473,53 @@
|
| break;
|
| }
|
| return false;
|
| +}
|
| +
|
| +// 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
|
| @@ -234,11 +603,21 @@
|
| }
|
|
|
| // static
|
| -bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
|
| - for (int i = 0; i < NumberOfOperands(bytecode); i++) {
|
| - if (OperandIsScalable(bytecode, i)) return true;
|
| - }
|
| - return false;
|
| +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;
|
| + }
|
| + return 0;
|
| }
|
|
|
| // static
|
| @@ -255,28 +634,25 @@
|
| }
|
|
|
| // static
|
| -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];
|
| +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;
|
| + }
|
| }
|
|
|
| // static
|
| @@ -290,6 +666,22 @@
|
| 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
|
|
|