| 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..b7a6dcca39c9f383592b269c45a954efba4a67fd 100644
|
| --- a/src/interpreter/bytecode-array-iterator.cc
|
| +++ b/src/interpreter/bytecode-array-iterator.cc
|
| @@ -12,31 +12,44 @@ namespace interpreter {
|
|
|
| BytecodeArrayIterator::BytecodeArrayIterator(
|
| Handle<BytecodeArray> bytecode_array)
|
| - : bytecode_array_(bytecode_array), bytecode_offset_(0) {}
|
| -
|
| + : bytecode_array_(bytecode_array),
|
| + bytecode_offset_(0),
|
| + operand_scale_(1),
|
| + 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);
|
| + operand_scale_ = Bytecodes::GetPrefixBytecodeScale(current_bytecode);
|
| + prefix_offset_ = current_operand_scale() > 1 ? 1 : 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);
|
| + 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 {
|
| DCHECK_GE(operand_index, 0);
|
| @@ -45,57 +58,89 @@ uint32_t BytecodeArrayIterator::GetRawOperand(int operand_index,
|
| Bytecodes::GetOperandType(current_bytecode(), operand_index));
|
| 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())) {
|
| 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::GetRawOperandSigned(
|
| + 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 =
|
| + 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())) {
|
| + 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 GetRawOperand(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 GetRawOperandSigned(operand_index, OperandType::kImm);
|
| }
|
|
|
| +uint32_t BytecodeArrayIterator::GetRegisterCountOperand(
|
| + int operand_index) const {
|
| + DCHECK(Bytecodes::GetOperandType(current_bytecode(), operand_index) ==
|
| + OperandType::kRegCount);
|
| + return GetRawOperand(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);
|
| + return GetRawOperand(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)) {
|
| + switch (Bytecodes::GetOperandSize(current_bytecode(), operand_index,
|
| + current_operand_scale())) {
|
| 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::kQuad:
|
| + reg = Register::FromRawOperand(operand);
|
| + break;
|
| case OperandSize::kNone:
|
| UNREACHABLE();
|
| reg = Register::invalid_value();
|
| @@ -116,13 +161,10 @@ 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 !=
|
| @@ -138,6 +180,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 GetRawOperand(operand_index, operand_type);
|
| +}
|
| +
|
| Handle<Object> BytecodeArrayIterator::GetConstantForIndexOperand(
|
| int operand_index) const {
|
| return FixedArray::get(bytecode_array()->constant_pool(),
|
| @@ -150,11 +199,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;
|
|
|