[wasm] Fix Int64Lowering for tagged stack-passed parameters

When lowering signatures, we must preserve the separation of parameters
into tagged and untagged sections.

Fixed: chromium:1320614
Change-Id: I8119ba23e35f499630c2d2494e99191ca793cb1a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3620283
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80327}
This commit is contained in:
Jakob Kummerow 2022-05-02 19:52:11 +02:00 committed by V8 LUCI CQ
parent f7895fc42b
commit 8062598f26

View File

@ -8566,16 +8566,10 @@ class LinkageLocationAllocator {
// must be offset to just before the param slots, using this |slot_offset_|.
int slot_offset_;
};
} // namespace
// General code uses the above configuration data.
CallDescriptor* GetWasmCallDescriptor(Zone* zone, const wasm::FunctionSig* fsig,
WasmCallKind call_kind,
bool need_frame_state) {
// The extra here is to accomodate the instance object as first parameter
// and, when specified, the additional callable.
bool extra_callable_param =
call_kind == kWasmImportWrapper || call_kind == kWasmCapiFunction;
LocationSignature* BuildLocations(Zone* zone, const wasm::FunctionSig* fsig,
bool extra_callable_param,
int* parameter_slots, int* return_slots) {
int extra_params = extra_callable_param ? 2 : 1;
LocationSignature::Builder locations(zone, fsig->return_count(),
fsig->parameter_count() + extra_params);
@ -8618,19 +8612,37 @@ CallDescriptor* GetWasmCallDescriptor(Zone* zone, const wasm::FunctionSig* fsig,
kJSFunctionRegister.code(), MachineType::TaggedPointer()));
}
int parameter_slots = AddArgumentPaddingSlots(params.NumStackSlots());
*parameter_slots = AddArgumentPaddingSlots(params.NumStackSlots());
// Add return location(s).
LinkageLocationAllocator rets(wasm::kGpReturnRegisters,
wasm::kFpReturnRegisters, parameter_slots);
wasm::kFpReturnRegisters, *parameter_slots);
const int return_count = static_cast<int>(locations.return_count_);
for (int i = 0; i < return_count; i++) {
const size_t return_count = locations.return_count_;
for (size_t i = 0; i < return_count; i++) {
MachineRepresentation ret = fsig->GetReturn(i).machine_representation();
locations.AddReturn(rets.Next(ret));
}
int return_slots = rets.NumStackSlots();
*return_slots = rets.NumStackSlots();
return locations.Build();
}
} // namespace
// General code uses the above configuration data.
CallDescriptor* GetWasmCallDescriptor(Zone* zone, const wasm::FunctionSig* fsig,
WasmCallKind call_kind,
bool need_frame_state) {
// The extra here is to accomodate the instance object as first parameter
// and, when specified, the additional callable.
bool extra_callable_param =
call_kind == kWasmImportWrapper || call_kind == kWasmCapiFunction;
int parameter_slots;
int return_slots;
LocationSignature* location_sig = BuildLocations(
zone, fsig, extra_callable_param, &parameter_slots, &return_slots);
const RegList kCalleeSaveRegisters;
const DoubleRegList kCalleeSaveFPRegisters;
@ -8656,7 +8668,7 @@ CallDescriptor* GetWasmCallDescriptor(Zone* zone, const wasm::FunctionSig* fsig,
descriptor_kind, // kind
target_type, // target MachineType
target_loc, // target location
locations.Build(), // location_sig
location_sig, // location_sig
parameter_slots, // parameter slot count
compiler::Operator::kNoProperties, // properties
kCalleeSaveRegisters, // callee-saved registers
@ -8707,78 +8719,45 @@ const wasm::FunctionSig* ReplaceTypeInSig(Zone* zone,
CallDescriptor* ReplaceTypeInCallDescriptorWith(
Zone* zone, const CallDescriptor* call_descriptor, size_t num_replacements,
wasm::ValueType input_type, wasm::ValueType output_type) {
size_t parameter_count = call_descriptor->ParameterCount();
size_t return_count = call_descriptor->ReturnCount();
for (size_t i = 0; i < call_descriptor->ParameterCount(); i++) {
if (call_descriptor->GetParameterType(i) == input_type.machine_type()) {
parameter_count += num_replacements - 1;
if (call_descriptor->wasm_sig() == nullptr) {
// This happens for builtins calls. They need no replacements anyway.
#if DEBUG
for (size_t i = 0; i < call_descriptor->ParameterCount(); i++) {
DCHECK_NE(call_descriptor->GetParameterType(i),
input_type.machine_type());
}
}
for (size_t i = 0; i < call_descriptor->ReturnCount(); i++) {
if (call_descriptor->GetReturnType(i) == input_type.machine_type()) {
return_count += num_replacements - 1;
for (size_t i = 0; i < call_descriptor->ReturnCount(); i++) {
DCHECK_NE(call_descriptor->GetReturnType(i), input_type.machine_type());
}
}
if (parameter_count == call_descriptor->ParameterCount() &&
return_count == call_descriptor->ReturnCount()) {
#endif
return const_cast<CallDescriptor*>(call_descriptor);
}
const wasm::FunctionSig* sig =
ReplaceTypeInSig(zone, call_descriptor->wasm_sig(), input_type,
output_type, num_replacements);
// If {ReplaceTypeInSig} took the early fast path, there's nothing to do.
if (sig == call_descriptor->wasm_sig()) {
return const_cast<CallDescriptor*>(call_descriptor);
}
LocationSignature::Builder locations(zone, return_count, parameter_count);
// The last parameter may be the special callable parameter. In that case we
// have to preserve it as the last parameter, i.e. we allocate it in the new
// location signature again in the same register.
bool has_callable_param =
bool extra_callable_param =
(call_descriptor->GetInputLocation(call_descriptor->InputCount() - 1) ==
LinkageLocation::ForRegister(kJSFunctionRegister.code(),
MachineType::TaggedPointer()));
LinkageLocationAllocator params(
wasm::kGpParamRegisters, wasm::kFpParamRegisters, 0 /* no slot offset */);
for (size_t i = 0;
i < call_descriptor->ParameterCount() - (has_callable_param ? 1 : 0);
i++) {
if (call_descriptor->GetParameterType(i) == input_type.machine_type()) {
for (size_t j = 0; j < num_replacements; j++) {
locations.AddParam(params.Next(output_type.machine_representation()));
}
} else {
locations.AddParam(
params.Next(call_descriptor->GetParameterType(i).representation()));
}
}
if (has_callable_param) {
locations.AddParam(LinkageLocation::ForRegister(
kJSFunctionRegister.code(), MachineType::TaggedPointer()));
}
int parameter_slots = AddArgumentPaddingSlots(params.NumStackSlots());
LinkageLocationAllocator rets(wasm::kGpReturnRegisters,
wasm::kFpReturnRegisters, parameter_slots);
for (size_t i = 0; i < call_descriptor->ReturnCount(); i++) {
if (call_descriptor->GetReturnType(i) == input_type.machine_type()) {
for (size_t j = 0; j < num_replacements; j++) {
locations.AddReturn(rets.Next(output_type.machine_representation()));
}
} else {
locations.AddReturn(
rets.Next(call_descriptor->GetReturnType(i).representation()));
}
}
int return_slots = rets.NumStackSlots();
auto sig = ReplaceTypeInSig(zone, call_descriptor->wasm_sig(), input_type,
output_type, num_replacements);
int parameter_slots;
int return_slots;
LocationSignature* location_sig = BuildLocations(
zone, sig, extra_callable_param, &parameter_slots, &return_slots);
return zone->New<CallDescriptor>( // --
call_descriptor->kind(), // kind
call_descriptor->GetInputType(0), // target MachineType
call_descriptor->GetInputLocation(0), // target location
locations.Build(), // location_sig
location_sig, // location_sig
parameter_slots, // parameter slot count
call_descriptor->properties(), // properties
call_descriptor->CalleeSavedRegisters(), // callee-saved registers