[JS IR] Ignore fake override calls in IC
Fake overrides don't have a signature and can't be assiciated with klib index, therefore they can't be tracked with incremental cache invalidation logic. Should be fixed after KT-51896.
This commit is contained in:
committed by
Space
parent
3ee8aabe4c
commit
2f3ad476be
+11
-4
@@ -63,7 +63,10 @@ class InlineFunctionHashBuilder(
|
||||
override fun visitCall(expression: IrCall, data: MutableSet<IrFunction>) {
|
||||
val callee = expression.symbol.owner
|
||||
if (callee.isInline) {
|
||||
data += callee
|
||||
// TODO: do not ignore fake overides after KT-51896
|
||||
if (!callee.isFakeOverride) {
|
||||
data += callee
|
||||
}
|
||||
inlineFunctionCallDepth += 1
|
||||
}
|
||||
expression.acceptChildren(this, data)
|
||||
@@ -78,7 +81,10 @@ class InlineFunctionHashBuilder(
|
||||
override fun visitFunctionReference(expression: IrFunctionReference, data: MutableSet<IrFunction>) {
|
||||
val reference = expression.symbol.owner
|
||||
if (inlineFunctionCallDepth > 0 && reference.isInline) {
|
||||
data += reference
|
||||
// this if is fine, because fake overrides are not inlined as function reference calls even as inline function args
|
||||
if (!reference.isFakeOverride) {
|
||||
data += reference
|
||||
}
|
||||
}
|
||||
expression.acceptChildren(this, data)
|
||||
}
|
||||
@@ -135,12 +141,13 @@ class InlineFunctionHashBuilder(
|
||||
val usedInlineFunctions = mutableMapOf<IdSignature, ICHash>()
|
||||
it.value.forEach { edges ->
|
||||
edges.forEach { callee ->
|
||||
// TODO: do not ignore fake overides after KT-51896
|
||||
if (!callee.isFakeOverride) {
|
||||
val signature = callee.symbol.signature // ?: error("Expecting signature for ${callee.render()}")
|
||||
val signature = callee.symbol.signature
|
||||
if (signature?.visibleCrossFile == true) {
|
||||
val calleeHash = computedHashed[callee]
|
||||
?: hashProvider.hashForExternalFunction(callee)
|
||||
?: error("Internal error: No has found for ${callee.render()}")
|
||||
?: error("Internal error: No hash found for ${callee.render()}")
|
||||
usedInlineFunctions[signature] = calleeHash
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -50,6 +50,11 @@ public class InvalidationTestGenerated extends AbstractInvalidationTest {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/crossModuleReferences/");
|
||||
}
|
||||
|
||||
@TestMetadata("fakeOverride")
|
||||
public void testFakeOverride() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/fakeOverride/");
|
||||
}
|
||||
|
||||
@TestMetadata("fastPath1")
|
||||
public void testFastPath1() throws Exception {
|
||||
runTest("js/js.translator/testData/incremental/invalidation/fastPath1/");
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
abstract class ClassA {
|
||||
inline fun <reified T> Any.castTo(): T? = this as? T
|
||||
abstract fun test1(): String?
|
||||
abstract fun test2(): String?
|
||||
|
||||
inline fun fakeOverrideFunction() = 0
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
abstract class ClassA {
|
||||
inline fun <reified T> Any.castTo(): T? = (this as? T) ?: "OTHER ${this as? Int}" as T
|
||||
abstract fun test1(): String?
|
||||
abstract fun test2(): String?
|
||||
|
||||
inline fun fakeOverrideFunction() = 0
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
abstract class ClassA {
|
||||
inline fun <reified T> Any.castTo(): T? = (this as? T) ?: "OTHER ${this as? Int}" as T
|
||||
abstract fun test1(): String?
|
||||
abstract fun test2(): String?
|
||||
|
||||
inline fun fakeOverrideFunction() = 2
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
STEP 0:
|
||||
dependencies: stdlib
|
||||
dirty: l1.kt
|
||||
STEP 1:
|
||||
dependencies: stdlib
|
||||
modifications:
|
||||
U : l1.kt.1.txt -> l1.kt
|
||||
dirty: l1.kt
|
||||
STEP 2:
|
||||
dependencies: stdlib
|
||||
modifications:
|
||||
U : l1.kt.2.txt -> l1.kt
|
||||
dirty: l1.kt
|
||||
@@ -0,0 +1,4 @@
|
||||
class ClassB: ClassA() {
|
||||
override fun test1() = "ClassB::test1".castTo<String>()
|
||||
override fun test2() = 1.castTo<String>()
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
STEP 0:
|
||||
dependencies: stdlib, lib1
|
||||
dirty: l2.kt
|
||||
STEP 1..2:
|
||||
dependencies: stdlib, lib1
|
||||
@@ -0,0 +1,39 @@
|
||||
inline fun callIt(f: () -> Int) = f()
|
||||
|
||||
fun box(stepId: Int): String {
|
||||
val a = object : ClassA() {
|
||||
override fun test1() = "object::test1".castTo<String>()
|
||||
override fun test2() = 2.castTo<String>()
|
||||
}
|
||||
|
||||
val b = ClassB()
|
||||
|
||||
if (a.test1() != "object::test1") return "Fail 1"
|
||||
if (b.test1() != "ClassB::test1") return "Fail 2"
|
||||
|
||||
when (stepId) {
|
||||
0 -> {
|
||||
if (a.test2() != null) return "Fail 0-1"
|
||||
if (b.test2() != null) return "Fail 0-2"
|
||||
|
||||
if (a.fakeOverrideFunction() != 0) return "Fail 0-3"
|
||||
if (b.fakeOverrideFunction() != 0) return "Fail 0-4"
|
||||
|
||||
if (callIt(a::fakeOverrideFunction) != 0) return "Fail 0-5"
|
||||
if (callIt(b::fakeOverrideFunction) != 0) return "Fail 0-6"
|
||||
}
|
||||
1 -> {
|
||||
if (a.test2() != null) return "Fail 1-1" // TODO: test2() must return "OTHER 2", should be fixed in KT-51896
|
||||
if (b.test2() != null) return "Fail 1-2" // TODO: test2() must return "OTHER 1", should be fixed in KT-51896
|
||||
}
|
||||
2 -> {
|
||||
if (a.fakeOverrideFunction() != 0) return "Fail 2-1" // TODO: fakeOverrideFunction() must return 2, should be fixed in KT-51896
|
||||
if (b.fakeOverrideFunction() != 0) return "Fail 2-2" // TODO: fakeOverrideFunction() must return 2, should be fixed in KT-51896
|
||||
|
||||
if (callIt(a::fakeOverrideFunction) != 2) return "Fail 2-3"
|
||||
if (callIt(b::fakeOverrideFunction) != 2) return "Fail 2-4"
|
||||
}
|
||||
else -> return "Unknown"
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
STEP 0:
|
||||
dependencies: stdlib, lib1, lib2
|
||||
dirty: m.kt
|
||||
STEP 1..2:
|
||||
dependencies: stdlib, lib1, lib2
|
||||
@@ -0,0 +1,8 @@
|
||||
MODULES: lib1, lib2, main
|
||||
|
||||
STEP 0:
|
||||
libs: lib1, lib2, main
|
||||
dirty js: stdlib, lib1, lib2, main
|
||||
STEP 1..2:
|
||||
libs: lib1, lib2, main
|
||||
dirty js: lib1
|
||||
Reference in New Issue
Block a user