public final class IndyInvalidation
extends Object
Scoped invokedynamic SwitchPoint invalidation for the Groovy MOP (GROOVY-12191).
Domain: one SwitchPoint domain per Class, owned by its
ClassInfo and covering every MetaClass generation of that class
(pre-MetaClass link included). The domain outlives the MetaClass
object, so exact-class invalidation still reaches installed guards
after a soft/weak MetaClass has been collected. Monomorphic indy sites
install a single guardWithTest on the class-level domain observed
at link time.
MetaClassImpl / EMC changes (including ClassInfo.incVersion,
registry replace, per-instance MetaClass).MetaClass.invokeMethod / property miss and walks the hierarchy live
from the registry each call. Construction-time snapshots of ancestor expando
methods are pre-existing MOP behaviour and are not refreshed by SwitchPoint
retirement. See also MetaClassImpl.findMethodInClassHierarchy.
Optional stats: -Dgroovy.indy.invalidation.stats=true.
Production guards: IndyInterface.applyMopSwitchPoints; tests may use
guardWithMopSwitchPoints.
| Type Params | Return Type | Name and description |
|---|---|---|
|
public static void |
anchorClassDomain(ClassInfo owner, SwitchPointInvalidator domain)Anchors a reclaim reference for a ClassInfo-owned class domain: when the ClassInfo (and with it the class) becomes unreachable while the domain still has a live registered SwitchPoint, the reference is delivered by the shared weak-bundle manager and the domain is retired — installed guards keep only the SwitchPoint's internal invoker reachable, so retiring the orphan forces straggler sites to re-link, which is always safe. |
|
public static long |
bulkInvalidationCount()Non-category process-wide bulk event count (invalidateBulk() / invalidateUnscoped()). |
|
public static long |
categoryInvalidationCount()Category-style bulk invalidation count (invalidateCategory()). |
|
public static long |
classInvalidationCount()Exact-class invalidation event count (invalidateClass(Class)). |
|
public static SwitchPoint |
classSwitchPointFor(Object receiver)Returns the class-level MetaClass SwitchPoint for the given receiver. |
|
public static SwitchPoint |
classSwitchPointFor(Class<?> type)Returns the SwitchPoint for the given class at link time: the current generation of the ClassInfo-owned class domain (defineClass-safe — does not create or consult a MetaClass). |
|
public static void |
collectLiveForClass(Class<?> type, List<SwitchPoint> out)Collects the live SwitchPoint (if any) of type's class domain.
|
|
public static MethodHandle |
guardWithMopSwitchPoints(MethodHandle handle, MethodHandle fallback, Object receiver)Installs a MetaClass SwitchPoint guard on handle.
|
|
public static MethodHandle |
guardWithMopSwitchPoints(MethodHandle handle, MethodHandle fallback, Class<?> receiverClass)Installs a MetaClass SwitchPoint guard on handle. |
|
public static void |
invalidateBulk()Process-wide bulk retirement for non-stock (custom) MetaClass registry events — correctness-first when selection may consult state outside the stock miss walk. |
|
public static void |
invalidateCategory()Category enter/leave and VMPlugin.invalidateCallSites().
|
|
public static void |
invalidateClass(Class<?> type)Retires only type's MetaClass SwitchPoint domain (exact class;
no subtype fan-out). |
|
public static void |
invalidateForMetaClassChange(MetaClassRegistryChangeEvent event)Registry-driven invalidation: exact class for stock MetaClass kinds and per-instance changes; process-wide bulk for custom MetaClass kinds or unattributed events. |
|
public static void |
invalidateMetaClass(MetaClass mc)Retires the class domain of mc's class (if a generation was
allocated). |
|
public static void |
invalidateUnscoped()Process-wide bulk retirement when a MetaClass registry event carries no Class attribution. |
|
public static boolean |
isStockMetaClass(MetaClass mc)Whether mc is a stock MOP MetaClass for which exact-class
invalidation is sufficient: null, or unwrapped
MetaClassImpl (includes EMC and subclasses). |
|
public static boolean |
needsBulkInvalidation(MetaClass oldMc, MetaClass newMc)Whether a class-level MetaClass change involving oldMc/newMc
requires process-wide bulk invalidation. |
|
public static void |
resetCountersForTesting()Resets process-wide counters (tests only). |
|
public static Class<?> |
switchPointClassFor(Object receiver)Resolves the class used for the MetaClass SwitchPoint domain of a receiver. |
|
public static SwitchPoint |
switchPointForMetaClass(MetaClass mc)Returns the class-domain SwitchPoint for a MetaClass. |
Anchors a reclaim reference for a ClassInfo-owned class domain: when the ClassInfo (and with it the class) becomes unreachable while the domain still has a live registered SwitchPoint, the reference is delivered by the shared weak-bundle manager and the domain is retired — installed guards keep only the SwitchPoint's internal invoker reachable, so retiring the orphan forces straggler sites to re-link, which is always safe.
Reachability: the live-SwitchPoint registry holds the invalidator strongly, and the invalidator holds the reclaim reference, so cleanup stays reachable exactly as long as there is something to clean; once the domain is retired the whole chain becomes collectable.
owner - the ClassInfo owning the domain (must not be null)domain - the class-level domain (must not be null)Non-category process-wide bulk event count (invalidateBulk() / invalidateUnscoped()).
Category-style bulk invalidation count (invalidateCategory()).
Exact-class invalidation event count (invalidateClass(Class)).
Returns the class-level MetaClass SwitchPoint for the given receiver.
receiver - the call receiver (may be null)Returns the SwitchPoint for the given class at link time: the current generation of the ClassInfo-owned class domain (defineClass-safe — does not create or consult a MetaClass).
type - the class (must not be null) Collects the live SwitchPoint (if any) of type's class domain.
Does not create a MetaClass and does not allocate a domain generation.
type - class to inspect (must not be null)out - destination list Installs a MetaClass SwitchPoint guard on handle.
Public entry for tests; production uses IndyInterface.applyMopSwitchPoints.
handle - the fast-path handlefallback - the re-link / fallback handlereceiver - the receiver used to select the MetaClass-domain switch point Installs a MetaClass SwitchPoint guard on handle.
handle - the fast-path handlefallback - the re-link / fallback handlereceiverClass - the class whose class-level MetaClass domain guards this siteProcess-wide bulk retirement for non-stock (custom) MetaClass registry events — correctness-first when selection may consult state outside the stock miss walk. Rare.
Category enter/leave and VMPlugin.invalidateCallSites().
Retires every loaded class-level domain so sites re-link under the new
category state. No separate category SwitchPoint on the hot path.
Retires only type's MetaClass SwitchPoint domain (exact class;
no subtype fan-out). No-op when type is null. Does not
bump ClassInfo.getVersion.
Used by ClassInfo.incVersion, stock registry MetaClass changes, and per-instance MetaClass changes. Non-stock MetaClass kinds use invalidateBulk() instead.
type - the class whose MetaClass changedRegistry-driven invalidation: exact class for stock MetaClass kinds and per-instance changes; process-wide bulk for custom MetaClass kinds or unattributed events. See class javadoc.
event - the registry change event (must not be null) Retires the class domain of mc's class (if a generation was
allocated). Does not bump counters (local domain retire; width policy is
separate).
mc - MetaClass (may be null) Process-wide bulk retirement when a MetaClass registry event carries no
Class attribution.
Whether mc is a stock MOP MetaClass for which exact-class
invalidation is sufficient: null, or unwrapped
MetaClassImpl (includes EMC and subclasses). Any other kind is
non-stock and triggers bulk invalidation on registry replace.
mc - MetaClass to classify (may be null)true if exact-class invalidation is sufficient Whether a class-level MetaClass change involving oldMc/newMc
requires process-wide bulk invalidation.
Bulk is reserved for non-stock MetaClass kinds: not MetaClassImpl after adapter unwrap. Stock pairs stay exact-class.
oldMc - previous MetaClass (may be null)newMc - new MetaClass (may be null on remove)true if bulk invalidation is requiredResets process-wide counters (tests only). Does not reset live switch points.
Resolves the class used for the MetaClass SwitchPoint domain of a receiver.
null maps to NullObject; a Class receiver uses itself.
receiver - the call receiver (may be null)Returns the class-domain SwitchPoint for a MetaClass. The domain belongs to the class, not the MetaClass instance, so every generation (and every adapter wrapping) of a class's MetaClass shares one domain.
mc - MetaClass (must not be null)