RelocInfo modes were not propagated when computing

MemoryOperands, on IA32. This needed to be fixed so that we can
compile wasm code before creating instances, since the compiled code
needs to be patched up for memory and globals references.

This surfaces in asm-to-wasm scenarios.

Added testing (rather, enhanced existing tests).
Note patch#1 where we fail on ia32, and patch#2 with the fix.

BUG=v8:5072

Review-Url: https://codereview.chromium.org/2061583002
Cr-Commit-Position: refs/heads/master@{#36911}
This commit is contained in:
mtrofin 2016-06-12 21:20:59 -07:00 committed by Commit bot
parent 35f5b3dca4
commit 8c1ba59aee
2 changed files with 93 additions and 8 deletions

View File

@ -119,8 +119,8 @@ class IA32OperandConverter : public InstructionOperandConverter {
} }
case kMode_MRI: { case kMode_MRI: {
Register base = InputRegister(NextOffset(offset)); Register base = InputRegister(NextOffset(offset));
int32_t disp = InputInt32(NextOffset(offset)); Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset)));
return Operand(base, disp); return Operand(base, ctant.ToInt32(), ctant.rmode());
} }
case kMode_MR1: case kMode_MR1:
case kMode_MR2: case kMode_MR2:
@ -139,8 +139,8 @@ class IA32OperandConverter : public InstructionOperandConverter {
Register base = InputRegister(NextOffset(offset)); Register base = InputRegister(NextOffset(offset));
Register index = InputRegister(NextOffset(offset)); Register index = InputRegister(NextOffset(offset));
ScaleFactor scale = ScaleFor(kMode_MR1I, mode); ScaleFactor scale = ScaleFor(kMode_MR1I, mode);
int32_t disp = InputInt32(NextOffset(offset)); Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset)));
return Operand(base, index, scale, disp); return Operand(base, index, scale, ctant.ToInt32(), ctant.rmode());
} }
case kMode_M1: case kMode_M1:
case kMode_M2: case kMode_M2:
@ -157,12 +157,12 @@ class IA32OperandConverter : public InstructionOperandConverter {
case kMode_M8I: { case kMode_M8I: {
Register index = InputRegister(NextOffset(offset)); Register index = InputRegister(NextOffset(offset));
ScaleFactor scale = ScaleFor(kMode_M1I, mode); ScaleFactor scale = ScaleFor(kMode_M1I, mode);
int32_t disp = InputInt32(NextOffset(offset)); Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset)));
return Operand(index, scale, disp); return Operand(index, scale, ctant.ToInt32(), ctant.rmode());
} }
case kMode_MI: { case kMode_MI: {
int32_t disp = InputInt32(NextOffset(offset)); Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset)));
return Operand(Immediate(disp)); return Operand(ctant.ToInt32(), ctant.rmode());
} }
case kMode_None: case kMode_None:
UNREACHABLE(); UNREACHABLE();

View File

@ -26,6 +26,17 @@ using namespace v8::internal::wasm;
#define RET(x) x, kExprReturn, 1 #define RET(x) x, kExprReturn, 1
#define RET_I8(x) kExprI8Const, x, kExprReturn, 1 #define RET_I8(x) kExprI8Const, x, kExprReturn, 1
namespace {
uint32_t GetMatchingRelocInfoCount(Handle<Code> code, RelocInfo::Mode rmode) {
int filter = 1 << rmode;
uint32_t ret = 0;
for (RelocIterator it(*code, filter); !it.done(); it.next()) {
++ret;
}
return ret;
}
}
WASM_EXEC_TEST(Int32AsmjsDivS) { WASM_EXEC_TEST(Int32AsmjsDivS) {
WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
MachineType::Int32()); MachineType::Int32());
@ -197,3 +208,77 @@ WASM_EXEC_TEST(StoreMemI32_oob_asm) {
CHECK_EQ(7777, r.Call(offset, 7777)); CHECK_EQ(7777, r.Call(offset, 7777));
} }
} }
#define FOREACH_INT_CHECKED_LOAD_OP(TEST_BODY) \
TEST_BODY(kExprI32AsmjsLoadMem8S) \
TEST_BODY(kExprI32AsmjsLoadMem8U) \
TEST_BODY(kExprI32AsmjsLoadMem16S) \
TEST_BODY(kExprI32AsmjsLoadMem16U) \
TEST_BODY(kExprI32AsmjsLoadMem)
#define FOREACH_INT_CHECKED_STORE_OP(TEST_BODY) \
TEST_BODY(kExprI32AsmjsStoreMem8) \
TEST_BODY(kExprI32AsmjsStoreMem16) \
TEST_BODY(kExprI32AsmjsStoreMem)
#define INT_LOAD_TEST(OP_TYPE) \
TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \
TestingModule module(kExecuteCompiled); \
WasmRunner<int32_t> r(&module, MachineType::Uint32()); \
BUILD(r, WASM_UNOP(OP_TYPE, WASM_GET_LOCAL(0))); \
CHECK_EQ(1, GetMatchingRelocInfoCount(module.instance->function_code[0], \
RelocInfo::WASM_MEMORY_REFERENCE)); \
}
FOREACH_INT_CHECKED_LOAD_OP(INT_LOAD_TEST)
#define INT_STORE_TEST(OP_TYPE) \
TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \
TestingModule module(kExecuteCompiled); \
WasmRunner<int32_t> r(&module, MachineType::Uint32(), \
MachineType::Uint32()); \
BUILD(r, WASM_BINOP(OP_TYPE, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); \
CHECK_EQ(1, GetMatchingRelocInfoCount(module.instance->function_code[0], \
RelocInfo::WASM_MEMORY_REFERENCE)); \
}
FOREACH_INT_CHECKED_STORE_OP(INT_STORE_TEST)
TEST(RunWasm_AsmCheckedLoadFloat32RelocInfo) {
TestingModule module(kExecuteCompiled);
WasmRunner<float_t> r(&module, MachineType::Uint32());
BUILD(r, WASM_UNOP(kExprF32AsmjsLoadMem, WASM_GET_LOCAL(0)));
CHECK_EQ(1, GetMatchingRelocInfoCount(module.instance->function_code[0],
RelocInfo::WASM_MEMORY_REFERENCE));
}
TEST(RunWasm_AsmCheckedStoreFloat32RelocInfo) {
TestingModule module(kExecuteCompiled);
WasmRunner<float_t> r(&module, MachineType::Uint32(), MachineType::Float32());
BUILD(r, WASM_BINOP(kExprF32AsmjsStoreMem, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1)));
CHECK_EQ(1, GetMatchingRelocInfoCount(module.instance->function_code[0],
RelocInfo::WASM_MEMORY_REFERENCE));
}
TEST(RunWasm_AsmCheckedLoadFloat64RelocInfo) {
TestingModule module(kExecuteCompiled);
WasmRunner<double_t> r(&module, MachineType::Uint32());
BUILD(r, WASM_UNOP(kExprF64AsmjsLoadMem, WASM_GET_LOCAL(0)));
CHECK_EQ(1, GetMatchingRelocInfoCount(module.instance->function_code[0],
RelocInfo::WASM_MEMORY_REFERENCE));
}
TEST(RunWasm_AsmCheckedStoreFloat64RelocInfo) {
TestingModule module(kExecuteCompiled);
WasmRunner<double_t> r(&module, MachineType::Uint32(),
MachineType::Float64());
BUILD(r, WASM_BINOP(kExprF64AsmjsStoreMem, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1)));
CHECK_EQ(1, GetMatchingRelocInfoCount(module.instance->function_code[0],
RelocInfo::WASM_MEMORY_REFERENCE));
}