[JS IR] Fix inline functions call graph in IC
Add a dependency for inline function references, because in some cases the references may be inlined. ^KT-55144 Fixed
This commit is contained in:
committed by
Space Team
parent
c31705240a
commit
d8ab9498ab
+4
-11
@@ -53,9 +53,9 @@ internal class IdSignatureHashCalculator {
|
||||
}
|
||||
|
||||
private inner class InlineFunctionCallGraphBuilder : IrElementVisitor<Unit, MutableSet<IrFunction>> {
|
||||
var inlineFunctionCallDepth: Int = 0
|
||||
|
||||
override fun visitElement(element: IrElement, data: MutableSet<IrFunction>) = element.acceptChildren(this, data)
|
||||
override fun visitElement(element: IrElement, data: MutableSet<IrFunction>) {
|
||||
element.acceptChildren(this, data)
|
||||
}
|
||||
|
||||
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: MutableSet<IrFunction>) {
|
||||
if (declaration in inlineFunctionCallGraph) {
|
||||
@@ -70,20 +70,13 @@ internal class IdSignatureHashCalculator {
|
||||
val callee = expression.symbol.owner
|
||||
if (callee.isInline) {
|
||||
data += callee
|
||||
inlineFunctionCallDepth += 1
|
||||
}
|
||||
expression.acceptChildren(this, data)
|
||||
if (callee.isInline) {
|
||||
inlineFunctionCallDepth -= 1
|
||||
if (inlineFunctionCallDepth < 0) {
|
||||
icError("inline function calls depth inconsistent")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference, data: MutableSet<IrFunction>) {
|
||||
val reference = expression.symbol.owner
|
||||
if (inlineFunctionCallDepth > 0 && reference.isInline) {
|
||||
if (reference.isInline) {
|
||||
// this if is fine, because fake overrides are not inlined as function reference calls even as inline function args
|
||||
if (!reference.isFakeOverride) {
|
||||
data += reference
|
||||
|
||||
+10
@@ -190,6 +190,11 @@ public class InvalidationTestGenerated extends AbstractInvalidationTest {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/inlineBecomeNonInline/");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionAsFunctionReference")
|
||||
public void testInlineFunctionAsFunctionReference() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/inlineFunctionAsFunctionReference/");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionAsParam")
|
||||
public void testInlineFunctionAsParam() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/inlineFunctionAsParam/");
|
||||
@@ -255,6 +260,11 @@ public class InvalidationTestGenerated extends AbstractInvalidationTest {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/nonInlineBecomeInline/");
|
||||
}
|
||||
|
||||
@TestMetadata("privateDeclarationLeakThroughDefaultParam")
|
||||
public void testPrivateDeclarationLeakThroughDefaultParam() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/privateDeclarationLeakThroughDefaultParam/");
|
||||
}
|
||||
|
||||
@TestMetadata("privateInlineFunction1")
|
||||
public void testPrivateInlineFunction1() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/privateInlineFunction1/");
|
||||
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
inline fun bar() = "0"
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
inline fun bar() = "1"
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
inline fun bar() = "2"
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
inline fun foo(callableReference: () -> String = ::bar): String {
|
||||
return callableReference()
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
inline fun foo(): String {
|
||||
val callableReference: () -> String = ::bar
|
||||
return (callableReference().toInt() + 1).toString()
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
STEP 0:
|
||||
modifications:
|
||||
U : l1.0.kt -> l1.kt
|
||||
U : l2.0.kt -> l2.kt
|
||||
added file: l1.kt, l2.kt
|
||||
STEP 1:
|
||||
modifications:
|
||||
U : l1.1.kt -> l1.kt
|
||||
modified ir: l1.kt
|
||||
updated imports: l2.kt
|
||||
STEP 2:
|
||||
modifications:
|
||||
U : l2.2.kt -> l2.kt
|
||||
modified ir: l2.kt
|
||||
STEP 3:
|
||||
modifications:
|
||||
U : l1.3.kt -> l1.kt
|
||||
modified ir: l1.kt
|
||||
updated imports: l2.kt
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
fun box(stepId: Int): String {
|
||||
val x = foo().toInt()
|
||||
if (x != stepId) {
|
||||
return "Fail $x != $stepId"
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
STEP 0:
|
||||
dependencies: lib1
|
||||
added file: m.kt
|
||||
STEP 1:
|
||||
dependencies: lib1
|
||||
updated imports: m.kt
|
||||
STEP 2:
|
||||
dependencies: lib1
|
||||
modified ir: m.kt
|
||||
STEP 3:
|
||||
dependencies: lib1
|
||||
updated imports: m.kt
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
MODULES: lib1, main
|
||||
|
||||
STEP 0..3:
|
||||
libs: lib1, main
|
||||
dirty js: lib1, main
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
private val prop = "0"
|
||||
|
||||
internal inline fun foo(lambda: () -> String = ::prop): String {
|
||||
return lambda()
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
private val prop = "1"
|
||||
|
||||
internal inline fun foo(lambda: () -> String = ::prop): String {
|
||||
return lambda()
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
private object Obj {
|
||||
val x = "10"
|
||||
}
|
||||
|
||||
private inline fun bar() = Obj.x
|
||||
|
||||
internal inline fun foo(lambda: () -> String = ::bar): String {
|
||||
return lambda()
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
private object Obj {
|
||||
val x = "11"
|
||||
}
|
||||
|
||||
private inline fun bar() = Obj.x
|
||||
|
||||
internal inline fun foo(lambda: () -> String = ::bar): String {
|
||||
return lambda()
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
private object Obj {
|
||||
inline val x get() = "12"
|
||||
}
|
||||
|
||||
private inline fun bar() = Obj.x
|
||||
|
||||
internal inline fun foo(lambda: () -> String = ::bar): String {
|
||||
return lambda()
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
private object Obj {
|
||||
inline val x get() = "13"
|
||||
}
|
||||
|
||||
private inline fun bar() = Obj.x
|
||||
|
||||
internal inline fun foo(lambda: () -> String = ::bar): String {
|
||||
return lambda()
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
private val prop get() = "2"
|
||||
|
||||
internal inline fun foo(lambda: () -> String = ::prop): String {
|
||||
return lambda()
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
private fun prop() = "3"
|
||||
|
||||
internal inline fun foo(lambda: () -> String = ::prop): String {
|
||||
return lambda()
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
private fun prop() = "3"
|
||||
|
||||
internal inline fun foo(lambda: () -> String = { "4" }): String {
|
||||
return lambda()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
internal inline fun foo(lambda: () -> String = { "5" }): String {
|
||||
return lambda()
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
private inline fun prop() = "6"
|
||||
|
||||
internal inline fun foo(lambda: () -> String = ::prop): String {
|
||||
return lambda()
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
private inline fun prop() = "7"
|
||||
|
||||
internal inline fun foo(lambda: () -> String = ::prop): String {
|
||||
return lambda()
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
private object Obj {
|
||||
val x = "8"
|
||||
|
||||
override fun toString() = x
|
||||
}
|
||||
|
||||
internal inline fun foo(lambda: () -> String = { "$Obj" } ): String {
|
||||
return lambda()
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
private object Obj {
|
||||
val x = "9"
|
||||
|
||||
override fun toString() = x
|
||||
}
|
||||
|
||||
internal inline fun foo(lambda: () -> String = { "$Obj" } ): String {
|
||||
return lambda()
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fun box(stepId: Int): String {
|
||||
val x = foo().toInt()
|
||||
if (x != stepId) {
|
||||
return "Fail $x != $stepId"
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
STEP 0:
|
||||
modifications:
|
||||
U : f.0.kt -> f.kt
|
||||
added file: m.kt, f.kt
|
||||
STEP 1:
|
||||
modifications:
|
||||
U : f.1.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
STEP 2:
|
||||
modifications:
|
||||
U : f.2.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
STEP 3:
|
||||
modifications:
|
||||
U : f.3.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
updated imports: m.kt
|
||||
STEP 4:
|
||||
modifications:
|
||||
U : f.4.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
updated imports: m.kt
|
||||
STEP 5:
|
||||
modifications:
|
||||
U : f.5.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
updated imports: m.kt
|
||||
STEP 6:
|
||||
modifications:
|
||||
U : f.6.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
updated imports: m.kt
|
||||
STEP 7:
|
||||
modifications:
|
||||
U : f.7.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
updated imports: m.kt
|
||||
STEP 8:
|
||||
modifications:
|
||||
U : f.8.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
updated imports: m.kt
|
||||
STEP 9:
|
||||
modifications:
|
||||
U : f.9.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
STEP 10:
|
||||
modifications:
|
||||
U : f.10.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
updated imports: m.kt
|
||||
STEP 11:
|
||||
modifications:
|
||||
U : f.11.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
STEP 12:
|
||||
modifications:
|
||||
U : f.12.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
updated imports: m.kt
|
||||
STEP 13:
|
||||
modifications:
|
||||
U : f.13.kt -> f.kt
|
||||
modified ir: f.kt
|
||||
updated imports: m.kt
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
MODULES: main
|
||||
|
||||
STEP 0..13:
|
||||
libs: main
|
||||
dirty js: main
|
||||
Reference in New Issue
Block a user