我知道invokedynamic指令。
我也知道它实现的基本过程。但是当我到达代码时。我无法理解StringConcatFactory
中的代码。
你能告诉我这六种策略是如何通过源代码实现的。仅完成默认策略。作为一名大学生,我不能根据源代码。
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
}
答案 0 :(得分:2)
makeConcat()
和makeConcatWithConstants()
StringConcatFactory
API入口点均使用doStringConcat()
,CallSite
生成invokedynamic
doStringConcat()
generate(Lookup, String, MethodType, Recipe)
调用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");
}
,其中包含您要询问的枚举上的以下开关:
BytecodeStringBuilderStrategy
BC_SB
处理BC_SB_SIZED
,BC_SB_SIZED_EXACT
和StringBuilder
。它生成相同的javac
- 使用Unsafe.defineAnonymousClass()
生成的字节代码,如果您刚刚在Java代码中编写了连接。主要区别在于此字节代码是在运行时(而不是编译时)生成的,并使用MethodHandleStringBuilderStrategy
加载。MH_SB_SIZED
处理MH_SB_SIZED_EXACT
和MethodHandle
。它使用MethodHandle
机制(包括StringBuilder
组合)在Unsafe
调用之上构建相同的连接链。它不使用任何私有API(如MethodHandleInlineCopyStrategy
),因此它可能是最不可移植的策略。MH_INLINE_SIZED_EXACT
处理MethodHandle
。它还使用MethodHandle
机制来构建具有StringBuffer
组合的连接链,但它不是String
,而是直接使用字节数组,避免在可能的情况下进行复制。为此,它使用一些内部API和一些有关JDK实现细节的知识(如BytecodeStringBuilderStrategy
构造函数,避免复制字符串字节)。因此,这种实现更加脆弱(对于JDK更改),但它也允许更快的速度。我们可以看到三者在两个方面有所不同: a)用作构建字符串的缓冲区和 b)如何创建串联链
BC_SB_xxx
(StringBuilder
)使用MethodHandleStringBuilderStrategy
和运行时代码生成。MH_SB_xxx
(StringBuilder
)使用MethodHandle
和MethodHandleInlineCopyStrategy
s MH_INLINE_SIZED_EXACT
(MethodHandle
)使用字节数组和$_SESSION ['success'] = "Data save successfully";
s。