Package kilim.analysis
Class MethodWeaver
java.lang.Object
kilim.analysis.MethodWeaver
This class takes the basic blocks from a MethodFlow and generates
all the extra code to support continuations.
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate ArrayList<CallWeaver> private ClassWeaverprivate Detector(package private) static String(package private) static Stringprivate intThe last parameter to a pausable method is a Fiber ref.private booleanprivate booleanprivate intprivate intprivate MethodFlowprivate int -
Constructor Summary
ConstructorsConstructorDescriptionMethodWeaver(ClassWeaver cw, Detector detector, MethodFlow mf, boolean isSAM) -
Method Summary
Modifier and TypeMethodDescriptionvoidaccept(org.objectweb.asm.ClassVisitor cv) (package private) voidaccept(org.objectweb.asm.MethodVisitor mv) private static Stringprivate static org.objectweb.asm.TypeaddFiberType(org.objectweb.asm.Type type) private voidcreateStateClass(ValInfoList valInfoList) (package private) voidensureMaxStack(int numStack) (package private) voidensureMaxVars(int numVars) private voidgenException(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.(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 List<CallWeaver> getCallsUnderCatchBlock(BasicBlock catchBB) (package private) ClassWeaver(package private) int(package private) int(package private) MethodFlow(package private) int(package private) intgetPC(CallWeaver weaver) private boolean(package private) booleanisStatic()(package private) voidmakeNotWovenMethod(org.objectweb.asm.ClassVisitor cv, MethodFlow mf, boolean isSAM) voidat 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 Details
-
classWeaver
-
methodFlow
-
isPausable
private boolean isPausable -
maxVars
private int maxVars -
maxStack
private int maxStack -
isSAM
private boolean isSAM -
fiberVar
private int fiberVarThe 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
-
detector
-
dslName
-
dslDesc
-
-
Constructor Details
-
MethodWeaver
MethodWeaver(ClassWeaver cw, Detector detector, MethodFlow mf, boolean isSAM)
-
-
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
-
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
-
genPausableMethod
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:
mv-bb- The BasicBlock that contains the pausable method invocation as the first instruction
-
genGetCurrentTask
-
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
-
createStateClass
-
makeNotWovenMethod
-
getClassWeaver
ClassWeaver getClassWeaver() -
getMethodFlow
MethodFlow getMethodFlow()
-