Class InvocationMethodFactory
java.lang.Object
org.jruby.runtime.MethodFactory
org.jruby.internal.runtime.methods.InvocationMethodFactory
- All Implemented Interfaces:
org.objectweb.asm.Opcodes
- Direct Known Subclasses:
DumpingInvocationMethodFactory,InvokeDynamicMethodFactory
In order to avoid the overhead with reflection-based method handles, this
MethodFactory uses ASM to generate tiny invoker classes. This allows for
better performance and more specialization per-handle than can be supported
via reflection. It also allows optimizing away many conditionals that can
be determined once ahead of time.
When running in secured environments, this factory may not function. When
this can be detected, MethodFactory will fall back on the reflection-based
factory instead.
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intThe lvar index of the method args on the callstatic final intThe lvar index of the passed-in Block on the callstatic final intThe lvar index of the RubyClass being invoked againstprotected final ClassDefiningJRubyClassLoaderThe classloader to use for code loadingprivate static final StringThe outward call signature for compiled Ruby method handles.private static final StringThe outward call signature for compiled Ruby method handles.private static final StringThe outward arity-one call-without-block signature for compiled Ruby method handles.private static final StringThe outward arity-one call-with-block signature for compiled Ruby method handles.private static final StringThe outward arity-three call-without-block signature for compiled Ruby method handles.private static final StringThe outward arity-three call-with-block signature for compiled Ruby method handles.private static final StringThe outward arity-two call-without-block signature for compiled Ruby method handles.private static final StringThe outward arity-two call-with-block signature for compiled Ruby method handles.private static final StringThe outward arity-zero call-without-block signature for compiled Ruby method handles.private static final StringThe outward arity-zero call-with-block signature for compiled Ruby method handles.private static final booleanprivate booleanWhether we've informed the user that we've seen undefined methods; this is to avoid a flood of repetitive information.private static final StringThe super constructor signature for Java-based method handles.private static final Loggerstatic final intThe lvar index method name being invokedstatic final intThe lvar index of the method-receiving objectprivate static final Class[]Deprecated.private static final Class[]private booleanWhether this factory has seen undefined methods already.protected final ObjectAn object to sync against when loading classes, to avoid dupsstatic final intThe lvar index of "this"static final intThe lvar index of the passed-in ThreadContextFields 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, V9 -
Constructor Summary
ConstructorsConstructorDescriptionInvocationMethodFactory(ClassLoader classLoader) Construct a new InvocationMethodFactory using the specified classloader to load code. -
Method Summary
Modifier and TypeMethodDescriptionprivate voidaddAnnotatedMethodInvoker(org.objectweb.asm.ClassWriter cw, String superClass, List<JavaMethodDescriptor> descs) private SkinnyMethodAdapterbeginMethod(org.objectweb.asm.ClassWriter cw, String methodName, int specificArity, boolean block) private static voidcheckArity(JRubyMethod jrubyMethod, SkinnyMethodAdapter method, int specificArity) Emit code to check the arity of a call to a Java-based method.constructJavaMethod(RubyModule implementationClass, JavaMethodDescriptor desc, String name, Class c) private voidcreateAnnotatedMethodInvocation(JavaMethodDescriptor desc, SkinnyMethodAdapter method, String superClass, int specificArity, boolean block) private static org.objectweb.asm.ClassWritercreateJavaMethodCtor(String namePath, String sup, String parameterDesc) private static Classprotected ClassgetAnnotatedMethod(RubyModule implementationClass, List<JavaMethodDescriptor> descs, String name) Use code generation to provide a method handle based on an annotated Java method.getAnnotatedMethod(RubyModule implementationClass, JavaMethodDescriptor desc, String name) Use code generation to provide a method handle based on an annotated Java method.Use code generation to provide a method handle based on an annotated Java method.static StringgetPostMethod(CallConfiguration callConfig) private static StringgetPreMethod(CallConfiguration callConfig) private static StringgetPreSignature(CallConfiguration callConfig) private voidinvokeCallConfigPost(SkinnyMethodAdapter mv, String superClass, CallConfiguration callConfig) private voidinvokeCallConfigPre(SkinnyMethodAdapter mv, String superClass, int specificArity, boolean block, CallConfiguration callConfig) private static voidinvokeCCallTrace(SkinnyMethodAdapter method, int traceBoolIndex) private static voidinvokeCReturnTrace(SkinnyMethodAdapter method, int traceBoolIndex) private static voidloadArguments(SkinnyMethodAdapter mv, JavaMethodDescriptor desc, int specificArity) private static voidloadArgumentWithCast(SkinnyMethodAdapter mv, int argNumber, Class coerceType) private static voidloadBlock(SkinnyMethodAdapter mv, int specificArity, boolean getsBlock) load the block argument from the correct position.private static voidloadBlockForPre(SkinnyMethodAdapter mv, int specificArity, boolean getsBlock) load block argument for pre() call.private static voidloadReceiver(String typePath, JavaMethodDescriptor desc, SkinnyMethodAdapter mv) private static voidprepareForPre(SkinnyMethodAdapter mv, int specificArity, boolean block, CallConfiguration callConfig) private ClassMethods inherited from class org.jruby.runtime.MethodFactory
createFactory
-
Field Details
-
LOG
-
DEBUG
private static final boolean DEBUG- See Also:
-
COMPILED_CALL_SIG
The outward call signature for compiled Ruby method handles. -
COMPILED_CALL_SIG_BLOCK
The outward call signature for compiled Ruby method handles. -
COMPILED_CALL_SIG_ZERO_BLOCK
The outward arity-zero call-with-block signature for compiled Ruby method handles. -
COMPILED_CALL_SIG_ZERO
The outward arity-zero call-without-block signature for compiled Ruby method handles. -
COMPILED_CALL_SIG_ONE_BLOCK
The outward arity-one call-with-block signature for compiled Ruby method handles. -
COMPILED_CALL_SIG_ONE
The outward arity-one call-without-block signature for compiled Ruby method handles. -
COMPILED_CALL_SIG_TWO_BLOCK
The outward arity-two call-with-block signature for compiled Ruby method handles. -
COMPILED_CALL_SIG_TWO
The outward arity-two call-without-block signature for compiled Ruby method handles. -
COMPILED_CALL_SIG_THREE_BLOCK
The outward arity-three call-with-block signature for compiled Ruby method handles. -
COMPILED_CALL_SIG_THREE
The outward arity-three call-without-block signature for compiled Ruby method handles. -
JAVA_SUPER_SIG
The super constructor signature for Java-based method handles. -
THIS_INDEX
public static final int THIS_INDEXThe lvar index of "this"- See Also:
-
THREADCONTEXT_INDEX
public static final int THREADCONTEXT_INDEXThe lvar index of the passed-in ThreadContext- See Also:
-
RECEIVER_INDEX
public static final int RECEIVER_INDEXThe lvar index of the method-receiving object- See Also:
-
CLASS_INDEX
public static final int CLASS_INDEXThe lvar index of the RubyClass being invoked against- See Also:
-
NAME_INDEX
public static final int NAME_INDEXThe lvar index method name being invoked- See Also:
-
ARGS_INDEX
public static final int ARGS_INDEXThe lvar index of the method args on the call- See Also:
-
BLOCK_INDEX
public static final int BLOCK_INDEXThe lvar index of the passed-in Block on the call- See Also:
-
classLoader
The classloader to use for code loading -
syncObject
An object to sync against when loading classes, to avoid dups -
seenUndefinedClasses
private boolean seenUndefinedClassesWhether this factory has seen undefined methods already. This is used to detect likely method handle collisions when we expect to create a new handle for each call. -
haveWarnedUser
private boolean haveWarnedUserWhether we've informed the user that we've seen undefined methods; this is to avoid a flood of repetitive information. -
RubyModule_and_Visibility_and_Name
-
RubyModule_and_Visibility
Deprecated.
-
-
Constructor Details
-
InvocationMethodFactory
Construct a new InvocationMethodFactory using the specified classloader to load code. If the target classloader is not an instance of JRubyClassLoader, it will be wrapped with one.- Parameters:
classLoader- The classloader to use, or to wrap if it is not a JRubyClassLoader instance.
-
-
Method Details
-
getAnnotatedMethod
public DynamicMethod getAnnotatedMethod(RubyModule implementationClass, List<JavaMethodDescriptor> descs, String name) Use code generation to provide a method handle based on an annotated Java method.- Specified by:
getAnnotatedMethodin classMethodFactory- Parameters:
implementationClass- The target class or module on which the method will be bound.- Returns:
- A method handle for the target object.
- See Also:
-
getAnnotatedMethodClass
Use code generation to provide a method handle based on an annotated Java method. Return the resulting generated or loaded class. -
determineSuperclass
-
getAnnotatedMethod
public DynamicMethod getAnnotatedMethod(RubyModule implementationClass, JavaMethodDescriptor desc, String name) Use code generation to provide a method handle based on an annotated Java method.- Specified by:
getAnnotatedMethodin classMethodFactory- Parameters:
implementationClass- The target class or module on which the method will be bound.desc- A JavaMethodDescriptor describing the target method- Returns:
- A method handle for the target object.
- See Also:
-
constructJavaMethod
public JavaMethod constructJavaMethod(RubyModule implementationClass, JavaMethodDescriptor desc, String name, Class c) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException -
checkArity
private static void checkArity(JRubyMethod jrubyMethod, SkinnyMethodAdapter method, int specificArity) Emit code to check the arity of a call to a Java-based method.- Parameters:
jrubyMethod- The annotation of the called methodmethod- The code generator for the handle being created
-
createJavaMethodCtor
-
invokeCallConfigPre
private void invokeCallConfigPre(SkinnyMethodAdapter mv, String superClass, int specificArity, boolean block, CallConfiguration callConfig) -
invokeCallConfigPost
private void invokeCallConfigPost(SkinnyMethodAdapter mv, String superClass, CallConfiguration callConfig) -
prepareForPre
private static void prepareForPre(SkinnyMethodAdapter mv, int specificArity, boolean block, CallConfiguration callConfig) -
getPreMethod
-
getPreSignature
-
getPostMethod
-
loadArguments
private static void loadArguments(SkinnyMethodAdapter mv, JavaMethodDescriptor desc, int specificArity) -
loadArgumentWithCast
-
loadBlockForPre
load block argument for pre() call. Since we have fixed-arity call paths we need calculate where the last var holding the block is. is we don't have a block we setup NULL_BLOCK as part of our null pattern strategy (we do not allow null in any field which accepts block). -
loadBlock
load the block argument from the correct position. Since we have fixed- arity call paths we need to calculate where the last var holding the block is. If we don't have a block then this does nothing. -
loadReceiver
private static void loadReceiver(String typePath, JavaMethodDescriptor desc, SkinnyMethodAdapter mv) -
tryClass
-
endClass
-
beginMethod
private SkinnyMethodAdapter beginMethod(org.objectweb.asm.ClassWriter cw, String methodName, int specificArity, boolean block) -
addAnnotatedMethodInvoker
private void addAnnotatedMethodInvoker(org.objectweb.asm.ClassWriter cw, String superClass, List<JavaMethodDescriptor> descs) -
createAnnotatedMethodInvocation
private void createAnnotatedMethodInvocation(JavaMethodDescriptor desc, SkinnyMethodAdapter method, String superClass, int specificArity, boolean block) -
invokeCCallTrace
-
invokeCReturnTrace
-