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; |