[wasm][liftoff] Fix reftype parameter handling
LiftoffCompiler::ProcessParameter assumed that by processing parameters in the order of their index, register parameters get processed first, and that for processing stack parameters it can already use all registers as temp registers. This is not true with reference type parameters, because registers always first get assigned to value type parameters even when there is a reference type parameter with a lower index. Because of this incorrect assumption register parameters were overwritten by reference type parameters on the stack that got processed first. With this CL, only those registers get used as temp registers for reference type parameters that are not used for parameters. CC=jkummerow@chromium.org, clemensb@chromium.org R=thibaudm@chromium.org Bug: v8:11596 Change-Id: I30ed7f073147df0bd81b9ef4d2b2a54d7badc937 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2784560 Commit-Queue: Andreas Haas <ahaas@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Cr-Commit-Position: refs/heads/master@{#73635}
This commit is contained in:
parent
f613ad3871
commit
7d844bdbb0
@ -594,6 +594,14 @@ class LiftoffCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr LiftoffRegList RegsUnusedByParams() {
|
||||||
|
LiftoffRegList regs = kGpCacheRegList;
|
||||||
|
for (auto reg : kGpParamRegisters) {
|
||||||
|
regs.clear(reg);
|
||||||
|
}
|
||||||
|
return regs;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the number of inputs processed (1 or 2).
|
// Returns the number of inputs processed (1 or 2).
|
||||||
uint32_t ProcessParameter(ValueKind kind, uint32_t input_idx) {
|
uint32_t ProcessParameter(ValueKind kind, uint32_t input_idx) {
|
||||||
const bool needs_pair = needs_gp_reg_pair(kind);
|
const bool needs_pair = needs_gp_reg_pair(kind);
|
||||||
@ -608,7 +616,12 @@ class LiftoffCompiler {
|
|||||||
location.AsRegister());
|
location.AsRegister());
|
||||||
}
|
}
|
||||||
DCHECK(location.IsCallerFrameSlot());
|
DCHECK(location.IsCallerFrameSlot());
|
||||||
LiftoffRegister reg = __ GetUnusedRegister(rc, pinned);
|
// For reference type parameters we have to use registers that were not
|
||||||
|
// used for parameters because some reference type stack parameters may
|
||||||
|
// get processed before some value type register parameters.
|
||||||
|
LiftoffRegister reg = is_reference(reg_kind)
|
||||||
|
? __ GetUnusedRegister(RegsUnusedByParams())
|
||||||
|
: __ GetUnusedRegister(rc, pinned);
|
||||||
__ LoadCallerFrameSlot(reg, -location.AsCallerFrameSlot(), reg_kind);
|
__ LoadCallerFrameSlot(reg, -location.AsCallerFrameSlot(), reg_kind);
|
||||||
return reg;
|
return reg;
|
||||||
};
|
};
|
||||||
|
@ -1163,6 +1163,48 @@ WASM_COMPILED_EXEC_TEST(CallRef) {
|
|||||||
tester.CheckResult(caller, 47, 5);
|
tester.CheckResult(caller, 47, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WASM_COMPILED_EXEC_TEST(CallReftypeParameters) {
|
||||||
|
WasmGCTester tester(execution_tier);
|
||||||
|
byte type_index = tester.DefineStruct({F(wasm::kWasmI32, true)});
|
||||||
|
ValueType kRefType{optref(type_index)};
|
||||||
|
ValueType sig_types[] = {kWasmI32, kRefType, kRefType, kRefType, kRefType,
|
||||||
|
kWasmI32, kWasmI32, kWasmI32, kWasmI32};
|
||||||
|
FunctionSig sig(1, 8, sig_types);
|
||||||
|
byte adder = tester.DefineFunction(
|
||||||
|
&sig, {},
|
||||||
|
{WASM_I32_ADD(
|
||||||
|
WASM_STRUCT_GET(type_index, 0, WASM_LOCAL_GET(0)),
|
||||||
|
WASM_I32_ADD(
|
||||||
|
WASM_STRUCT_GET(type_index, 0, WASM_LOCAL_GET(1)),
|
||||||
|
WASM_I32_ADD(
|
||||||
|
WASM_STRUCT_GET(type_index, 0, WASM_LOCAL_GET(2)),
|
||||||
|
WASM_I32_ADD(
|
||||||
|
WASM_STRUCT_GET(type_index, 0, WASM_LOCAL_GET(3)),
|
||||||
|
WASM_I32_ADD(
|
||||||
|
WASM_LOCAL_GET(4),
|
||||||
|
WASM_I32_ADD(WASM_LOCAL_GET(5),
|
||||||
|
WASM_I32_ADD(WASM_LOCAL_GET(6),
|
||||||
|
WASM_LOCAL_GET(7)))))))),
|
||||||
|
kExprEnd});
|
||||||
|
byte caller = tester.DefineFunction(
|
||||||
|
tester.sigs.i_v(), {},
|
||||||
|
{WASM_CALL_FUNCTION(adder,
|
||||||
|
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(2),
|
||||||
|
WASM_RTT_CANON(type_index)),
|
||||||
|
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(4),
|
||||||
|
WASM_RTT_CANON(type_index)),
|
||||||
|
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(8),
|
||||||
|
WASM_RTT_CANON(type_index)),
|
||||||
|
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(16),
|
||||||
|
WASM_RTT_CANON(type_index)),
|
||||||
|
WASM_I32V(32), WASM_I32V(64), WASM_I32V(128),
|
||||||
|
WASM_I32V(256)),
|
||||||
|
kExprEnd});
|
||||||
|
|
||||||
|
tester.CompileModule();
|
||||||
|
tester.CheckResult(caller, 510);
|
||||||
|
}
|
||||||
|
|
||||||
WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) {
|
WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) {
|
||||||
WasmGCTester tester(execution_tier);
|
WasmGCTester tester(execution_tier);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user