Index: src/interpreter/bytecodes.cc |
diff --git a/src/interpreter/bytecodes.cc b/src/interpreter/bytecodes.cc |
index 281a883e847b7d928b334ac4c432bc5f8c834dd7..5f43ea3370f46619c25f8ac3b065a46f5adb0207 100644 |
--- a/src/interpreter/bytecodes.cc |
+++ b/src/interpreter/bytecodes.cc |
@@ -5,25 +5,12 @@ |
#include "src/interpreter/bytecodes.h" |
#include "src/frames.h" |
+#include "src/interpreter/bytecode-traits.h" |
namespace v8 { |
namespace internal { |
namespace interpreter { |
-// Maximum number of operands a bytecode may have. |
-static const int kMaxOperands = 3; |
- |
-// kBytecodeTable relies on kNone being the same as zero to detect length. |
-STATIC_ASSERT(static_cast<int>(OperandType::kNone) == 0); |
- |
-static const OperandType kBytecodeTable[][kMaxOperands] = { |
-#define DECLARE_OPERAND(_, ...) \ |
- { __VA_ARGS__ } \ |
- , |
- BYTECODE_LIST(DECLARE_OPERAND) |
-#undef DECLARE_OPERAND |
-}; |
- |
// static |
const char* Bytecodes::ToString(Bytecode bytecode) { |
@@ -42,7 +29,7 @@ const char* Bytecodes::ToString(Bytecode bytecode) { |
// static |
const char* Bytecodes::OperandTypeToString(OperandType operand_type) { |
switch (operand_type) { |
-#define CASE(Name) \ |
+#define CASE(Name, _) \ |
case OperandType::k##Name: \ |
return #Name; |
OPERAND_TYPE_LIST(CASE) |
@@ -54,6 +41,21 @@ const char* Bytecodes::OperandTypeToString(OperandType operand_type) { |
// 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"; |
+ } |
+ UNREACHABLE(); |
+ return ""; |
+} |
+ |
+ |
+// static |
uint8_t Bytecodes::ToByte(Bytecode bytecode) { |
return static_cast<uint8_t>(bytecode); |
} |
@@ -68,38 +70,92 @@ Bytecode Bytecodes::FromByte(uint8_t value) { |
// static |
+int Bytecodes::Size(Bytecode bytecode) { |
+ DCHECK(bytecode <= Bytecode::kLast); |
+ switch (bytecode) { |
+#define CASE(Name, ...) \ |
+ case Bytecode::k##Name: \ |
+ return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize; |
+ BYTECODE_LIST(CASE) |
+#undef CASE |
+ } |
+ UNREACHABLE(); |
+ return 0; |
+} |
+ |
+ |
+// static |
int Bytecodes::NumberOfOperands(Bytecode bytecode) { |
DCHECK(bytecode <= Bytecode::kLast); |
- int count; |
- uint8_t row = ToByte(bytecode); |
- for (count = 0; count < kMaxOperands; count++) { |
- if (kBytecodeTable[row][count] == OperandType::kNone) { |
- break; |
- } |
+ switch (bytecode) { |
+#define CASE(Name, ...) \ |
+ case Bytecode::k##Name: \ |
+ return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kOperandCount; |
+ BYTECODE_LIST(CASE) |
+#undef CASE |
} |
- return count; |
+ UNREACHABLE(); |
+ return 0; |
} |
// static |
OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) { |
- DCHECK(bytecode <= Bytecode::kLast && i < NumberOfOperands(bytecode)); |
- return kBytecodeTable[ToByte(bytecode)][i]; |
+ DCHECK(bytecode <= Bytecode::kLast); |
+ switch (bytecode) { |
+#define CASE(Name, ...) \ |
+ case Bytecode::k##Name: \ |
+ return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandType(i); |
+ BYTECODE_LIST(CASE) |
+#undef CASE |
+ } |
+ UNREACHABLE(); |
+ return OperandType::kNone; |
} |
// static |
-int Bytecodes::Size(Bytecode bytecode) { |
- return 1 + NumberOfOperands(bytecode); |
+OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i) { |
+ DCHECK(bytecode <= Bytecode::kLast); |
+ switch (bytecode) { |
+#define CASE(Name, ...) \ |
+ case Bytecode::k##Name: \ |
+ return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandSize(i); |
+ BYTECODE_LIST(CASE) |
+#undef CASE |
+ } |
+ UNREACHABLE(); |
+ return OperandSize::kNone; |
} |
// static |
-int Bytecodes::MaximumNumberOfOperands() { return kMaxOperands; } |
+int Bytecodes::GetOperandOffset(Bytecode bytecode, int i) { |
+ DCHECK(bytecode <= Bytecode::kLast); |
+ switch (bytecode) { |
+#define CASE(Name, ...) \ |
+ case Bytecode::k##Name: \ |
+ return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandOffset(i); |
+ BYTECODE_LIST(CASE) |
+#undef CASE |
+ } |
+ UNREACHABLE(); |
+ return 0; |
+} |
// static |
-int Bytecodes::MaximumSize() { return 1 + kMaxOperands; } |
+OperandSize Bytecodes::SizeOfOperand(OperandType operand_type) { |
+ switch (operand_type) { |
+#define CASE(Name, Size) \ |
+ case OperandType::k##Name: \ |
+ return Size; |
+ OPERAND_TYPE_LIST(CASE) |
+#undef CASE |
+ } |
+ UNREACHABLE(); |
+ return OperandSize::kNone; |
+} |
// static |
@@ -118,6 +174,18 @@ bool Bytecodes::IsJumpConstant(Bytecode bytecode) { |
// static |
+uint16_t Bytecodes::ShortOperandFromBytes(const uint8_t* bytes) { |
+ return *reinterpret_cast<const uint16_t*>(bytes); |
+} |
+ |
+ |
+// static |
+void Bytecodes::ShortOperandToBytes(uint16_t operand, uint8_t* bytes_out) { |
+ *reinterpret_cast<uint16_t*>(bytes_out) = operand; |
+} |
+ |
+ |
+// static |
std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start, |
int parameter_count) { |
Vector<char> buf = Vector<char>::New(50); |
@@ -129,29 +197,34 @@ std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start, |
SNPrintF(buf, "%02x ", bytecode_start[i]); |
os << buf.start(); |
} |
- for (int i = bytecode_size; i < Bytecodes::MaximumSize(); i++) { |
+ const int kBytecodeColumnSize = 6; |
+ for (int i = bytecode_size; i < kBytecodeColumnSize; i++) { |
os << " "; |
} |
os << bytecode << " "; |
- const uint8_t* operands_start = bytecode_start + 1; |
- int operands_size = bytecode_size - 1; |
- for (int i = 0; i < operands_size; i++) { |
+ int number_of_operands = NumberOfOperands(bytecode); |
+ for (int i = 0; i < number_of_operands; i++) { |
OperandType op_type = GetOperandType(bytecode, i); |
- uint8_t operand = operands_start[i]; |
+ const uint8_t* operand_start = |
+ &bytecode_start[GetOperandOffset(bytecode, i)]; |
switch (op_type) { |
- case interpreter::OperandType::kCount: |
- os << "#" << static_cast<unsigned int>(operand); |
+ case interpreter::OperandType::kCount8: |
+ os << "#" << static_cast<unsigned int>(*operand_start); |
+ break; |
+ case interpreter::OperandType::kIdx8: |
+ os << "[" << static_cast<unsigned int>(*operand_start) << "]"; |
break; |
- case interpreter::OperandType::kIdx: |
- os << "[" << static_cast<unsigned int>(operand) << "]"; |
+ case interpreter::OperandType::kIdx16: { |
+ os << "[" << Bytecodes::ShortOperandFromBytes(operand_start) << "]"; |
break; |
+ } |
case interpreter::OperandType::kImm8: |
- os << "#" << static_cast<int>(static_cast<int8_t>(operand)); |
+ os << "#" << static_cast<int>(static_cast<int8_t>(*operand_start)); |
break; |
- case interpreter::OperandType::kReg: { |
- Register reg = Register::FromOperand(operand); |
+ case interpreter::OperandType::kReg8: { |
+ Register reg = Register::FromOperand(*operand_start); |
if (reg.is_parameter()) { |
int parameter_index = reg.ToParameterIndex(parameter_count); |
if (parameter_index == 0) { |
@@ -168,7 +241,7 @@ std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start, |
UNREACHABLE(); |
break; |
} |
- if (i != operands_size - 1) { |
+ if (i != number_of_operands - 1) { |
os << ", "; |
} |
} |
@@ -186,6 +259,11 @@ std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) { |
} |
+std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) { |
+ return os << Bytecodes::OperandSizeToString(operand_size); |
+} |
+ |
+ |
static const int kLastParamRegisterIndex = |
-InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; |