Top Description Fields Constructors Methods
org.jruby.internal.runtime.methods

public Class InvocationMethodFactory

extends MethodFactory
implements Opcodes
Class Inheritance
All Implemented Interfaces
org.objectweb.asm.Opcodes
Known Direct Subclasses
org.jruby.internal.runtime.methods.InvokeDynamicMethodFactory, org.jruby.internal.runtime.methods.DumpingInvocationMethodFactory
Imports
org.jruby.Ruby, .RubyInstanceConfig, .RubyModule, .RubyString, org.jruby.anno.JRubyMethod, .JavaMethodDescriptor, .TypePopulator, org.jruby.compiler.impl.SkinnyMethodAdapter, org.jruby.runtime.Arity, .Block, .MethodFactory, .ThreadContext, .Visibility, org.jruby.runtime.builtin.IRubyObject, org.jruby.util.ClassDefiningJRubyClassLoader, .CodegenUtils, org.jruby.util.log.Logger, .LoggerFactory, org.objectweb.asm.AnnotationVisitor, .ClassReader, .ClassWriter, .Label, .Opcodes, org.objectweb.asm.util.CheckClassAdapter, java.io.PrintWriter, java.lang.reflect.Modifier, java.net.URL, java.util.Collections, .List

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
org.jruby.runtime.MethodFactory

Field Summary

Modifier and TypeField and Description
public static final int
ARGS_INDEX

The lvar index of the method args on the call

public static final int
BLOCK_INDEX

The lvar index of the passed-in Block on the call

public static final int
CLASS_INDEX

The lvar index of the RubyClass being invoked against

protected final ClassDefiningJRubyClassLoader
classLoader

The classloader to use for code loading

private static final String
COMPILED_CALL_SIG

The outward call signature for compiled Ruby method handles.

private static final String
COMPILED_CALL_SIG_BLOCK

The outward call signature for compiled Ruby method handles.

private static final String
COMPILED_CALL_SIG_ONE

The outward arity-one call-without-block signature for compiled Ruby method handles.

private static final String
COMPILED_CALL_SIG_ONE_BLOCK

The outward arity-one call-with-block signature for compiled Ruby method handles.

private static final String
COMPILED_CALL_SIG_THREE

The outward arity-three call-without-block signature for compiled Ruby method handles.

private static final String
COMPILED_CALL_SIG_THREE_BLOCK

The outward arity-three call-with-block signature for compiled Ruby method handles.

private static final String
COMPILED_CALL_SIG_TWO

The outward arity-two call-without-block signature for compiled Ruby method handles.

private static final String
COMPILED_CALL_SIG_TWO_BLOCK

The outward arity-two call-with-block signature for compiled Ruby method handles.

private static final String
COMPILED_CALL_SIG_ZERO

The outward arity-zero call-without-block signature for compiled Ruby method handles.

private static final String
COMPILED_CALL_SIG_ZERO_BLOCK

The outward arity-zero call-with-block signature for compiled Ruby method handles.

private static final boolean
private boolean
haveWarnedUser

Whether we've informed the user that we've seen undefined methods; this is to avoid a flood of repetitive information.

private static final String
JAVA_SUPER_SIG

The super constructor signature for Java-based method handles.

private static final Logger
public static final int
NAME_INDEX

The lvar index method name being invoked

public static final int
RECEIVER_INDEX

The lvar index of the method-receiving object

private static final Class<T>[]
private static final Class<T>[]
private boolean
seenUndefinedClasses

Whether this factory has seen undefined methods already.

protected final Object
syncObject

An object to sync against when loading classes, to avoid dups

public static final int
THIS_INDEX

The lvar index of "this"

public static final int
THREADCONTEXT_INDEX

The lvar index of the passed-in ThreadContext

Constructor Summary

AccessConstructor and Description
public
InvocationMethodFactory(ClassLoader
The classloader to use, or to wrap if it is not a JRubyClassLoader instance.
classLoader
)

Construct a new InvocationMethodFactory using the specified classloader to load code.

Method Summary

Modifier and TypeMethod and Description
private void
addAnnotatedMethodInvoker(ClassWriter cw, String superClass, List<JavaMethodDescriptor> descs, boolean acceptsKeywords)

private SkinnyMethodAdapter
beginMethod(ClassWriter cw, String methodName, int specificArity, boolean block)

private static void
checkArity(JRubyMethod
The annotation of the called method
jrubyMethod
,
SkinnyMethodAdapter
The code generator for the handle being created
method
,
int specificArity)

Emit code to check the arity of a call to a Java-based method.

public JavaMethod
constructJavaMethod(RubyModule implementationClass, JavaMethodDescriptor desc, String name, Class<T> c)

private void
createAnnotatedMethodInvocation(JavaMethodDescriptor desc, SkinnyMethodAdapter method, String superClass, int specificArity, boolean block, boolean acceptsKeywords)

private static ClassWriter
createJavaMethodCtor(String namePath, String sup, String parameterDesc)

private static Class<T>
protected Class<T>
public DynamicMethod
getAnnotatedMethod(RubyModule
The target class or module on which the method will be bound.
implementationClass
,
List<JavaMethodDescriptor> descs, String name)

Implements abstract org.jruby.runtime.MethodFactory.getAnnotatedMethod.

Use code generation to provide a method handle based on an annotated Java method.

public DynamicMethod
getAnnotatedMethod(RubyModule
The target class or module on which the method will be bound.
implementationClass
,
JavaMethodDescriptor
A JavaMethodDescriptor describing the target method
desc
,
String name)

Implements abstract org.jruby.runtime.MethodFactory.getAnnotatedMethod.

Use code generation to provide a method handle based on an annotated Java method.

public Class<T>
getAnnotatedMethodClass(List<JavaMethodDescriptor> descs)

Use code generation to provide a method handle based on an annotated Java method.

public static String
private static String
private static String
private void
private void
invokeCallConfigPre(SkinnyMethodAdapter mv, String superClass, int specificArity, boolean block, CallConfiguration callConfig)

private static void
invokeCCallTrace(SkinnyMethodAdapter method, int traceBoolIndex)

private static void
invokeCReturnTrace(SkinnyMethodAdapter method, int traceBoolIndex)

private static void
private static void
loadArgumentWithCast(SkinnyMethodAdapter mv, int argNumber, Class<T> coerceType)

private static void
loadBlock(SkinnyMethodAdapter mv, int specificArity, boolean getsBlock)

load the block argument from the correct position.

private static void
loadBlockForPre(SkinnyMethodAdapter mv, int specificArity, boolean getsBlock)

load block argument for pre() call.

private static void
private static void
prepareForPre(SkinnyMethodAdapter mv, int specificArity, boolean block, CallConfiguration callConfig)

private Class<T>
tryClass(String name, String path, Class<T> targetClass, Class<T> expectedSuperclass)

Inherited from org.jruby.runtime.MethodFactory:
createFactory

Field Detail

ARGS_INDEXback to summary
public static final int ARGS_INDEX

The lvar index of the method args on the call

BLOCK_INDEXback to summary
public static final int BLOCK_INDEX

The lvar index of the passed-in Block on the call

CLASS_INDEXback to summary
public static final int CLASS_INDEX

The lvar index of the RubyClass being invoked against

classLoaderback to summary
protected final ClassDefiningJRubyClassLoader classLoader

The classloader to use for code loading

COMPILED_CALL_SIGback to summary
private static final String COMPILED_CALL_SIG

The outward call signature for compiled Ruby method handles.

COMPILED_CALL_SIG_BLOCKback to summary
private static final String COMPILED_CALL_SIG_BLOCK

The outward call signature for compiled Ruby method handles.

COMPILED_CALL_SIG_ONEback to summary
private static final String COMPILED_CALL_SIG_ONE

The outward arity-one call-without-block signature for compiled Ruby method handles.

COMPILED_CALL_SIG_ONE_BLOCKback to summary
private static final String COMPILED_CALL_SIG_ONE_BLOCK

The outward arity-one call-with-block signature for compiled Ruby method handles.

COMPILED_CALL_SIG_THREEback to summary
private static final String COMPILED_CALL_SIG_THREE

The outward arity-three call-without-block signature for compiled Ruby method handles.

COMPILED_CALL_SIG_THREE_BLOCKback to summary
private static final String COMPILED_CALL_SIG_THREE_BLOCK

The outward arity-three call-with-block signature for compiled Ruby method handles.

COMPILED_CALL_SIG_TWOback to summary
private static final String COMPILED_CALL_SIG_TWO

The outward arity-two call-without-block signature for compiled Ruby method handles.

COMPILED_CALL_SIG_TWO_BLOCKback to summary
private static final String COMPILED_CALL_SIG_TWO_BLOCK

The outward arity-two call-with-block signature for compiled Ruby method handles.

COMPILED_CALL_SIG_ZEROback to summary
private static final String COMPILED_CALL_SIG_ZERO

The outward arity-zero call-without-block signature for compiled Ruby method handles.

COMPILED_CALL_SIG_ZERO_BLOCKback to summary
private static final String COMPILED_CALL_SIG_ZERO_BLOCK

The outward arity-zero call-with-block signature for compiled Ruby method handles.

DEBUGback to summary
private static final boolean DEBUG
haveWarnedUserback to summary
private boolean haveWarnedUser

Whether we've informed the user that we've seen undefined methods; this is to avoid a flood of repetitive information.

JAVA_SUPER_SIGback to summary
private static final String JAVA_SUPER_SIG

The super constructor signature for Java-based method handles.

LOGback to summary
private static final Logger LOG
NAME_INDEXback to summary
public static final int NAME_INDEX

The lvar index method name being invoked

RECEIVER_INDEXback to summary
public static final int RECEIVER_INDEX

The lvar index of the method-receiving object

RubyModule_and_Visibilityback to summary
private static final Class<T>[] RubyModule_and_Visibility

Deprecated

Annotations
@Deprecated
RubyModule_and_Visibility_and_Nameback to summary
private static final Class<T>[] RubyModule_and_Visibility_and_Name
seenUndefinedClassesback to summary
private boolean seenUndefinedClasses

Whether 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.

syncObjectback to summary
protected final Object syncObject

An object to sync against when loading classes, to avoid dups

THIS_INDEXback to summary
public static final int THIS_INDEX

The lvar index of "this"

THREADCONTEXT_INDEXback to summary
public static final int THREADCONTEXT_INDEX

The lvar index of the passed-in ThreadContext

Constructor Detail

InvocationMethodFactoryback to summary
public InvocationMethodFactory(ClassLoader classLoader)

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:ClassLoader

The classloader to use, or to wrap if it is not a JRubyClassLoader instance.

Method Detail

addAnnotatedMethodInvokerback to summary
private void addAnnotatedMethodInvoker(ClassWriter cw, String superClass, List<JavaMethodDescriptor> descs, boolean acceptsKeywords)
beginMethodback to summary
private SkinnyMethodAdapter beginMethod(ClassWriter cw, String methodName, int specificArity, boolean block)
checkArityback to summary
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:JRubyMethod

The annotation of the called method

method:SkinnyMethodAdapter

The code generator for the handle being created

constructJavaMethodback to summary
public JavaMethod constructJavaMethod(RubyModule implementationClass, JavaMethodDescriptor desc, String name, Class<T> c) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
Annotations
@SuppressWarnings:deprecation
createAnnotatedMethodInvocationback to summary
private void createAnnotatedMethodInvocation(JavaMethodDescriptor desc, SkinnyMethodAdapter method, String superClass, int specificArity, boolean block, boolean acceptsKeywords)
createJavaMethodCtorback to summary
private static ClassWriter createJavaMethodCtor(String namePath, String sup, String parameterDesc)
determineSuperclassback to summary
private static Class<T> determineSuperclass(DescriptorInfo info)
endClassback to summary
protected Class<T> endClass(ClassWriter cw, String name)
getAnnotatedMethodback to summary
public DynamicMethod getAnnotatedMethod(RubyModule implementationClass, List<JavaMethodDescriptor> descs, String name)

Implements abstract org.jruby.runtime.MethodFactory.getAnnotatedMethod.

Use code generation to provide a method handle based on an annotated Java method.

Parameters
implementationClass:RubyModule

Doc from org.jruby.runtime.MethodFactory.getAnnotatedMethod.

The target class or module on which the method will be bound.

Returns:DynamicMethod

Doc from org.jruby.runtime.MethodFactory.getAnnotatedMethod.

A method handle for the target object.

See Also
org.jruby.runtime.MethodFactory#getAnnotatedMethod
getAnnotatedMethodback to summary
public DynamicMethod getAnnotatedMethod(RubyModule implementationClass, JavaMethodDescriptor desc, String name)

Implements abstract org.jruby.runtime.MethodFactory.getAnnotatedMethod.

Use code generation to provide a method handle based on an annotated Java method.

Parameters
implementationClass:RubyModule

Doc from org.jruby.runtime.MethodFactory.getAnnotatedMethod.

The target class or module on which the method will be bound.

desc:JavaMethodDescriptor

Doc from org.jruby.runtime.MethodFactory.getAnnotatedMethod.

A JavaMethodDescriptor describing the target method

Returns:DynamicMethod

Doc from org.jruby.runtime.MethodFactory.getAnnotatedMethod.

A method handle for the target object.

See Also
org.jruby.runtime.MethodFactory#getAnnotatedMethod
getAnnotatedMethodClassback to summary
public Class<T> getAnnotatedMethodClass(List<JavaMethodDescriptor> descs)

Use code generation to provide a method handle based on an annotated Java method. Return the resulting generated or loaded class.

See Also
org.jruby.runtime.MethodFactory#getAnnotatedMethod
getPostMethodback to summary
public static String getPostMethod(CallConfiguration callConfig)
getPreMethodback to summary
private static String getPreMethod(CallConfiguration callConfig)
getPreSignatureback to summary
private static String getPreSignature(CallConfiguration callConfig)
invokeCallConfigPostback to summary
private void invokeCallConfigPost(SkinnyMethodAdapter mv, String superClass, CallConfiguration callConfig)
invokeCallConfigPreback to summary
private void invokeCallConfigPre(SkinnyMethodAdapter mv, String superClass, int specificArity, boolean block, CallConfiguration callConfig)
invokeCCallTraceback to summary
private static void invokeCCallTrace(SkinnyMethodAdapter method, int traceBoolIndex)
invokeCReturnTraceback to summary
private static void invokeCReturnTrace(SkinnyMethodAdapter method, int traceBoolIndex)
loadArgumentsback to summary
private static void loadArguments(SkinnyMethodAdapter mv, JavaMethodDescriptor desc, int specificArity)
loadArgumentWithCastback to summary
private static void loadArgumentWithCast(SkinnyMethodAdapter mv, int argNumber, Class<T> coerceType)
loadBlockback to summary
private static void loadBlock(SkinnyMethodAdapter mv, int specificArity, boolean getsBlock)

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.

loadBlockForPreback to summary
private static void loadBlockForPre(SkinnyMethodAdapter mv, int specificArity, boolean getsBlock)

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).

loadReceiverback to summary
private static void loadReceiver(String typePath, JavaMethodDescriptor desc, SkinnyMethodAdapter mv)
prepareForPreback to summary
private static void prepareForPre(SkinnyMethodAdapter mv, int specificArity, boolean block, CallConfiguration callConfig)
tryClassback to summary
private Class<T> tryClass(String name, String path, Class<T> targetClass, Class<T> expectedSuperclass)