package som.interpreter.nodes.dispatch;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;


public final class CachedDispatchNode extends AbstractDispatchNode {

  @Child private DirectCallNode       cachedMethod;
  @Child private AbstractDispatchNode nextInCache;

  private final DispatchGuard         guard;

  public CachedDispatchNode(final CallTarget methodCallTarget,
      final DispatchGuard guard, final AbstractDispatchNode nextInCache) {
    super(nextInCache.getSourceSection());
    this.cachedMethod = Truffle.getRuntime().createDirectCallNode(methodCallTarget);
    this.guard        = guard;
    this.nextInCache  = nextInCache;
  }

  @Override
  public Object executeDispatch(final VirtualFrame frame, final Object[] arguments) {
    try {
      if (guard.entryMatches(arguments[0])) {
        return cachedMethod.call(frame, arguments);
      } else {
        return nextInCache.executeDispatch(frame, arguments);
      }
    } catch (InvalidAssumptionException e) {
      CompilerDirectives.transferToInterpreter();
      return replace(nextInCache).
          executeDispatch(frame, arguments);
    }
  }

  @Override
  public int lengthOfDispatchChain() {
    return 1 + nextInCache.lengthOfDispatchChain();
  }
}

@@ -34,16 +34,43 @@
 patch;%0A%0A
+import som.compiler.Tags;%0A%0A
 import c
@@ -103,16 +103,16 @@
 Target;%0A
-
 import c
@@ -359,16 +359,37 @@
 ption;%0A%0A
+import dym.Tagging;%0A%0A
 %0Apublic 
@@ -451,16 +451,221 @@
 Node %7B%0A%0A
+  private static final String%5B%5D VIRTUAL_INVOKE = new String%5B%5D %7BTags.CACHED_VIRTUAL_INVOKE%7D;%0A  private static final String%5B%5D NOT_A = new String%5B%5D %7BTags.LOOP_BODY, Tags.LOOP_NODE, Tags.UNSPECIFIED_INVOKE%7D;%0A%0A
   @Child
@@ -954,16 +954,43 @@
   super(
+Tagging.cloneAndUpdateTags(
 nextInCa
@@ -1011,16 +1011,40 @@
 ection()
+, VIRTUAL_INVOKE, NOT_A)
 );%0A    t

Tag cached dispatch nodes