Package kilim.analysis
Class MethodWeaver
- java.lang.Object
-
- kilim.analysis.MethodWeaver
-
public class MethodWeaver extends java.lang.ObjectThis class takes the basic blocks from a MethodFlow and generates all the extra code to support continuations.
-
-
Field Summary
Fields Modifier and Type Field Description private java.util.ArrayList<CallWeaver>callWeaversprivate ClassWeaverclassWeaverprivate Detectordetector(package private) static java.lang.StringdslDesc(package private) static java.lang.StringdslNameprivate intfiberVarThe last parameter to a pausable method is a Fiber ref.private booleanisPausableprivate booleanisSAMprivate intmaxStackprivate intmaxVarsprivate MethodFlowmethodFlowprivate intnumWordsInSig
-
Constructor Summary
Constructors Constructor Description MethodWeaver(ClassWeaver cw, Detector detector, MethodFlow mf, boolean isSAM)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaccept(org.objectweb.asm.ClassVisitor cv)(package private) voidaccept(org.objectweb.asm.MethodVisitor mv)private static java.lang.StringaddFiber(java.lang.String type)private static org.objectweb.asm.TypeaddFiberType(org.objectweb.asm.Type type)private voidcreateCallWeavers()java.lang.StringcreateStateClass(ValInfoList valInfoList)(package private) voidensureMaxStack(int numStack)(package private) voidensureMaxVars(int numVars)private voidgenException(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.(package private) voidgenGetCurrentTask(org.objectweb.asm.MethodVisitor mv, BasicBlock bb)private voidgenPausableMethod(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.private voidgenPrelude(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.private java.util.List<CallWeaver>getCallsUnderCatchBlock(BasicBlock catchBB)(package private) ClassWeavergetClassWeaver()(package private) intgetFiberArgVar()(package private) intgetFiberVar()(package private) MethodFlowgetMethodFlow()(package private) intgetNumWordsInSig()(package private) intgetPC(CallWeaver weaver)private booleanhasGetCurrentTask()(package private) booleanisStatic()(package private) voidmakeNotWovenMethod(org.objectweb.asm.ClassVisitor cv, MethodFlow mf, boolean isSAM)voidpreweaveDeserializeLambda()at least with openjdk 8-11, deserializing lambdas checks the signature or the target.private voidtransformIndyBootstrap(org.objectweb.asm.MethodVisitor mv, org.objectweb.asm.tree.AbstractInsnNode ain)private voidvisitAttrs(org.objectweb.asm.MethodVisitor mv)private voidvisitCode(org.objectweb.asm.MethodVisitor mv)private voidvisitInstructions(org.objectweb.asm.MethodVisitor mv)private voidvisitLineNumbers(org.objectweb.asm.MethodVisitor mv)private voidvisitLocals(org.objectweb.asm.MethodVisitor mv)(package private) voidvisitTryCatchBlocks(org.objectweb.asm.MethodVisitor mv)
-
-
-
Field Detail
-
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 java.util.ArrayList<CallWeaver> callWeavers
-
detector
private Detector detector
-
dslName
static java.lang.String dslName
-
dslDesc
static java.lang.String dslDesc
-
-
Constructor Detail
-
MethodWeaver
MethodWeaver(ClassWeaver cw, Detector detector, MethodFlow mf, boolean isSAM)
-
-
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 blockF_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 instructionmv-
-
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)
-
getPC
int getPC(CallWeaver weaver)
-
createStateClass
public java.lang.String createStateClass(ValInfoList valInfoList)
-
makeNotWovenMethod
void makeNotWovenMethod(org.objectweb.asm.ClassVisitor cv, MethodFlow mf, boolean isSAM)
-
getClassWeaver
ClassWeaver getClassWeaver()
-
getMethodFlow
MethodFlow getMethodFlow()
-
-