coroutines intrinsic lambda.
The logic is if the lambda is crossinline we need to generate the
accessor. However, suspendCoroutine's and
suspendCoroutineUninterceptedOrReturn's parameter, despite being
crossinline, are effectively inline. Thus, we do not need to generate
the accessor.
#KT-27503 Fixed
last-exclusive progressions (i.e., "until" progressions and loop over
array indices).
This change makes it possible to correctly implement the handling of
"step" progressions. Computing the last element of a stepped progression
requires that the last is inclusive.
Also invert the while loop (into if + do-while) that is used when
lowering for-loops over progressions that cannot overflow. This keeps
the performance characteristics closer to the ForLoopsLowering in
kotlin-native, since the goal is to converge to this shared version.
Also used IrType instead of KotlinType, where possible.
https://github.com/JetBrains/kotlin/pull/2390https://github.com/JetBrains/kotlin/pull/2305
Unfortunately this cannot currently be done for the extension overload which accepts a radix due to behavior difference with regard to invalid radix values.
The kotlin-scripting-compiler-impl jar is used in the idea plugin and
therefore should not depend on the cli parts of the compiler to avoid
dependency from the plugin to the kotlin-compiler.jar.
Therefore the cli-dependent parts were moved to the scripting plugin
jar, which is used only in cli compiler based environments.
Also implement required abstractions to allow this movement and
drop some redundant dependencies to the cli parts in other projects.
This fixes an issue in constructing annotation instances with array
class elements. For some reason, behavior of `ClassLoader.loadClass`
differs from `Class.forName` in handling arrays, namely:
* `loadClass("[Ltest.Foo;")` returns null
* `Class.forName("[Ltest.Foo;")` returns class for array of test.Foo
Overall, there doesn't seem to be any way to load an array class with
`CLassLoader.loadClass`.
We pass initialize=false to forName because this is the behavior of
ClassLoader.loadClass: it doesn't perform class initialization (e.g.
<clinit> is not executed).
#KT-31318 Fixed
Context for determine if a value parameter is captured from outer
context is not directly available after lowering, hence introduce a new
IrDeclarationOrigin for captured receiver parameter to avoid duplicate
calculation.
re-ordering the lowering phases.
The changes in InterfaceLowering are necessary so that IrElements that
target the removed functions are re-targeted to the new functions in
DefaultImpls. This affects local functions in interface functions since
now LocalDeclarationsLowering comes before InterfaceLowering.
Before 5b7cee6221 JVM CLI compiler
was calling `KotlinToJVMBytecodeCompiler.compileBunchOfSources`.
`compileBunchOfSources` detected possible main classes,
and filled the Main-Class attribute in output jar
if if there was only one candidate.
After the change JVM CLI began calling
`KotlinToJVMBytecodeCompiler.compileModules`, which was not searching for a main class.
This change adds searching for main classes to `compileModules`.
We search for a main class only when one module is compiled,
and an output is written a jar file (so the change only affects JVM CLI compilation).
#KT-32272 Fixed
There was an inconsistency on creating PSI call and corresponding
descriptor. See variable `catchBlocks` from visitor, it's created
only if PSI elements are not null, but for descriptor parameters
there wasn't such check
#KT-32134 Fixed
#EA-139748 Fixed
If new inference is enabled only for IDE analysis, then this feature
will be disabled to reduce difference between new and old inference,
but if new inference is enabled in the compiler, then this feature
will be enabled too to preserve behavior of new inference for
compilation
#KT-32175 Fixed
#KT-32143 Fixed
#KT-32123 Fixed
#KT-32230 Fixed
Incorporate PR from Steven Schäfer into IrType-based implicit cast
insertion (commit 17b925636e8717e7648c5d7b792c6ab4d18f776d).
NB this still uses originalKotlinType to determine if the type was
nullability flexible. It is somewhat error-prone and something we want
to get rid of. However, it boils down to some design questions related
to implicit null checks in Kotlin - e.g., it might be Ok to just treat
nullability flexible type `T!` as `T?` in IR, generate null checks for
all usages of type `T?` where a non-null type is expected, and later
eliminate the null checks that are redundant according to the (quite
conservative) criterion in the redundant null check elimination.
Profiling the compilation of kotlinx.serialization, MaxStackFrameSizeAndLocalsCalculator
causes ~7% of the runtime to be spent in java.lang.Object.hashCode
This is through two uses:
- visitMaxs(..) has a pushed hashSet that causes ~2%
- labelWrappersMap used to attach additional data to asm Labels, causes ~ 5%
visitMaxs can use the existing SmartSet (not to be confused with SmartHashSet)
Analysis of the visitMaxs HashSet creation & sizes:
| What | Amount |
| calls to visitMaxs | 4416 |
| max pushed | 158 |
| median pushed | 4 |
| average pushed | 5.20 |
| stddev pushed | 7.66 |
| 90 percentile | 10 |
Analysis of labelWrappersMap creation & sizes:
| What | Amount |
| ------------------ | ------ |
| hashtables created | 4006 |
| max entries | 175 |
| median entries | 5 |
| average entries | 6.10 |
| stdev entries | 8.28 |
| 90 percentile | 11 |
testing with a non hash based map using an array for keys and an array for values
showed that the cost of MaxStackFrameSizeAndLocalsCalculator became neglible to
the overall running time.
SmartIdentityTable is a Map like structure that uses reference identity for keys.
It uses 2 arrays to store keys & values until the number of entries stored is larger than 10.
At that point it switches to using an IdentityHashMap.
This structure can be used instead of HashMap when reference identity can be used and
the number of entries inserted is small (<= 10) on average, drastically reducing the overhead
of calls to Object.hashCode
Between the two changes, compilation of kotlinx.serialization through kotlinc
commandline decreased from 14 seconds to 11 seconds on my machine
Consider call `foo(bar())` where bar() returns some type variable `T`;
We had a contract that call `bar` can be completed without completion
of foo (type variables can be inferred from the current context) if `T`
has at least one proper lower constraint (ProperType <: T).
Indeed, new constraints can be added only as upper ones, so there is
no need to grow constraint system.
Unfortunately, we have Exact annotation that is used on return type of
elvis. Now, consider the following situation:
```
fun foo(a: Any) {}
fun bar(e: T): @Exact T
foo(bar("str"))
```
Here, because of Exact annotation, constraint with `Any`-type will be
added as an equal one => our prerequisite that there will be no new
lower constraints is false. `bar("str")` is inferred to Any in OI,
this seems conceptually wrong, but it's another topic of discussion.
In NI we can't just grow constraint system to use outer call because
of another important use-case:
```
fun <T> generic(i: Inv<T>) {}
fun test(a: Inv<*>?, b: Inv<*>) {
generic(a ?: b)
}
```
Common constraint system for these two calls can't be solved
(fundamentally) for this example, only if (a ?: b) and generic(result)
are computed separately.
So, to mitigate initial issue, we'll grow constraint system only if
there is at least one non-proper constraint.
#KT-31969 Fixed