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

Unified Diff: src/interpreter/bytecode-array-iterator.cc

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Additional test for debugger stepping and wider constant array builder test. Created 4 years, 9 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
Index: src/interpreter/bytecode-array-iterator.cc
diff --git a/src/interpreter/bytecode-array-iterator.cc b/src/interpreter/bytecode-array-iterator.cc
index 0fea985efee2911cb141fdc4857e2d021d42a407..9017c10834af3897471ef0c7847edf115c7a6aa0 100644
--- a/src/interpreter/bytecode-array-iterator.cc
+++ b/src/interpreter/bytecode-array-iterator.cc
@@ -12,95 +12,133 @@ namespace interpreter {
BytecodeArrayIterator::BytecodeArrayIterator(
Handle<BytecodeArray> bytecode_array)
- : bytecode_array_(bytecode_array), bytecode_offset_(0) {}
-
+ : bytecode_array_(bytecode_array),
+ bytecode_offset_(0),
+ operand_scale_(OperandScale::k1X),
+ prefix_offset_(0) {
+ update_operand_scale();
+}
void BytecodeArrayIterator::Advance() {
- bytecode_offset_ += Bytecodes::Size(current_bytecode());
+ bytecode_offset_ += current_bytecode_size();
+ update_operand_scale();
}
+void BytecodeArrayIterator::update_operand_scale() {
+ if (!done()) {
+ uint8_t current_byte = bytecode_array()->get(bytecode_offset_);
+ Bytecode current_bytecode = Bytecodes::FromByte(current_byte);
+ if (Bytecodes::IsPrefixScalingBytecode(current_bytecode)) {
+ operand_scale_ =
+ Bytecodes::PrefixBytecodeToOperandScale(current_bytecode);
+ prefix_offset_ = 1;
+ } else {
+ operand_scale_ = OperandScale::k1X;
+ prefix_offset_ = 0;
+ }
+ }
+}
bool BytecodeArrayIterator::done() const {
return bytecode_offset_ >= bytecode_array()->length();
}
-
Bytecode BytecodeArrayIterator::current_bytecode() const {
DCHECK(!done());
- uint8_t current_byte = bytecode_array()->get(bytecode_offset_);
- return interpreter::Bytecodes::FromByte(current_byte);
+ uint8_t current_byte =
+ bytecode_array()->get(bytecode_offset_ + current_prefix_offset());
+ Bytecode current_bytecode = Bytecodes::FromByte(current_byte);
+ DCHECK(!Bytecodes::IsPrefixScalingBytecode(current_bytecode));
+ return current_bytecode;
}
-
int BytecodeArrayIterator::current_bytecode_size() const {
- return Bytecodes::Size(current_bytecode());
+ return current_prefix_offset() +
+ Bytecodes::Size(current_bytecode(), current_operand_scale());
}
-
-uint32_t BytecodeArrayIterator::GetRawOperand(int operand_index,
- OperandType operand_type) const {
+uint32_t BytecodeArrayIterator::GetUnsignedOperand(
+ int operand_index, OperandType operand_type) const {
DCHECK_GE(operand_index, 0);
DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(current_bytecode()));
DCHECK_EQ(operand_type,
Bytecodes::GetOperandType(current_bytecode(), operand_index));
+ DCHECK(Bytecodes::IsUnsignedOperandType(operand_type));
uint8_t* operand_start =
bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ +
- Bytecodes::GetOperandOffset(current_bytecode(), operand_index);
- switch (Bytecodes::SizeOfOperand(operand_type)) {
+ current_prefix_offset() +
+ Bytecodes::GetOperandOffset(current_bytecode(), operand_index,
+ current_operand_scale());
+ switch (Bytecodes::SizeOfOperand(operand_type, current_operand_scale())) {
rmcilroy 2016/03/17 17:30:49 I think you could use DecodeUnsignedOperand here t
oth 2016/03/21 09:16:53 Done.
case OperandSize::kByte:
return static_cast<uint32_t>(*operand_start);
case OperandSize::kShort:
return ReadUnalignedUInt16(operand_start);
+ case OperandSize::kQuad:
+ return ReadUnalignedUInt32(operand_start);
case OperandSize::kNone:
UNREACHABLE();
}
return 0;
}
+int32_t BytecodeArrayIterator::GetSignedOperand(
+ int operand_index, OperandType operand_type) const {
+ DCHECK_GE(operand_index, 0);
+ DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(current_bytecode()));
+ DCHECK_EQ(operand_type,
+ Bytecodes::GetOperandType(current_bytecode(), operand_index));
+ DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type));
+ uint8_t* operand_start =
+ bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ +
+ current_prefix_offset() +
+ Bytecodes::GetOperandOffset(current_bytecode(), operand_index,
+ current_operand_scale());
+ switch (Bytecodes::SizeOfOperand(operand_type, current_operand_scale())) {
rmcilroy 2016/03/17 17:30:49 I think you could use DecodeSignedOperand here to
oth 2016/03/21 09:16:53 Yep, got all these before getting this far in the
+ case OperandSize::kByte:
+ return static_cast<int8_t>(*operand_start);
+ case OperandSize::kShort:
+ return static_cast<int16_t>(ReadUnalignedUInt16(operand_start));
+ case OperandSize::kQuad:
+ return static_cast<int32_t>(ReadUnalignedUInt32(operand_start));
+ case OperandSize::kNone:
+ UNREACHABLE();
+ }
+ return 0;
+}
-int8_t BytecodeArrayIterator::GetImmediateOperand(int operand_index) const {
- uint32_t operand = GetRawOperand(operand_index, OperandType::kImm8);
- return static_cast<int8_t>(operand);
+uint32_t BytecodeArrayIterator::GetFlagOperand(int operand_index) const {
+ DCHECK(Bytecodes::GetOperandType(current_bytecode(), operand_index) ==
+ OperandType::kFlag8);
+ return GetUnsignedOperand(operand_index, OperandType::kFlag8);
}
-int BytecodeArrayIterator::GetRegisterCountOperand(int operand_index) const {
- OperandSize size =
- Bytecodes::GetOperandSize(current_bytecode(), operand_index);
- OperandType type = (size == OperandSize::kByte) ? OperandType::kRegCount8
- : OperandType::kRegCount16;
- uint32_t operand = GetRawOperand(operand_index, type);
- return static_cast<int>(operand);
+int32_t BytecodeArrayIterator::GetImmediateOperand(int operand_index) const {
+ DCHECK(Bytecodes::GetOperandType(current_bytecode(), operand_index) ==
+ OperandType::kImm);
+ return GetSignedOperand(operand_index, OperandType::kImm);
}
+uint32_t BytecodeArrayIterator::GetRegisterCountOperand(
+ int operand_index) const {
+ DCHECK(Bytecodes::GetOperandType(current_bytecode(), operand_index) ==
rmcilroy 2016/03/17 17:30:49 DCHECK_EQ
oth 2016/03/21 09:16:53 Done.
+ OperandType::kRegCount);
+ return GetUnsignedOperand(operand_index, OperandType::kRegCount);
+}
-int BytecodeArrayIterator::GetIndexOperand(int operand_index) const {
+uint32_t BytecodeArrayIterator::GetIndexOperand(int operand_index) const {
OperandType operand_type =
Bytecodes::GetOperandType(current_bytecode(), operand_index);
- DCHECK(operand_type == OperandType::kIdx8 ||
- operand_type == OperandType::kIdx16);
- uint32_t operand = GetRawOperand(operand_index, operand_type);
- return static_cast<int>(operand);
+ DCHECK(operand_type == OperandType::kIdx);
rmcilroy 2016/03/17 17:30:49 DCHECK_EQ
oth 2016/03/21 09:16:53 Done.
+ return GetUnsignedOperand(operand_index, operand_type);
}
-
Register BytecodeArrayIterator::GetRegisterOperand(int operand_index) const {
OperandType operand_type =
Bytecodes::GetOperandType(current_bytecode(), operand_index);
DCHECK(Bytecodes::IsRegisterOperandType(operand_type));
- uint32_t operand = GetRawOperand(operand_index, operand_type);
- Register reg;
- switch (Bytecodes::GetOperandSize(current_bytecode(), operand_index)) {
- case OperandSize::kByte:
- reg = Register::FromOperand(static_cast<uint8_t>(operand));
- break;
- case OperandSize::kShort:
- reg = Register::FromWideOperand(static_cast<uint16_t>(operand));
- break;
- case OperandSize::kNone:
- UNREACHABLE();
- reg = Register::invalid_value();
- break;
- }
+ int32_t operand = GetSignedOperand(operand_index, operand_type);
+ Register reg = Register::FromOperand(operand);
DCHECK_GE(reg.index(),
Register::FromParameterIndex(0, bytecode_array()->parameter_count())
.index());
@@ -116,20 +154,17 @@ int BytecodeArrayIterator::GetRegisterOperandRange(int operand_index) const {
Bytecodes::GetOperandType(current_bytecode(), operand_index);
DCHECK(Bytecodes::IsRegisterOperandType(operand_type));
switch (operand_type) {
- case OperandType::kRegPair8:
- case OperandType::kRegPair16:
- case OperandType::kRegOutPair8:
- case OperandType::kRegOutPair16:
+ case OperandType::kRegPair:
+ case OperandType::kRegOutPair:
return 2;
- case OperandType::kRegOutTriple8:
- case OperandType::kRegOutTriple16:
+ case OperandType::kRegOutTriple:
return 3;
default: {
if (operand_index + 1 !=
Bytecodes::NumberOfOperands(current_bytecode())) {
OperandType next_operand_type =
Bytecodes::GetOperandType(current_bytecode(), operand_index + 1);
- if (Bytecodes::IsRegisterCountOperandType(next_operand_type)) {
+ if (OperandType::kRegCount == next_operand_type) {
return GetRegisterCountOperand(operand_index + 1);
}
}
@@ -138,6 +173,13 @@ int BytecodeArrayIterator::GetRegisterOperandRange(int operand_index) const {
}
}
+uint32_t BytecodeArrayIterator::GetRuntimeIdOperand(int operand_index) const {
+ OperandType operand_type =
+ Bytecodes::GetOperandType(current_bytecode(), operand_index);
+ DCHECK(operand_type == OperandType::kRuntimeId);
+ return GetUnsignedOperand(operand_index, operand_type);
+}
+
Handle<Object> BytecodeArrayIterator::GetConstantForIndexOperand(
int operand_index) const {
return FixedArray::get(bytecode_array()->constant_pool(),
@@ -150,11 +192,10 @@ int BytecodeArrayIterator::GetJumpTargetOffset() const {
Bytecode bytecode = current_bytecode();
if (interpreter::Bytecodes::IsJumpImmediate(bytecode)) {
int relative_offset = GetImmediateOperand(0);
- return current_offset() + relative_offset;
- } else if (interpreter::Bytecodes::IsJumpConstant(bytecode) ||
- interpreter::Bytecodes::IsJumpConstantWide(bytecode)) {
+ return current_offset() + relative_offset + current_prefix_offset();
+ } else if (interpreter::Bytecodes::IsJumpConstant(bytecode)) {
Smi* smi = Smi::cast(*GetConstantForIndexOperand(0));
- return current_offset() + smi->value();
+ return current_offset() + smi->value() + current_prefix_offset();
} else {
UNREACHABLE();
return kMinInt;

Powered by Google App Engine
This is Rietveld 408576698