Class MethodWeaver


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

      • 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 java.util.ArrayList<CallWeaver> callWeavers
      • dslName

        static java.lang.String dslName
      • dslDesc

        static java.lang.String dslDesc
    • Method Detail

      • 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 java.lang.String addFiber​(java.lang.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 java.util.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:
        bb - The BasicBlock that contains the pausable method invocation as the first instruction
        mv -
      • 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,
                                  java.util.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)
      • createStateClass

        public java.lang.String createStateClass​(ValInfoList valInfoList)
      • makeNotWovenMethod

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