[DCE] Reference public external functions + test
This commit is contained in:
+7
-6
@@ -326,13 +326,14 @@ internal object DFGSerializer {
|
||||
}
|
||||
}
|
||||
|
||||
class ExternalFunctionSymbol(val hash: Long, val name: String?) {
|
||||
class ExternalFunctionSymbol(val hash: Long, val name: String?, val isExported: Boolean) {
|
||||
|
||||
constructor(data: ArraySlice) : this(data.readLong(), data.readNullableString())
|
||||
constructor(data: ArraySlice) : this(data.readLong(), data.readNullableString(), data.readBoolean())
|
||||
|
||||
fun write(result: ArraySlice) {
|
||||
result.writeLong(hash)
|
||||
result.writeNullableString(name)
|
||||
result.writeBoolean(isExported)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,8 +380,8 @@ internal object DFGSerializer {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun external(base: FunctionSymbolBase, hash: Long, name: String?) =
|
||||
FunctionSymbol(base, ExternalFunctionSymbol(hash, name), null, null)
|
||||
fun external(base: FunctionSymbolBase, hash: Long, name: String?, isExported: Boolean) =
|
||||
FunctionSymbol(base, ExternalFunctionSymbol(hash, name, isExported), null, null)
|
||||
|
||||
fun public(base: FunctionSymbolBase, hash: Long, index: Int, bridgeTarget: Int?, name: String?) =
|
||||
FunctionSymbol(base, null, PublicFunctionSymbol(hash, index, bridgeTarget, name), null)
|
||||
@@ -876,7 +877,7 @@ internal object DFGSerializer {
|
||||
val bridgeTarget = (symbol as? DataFlowIR.FunctionSymbol.Declared)?.let { functionSymbolMap[it] }
|
||||
when (symbol) {
|
||||
is DataFlowIR.FunctionSymbol.External ->
|
||||
FunctionSymbol.external(buildFunctionSymbolBase(symbol), symbol.hash, symbol.name)
|
||||
FunctionSymbol.external(buildFunctionSymbolBase(symbol), symbol.hash, symbol.name, symbol.isExported)
|
||||
|
||||
is DataFlowIR.FunctionSymbol.Public ->
|
||||
FunctionSymbol.public(buildFunctionSymbolBase(symbol), symbol.hash,
|
||||
@@ -1051,7 +1052,7 @@ internal object DFGSerializer {
|
||||
val private = it.private
|
||||
when {
|
||||
external != null ->
|
||||
DataFlowIR.FunctionSymbol.External(external.hash, attributes, null, external.name)
|
||||
DataFlowIR.FunctionSymbol.External(external.hash, attributes, null, external.name, external.isExported)
|
||||
|
||||
public != null -> {
|
||||
val symbolTableIndex = public.index
|
||||
|
||||
+2
-2
@@ -132,7 +132,7 @@ internal object DataFlowIR {
|
||||
var escapes: Int? = null
|
||||
var pointsTo: IntArray? = null
|
||||
|
||||
class External(val hash: Long, attributes: Int, irFunction: IrFunction?, name: String? = null)
|
||||
class External(val hash: Long, attributes: Int, irFunction: IrFunction?, name: String? = null, val isExported: Boolean)
|
||||
: FunctionSymbol(attributes, irFunction, name) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
@@ -609,7 +609,7 @@ internal object DataFlowIR {
|
||||
val escapesBitMask = (escapesAnnotation?.getValueArgument(0) as? IrConst<Int>)?.value
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val pointsToBitMask = (pointsToAnnotation?.getValueArgument(0) as? IrVararg)?.elements?.map { (it as IrConst<Int>).value }
|
||||
FunctionSymbol.External(name.localHash.value, attributes, it, takeName { name }).apply {
|
||||
FunctionSymbol.External(name.localHash.value, attributes, it, takeName { name }, it.isExported()).apply {
|
||||
escapes = escapesBitMask
|
||||
pointsTo = pointsToBitMask?.let { it.toIntArray() }
|
||||
}
|
||||
|
||||
+12
-8
@@ -64,14 +64,18 @@ internal object Devirtualization {
|
||||
val exportedFunctions =
|
||||
if (entryPoint != null)
|
||||
listOf(moduleDFG.symbolTable.mapFunction(entryPoint).resolved())
|
||||
else
|
||||
// In a library every public function and every function accessible via virtual call belongs to the rootset.
|
||||
moduleDFG.symbolTable.functionMap.values.filterIsInstance<DataFlowIR.FunctionSymbol.Public>() +
|
||||
moduleDFG.symbolTable.classMap.values
|
||||
.filterIsInstance<DataFlowIR.Type.Declared>()
|
||||
.flatMap { it.vtable + it.itable.values }
|
||||
.filterIsInstance<DataFlowIR.FunctionSymbol.Declared>()
|
||||
.filter { moduleDFG.functions.containsKey(it) }
|
||||
else {
|
||||
// In a library every public function and every function accessible via virtual call belongs to the rootset.
|
||||
moduleDFG.symbolTable.functionMap.values.filter {
|
||||
it is DataFlowIR.FunctionSymbol.Public
|
||||
|| (it as? DataFlowIR.FunctionSymbol.External)?.isExported == true
|
||||
} +
|
||||
moduleDFG.symbolTable.classMap.values
|
||||
.filterIsInstance<DataFlowIR.Type.Declared>()
|
||||
.flatMap { it.vtable + it.itable.values }
|
||||
.filterIsInstance<DataFlowIR.FunctionSymbol.Declared>()
|
||||
.filter { moduleDFG.functions.containsKey(it) }
|
||||
}
|
||||
// TODO: Are globals initializers always called whether they are actually reachable from roots or not?
|
||||
val globalInitializers =
|
||||
moduleDFG.symbolTable.functionMap.values.filter { it.isGlobalInitializer } +
|
||||
|
||||
@@ -1123,6 +1123,7 @@ __attribute__((swift_name("ValuesKt")))
|
||||
+ (BOOL)testInterfaceTypeCheckX:(id)x __attribute__((swift_name("testInterfaceTypeCheck(x:)")));
|
||||
+ (int32_t)testAbstractInterfaceCallX:(id<ValuesIAbstractInterface>)x __attribute__((swift_name("testAbstractInterfaceCall(x:)")));
|
||||
+ (int32_t)testAbstractInterfaceCall2X:(id<ValuesIAbstractInterface2>)x __attribute__((swift_name("testAbstractInterfaceCall2(x:)")));
|
||||
+ (void)fooA:(ValuesKotlinAtomicReference *)a __attribute__((swift_name("foo(a:)")));
|
||||
@property (class, readonly) double dbl __attribute__((swift_name("dbl")));
|
||||
@property (class, readonly) float flt __attribute__((swift_name("flt")));
|
||||
@property (class, readonly) int32_t integer __attribute__((swift_name("integer")));
|
||||
|
||||
@@ -830,4 +830,6 @@ object GH3525 : GH3525Base() {
|
||||
|
||||
class TestStringConversion {
|
||||
lateinit var str: Any
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(a: kotlin.native.concurrent.AtomicReference<*>) {}
|
||||
Reference in New Issue
Block a user