Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Unified Diff: src/interpreter/bytecodes.cc

Issue 2358423002: Version 5.5.251.1 (cherry-pick) (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/interpreter/bytecodes.h ('k') | src/v8.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 @@ 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) {
@@ -98,7 +124,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; \
}
@@ -109,6 +135,224 @@ 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::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
int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
OperandScale operand_scale) {
DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
@@ -123,6 +367,71 @@ int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
}
// 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 @@ 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:
@@ -154,6 +476,53 @@ 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, _) \
@@ -234,11 +603,21 @@ bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
}
// static
-bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
- for (int i = 0; i < NumberOfOperands(bytecode); i++) {
- if (OperandIsScalable(bytecode, i)) return true;
+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 false;
+ return 0;
}
// static
@@ -255,28 +634,25 @@ bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
}
// 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 @@ 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
« no previous file with comments | « src/interpreter/bytecodes.h ('k') | src/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698