mirror of
https://github.com/FEX-Emu/FEX.git
synced 2025-01-19 04:42:27 +00:00
Thunks/gen: Repack out-parameters on exit
To avoid performance traps, several conditions must hold for exit repacking to apply: * Argument must be a pointer * The pointee type must have differing data layout between guest and host * The pointee type must be non-const Arguments that don't meet the first two conditions are safe *not* to repack on exit, since they're either passed by copy or have consistent data layout. The third condition is a heuristic: In principle, an API function could modify data through nested pointers even if the argument pointer is const. However, automatic repacking is not supported for such types anyway, so this is a safe heuristic to use.
This commit is contained in:
parent
dc477c3bd7
commit
4cbaad298a
@ -265,6 +265,20 @@ struct repack_wrapper {
|
||||
}
|
||||
}
|
||||
|
||||
~repack_wrapper() {
|
||||
// TODO: Properly detect opaque types
|
||||
if constexpr (requires(guest_layout<T> t, decltype(data) h) { t.get_pointer(); (bool)h; *data; }) {
|
||||
if constexpr (!std::is_const_v<std::remove_pointer_t<T>>) { // Skip exit-repacking for const pointees
|
||||
if (data) {
|
||||
constexpr bool is_compatible = has_compatible_data_layout<T> && std::is_same_v<T, GuestT>;
|
||||
if constexpr (!is_compatible && std::is_class_v<std::remove_pointer_t<T>>) {
|
||||
*orig_arg.get_pointer() = to_guest(*data); // TODO: Only if annotated as out-parameter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator PointeeT*() {
|
||||
static_assert(sizeof(PointeeT) == sizeof(host_layout<PointeeT>));
|
||||
static_assert(alignof(PointeeT) == alignof(host_layout<PointeeT>));
|
||||
|
Loading…
x
Reference in New Issue
Block a user