Skip to content

fix(runtime): PPI DESTROY/refcount wiring + PPI future-work doc#737

Open
fglock wants to merge 4 commits into
masterfrom
fix/ppi-destroy-and-ppi-module-plan
Open

fix(runtime): PPI DESTROY/refcount wiring + PPI future-work doc#737
fglock wants to merge 4 commits into
masterfrom
fix/ppi-destroy-and-ppi-module-plan

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented May 15, 2026

Summary

  • Harden runtime behavior that affects PPI (and other modules) when DESTROY is resolved during load order transitions: avoid caching a failed DESTROY lookup as null, and avoid setting destroyFired before we know Perl DESTROY will run.
  • Improve incrementRefCountForContainerStore so nested anonymous referents at refCount == -1 are activated before the container-store increment (skip destroyed and weak-tracked referents).
  • Extend dev/modules/ppi.md with a dated follow-up section for t/04_element.t / %PPI::Singletons::_PARENT (tests 202 and 206 still fail after this PR; the doc lists ordered next steps). Link the module doc from dev/modules/README.md.

Test plan

  • make (full unit suite) — passed locally before push.
  • PPI: ./jcpan -t PPI or timeout 180 ./jperl … cpan/build/PPI-*/t/04_element.t — expect 202 and 206 to still fail until follow-up refcount work; no regression target asserted for the full PPI suite in this change.

fglock and others added 4 commits May 15, 2026 11:58
…module plan

- InheritanceResolver: do not cache failed DESTROY lookups as null (compile
  order can define DESTROY after an early miss).
- DestroyDispatch: set destroyFired only once Perl DESTROY will run, so a
  transient resolution miss does not skip PPI::Element::DESTROY.
- RuntimeScalar: incrementRefCountForContainerStore activates refCount=-1
  nested referents and skips MIN_VALUE / WEAKLY_TRACKED.
- dev/modules/ppi.md: future work for t/04_element.t %_PARENT teardown; README
  index row for PPI.

PPI t/04_element.t tests 202/206 remain failing; the doc lists next steps.

Generated with [Cursor](https://cursor.com/docs)

Co-Authored-By: Cursor <bot@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…f skipping misses

Cache failed DESTROY lookups as null for performance, but clear DESTROY-related
methodCache entries and DestroyDispatch caches whenever *::DESTROY map slots
change or a stash CV is defined in-place (globalCodeRefFqn + setLargeRefCounted).

Generated with [Cursor](https://cursor.com/docs)

Co-Authored-By: Cursor <noreply@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Replace DESTROY-only methodCache flush with invalidateMethodLookupCachesForStashSubKey:
drop cached lookups matching the sub's final segment (e.g. My::Pkg::foo → foo,
including \0noautoload keys). DestroyDispatch still clears only when the leaf is
DESTROY.

GlobalCodeRefMap skips invalidation on first empty stub put; put/remove and
setLargeRefCounted cover defined installs and in-place CV updates.

Generated with [Cursor](https://cursor.com/docs)

Co-Authored-By: Cursor <noreply@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…hes/arrays

incrementRefCountForContainerStore must only bootstrap RuntimeHash/RuntimeArray
slots from refCount=-1; promoting other referents (e.g. weak_ref targets that
are refs to readonly scalars) regressed Moo's t/accessor-weaken.t.

PPI nested {children} containers remain covered.

Generated with [Cursor](https://cursor.com/docs)

Co-Authored-By: Cursor <noreply@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.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