Class SAMweaver
- java.lang.Object
-
- kilim.analysis.SAMweaver
-
- All Implemented Interfaces:
Constants,org.objectweb.asm.Opcodes
public class SAMweaver extends java.lang.Object implements Constants
SAMweavergenerates code to support functional interfaces (also known as SAM, for Single Abstract Method), where the SAM method is pausable. What makes SAM interfaces special compared to regular interfaces is that they can represent a lambda function in java8. More on this later. Imagine that a class calledXuses aIof the following form:interface I { int foo(double d) throws Pausable; }SinceIis a SAM,CallWeaverreplaces allinvokeinterface I.foo(double)with a static invocation of a tiny wrapper method ('shim') in X like this:invokestatic X.$shim$2(I callee, double d, Fiber f)The shim method in turn turns around and callsI.foo(double):private static int X.$shim$2(I callee, double d, Fiber f) { int ret = callee.f(d, f); f.setCallee(callee); // this is the purpose of the shim return ret; }The purpose ofSAMweaveris to generate the shim above.Why?
Ordinarily, all hand-written code is modified by the weaver if it contains definitions or invocations of pausable methods. Lambda expressions however rely on the VM generating a class at run-time, which implements the functional interface (
Iin the example). The problem is that this class needs to be woven to support kilim Fibers, but we don't have an easy portable hook to weave it at run-time.As it turns out, practically all the weaving work is already complete at compile time. This is because, the body of the lambda expression is already available to the weaver as an ordinary method in the host class
X, and is treated like any another pausable method. In other words, the transformations at the calling site and in the body of the called method are as usual. All that this is left for the shim to do is to capture the object's reference (f.setCallee); the fiber needs it while resuming. The call to setCallee is redundant for ordinary hand-written implementations of SAM interfaces, but is necessary if the implementation happens to be generated by the VM as described above.Of course, all this applies only if the functional method is pausable.
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from interface kilim.Constants
Constants.Util
-
-
Field Summary
Fields Modifier and Type Field Description (package private) KilimContextcontext(package private) java.lang.Stringdesc(package private) intindex(package private) java.lang.StringinterfaceName(package private) booleanitf(package private) java.lang.StringmethodName-
Fields inherited from interface kilim.Constants
ALOAD_0, ASTORE_0, D_ARRAY_BOOLEAN, D_ARRAY_BYTE, D_ARRAY_CHAR, D_ARRAY_DOUBLE, D_ARRAY_FLOAT, D_ARRAY_INT, D_ARRAY_LONG, D_ARRAY_SHORT, D_BOOLEAN, D_BYTE, D_CHAR, D_DOUBLE, D_FIBER, D_FIBER_LAST_ARG, D_FLOAT, D_INT, D_LONG, D_NULL, D_OBJECT, D_PAUSABLE, D_RETURN_ADDRESS, D_SHORT, D_STATE, D_STRING, D_TASK, D_THROWABLE, D_UNDEFINED, D_VOID, DLOAD_0, DSTORE_0, FIBER_CLASS, FLOAD_0, FSTORE_0, ILOAD_0, ISTORE_0, KILIM_ASM, KILIM_VERSION, LDC2_W, LLOAD_0, LSTORE_0, NOT_PAUSABLE_CLASS, PAUSABLE_CLASS, SAM_SHIM_PREFIX, STATE_CLASS, TASK_CLASS, THROWABLE_CLASS, WOVEN_FIELD
-
Fields inherited from interface org.objectweb.asm.Opcodes
AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_DEPRECATED, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_MANDATED, ACC_MODULE, ACC_NATIVE, ACC_OPEN, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_RECORD, ACC_STATIC, ACC_STATIC_PHASE, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_TRANSITIVE, ACC_VARARGS, ACC_VOLATILE, ACONST_NULL, ALOAD, ANEWARRAY, ARETURN, ARRAYLENGTH, ASM10_EXPERIMENTAL, ASM4, ASM5, ASM6, ASM7, ASM8, ASM9, ASTORE, ATHROW, BALOAD, BASTORE, BIPUSH, CALOAD, CASTORE, CHECKCAST, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DMUL, DNEG, DOUBLE, DREM, DRETURN, DSTORE, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F_APPEND, F_CHOP, F_FULL, F_NEW, F_SAME, F_SAME1, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAT, FMUL, FNEG, FREM, FRETURN, FSTORE, FSUB, GETFIELD, GETSTATIC, GOTO, H_GETFIELD, H_GETSTATIC, H_INVOKEINTERFACE, H_INVOKESPECIAL, H_INVOKESTATIC, H_INVOKEVIRTUAL, H_NEWINVOKESPECIAL, H_PUTFIELD, H_PUTSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILOAD, IMUL, INEG, INSTANCEOF, INTEGER, INVOKEDYNAMIC, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISUB, IUSHR, IXOR, JSR, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDIV, LLOAD, LMUL, LNEG, LONG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, NEW, NEWARRAY, NOP, NULL, POP, POP2, PUTFIELD, PUTSTATIC, RET, RETURN, SALOAD, SASTORE, SIPUSH, SOURCE_DEPRECATED, SOURCE_MASK, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, TOP, UNINITIALIZED_THIS, V_PREVIEW, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V9
-
-
Constructor Summary
Constructors Constructor Description SAMweaver(KilimContext context, java.lang.String interfaceName, java.lang.String methodName, java.lang.String desc, boolean itf)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaccept(org.objectweb.asm.ClassVisitor cv)Generate a method like this:booleanequals(java.lang.Object obj)private java.lang.String[]getExceptions()(package private) java.lang.StringgetShimDesc()(package private) java.lang.StringgetShimMethodName()inthashCode()(package private) static java.lang.String[]internalName(java.lang.String[] words)voidsetIndex(int index)java.lang.StringtoString()
-
-
-
Field Detail
-
interfaceName
java.lang.String interfaceName
-
methodName
java.lang.String methodName
-
desc
java.lang.String desc
-
itf
boolean itf
-
index
int index
-
context
KilimContext context
-
-
Constructor Detail
-
SAMweaver
public SAMweaver(KilimContext context, java.lang.String interfaceName, java.lang.String methodName, java.lang.String desc, boolean itf)
-
-
Method Detail
-
setIndex
public void setIndex(int index)
-
equals
public boolean equals(java.lang.Object obj)
- Overrides:
equalsin classjava.lang.Object
-
toString
public java.lang.String toString()
- Overrides:
toStringin classjava.lang.Object
-
hashCode
public int hashCode()
- Overrides:
hashCodein classjava.lang.Object
-
getShimMethodName
java.lang.String getShimMethodName()
-
getShimDesc
java.lang.String getShimDesc()
-
accept
public void accept(org.objectweb.asm.ClassVisitor cv)
Generate a method like this:private static $shim$1 (I callee, ...args..., f fiber) { load each arg call interface.method f.setCallee(arg0) xret }- Parameters:
cv-
-
internalName
static java.lang.String[] internalName(java.lang.String[] words)
-
getExceptions
private java.lang.String[] getExceptions()
-
-