Class MethodWeaver

java.lang.Object
kilim.analysis.MethodWeaver

public class MethodWeaver extends Object
This class takes the basic blocks from a MethodFlow and generates all the extra code to support continuations.
  • Field Details

    • classWeaver

      private ClassWeaver classWeaver
    • methodFlow

      private MethodFlow methodFlow
    • isPausable

      private boolean isPausable
    • maxVars

      private int maxVars
    • maxStack

      private int maxStack
    • isSAM

      private boolean isSAM
    • fiberVar

      private int fiberVar
      The last parameter to a pausable method is a Fiber ref. The rest of the code doesn't know this because we do local surgery, and so is likely to stomp on the corresponding local var. We need to save this in a slot beyond (the original) maxLocals that is a safe haven for keeping the fiberVar.
    • numWordsInSig

      private int numWordsInSig
    • callWeavers

      private ArrayList<CallWeaver> callWeavers
    • detector

      private Detector detector
    • dslName

      static String dslName
    • dslDesc

      static String dslDesc
  • Constructor Details

  • Method Details

    • accept

      public void accept(org.objectweb.asm.ClassVisitor cv)
    • accept

      void accept(org.objectweb.asm.MethodVisitor mv)
    • visitAttrs

      private void visitAttrs(org.objectweb.asm.MethodVisitor mv)
    • visitCode

      private void visitCode(org.objectweb.asm.MethodVisitor mv)
    • visitLineNumbers

      private void visitLineNumbers(org.objectweb.asm.MethodVisitor mv)
    • visitLocals

      private void visitLocals(org.objectweb.asm.MethodVisitor mv)
    • visitInstructions

      private void visitInstructions(org.objectweb.asm.MethodVisitor mv)
    • addFiber

      private static String addFiber(String type)
    • preweaveDeserializeLambda

      public void preweaveDeserializeLambda()
      at least with openjdk 8-11, deserializing lambdas checks the signature or the target. FIXME: this method is implementation dependent (probably unfixable, but want this line to show in a grep)
    • transformIndyBootstrap

      private void transformIndyBootstrap(org.objectweb.asm.MethodVisitor mv, org.objectweb.asm.tree.AbstractInsnNode ain)
    • addFiberType

      private static org.objectweb.asm.Type addFiberType(org.objectweb.asm.Type type)
    • getCallsUnderCatchBlock

      private List<CallWeaver> getCallsUnderCatchBlock(BasicBlock catchBB)
    • genPausableMethod

      private void genPausableMethod(org.objectweb.asm.MethodVisitor mv, BasicBlock bb)
      For a method invocation f(...), this method assumes that the arguments to the call have already been pushed in. We need to push in the Fiber as the final argument, make the call, then add the code for post-calls, then leave it to visitInstructions() to resume visiting the remaining instructions in the block
        F_CALL:
          aload <fiberVar>
          invokevirtual fiber.down() ;; returns Fiber
          ... invoke ....
          aload <fiberVar>
          ... post call code
        F_RESUME: 
       
      Parameters:
      mv -
      bb - The BasicBlock that contains the pausable method invocation as the first instruction
    • genGetCurrentTask

      void genGetCurrentTask(org.objectweb.asm.MethodVisitor mv, BasicBlock bb)
    • hasGetCurrentTask

      private boolean hasGetCurrentTask()
    • createCallWeavers

      private void createCallWeavers()
    • genPrelude

      private void genPrelude(org.objectweb.asm.MethodVisitor mv)
      Say there are two invocations to two pausable methods obj.f(int) (virtual) and fs(double) (a static call) ; load fiber from last arg, and save it in a fresh register ; lest it gets stomped on. This is because we only patch locally, and don't change the other instructions.
           aload lastVar
           dup
           astore fiberVar 
           switch (fiber.pc) { 
             default: 0: START 
             1: F_PASS_DOWN 
             2: FS_PASS_DOWN 
           }
       
    • isStatic

      boolean isStatic()
    • getFiberArgVar

      int getFiberArgVar()
    • getNumWordsInSig

      int getNumWordsInSig()
    • genException

      private void genException(org.objectweb.asm.MethodVisitor mv, BasicBlock bb, List<CallWeaver> cwList)
      Generate code for only those catch blocks that are reachable from one or more pausable blocks. fiber.pc tells us which nested call possibly caused an exception, fiber.status tells us whether there is any state that needs to be restored, and fiber.curState gives us access to that state. ; Figure out which pausable method could have caused this. switch (fiber.upEx()) { 0: goto NORMAL_EXCEPTION_HANDLING; 2: goto RESTORE_F } RESTORE_F: if (fiber.curStatus == HAS_STATE) { restore variables from the state. don't restore stack goto NORMAL_EXCEPTION_HANDLING } ... other RESTOREs NORMAL_EXCEPTION_HANDLING:
    • getFiberVar

      int getFiberVar()
    • visitTryCatchBlocks

      void visitTryCatchBlocks(org.objectweb.asm.MethodVisitor mv)
    • ensureMaxVars

      void ensureMaxVars(int numVars)
    • ensureMaxStack

      void ensureMaxStack(int numStack)
    • getPC

      int getPC(CallWeaver weaver)
    • createStateClass

      public String createStateClass(ValInfoList valInfoList)
    • makeNotWovenMethod

      void makeNotWovenMethod(org.objectweb.asm.ClassVisitor cv, MethodFlow mf, boolean isSAM)
    • getClassWeaver

      ClassWeaver getClassWeaver()
    • getMethodFlow

      MethodFlow getMethodFlow()