Skip to content

Avoid GC finalizers for trivially destructible native boxed values #186

Closed

Description

@dimensionscape

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.

Related: #151 for benchmark coverage.

Activity

  1. added
    haxe 5Only affects Haxe 5 (API level 500); fixable here, needs Haxe 5 to test
    on Oct 19, 2026
  2. added a commit that references this issue on Oct 20, 2026
    d5456f1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    haxe 5Only affects Haxe 5 (API level 500); fixable here, needs Haxe 5 to test

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions