Class CyclicAssumption

java.lang.Object
com.oracle.truffle.api.utilities.CyclicAssumption

public class CyclicAssumption extends Object
Holds an Assumption, and knows how to recreate it with the same properties on invalidation. Used as an Assumption factory that safely invalidates the previous Assumption and creates a new Assumption on invalidation.

Note that you should be careful that repeated invalidations do not cause a deoptimization loop in that same way that you would with any other assumption.

The Assumption instance should be obtained before doing the operation depending on it. In other words:

  1. Obtain the current Assumption with getAssumption()
  2. Perform the operation/lookup which depends on the assumption
  3. Cache the result and the Assumption
On the fast-path, first check if the assumption is valid and in that case return the cached result. When invalidating, first write the new value, then invalidate the CyclicAssumption.
class MyContext {
    CyclicAssumption symbolsRedefined = new CyclicAssumption("symbols");
    Map<String, Object> symbols = new ConcurrentHashMap<>();

    public void redefineSymbol(String symbol, Object value) {
        symbols.put(symbol, value);
        symbolsRedefined.invalidate();
    }
}

class SymbolLookupNode extends Node {
    final MyContext context;
    final String symbol;

    @CompilationFinal volatile LookupResult cachedLookup;

    SymbolLookupNode(MyContext context, String symbol) {
        this.context = context;
        this.symbol = symbol;
    }

    public Object execute() {
        LookupResult lookup = cachedLookup;
        if (lookup == null || !lookup.assumption.isValid()) {
            CompilerDirectives.transferToInterpreterAndInvalidate();
            cachedLookup = doLookup(symbol);
        }
        return cachedLookup.value;
    }

    private LookupResult doLookup(String name) {
        // First get the Assumption
        CyclicAssumption symbolsRedefined = context.symbolsRedefined;
        Assumption assumption = symbolsRedefined.getAssumption();
        // Then lookup the value
        Object value = context.symbols.get(name);
        return new LookupResult(assumption, value);
    }
}

class LookupResult {
    final Assumption assumption;
    final Object value;

    LookupResult(Assumption assumption, Object value) {
        this.assumption = assumption;
        this.value = value;
    }
}
Since:
0.8 or earlier
  • Constructor Details

    • CyclicAssumption

      public CyclicAssumption(String name)
      Since:
      0.8 or earlier
  • Method Details

    • invalidate

      public void invalidate()
      Since:
      0.8 or earlier
    • invalidate

      public void invalidate(String message)
      Since:
      0.33
    • getAssumption

      public Assumption getAssumption()
      Since:
      0.8 or earlier