You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Avoid GC finalizers for trivially destructible native boxed values #186
Every constructor in include/cpp/marshal/Boxed.hpp selects its finalizer path with std::is_destructible. That trait is true for scalar types, pointers and ordinary trivial structs, so these boxes register a GC finalizer even when destroying their value does no work.
For example, int and int* are both destructible and trivially destructible. Boxed_obj and Boxed_obj<int*> still call GCSetFinalizer(this, finalise). The callback only invokes value.~T(), which is unnecessary for those types.
This adds registration in the global native finalizer map, its locking and bookkeeping, and work during GC finalizer processing. It is especially worth measuring for native interop that creates many boxes. This concerns cpp::marshal::Boxed_obj, not the ordinary Dynamic integer cache fixed in #172.
I'd compare scalar, pointer, trivial-struct and nontrivial-struct boxes. Record registration counts, allocation throughput and collection pauses with the existing behavior and with finalizers omitted for trivially destructible values. No speedup has been measured yet; this is a source-backed optimization candidate.
Use a trait based on nontrivial destruction when selecting whether to register, while preserving exactly-once cleanup for nontrivial native values. Test every constructor, copied native values and a destructor with a visible resource-release effect. Keep this separate from whether the boxed type contains GC references, since the class is documented for non-GC native values.
Activity
Skip finalizers for trivially destructible boxed values