Precondition loops are better optimized by HotSpot
(and, quite likely, by ART).
Also, we generate more compact bytecode that way.
KT-17903 Generate 'for-in-indices' as a precondition loop
- A LINENUMEBER node is "dead" if the corresponding instruction interval
contains at least one "dead" bytecode instruction
and no live bytecode instructions
- Observable local variable lifetimes should be taken into account
when determining if a NOP is required for debugger.
- Turn some const conditions into non-const conditions
- Make sure inlined const values are used where required
(otherwise they are eliminated by POP backward propagation)
Using basic constant propagation (only integer constants, no arithmetic
calculations), rewrite conditional jump instructions with constant
arguments.
This covers problem description in KT-17007.
Note that it also works transparently with inline functions.
Partial evaluation is required to cover more "advanced" cases.
As a side effect, this also covers KT-3098:
rewrite IF_ICMP<cmp_op>(x, 0) to IF<cmp0_op>(x).
In code like 'a?.b == 42', we can immediately generate equality
comparison result when receiver is null (false for '==', true for '!='),
since the primitive value is definitely non-null.
Otherwise unnecessary boxing/unboxing is generated to handle possibly
null result of 'a?.b'.
The problem was that the resume call (from doResume) for open members
was based on common INVOKEVIRTUAL to the original function
that lead to the invocation of the override when it was expected
to be the overridden (after super-call being suspended)
The solution is to generate method bodies for open members into
the special $suspendImpl synthetic function that may be called
from the doResume implementation
#KT-17587 Fixed
The reason is that when it gets captured into the field
having name $$continuation inliner fails with an exception
as it skips fields starting with '$$'
At the same time it doesn't really matter how to call
that parameter because it's only visible in Java
#KT-17585 In Progress
#KT-16603 In Progress
The main idea is to leave all the inline functions as is, without
state machines (but keeping suspend-calls markers) and
determine whether we need a state machine from the bytecode
after inlining into a non-inline function
#KT-17585 In Progress
#KT-16603 In Progress
#KT-16448 Fixed
Friend modules should be provided using the -Xfriend-modules flag
in the same format as -libraries. No manual configuration required for
JPS, Gradle and Maven plugins.
Friend modules could be switched off using the -Xfriend-modules-disabled
flag. Doing that will
* prevent internal declarations from being exported,
* values provided by -Xfriend-modules ignored,
* raise a compilation error on attemps to use internal declarations from other modules
Fixes #KT-15135 and #KT-16568.
NB: for-in-until loop is generated as precondition loop, because the
corresponding range is right-exclusive (and thus we have no problems
with integer overflows).
#KT-10397 Fixed
According to JVMS (p. 4.3.4) inner classes should be separated with `$` in generic signature.
Note that in Java, inner types separated with `.` after first parameterized type, and now we preserve the same behaviour. See tests for clarification.
Local returns normalization can generate POP instructions.
These POP instructions can drop functional parameters, as in KT-17590,
and should be processed in markPlacesForInlineAndRemoveInlinable just
as other POP instructions.
KT-17590 conditional return in inline function parameter argument causes compilation exception
It never terminates, so the corresponding value on stack can't be used.
However, if this happens in an inlined lambda argument, the inliner is
unable to remove the corresponding ALOAD instruction (because default
handler never terminates, and thus corresponding ALOAD is not used for
lambda invocation).
KT-17573 try-finally expression in inlined function parameter argument fails with VerifyError
When a try-catch expression is passed as an argument to the inline
lambda parameter, lambda variable on stack is spilled and restored in
several different locations (1 for try-block, 1 for each catch-blocks).
So it's possible that lambda to be invoked comes from multiple loads,
all of which should have the same "root" lambda parameter.
In cases like KT-17384, where 'break' or 'continue' happens in an argument
to an inlined lambda call, fix-stack transformation sees corresponding
ALOAD for lambda, and inserts corresponding POP instruction before jump.
However, this ALOAD is later removed during inlining.
So, we should also remove the related POP instructions.
Don't use coroutine facade in following cases:
* When calling coroutine functions in non-suspend mode (i.e.
suspend flag is either false or skipped).
* When passing continuation from suspend function to suspend function.
Use facade only for corresponding intrinsics.
Reason: interceptor should not be called on each suspend function
invocation, it should be called after resume from innermost
suspend function.
Fix KT-17067. The example provided with the issue is very similar to
dispatchResume.kt which passes after these changes.
Add test to prove that KT-17446 is no more reproducible.
Before this fix line numbers for function call arguments were not generated,
so if argument was on another line than function call it was
impossible to stop on argument line during debugging.
Now line number for each argument is generated if necessary
(another line than function call line).
#KT-17144 Fixed