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

Unified Diff: src/interpreter/bytecodes.cc

Issue 2351763002: [Interpreter] Optimize BytecodeArrayBuilder and BytecodeArrayWriter. (Closed)
Patch Set: Fix Chromium Windows bots. 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 8b78ee2e4929036f0acd5e54af2e27e9654d88eb..c58f4685a2d3d03bf344ea350366be359ba8c148 100644
--- a/src/interpreter/bytecodes.cc
+++ b/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::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));
@@ -367,71 +119,6 @@ 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:
@@ -450,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:
@@ -476,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, _) \
@@ -603,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
@@ -634,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
@@ -666,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
« 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