Strategy in StringConcatFactory

你。 提交于 2021-02-19 03:55:09

问题


I have know the invokedynamic instruction.

Also I have known the basic process how it implements. But when I arrive the code. I can't understand the code in StringConcatFactory.

Can you tell me how the six strategies implements by the source code. Only the default strategy is also done. As a university student, I can't under the source code.

private enum Strategy {
    /**
     * Bytecode generator, calling into {@link java.lang.StringBuilder}.
     */
    BC_SB,

    /**
     * Bytecode generator, calling into {@link java.lang.StringBuilder};
     * but trying to estimate the required storage.
     */
    BC_SB_SIZED,

    /**
     * Bytecode generator, calling into {@link java.lang.StringBuilder};
     * but computing the required storage exactly.
     */
    BC_SB_SIZED_EXACT,

    /**
     * MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
     * This strategy also tries to estimate the required storage.
     */
    MH_SB_SIZED,

    /**
     * MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
     * This strategy also estimate the required storage exactly.
     */
    MH_SB_SIZED_EXACT,

    /**
     * MethodHandle-based generator, that constructs its own byte[] array from
     * the arguments. It computes the required storage exactly.
     */
    MH_INLINE_SIZED_EXACT
}

回答1:


makeConcat() and makeConcatWithConstants(), which are StringConcatFactory API entry points, both use doStringConcat(), which produces a CallSite used by the invokedynamic.

doStringConcat() calls generate(Lookup, String, MethodType, Recipe) which contains the following switch on the enum you are asking about:

switch (STRATEGY) {
    case BC_SB:
        return StringConcatFactory.BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, StringConcatFactory.Mode.DEFAULT);
    case BC_SB_SIZED:
        return StringConcatFactory.BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, StringConcatFactory.Mode.SIZED);
    case BC_SB_SIZED_EXACT:
        return StringConcatFactory.BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, StringConcatFactory.Mode.SIZED_EXACT);
    case MH_SB_SIZED:
        return StringConcatFactory.MethodHandleStringBuilderStrategy.generate(mt, recipe, StringConcatFactory.Mode.SIZED);
    case MH_SB_SIZED_EXACT:
        return StringConcatFactory.MethodHandleStringBuilderStrategy.generate(mt, recipe, StringConcatFactory.Mode.SIZED_EXACT);
    case MH_INLINE_SIZED_EXACT:
        return StringConcatFactory.MethodHandleInlineCopyStrategy.generate(mt, recipe);
    default:
        throw new StringConcatException("Concatenation strategy " + STRATEGY + " is not implemented");
}
  1. BytecodeStringBuilderStrategy handles BC_SB, BC_SB_SIZED and BC_SB_SIZED_EXACT. It generates the same StringBuilder-using byte-code that javac would generate if you just wrote the concatenation in your Java code. The major difference is that this byte-code is generated at runtime (and not compile time) and loaded using Unsafe.defineAnonymousClass().
  2. MethodHandleStringBuilderStrategy handles MH_SB_SIZED and MH_SB_SIZED_EXACT. It uses MethodHandle machinery (including MethodHandle composition) to build the same concatenation chain on top of StringBuilder calls. It does not use any private APIs (like Unsafe), so it is probably the least non-portable strategy.
  3. MethodHandleInlineCopyStrategy handles MH_INLINE_SIZED_EXACT. It also uses MethodHandle machinery to build concatenation chain with MethodHandle composition, but instead of StringBuffer it works with a byte array directly, avoiding copying where possible. To do it, it uses some internal APIs and some knowledge about JDK implementation details (like String constructor that avoids copying string bytes). So this implementation is more fragile (to JDK changes), but also it allows more speed.

A little summary

We can see that the three differ in two aspects: a) what is used as a buffer to build up the string and b) how the concatenation chain is created.

  1. BytecodeStringBuilderStrategy (BC_SB_xxx) uses StringBuilder and runtime code generation.
  2. MethodHandleStringBuilderStrategy (MH_SB_xxx) uses StringBuilder and MethodHandles
  3. MethodHandleInlineCopyStrategy (MH_INLINE_SIZED_EXACT) uses byte array and MethodHandles.


来源:https://stackoverflow.com/questions/50084240/strategy-in-stringconcatfactory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!