[
https://issues.apache.org/jira/browse/GROOVY-12191?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18099129#comment-18099129
]
ASF GitHub Bot commented on GROOVY-12191:
-----------------------------------------
testlens-app[bot] commented on PR #2736:
URL: https://github.com/apache/groovy/pull/2736#issuecomment-5078820987
## ✅ All tests passed ✅
🏷️ Commit: 793abf88981fc6ae3f8025d44ef8a5b521026a39
▶️ Tests: 107086 executed
⚪️ Checks: 31/31 completed
---
_Learn more about TestLens at [testlens.app](https://testlens.app)._
> Scope indy SwitchPoint invalidation and harden PIC/math paths
> -------------------------------------------------------------
>
> Key: GROOVY-12191
> URL: https://issues.apache.org/jira/browse/GROOVY-12191
> Project: Groovy
> Issue Type: Improvement
> Reporter: Daniel Sun
> Priority: Major
>
> h3. Problem this targets
> With invokedynamic enabled (default since Groovy 4), a *single process-wide*
> {{SwitchPoint}} guarded essentially all linked MOP call sites. Any MetaClass
> registry change or category enter/leave invalidated that switch point, so
> *all* sites fell back and re-linked — including sites whose receiver type was
> unrelated.
> That global invalidation shows up as:
> * Startup / request paths with ExpandoMetaClass / mixins (Grails-like
> patterns) pay repeated re-link cost
> * Category {{use}} thrashing deoptimizes the whole application
> * JMH benches under {{subprojects/performance}} document this cost pattern
> h3. What changes proposed
> Four complementary layers under the indy / MOP runtime:
> ||#||Area||Behaviour||
> |1|Scoped SwitchPoint invalidation|Per-{{{}ClassInfo{}}} domain + hierarchy
> fan-out to loaded subtypes; separate *category-global* domain for
> {{{}use(Category){}}}. MetaClass change for class {{A}} no longer invalidates
> sites for unrelated class {{B}}|
> |2|PIC polymorphism policy|{{CallSiteTracker}} counts distinct receiver
> shapes; at {{max.poly}} the site becomes sticky *megamorphic* (pin default
> boot target, no monomorphic {{setTarget}} thrash). Selection stays amortized
> via the PIC|
> |3|Bimorphic promote|Two stable receiver shapes can share one nested
> {{guardWithTest}} target instead of alternating monomorphic targets|
> |4|IndyMath completeness|BigDecimal-category ops (and mixed integral+BD) via
> {{{}NumberMath{}}}; {{div}} / {{{}intdiv{}}}; primitive
> {{rightShiftUnsigned}} table entries. Shift ops stay off the
> GeneratedMetaMethod→IndyMath fast path so mixed {{{}int{}}}/{{{}long{}}}
> keeps left-operand result typing|
> h3. Invalidation model (after the changes)
> ||Domain||Invalidated when||Guards||
> |Per-class (+ subtypes)|{{ClassInfo.incVersion}} / MetaClass registry change
> for that type|Receiver class (or {{Class}} for static sites); hierarchy
> fan-out invalidates subtype SwitchPoints|
> |Category-global|Category enter/leave
> ({{{}VMPlugin.invalidateCallSites{}}})|Always dual-guarded with the class
> domain; *never* fails over (correctness)|
> Per-class SwitchPoint can fail over after repeated retirements (default 100)
> to a {{ClassInfo.version}} equality guard (avoids permanent-invalid SP
> recursion). Concurrent failover drains any raced-in SwitchPoint so none
> remains valid after the domain has failed over. Category domain stays
> unlimited.
> Generation bump on MetaClass *replacement* / clear retires that class's
> SwitchPoint; first MetaClass install only bumps version (no linked sites
> yet). Hierarchy fan-out remains on {{incVersion}} and registry listeners.
> h3. Tunables (system properties)
> ||Property||Default||Meaning||
> |{{groovy.indy.switchpoint.max.failures}}|{{100}}|Live SP retirements before
> per-class failover (value less than or equal to 0 = unlimited)|
> |{{groovy.indy.invalidation.stats}}|{{false}}|Log invalidation counters|
> |{{groovy.indy.callsite.max.poly}}|{{8}}|Distinct shapes to sticky
> megamorphic (value less than or equal to 0 disables)|
> |{{groovy.indy.callsite.mega.sticky}}|{{true}}|Mega flag survives shape clear|
> |{{groovy.indy.callsite.bimorphic}}|{{true}}|Allow dual-shape target promote|
> |{{groovy.indy.callsite.cache.size}}|{{8}}|PIC LRU size|
--
This message was sent by Atlassian Jira
(v8.20.10#820010)