For example, given this static method:
void logIf(boolean flag, Supplier<String> message) {
if (flag) System.out.println(message.get());
}
and this use:
invokedynamic{ new Supplier(){ public String get() { return "it's late"; } } }
We notice in this case that if the flag is usually false then we can delay building the anonymous class instance (under Supplier).
After inlining, the steps become clear.
* an inner class construction call
* initialization into the object (as into a box) of all relevant environmental values
* inlined invocation of logIf(false, …)
* the closure is not created
* inlined inaction of logIf(true, …)
* the closure is still not created, at least until it need to escapes as a normal object
* in normal operation, the box does not really exist
One bit of strategy is important: Make methods more attractive to inline if they operate on their operands. Getting the operand creation into the same scope as the final operation leads to many code simplifications.
void logIf(boolean flag, Supplier<String> message) {
if (flag) System.out.println(message.get());
}
and this use:
invokedynamic{ new Supplier(){ public String get() { return "it's late"; } } }
We notice in this case that if the flag is usually false then we can delay building the anonymous class instance (under Supplier).
After inlining, the steps become clear.
* an inner class construction call
* initialization into the object (as into a box) of all relevant environmental values
* inlined invocation of logIf(false, …)
* the closure is not created
* inlined inaction of logIf(true, …)
* the closure is still not created, at least until it need to escapes as a normal object
* in normal operation, the box does not really exist
One bit of strategy is important: Make methods more attractive to inline if they operate on their operands. Getting the operand creation into the same scope as the final operation leads to many code simplifications.
- relates to
-
JDK-8015416 tier one should collect context-dependent split profiles
- Open