| 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..a17efcb6ca4b5a36c240e32474fe0ef92834e96a 100644
|
| --- a/src/interpreter/bytecode-array-iterator.cc
|
| +++ b/src/interpreter/bytecode-array-iterator.cc
|
| @@ -12,103 +12,119 @@ 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::kSingle),
|
| + prefix_offset_(0) {
|
| + UpdateOperandScale();
|
| +}
|
|
|
| void BytecodeArrayIterator::Advance() {
|
| - bytecode_offset_ += Bytecodes::Size(current_bytecode());
|
| + bytecode_offset_ += current_bytecode_size();
|
| + UpdateOperandScale();
|
| }
|
|
|
| +void BytecodeArrayIterator::UpdateOperandScale() {
|
| + 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::kSingle;
|
| + 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));
|
| - uint8_t* operand_start =
|
| + DCHECK(Bytecodes::IsUnsignedOperandType(operand_type));
|
| + const uint8_t* operand_start =
|
| bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ +
|
| - Bytecodes::GetOperandOffset(current_bytecode(), operand_index);
|
| - switch (Bytecodes::SizeOfOperand(operand_type)) {
|
| - case OperandSize::kByte:
|
| - return static_cast<uint32_t>(*operand_start);
|
| - case OperandSize::kShort:
|
| - return ReadUnalignedUInt16(operand_start);
|
| - case OperandSize::kNone:
|
| - UNREACHABLE();
|
| - }
|
| - return 0;
|
| + current_prefix_offset() +
|
| + Bytecodes::GetOperandOffset(current_bytecode(), operand_index,
|
| + current_operand_scale());
|
| + return Bytecodes::DecodeUnsignedOperand(operand_start, operand_type,
|
| + current_operand_scale());
|
| }
|
|
|
| +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));
|
| + const uint8_t* operand_start =
|
| + bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ +
|
| + current_prefix_offset() +
|
| + Bytecodes::GetOperandOffset(current_bytecode(), operand_index,
|
| + current_operand_scale());
|
| + return Bytecodes::DecodeSignedOperand(operand_start, operand_type,
|
| + current_operand_scale());
|
| +}
|
|
|
| -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_EQ(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_EQ(Bytecodes::GetOperandType(current_bytecode(), operand_index),
|
| + OperandType::kImm);
|
| + return GetSignedOperand(operand_index, OperandType::kImm);
|
| }
|
|
|
| +uint32_t BytecodeArrayIterator::GetRegisterCountOperand(
|
| + int operand_index) const {
|
| + DCHECK_EQ(Bytecodes::GetOperandType(current_bytecode(), operand_index),
|
| + 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_EQ(operand_type, OperandType::kIdx);
|
| + 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;
|
| - }
|
| - DCHECK_GE(reg.index(),
|
| - Register::FromParameterIndex(0, bytecode_array()->parameter_count())
|
| - .index());
|
| - DCHECK(reg.index() < bytecode_array()->register_count() ||
|
| - (reg.index() == 0 &&
|
| - Bytecodes::IsMaybeRegisterOperandType(
|
| - Bytecodes::GetOperandType(current_bytecode(), operand_index))));
|
| - return reg;
|
| + const uint8_t* operand_start =
|
| + bytecode_array()->GetFirstBytecodeAddress() + bytecode_offset_ +
|
| + current_prefix_offset() +
|
| + Bytecodes::GetOperandOffset(current_bytecode(), operand_index,
|
| + current_operand_scale());
|
| + return Bytecodes::DecodeRegisterOperand(operand_start, operand_type,
|
| + current_operand_scale());
|
| }
|
|
|
| int BytecodeArrayIterator::GetRegisterOperandRange(int operand_index) const {
|
| @@ -116,20 +132,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 +151,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 +170,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;
|
|
|