Rewritten unneeded library purge machinery.
This commit is contained in:
committed by
alexander-gorshenev
parent
6382215b9d
commit
bddada22e5
+2
-6
@@ -49,7 +49,7 @@ internal fun produceOutput(context: Context) {
|
|||||||
val output = context.config.outputName
|
val output = context.config.outputName
|
||||||
val libraryName = context.config.moduleId
|
val libraryName = context.config.moduleId
|
||||||
val neededLibraries
|
val neededLibraries
|
||||||
= context.config.immediateLibraries.purgeUnneeded()
|
= context.config.librariesWithDependencies
|
||||||
val abiVersion = context.config.currentAbiVersion
|
val abiVersion = context.config.currentAbiVersion
|
||||||
val target = context.config.targetManager.target
|
val target = context.config.targetManager.target
|
||||||
val nopack = config.getBoolean(KonanConfigKeys.NOPACK)
|
val nopack = config.getBoolean(KonanConfigKeys.NOPACK)
|
||||||
@@ -80,8 +80,4 @@ internal fun produceOutput(context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun List<KonanLibraryReader>.purgeUnneeded(): List<KonanLibraryReader> {
|
|
||||||
return this.map {
|
|
||||||
if (!it.isNeededForLink && it.isDefaultLink) null else it
|
|
||||||
}.filterNotNull()
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-2
@@ -1297,7 +1297,7 @@ internal object EscapeAnalysis {
|
|||||||
val isStdlib = context.config.configuration[KonanConfigKeys.NOSTDLIB] == true
|
val isStdlib = context.config.configuration[KonanConfigKeys.NOSTDLIB] == true
|
||||||
|
|
||||||
val externalFunctionEAResults = mutableMapOf<String, FunctionEscapeAnalysisResult>()
|
val externalFunctionEAResults = mutableMapOf<String, FunctionEscapeAnalysisResult>()
|
||||||
context.config.libraries.forEach { library ->
|
context.config.librariesWithDependencies.forEach { library ->
|
||||||
val libraryEscapeAnalysis = library.escapeAnalysis
|
val libraryEscapeAnalysis = library.escapeAnalysis
|
||||||
if (libraryEscapeAnalysis != null) {
|
if (libraryEscapeAnalysis != null) {
|
||||||
DEBUG_OUTPUT(0) {
|
DEBUG_OUTPUT(0) {
|
||||||
@@ -1338,4 +1338,4 @@ internal object EscapeAnalysis {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-2
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.backend.konan
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.createForwardDeclarationsModule
|
import org.jetbrains.kotlin.backend.konan.descriptors.createForwardDeclarationsModule
|
||||||
import org.jetbrains.kotlin.backend.konan.library.*
|
import org.jetbrains.kotlin.backend.konan.library.*
|
||||||
import org.jetbrains.kotlin.backend.konan.library.impl.LibraryReaderImpl
|
import org.jetbrains.kotlin.backend.konan.library.impl.*
|
||||||
import org.jetbrains.kotlin.backend.konan.util.profile
|
import org.jetbrains.kotlin.backend.konan.util.profile
|
||||||
import org.jetbrains.kotlin.backend.konan.util.removeSuffixIfPresent
|
import org.jetbrains.kotlin.backend.konan.util.removeSuffixIfPresent
|
||||||
import org.jetbrains.kotlin.backend.konan.util.suffixIfNot
|
import org.jetbrains.kotlin.backend.konan.util.suffixIfNot
|
||||||
@@ -92,8 +92,13 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val libraries: List<LibraryReaderImpl> by lazy {
|
// Accessing this field before resolve is a bad idea.
|
||||||
|
// purgeUnneeded() only works correctly after we have
|
||||||
|
// completed resolve and successfully marked package files
|
||||||
|
// as needed or not needed.
|
||||||
|
val librariesWithDependencies: List<KonanLibraryReader> by lazy {
|
||||||
resolver.resolveLibrariesRecursive(immediateLibraries, targetManager.target, currentAbiVersion)
|
resolver.resolveLibrariesRecursive(immediateLibraries, targetManager.target, currentAbiVersion)
|
||||||
|
immediateLibraries.purgeUnneeded().withResolvedDependencies()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val loadedDescriptors = loadLibMetadata()
|
private val loadedDescriptors = loadLibMetadata()
|
||||||
@@ -109,6 +114,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
val allMetadata = mutableListOf<ModuleDescriptorImpl>()
|
val allMetadata = mutableListOf<ModuleDescriptorImpl>()
|
||||||
val specifics = configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS)!!
|
val specifics = configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS)!!
|
||||||
|
|
||||||
|
val libraries = immediateLibraries.withResolvedDependencies()
|
||||||
for (klib in libraries) {
|
for (klib in libraries) {
|
||||||
profile("Loading ${klib.libraryName}") {
|
profile("Loading ${klib.libraryName}") {
|
||||||
// MutableModuleContext needs ModuleDescriptorImpl, rather than ModuleDescriptor.
|
// MutableModuleContext needs ModuleDescriptorImpl, rather than ModuleDescriptor.
|
||||||
|
|||||||
+1
-1
@@ -235,7 +235,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
private val debug = config.get(KonanConfigKeys.DEBUG) ?: false
|
private val debug = config.get(KonanConfigKeys.DEBUG) ?: false
|
||||||
private val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
|
private val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
|
||||||
private val emitted = context.bitcodeFileName
|
private val emitted = context.bitcodeFileName
|
||||||
private val libraries = context.config.libraries.purgeUnneeded()
|
private val libraries = context.config.librariesWithDependencies
|
||||||
private fun MutableList<String>.addNonEmpty(elements: List<String>) {
|
private fun MutableList<String>.addNonEmpty(elements: List<String>) {
|
||||||
addAll(elements.filter { !it.isEmpty() })
|
addAll(elements.filter { !it.isEmpty() })
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -26,10 +26,9 @@ interface KonanLibraryReader {
|
|||||||
val bitcodePaths: List<String>
|
val bitcodePaths: List<String>
|
||||||
val includedPaths: List<String>
|
val includedPaths: List<String>
|
||||||
val linkerOpts: List<String>
|
val linkerOpts: List<String>
|
||||||
val dependencies: List<String>
|
val unresolvedDependencies: List<String>
|
||||||
val escapeAnalysis: ByteArray?
|
val escapeAnalysis: ByteArray?
|
||||||
val isNeededForLink: Boolean get() = true
|
val isNeededForLink: Boolean get() = true
|
||||||
val isDefaultLink: Boolean get() = false
|
|
||||||
val manifestProperties: Properties
|
val manifestProperties: Properties
|
||||||
val moduleHeaderData: ByteArray
|
val moduleHeaderData: ByteArray
|
||||||
fun packageMetadata(fqName: String): ByteArray
|
fun packageMetadata(fqName: String): ByteArray
|
||||||
|
|||||||
+37
-31
@@ -49,7 +49,7 @@ fun SearchPathResolver.resolveImmediateLibraries(libraryNames: List<String>,
|
|||||||
removeDuplicates: Boolean = true): List<LibraryReaderImpl> {
|
removeDuplicates: Boolean = true): List<LibraryReaderImpl> {
|
||||||
|
|
||||||
val defaultLibraries = defaultLinks(nostdlib = noStdLib, noDefaultLibs = noDefaultLibs).map {
|
val defaultLibraries = defaultLinks(nostdlib = noStdLib, noDefaultLibs = noDefaultLibs).map {
|
||||||
LibraryReaderImpl(it, abiVersion, target, isDefaultLink = true)
|
LibraryReaderImpl(it, abiVersion, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
val userProvidedLibraries = libraryNames
|
val userProvidedLibraries = libraryNames
|
||||||
@@ -65,33 +65,40 @@ fun SearchPathResolver.resolveImmediateLibraries(libraryNames: List<String>,
|
|||||||
|
|
||||||
fun SearchPathResolver.resolveLibrariesRecursive(immediateLibraries: List<LibraryReaderImpl>,
|
fun SearchPathResolver.resolveLibrariesRecursive(immediateLibraries: List<LibraryReaderImpl>,
|
||||||
target: KonanTarget,
|
target: KonanTarget,
|
||||||
abiVersion: Int): List<LibraryReaderImpl> {
|
abiVersion: Int) {
|
||||||
val result = mutableMapOf<File, LibraryReaderImpl>()
|
val cache = mutableMapOf<File, LibraryReaderImpl>()
|
||||||
result.putAll(immediateLibraries.map { it.libraryFile.absoluteFile to it })
|
cache.putAll(immediateLibraries.map { it.libraryFile.absoluteFile to it })
|
||||||
var newDependencies: Map<File, LibraryReaderImpl> = result
|
var newDependencies = cache.values.toList()
|
||||||
do {
|
do {
|
||||||
val defaultOverrides = mutableSetOf<File>()
|
newDependencies = newDependencies.map { library: LibraryReaderImpl ->
|
||||||
newDependencies = newDependencies.values.asSequence()
|
library.unresolvedDependencies
|
||||||
.flatMap { it.dependencies.asSequence() }
|
.map { resolve(it).absoluteFile }
|
||||||
.map { resolve(it).absoluteFile }
|
.map {
|
||||||
.onEach {
|
if (it in cache) {
|
||||||
if (result[it]?.isDefaultLink == true) {
|
library.resolvedDependencies.add(cache[it]!!)
|
||||||
defaultOverrides.add(it)
|
null
|
||||||
}
|
} else {
|
||||||
}
|
val reader = LibraryReaderImpl(it, abiVersion, target)
|
||||||
.filter { it !in result }
|
cache.put(it,reader)
|
||||||
.map { it to LibraryReaderImpl(it, abiVersion, target) }.toMap()
|
library.resolvedDependencies.add(reader)
|
||||||
|
reader
|
||||||
result.putAll(newDependencies)
|
}
|
||||||
|
}.filterNotNull()
|
||||||
// If there is a default link in immediateLibraries,
|
} .flatten()
|
||||||
// and we get the same library as a dependency,
|
|
||||||
// the resultant surviving library should not be a defaultLink anymore.
|
|
||||||
defaultOverrides.forEach {
|
|
||||||
result[it] = LibraryReaderImpl(it, abiVersion, target)
|
|
||||||
}
|
|
||||||
} while (newDependencies.isNotEmpty())
|
} while (newDependencies.isNotEmpty())
|
||||||
return result.values.toList()
|
}
|
||||||
|
|
||||||
|
fun List<LibraryReaderImpl>.withResolvedDependencies(): List<LibraryReaderImpl> {
|
||||||
|
val result = mutableSetOf<LibraryReaderImpl>()
|
||||||
|
result.addAll(this)
|
||||||
|
var newDependencies = result.toList()
|
||||||
|
do {
|
||||||
|
newDependencies = newDependencies
|
||||||
|
.map { it -> it.resolvedDependencies } .flatten()
|
||||||
|
.filter { it !in result }
|
||||||
|
result.addAll(newDependencies)
|
||||||
|
} while (newDependencies.isNotEmpty())
|
||||||
|
return result.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun SearchPathResolver.resolveLibrariesRecursive(libraryNames: List<String>,
|
fun SearchPathResolver.resolveLibrariesRecursive(libraryNames: List<String>,
|
||||||
@@ -99,17 +106,16 @@ fun SearchPathResolver.resolveLibrariesRecursive(libraryNames: List<String>,
|
|||||||
abiVersion: Int = 1,
|
abiVersion: Int = 1,
|
||||||
noStdLib: Boolean = false,
|
noStdLib: Boolean = false,
|
||||||
noDefaultLibs: Boolean = false): List<LibraryReaderImpl> {
|
noDefaultLibs: Boolean = false): List<LibraryReaderImpl> {
|
||||||
return resolveLibrariesRecursive(
|
val immediateLibraries = resolveImmediateLibraries(
|
||||||
resolveImmediateLibraries(
|
|
||||||
libraryNames = libraryNames,
|
libraryNames = libraryNames,
|
||||||
target = target,
|
target = target,
|
||||||
abiVersion = abiVersion,
|
abiVersion = abiVersion,
|
||||||
noStdLib = noStdLib,
|
noStdLib = noStdLib,
|
||||||
noDefaultLibs = noDefaultLibs,
|
noDefaultLibs = noDefaultLibs,
|
||||||
removeDuplicates = true
|
removeDuplicates = true
|
||||||
),
|
)
|
||||||
target, abiVersion
|
resolveLibrariesRecursive(immediateLibraries, target, abiVersion)
|
||||||
)
|
return immediateLibraries.withResolvedDependencies()
|
||||||
}
|
}
|
||||||
|
|
||||||
class KonanLibrarySearchPathResolver(
|
class KonanLibrarySearchPathResolver(
|
||||||
|
|||||||
+5
-2
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
|
||||||
class LibraryReaderImpl(var libraryFile: File, val currentAbiVersion: Int,
|
class LibraryReaderImpl(var libraryFile: File, val currentAbiVersion: Int,
|
||||||
val target: KonanTarget? = null, override val isDefaultLink: Boolean = false)
|
val target: KonanTarget? = null)
|
||||||
: KonanLibraryReader {
|
: KonanLibraryReader {
|
||||||
|
|
||||||
// For the zipped libraries inPlace gives files from zip file system
|
// For the zipped libraries inPlace gives files from zip file system
|
||||||
@@ -68,9 +68,11 @@ class LibraryReaderImpl(var libraryFile: File, val currentAbiVersion: Int,
|
|||||||
override val linkerOpts: List<String>
|
override val linkerOpts: List<String>
|
||||||
get() = manifestProperties.propertyList("linkerOpts", target!!.detailedName)
|
get() = manifestProperties.propertyList("linkerOpts", target!!.detailedName)
|
||||||
|
|
||||||
override val dependencies: List<String>
|
override val unresolvedDependencies: List<String>
|
||||||
get() = manifestProperties.propertyList("dependencies")
|
get() = manifestProperties.propertyList("dependencies")
|
||||||
|
|
||||||
|
val resolvedDependencies = mutableListOf<LibraryReaderImpl>()
|
||||||
|
|
||||||
override val moduleHeaderData: ByteArray by lazy {
|
override val moduleHeaderData: ByteArray by lazy {
|
||||||
reader.loadSerializedModule()
|
reader.loadSerializedModule()
|
||||||
}
|
}
|
||||||
@@ -96,3 +98,4 @@ class LibraryReaderImpl(var libraryFile: File, val currentAbiVersion: Int,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun <T: KonanLibraryReader> List<T>.purgeUnneeded(): List<T> = this.filter{ it.isNeededForLink }
|
||||||
|
|||||||
Reference in New Issue
Block a user