Commit 53c46f87 authored by akos.palfi's avatar akos.palfi Committed by Commit bot

MIPS: Fix unaligned read/write of bytecodes in interpreter.

On MIPS arch, all memory accesses (including halfword)
must be aligned to their native size or an alignment exception occurs.
The kernel will fix this up, but with performance penalty.

TEST=test-bytecode-generator/CallRuntime
BUG=

Review URL: https://codereview.chromium.org/1423373004

Cr-Commit-Position: refs/heads/master@{#31845}
parent 2a866bc4
......@@ -126,7 +126,7 @@ void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) {
break;
case OperandSize::kShort: {
uint8_t operand_bytes[2];
Bytecodes::ShortOperandToBytes(operands[i], operand_bytes);
WriteUnalignedUInt16(operand_bytes, operands[i]);
bytecodes()->insert(bytecodes()->end(), operand_bytes,
operand_bytes + 2);
break;
......
......@@ -48,7 +48,7 @@ uint32_t BytecodeArrayIterator::GetRawOperand(int operand_index,
case OperandSize::kByte:
return static_cast<uint32_t>(*operand_start);
case OperandSize::kShort:
return Bytecodes::ShortOperandFromBytes(operand_start);
return ReadUnalignedUInt16(operand_start);
}
}
......
......@@ -181,18 +181,6 @@ 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) {
......@@ -225,7 +213,7 @@ std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
os << "[" << static_cast<unsigned int>(*operand_start) << "]";
break;
case interpreter::OperandType::kIdx16: {
os << "[" << Bytecodes::ShortOperandFromBytes(operand_start) << "]";
os << "[" << ReadUnalignedUInt16(operand_start) << "]";
break;
}
case interpreter::OperandType::kImm8:
......
......@@ -328,12 +328,6 @@ class Bytecodes {
// constant pool entry (OperandType::kIdx).
static bool IsJumpConstant(Bytecode bytecode);
// Converts bytes[0] and bytes[1] to a 16 bit 'short' operand value.
static uint16_t ShortOperandFromBytes(const uint8_t* bytes);
// Converts 16 bit 'short' |operand| into bytes_out[0] and bytes_out[1].
static void ShortOperandToBytes(uint16_t operand, uint8_t* bytes_out);
// Decode a single bytecode and operands to |os|.
static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start,
int number_of_parameters);
......
......@@ -1734,6 +1734,42 @@ static inline void WriteDoubleValue(void* p, double value) {
#endif // V8_TARGET_ARCH_MIPS
}
static inline uint16_t ReadUnalignedUInt16(const void* p) {
#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64)
return *reinterpret_cast<const uint16_t*>(p);
#else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
// Prevent compiler from using load-half (mips lh) on (possibly)
// non-16-bit aligned address.
union conversion {
uint16_t h;
uint8_t b[2];
} c;
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(p);
c.b[0] = *ptr;
c.b[1] = *(ptr + 1);
return c.h;
#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
}
static inline void WriteUnalignedUInt16(void* p, uint16_t value) {
#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64)
*(reinterpret_cast<uint16_t*>(p)) = value;
#else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
// Prevent compiler from using store-half (mips sh) on (possibly)
// non-16-bit aligned address.
union conversion {
uint16_t h;
uint8_t b[2];
} c;
c.h = value;
uint8_t* ptr = reinterpret_cast<uint8_t*>(p);
*ptr = c.b[0];
*(ptr + 1) = c.b[1];
#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
}
} // namespace internal
} // namespace v8
......
......@@ -210,8 +210,8 @@ static void CheckBytecodeArrayEqual(const ExpectedSnippet<T, C>& expected,
static_cast<uint32_t>(expected.bytecode[operand_index]);
break;
case OperandSize::kShort:
expected_operand = Bytecodes::ShortOperandFromBytes(
&expected.bytecode[operand_index]);
expected_operand =
ReadUnalignedUInt16(&expected.bytecode[operand_index]);
break;
default:
UNREACHABLE();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment