Bytecode‑Based Method Invocation for High‑Performance Java Middleware

The article presents a bytecode‑generation technique that creates dynamic wrapper classes to invoke arbitrary Java methods with near‑native speed, avoiding reflection’s overhead, and details the CallerWrap base, generator, and thread‑safe cache implementation that together enable high‑performance middleware calls.

Youku Technology
Youku Technology
Youku Technology
Bytecode‑Based Method Invocation for High‑Performance Java Middleware

This article introduces a technique for invoking user‑defined methods in Java frameworks and middleware with performance close to native calls while retaining the flexibility of reflection. The author explains the motivation: traditional interface‑based callbacks are rigid and reflective calls are relatively slow, even after JDK optimisations.

The proposed solution is to generate bytecode at runtime that directly calls the target method. By creating a dynamic wrapper class (e.g., CallerWrap$A$Test) in memory, the framework can invoke any method without the overhead of reflection.

Example target class:

public static class A {
    public void test() {
        StringBuilder buf = new StringBuilder(100);
        for (int i = 0; i < 100; i++) {
            buf.append(i);
        }
    }
}

Dynamic wrapper class skeleton:

public class CallerWrap$A$Test {
    public Object call(A target) {
        target.test();
        return null;
    }
}

The core implementation consists of three parts:

CallerWrap base class: defines the abstract call(Object obj, Object[] args) method and holds static utilities for bytecode generation using cglib.

Generator class: extends AbstractClassGenerator<Object> and emits the bytecode for the call method. It handles loading the target object, casting arguments (including primitive wrappers), invoking the method via ReflectUtils.getMethodInfo, and returning the appropriate value (or null for void).

Caller cache: a thread‑safe ConcurrentHashMap keyed by class, method name, and parameter types to ensure each wrapper is generated only once.

Key code snippets from the generator (simplified):

public void generateClass(ClassVisitor v) {
    ClassEmitter ce = new ClassEmitter(v);
    ce.begin_class(Constants.V1_2, Constants.ACC_PUBLIC, getClassName(), CALL_WRAP, null, Constants.SOURCE_FILE);
    EmitUtils.null_constructor(ce);
    CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,
        new Signature("call", Constants.TYPE_OBJECT, new Type[]{Constants.TYPE_OBJECT, Constants.TYPE_OBJECT_ARRAY}),
        new Type[]{Constants.TYPE_THROWABLE});
    // load target and cast
    e.load_arg(0);
    e.checkcast(Type.getType(source));
    // load and cast arguments
    if (types != null) {
        int index = 0;
        for (Class<?> type : types) {
            e.load_arg(1);
            e.aaload(index++);
            if (type.isPrimitive()) {
                Class<?> wrap = primary2Wrap.get(type);
                e.checkcast(Type.getType(wrap));
                e.invoke(primaryValue.get(type));
            } else {
                e.checkcast(Type.getType(type));
            }
        }
    }
    // invoke target method
    Method method = getMethod(source, methodName, types);
    e.invoke(ReflectUtils.getMethodInfo(method));
    // handle return value
    Class<?> ret = method.getReturnType();
    if (ret.equals(void.class) || ret.equals(Void.class)) {
        e.aconst_null();
    }
    e.return_value();
    e.end_method();
    ce.end_class();
}

Finally, a static helper

Caller.call(Object obj, String methodName, Class<?>[] types, Object[] args)

looks up (or creates) the appropriate CallerWrap instance from the cache and delegates the call.

The article concludes that while JDK reflection has been optimised with MethodAccessor, bytecode generation still offers lower latency, especially for high‑frequency calls. For even more aggressive optimisation, the author mentions Java 7’s MethodHandle as an alternative.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaperformancebytecodemiddlewareReflectioncglib
Youku Technology
Written by

Youku Technology

Discover top-tier entertainment technology here.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.