[K/N][codegen] Build trampolines for abstract fake overrides
#KT-61924 Fixed
This commit is contained in:
+5
-10
@@ -202,16 +202,6 @@ private inline fun <T : FunctionGenerationContext> generateFunctionBody(
|
|||||||
functionGenerationContext.resetDebugLocation()
|
functionGenerationContext.resetDebugLocation()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrSimpleFunction.findOverriddenMethodOfAny(): IrSimpleFunction? {
|
|
||||||
if (modality == Modality.ABSTRACT) return null
|
|
||||||
val resolved = resolveFakeOverride()!!
|
|
||||||
if ((resolved.parent as IrClass).isAny()) {
|
|
||||||
return resolved
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object VirtualTablesLookup {
|
internal object VirtualTablesLookup {
|
||||||
private fun FunctionGenerationContext.getInterfaceTableRecord(typeInfo: LLVMValueRef, interfaceId: Int): LLVMValueRef {
|
private fun FunctionGenerationContext.getInterfaceTableRecord(typeInfo: LLVMValueRef, interfaceId: Int): LLVMValueRef {
|
||||||
val interfaceTableSize = load(structGep(typeInfo, 9 /* interfaceTableSize_ */))
|
val interfaceTableSize = load(structGep(typeInfo, 9 /* interfaceTableSize_ */))
|
||||||
@@ -307,6 +297,9 @@ internal object VirtualTablesLookup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun IrSimpleFunction.findOverriddenMethodOfAny() =
|
||||||
|
resolveFakeOverride(allowAbstract = false).takeIf { it?.parentClassOrNull?.isAny() == true }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special trampoline function to call actual virtual implementation. This helps with reducing
|
* Special trampoline function to call actual virtual implementation. This helps with reducing
|
||||||
* dependence between klibs/files (if vtable/itable of some class has changed, the call sites
|
* dependence between klibs/files (if vtable/itable of some class has changed, the call sites
|
||||||
@@ -317,8 +310,10 @@ internal fun CodeGenerator.getVirtualFunctionTrampoline(irFunction: IrSimpleFunc
|
|||||||
* Resolve owner of the call with special handling of Any methods:
|
* Resolve owner of the call with special handling of Any methods:
|
||||||
* if toString/eq/hc is invoked on an interface instance, we resolve
|
* if toString/eq/hc is invoked on an interface instance, we resolve
|
||||||
* owner as Any and dispatch it via vtable.
|
* owner as Any and dispatch it via vtable.
|
||||||
|
* Note: Keep on par with DFG builder.
|
||||||
*/
|
*/
|
||||||
val anyMethod = irFunction.findOverriddenMethodOfAny()
|
val anyMethod = irFunction.findOverriddenMethodOfAny()
|
||||||
|
|
||||||
return getVirtualFunctionTrampolineImpl(anyMethod ?: irFunction)
|
return getVirtualFunctionTrampolineImpl(anyMethod ?: irFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -769,7 +769,13 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val callee = value.symbol.owner
|
/*
|
||||||
|
* Resolve owner of the call with special handling of Any methods:
|
||||||
|
* if toString/eq/hc is invoked on an interface instance, we resolve
|
||||||
|
* owner as Any and dispatch it via vtable.
|
||||||
|
* Note: Keep on par with the codegen.
|
||||||
|
*/
|
||||||
|
val callee = value.symbol.owner.let { it.findOverriddenMethodOfAny() ?: it }
|
||||||
val arguments = value.getArgumentsWithIr()
|
val arguments = value.getArgumentsWithIr()
|
||||||
.map { expressionToEdge(it.second) }
|
.map { expressionToEdge(it.second) }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user