Summary
Several x86_64 emitters stamp heap allocations with a transposed magic word, 0x4548504c (E H P L), while the canonical constant checked by the refcount helpers is X86_64_HEAP_MAGIC_HI32 = 0x454C5048 (E L P H, see src/codegen/runtime/arrays/incref.rs:14, decref_object.rs:15). Any object stamped with the transposed word fails the magic check in __rt_incref / __rt_decref_object / deep-free, so every refcount operation on it is a silent no-op on linux-x86_64 — the object can never be freed, and acquire/release bookkeeping is inert for it.
Affected stamp sites (grep 0x4548504c)
src/codegen_ir/lower_inst/objects.rs (2: LogicException + Error throwable allocation)
src/codegen_ir/lower_inst/enums.rs (enum ValueError/TypeError throwers)
src/codegen_ir/lower_inst/static_properties.rs
src/codegen_ir/lower_inst/builtins/math.rs
src/codegen/runtime/arrays/value_error.rs
src/codegen/runtime/system/json_throw_error.rs
src/codegen/runtime/spl/doubly_linked_list.rs
src/codegen/runtime/spl/fixed_array.rs
src/codegen/builtins/math/clamp.rs
src/codegen/builtins/strings/hash_crypto.rs
src/codegen/expr/objects/allocation.rs (frozen legacy backend)
src/codegen/expr/objects/dispatch/enums.rs (frozen legacy backend)
By contrast, the main throwable allocation used by user-level new (src/codegen_ir/lower_inst/objects.rs, emit_throwable_allocation) and __rt_heap_alloc itself stamp the canonical 0x454C5048….
Impact
On linux-x86_64 only: throwables and objects created through the affected paths (runtime-raised ValueError/TypeError/LogicException/Error, JSON throw errors, some SPL/math/static-property paths) leak once released paths exist for them, and any ownership balancing around them silently does nothing. This was latent while caught exceptions were never released at all; PR #477 (issue #448) makes exception releases real, so these objects now diverge from the correctly-stamped ones (they leak instead of freeing — no crash).
Full disclosure: the enums.rs occurrences include code I added in #450/#453, faithfully copying the transposed literal from the pre-existing emit_throw_value_error_from_string_result_x86_64 — the constant deserves a single named const shared by every emitter so this class of typo cannot recur.
Suggested direction
Replace every literal 0x4548504c… stamp with the canonical constant (ideally exporting one X86_64_HEAP_MAGIC_HI32-derived kind-word helper for emitters), and add a debug assertion or test that greps/validates stamped magic words against the checker constant. Legacy-backend files can be skipped per the backend freeze policy.
Summary
Several x86_64 emitters stamp heap allocations with a transposed magic word,
0x4548504c(E H P L), while the canonical constant checked by the refcount helpers isX86_64_HEAP_MAGIC_HI32 = 0x454C5048(E L P H, seesrc/codegen/runtime/arrays/incref.rs:14,decref_object.rs:15). Any object stamped with the transposed word fails the magic check in__rt_incref/__rt_decref_object/ deep-free, so every refcount operation on it is a silent no-op on linux-x86_64 — the object can never be freed, and acquire/release bookkeeping is inert for it.Affected stamp sites (grep
0x4548504c)By contrast, the main throwable allocation used by user-level
new(src/codegen_ir/lower_inst/objects.rs,emit_throwable_allocation) and__rt_heap_allocitself stamp the canonical0x454C5048….Impact
On linux-x86_64 only: throwables and objects created through the affected paths (runtime-raised
ValueError/TypeError/LogicException/Error, JSON throw errors, some SPL/math/static-property paths) leak once released paths exist for them, and any ownership balancing around them silently does nothing. This was latent while caught exceptions were never released at all; PR #477 (issue #448) makes exception releases real, so these objects now diverge from the correctly-stamped ones (they leak instead of freeing — no crash).Full disclosure: the
enums.rsoccurrences include code I added in #450/#453, faithfully copying the transposed literal from the pre-existingemit_throw_value_error_from_string_result_x86_64— the constant deserves a single namedconstshared by every emitter so this class of typo cannot recur.Suggested direction
Replace every literal
0x4548504c…stamp with the canonical constant (ideally exporting oneX86_64_HEAP_MAGIC_HI32-derived kind-word helper for emitters), and add a debug assertion or test that greps/validates stamped magic words against the checker constant. Legacy-backend files can be skipped per the backend freeze policy.