[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:
parent
f7895fc42b
commit
8062598f26
@ -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, ¶meter_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, ¶meter_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
|
||||
|
Loading…
Reference in New Issue
Block a user