Skip to content

docs(D-W6.5): function-store + cmop-bootstrap reproducers; drift narrowed#609

Open
fglock wants to merge 1 commit intomasterfrom
fix/d-w6-function-hash-store
Open

docs(D-W6.5): function-store + cmop-bootstrap reproducers; drift narrowed#609
fglock wants to merge 1 commit intomasterfrom
fix/d-w6-function-hash-store

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 29, 2026

Summary

Two more focused reproducers + cumulative D-W6 findings.

What landed

src/test/resources/unit/refcount/drift/:

  • function_hash_store.t (18 tests) — five patterns of the
    sub setit { $METAS{$_[0]} = $_[1] } shape that
    Class::MOP::store_metaclass_by_name uses.
  • cmop_bootstrap.t (14 tests) — exact MOP shape: our %METAS
    global + weakened-back-ref Attribute + MetaClass with DESTROY.

Both pass on master AND with the walker gate disabled.

Cumulative D-W6 findings (sessions 1–5)

PerlOnJava's cooperative refcount handles ALL of these correctly
with the gate disabled. None is the drift source.

Reproducer Tests Patterns covered
sub_install.t 12 Glob assign, named sub, loop install, temp drop, nested install
closure_capture.t 8 Single → 5-layer wrap, 20-closure chain
hash_slot.t 14 Direct slot, package global, 50-entry registry, overwrite
weak_metaclass.t 14 Weak slot + outer keepalive, 20-loop, rescue
function_hash_store.t 18 Function-internal store via $_[N] and shift
cmop_bootstrap.t 14 %METAS + weak attr back-ref + DESTROY
Total 80

What this means

The actual Class::MOP drift is something more specific than any
of these clean shapes. Likely candidates left:

  1. Multi-level metaclass relationships
    Class::MOP::Class has 7+ ancestors via use parent.
  2. Attribute->attach_to_class called from many scopes.
  3. Method modifiers (add_around_method_modifier etc.).
  4. use parent / @ISA compile-time setup with mixin classes.

Suggestion for next session (in design doc)

Stop writing reproducers from scratch. Bisect the real
Class::MOP source
: take cmop_bootstrap.t and gradually add
features from Class::MOP::Class.pm until something breaks
without the gate.

The first feature to flip the test red is the smoking gun.

Test plan

  • make (build + unit tests) green.
  • All four new reproducers pass on master (gate active).
  • All four pass with the gate disabled in a probe build.

Generated with Devin

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

Two more focused reproducers landed in
src/test/resources/unit/refcount/drift/:

- function_hash_store.t (18 tests) — five patterns of the
  `sub setit { \$METAS{\$_[0]} = \$_[1] }` shape that
  Class::MOP::store_metaclass_by_name uses.
- cmop_bootstrap.t (14 tests) — exact MOP shape: `our %METAS` global,
  weakened-back-ref Attribute, MetaClass with DESTROY.

Both pass with the walker gate disabled. So the simple
function-internal hash store + weakened back-ref + DESTROY
combination is NOT the drift source either.

Cumulative across D-W6.1-D-W6.5: PerlOnJava's cooperative refcount
handles all of the following correctly with the gate disabled:

- Sub installation (5 patterns)
- Closure capture, up to 5-layer wrap
- Hash-slot tracking
- Weakened-hash + outer keepalive
- Function-internal hash store
- Weak attr back-ref + %METAS + DESTROY (cmop bootstrap shape)

The actual Class::MOP drift requires something MORE specific.
Likely candidates documented in moose_support.md:

1. Multi-level metaclass relationships (7+ ancestors).
2. Attribute->attach_to_class called from many scopes.
3. Method modifiers (add_around_method_modifier).
4. `use parent` / @isa setup at compile time.

Suggestion for next session: bisect the real Class::MOP source —
start from cmop_bootstrap.t and gradually add Class::MOP::Class.pm
features until something breaks. The smoking-gun feature is the
fix target.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant