Record Class LockIdentityValue
- All Implemented Interfaces:
AbstractValue
MutexLock object(s) a variable may currently
refer to at a given program point.
The identityTokens set carries every identity the variable could
have. In the common case the set is a singleton (one known lock); branch
joins, polymorphic-getter resolution, and call-site argument bindings
introduce multi-element sets. Phase C.3 iterates the cross-product of
outer × inner identities when applying the deadlock verdict — if any pair
forms a cycle (E08252) or a cross-thread same-lock pattern (E08253) the
error fires.
Each element is one of two token shapes:
- Allocation token — an opaque
Objectreference, freshly minted perMutexLock(...)constructor call site. Compared by Java==.ISymbolreferences (for field-rooted and capture-rooted receivers) follow the same rule — A.4 freshness guarantees one symbol per allocation. PlaceholderToken— symbolic identity for a parameter whose underlying object is unknown until resolved at a call site. Compared structurally on parameter FQN.
Why custom token equality and not the JDK Set contract:
Symbol.equals(Object) is structural by name +
category + genus + mutability. Two distinct fields both named lock
on different classes would compare equal under that contract. If we relied
on default HashSet/Set.copyOf semantics, those two
physically-distinct locks would silently collapse to one element, missing a
potential lock-order cycle. So this record stores its tokens in a
deduplicated backing collection that enforces the per-token-type equality
rules of LockTokenIdentity (same, hash) and overrides
equals/hashCode to use the same rules for set-level
comparison. The public identityTokens() accessor returns an
unmodifiable view; iterators preserve insertion order.
Why set-union lattice for deadlock detection: the usual constant-folding lattice widens to TOP when paths disagree because the downstream consumer only acts on certainty. Deadlock detection is the opposite — it acts on possibility. If any execution path could pair the outer hold with an inner enter that forms a cycle, we want to warn. So the join unions sets rather than widening; the verdict iterates all pairs; one bad pair is enough.
-
Constructor Summary
ConstructorsConstructorDescriptionLockIdentityValue(Set<Object> identityTokens) Creates an instance of aLockIdentityValuerecord class. -
Method Summary
Modifier and TypeMethodDescriptionbooleanIndicates whether some other object is "equal to" this one.evaluateCondition(String operator, AbstractValue operand) Evaluate whether this abstract value satisfies a comparison condition.static LockIdentityValuefromTokens(Iterable<? extends Object> tokens) Build a value from a collection of tokens, applying token-rule dedup.inthashCode()Returns a hash code value for this object.booleanConvenience accessor:truewhen at least one element of the set is aPlaceholderToken.Returns the value of theidentityTokensrecord component.booleanisBottom()Check if this value represents an unreachable program point.booleanisKnown()Check if this value represents a known state (not TOP and not BOTTOM).join(AbstractValue other) Join this value with another at a branch convergence point.static LockIdentityValueSingleton factory — wraps one identity token.toString()Returns a string representation of this record class.(package private) AbstractValueunion(LockIdentityValue other) The union of this lock's identities and another's - for deadlock detection every possibility must stay represented.Methods inherited from interface AbstractValue
isKnownSet
-
Constructor Details
-
LockIdentityValue
-
-
Method Details
-
of
Singleton factory — wraps one identity token. Used for the common case where a variable has exactly one possible identity at this program point. -
fromTokens
Build a value from a collection of tokens, applying token-rule dedup. -
hasPlaceholder
public boolean hasPlaceholder()Convenience accessor:truewhen at least one element of the set is aPlaceholderToken. A set may carry mixed token types (an allocation + a placeholder, post-substitution at a polymorphic call site). -
join
Description copied from interface:AbstractValueJoin this value with another at a branch convergence point. Returns the least upper bound of the two values. Every implementation delegates toLatticeJoin, THE join, so the result never depends on which of the two values is the receiver.Key rules:
- BOTTOM join X = X (unreachable path is ignored)
- X join BOTTOM = X
- TOP join X = TOP
- Constant(a) join Constant(a) = Constant(a) (both agree)
- Constant(a) join Constant(b) = TOP (disagreement)
- Specified by:
joinin interfaceAbstractValue
-
union
The union of this lock's identities and another's - for deadlock detection every possibility must stay represented. Called byLatticeJoin, which owns every other rule of the join. -
evaluateCondition
Description copied from interface:AbstractValueEvaluate whether this abstract value satisfies a comparison condition.- Specified by:
evaluateConditionin interfaceAbstractValue- Parameters:
operator- the comparison operator (==, <>, <, >, etc.)operand- the right-hand side value to compare against- Returns:
- TRUE if condition is always satisfied, FALSE if never satisfied, UNKNOWN if indeterminate
-
isKnown
public boolean isKnown()Description copied from interface:AbstractValueCheck if this value represents a known state (not TOP and not BOTTOM).- Specified by:
isKnownin interfaceAbstractValue
-
isBottom
public boolean isBottom()Description copied from interface:AbstractValueCheck if this value represents an unreachable program point.- Specified by:
isBottomin interfaceAbstractValue
-
equals
Indicates whether some other object is "equal to" this one. The objects are equal if the other object is of the same class and if all the record components are equal. All components in this record class are compared withObjects::equals(Object,Object). -
hashCode
-
toString
-
identityTokens
-