Squashed function_record_std_launder/manuscript — 57b9a0af815d19b236b74be06a172bc5c9956618 — 2025-03-30 20:14:21 -0700 (#5592)

[Browse function_record_std_launder/manuscript tree](57b9a0af81)

[Browse function_record_std_launder/manuscript commits](57b9a0af81/)
This commit is contained in:
Ralf W. Grosse-Kunstleve
2025-03-31 15:54:38 -07:00
committed by GitHub
parent a34fcdc48d
commit e03ec30632
4 changed files with 30 additions and 11 deletions

View File

@@ -272,6 +272,12 @@ struct function_record {
/// Pointer to next overload
function_record *next = nullptr;
};
// The main purpose of this macro is to make it easy to pin-point the critically related code
// sections.
#define PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(...) \
static_assert( \
__VA_ARGS__, \
"Violation of precondition for pybind11/functional.h performance optimizations!")
/// Special data structure which (temporarily) holds metadata about a bound class
struct type_record {

View File

@@ -123,6 +123,14 @@
# endif
#endif
#if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914))
# define PYBIND11_STD_LAUNDER std::launder
# define PYBIND11_HAS_STD_LAUNDER 1
#else
# define PYBIND11_STD_LAUNDER
# define PYBIND11_HAS_STD_LAUNDER 0
#endif
#if defined(PYBIND11_CPP20)
# define PYBIND11_CONSTINIT constinit
# define PYBIND11_DTOR_CONSTEXPR constexpr

View File

@@ -101,8 +101,14 @@ public:
*reinterpret_cast<const std::type_info *>(rec->data[1]))) {
struct capture {
function_type f;
static capture *from_data(void **data) {
return PYBIND11_STD_LAUNDER(reinterpret_cast<capture *>(data));
}
};
value = ((capture *) &rec->data)->f;
PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(
std::is_standard_layout<capture>::value);
value = capture::from_data(rec->data)->f;
return true;
}
rec = rec->next;

View File

@@ -38,13 +38,6 @@
PYBIND11_WARNING_DISABLE_CLANG("-Wgnu-zero-variadic-macro-arguments")
#endif
#if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914))
# define PYBIND11_STD_LAUNDER std::launder
# define PYBIND11_HAS_STD_LAUNDER 1
#else
# define PYBIND11_STD_LAUNDER
# define PYBIND11_HAS_STD_LAUNDER 0
#endif
#if defined(__GNUG__) && !defined(__clang__)
# include <cxxabi.h>
#endif
@@ -345,6 +338,10 @@ protected:
using namespace detail;
struct capture {
remove_reference_t<Func> f;
static capture *from_data(void **data) {
return PYBIND11_STD_LAUNDER(reinterpret_cast<capture *>(data));
}
};
/* Store the function including any extra state it might have (e.g. a lambda capture
@@ -364,7 +361,7 @@ protected:
PYBIND11_WARNING_DISABLE_GCC("-Wplacement-new")
#endif
new ((capture *) &rec->data) capture{std::forward<Func>(f)};
new (capture::from_data(rec->data)) capture{std::forward<Func>(f)};
#if !PYBIND11_HAS_STD_LAUNDER
PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
@@ -374,8 +371,8 @@ protected:
// a significant refactoring it's "impossible" to solve.
if (!std::is_trivially_destructible<capture>::value) {
rec->free_data = [](function_record *r) {
auto data = PYBIND11_STD_LAUNDER((capture *) &r->data);
(void) data;
auto data = capture::from_data(r->data);
(void) data; // suppress "unused variable" warnings
data->~capture();
};
}
@@ -492,6 +489,8 @@ protected:
using FunctionType = Return (*)(Args...);
constexpr bool is_function_ptr
= std::is_convertible<Func, FunctionType>::value && sizeof(capture) == sizeof(void *);
PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(
!is_function_ptr || std::is_standard_layout<capture>::value);
if (is_function_ptr) {
rec->is_stateless = true;
rec->data[1]