Don't mark library needed if it was touched while looking for cnames.*

Also do minor refactoring.
This commit is contained in:
Svyatoslav Scherbina
2017-10-11 11:47:15 +03:00
committed by SvyatoslavScherbina
parent de2cfce12f
commit 081b990863
6 changed files with 67 additions and 45 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.descriptors.ClassifierAliasingPackageFragmentDescriptor
import org.jetbrains.kotlin.backend.konan.descriptors.ExportedForwardDeclarationsPackageFragmentDescriptor
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.serialization.KonanPackageFragment
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
@@ -33,7 +34,7 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
interface InteropLibrary {
fun createSyntheticPackages(
module: ModuleDescriptor,
kotlinPackageFragments: List<PackageFragmentDescriptor>
konanPackageFragments: List<KonanPackageFragment>
): List<PackageFragmentDescriptor>
}
@@ -211,9 +212,9 @@ private class InteropLibraryImpl(
) : InteropLibrary {
override fun createSyntheticPackages(
module: ModuleDescriptor,
kotlinPackageFragments: List<PackageFragmentDescriptor>
konanPackageFragments: List<KonanPackageFragment>
): List<PackageFragmentDescriptor> {
val interopPackageFragments = kotlinPackageFragments.filter { it.fqName == packageFqName }
val interopPackageFragments = konanPackageFragments.filter { it.fqName == packageFqName }
val fqNames = InteropBuiltIns.FqNames
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.backend.konan.descriptors
import org.jetbrains.kotlin.backend.konan.InteropBuiltIns
import org.jetbrains.kotlin.backend.konan.serialization.KonanPackageFragment
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
@@ -72,14 +73,18 @@ class ExportedForwardDeclarationsPackageFragmentDescriptor(
* The package fragment that redirects all requests for classifier lookup to its targets.
*/
class ClassifierAliasingPackageFragmentDescriptor(
targets: List<PackageFragmentDescriptor>, module: ModuleDescriptor, fqName: FqName
targets: List<KonanPackageFragment>, module: ModuleDescriptor, fqName: FqName
) : PackageFragmentDescriptorImpl(module, fqName) {
private val memberScope = object : MemberScopeImpl() {
override fun getContributedClassifier(name: Name, location: LookupLocation) =
targets.firstNotNullResult {
it.getMemberScope().getContributedClassifier(name, location)
if (it.hasTopLevelClassifier(name)) {
it.getMemberScope().getContributedClassifier(name, location)
} else {
null
}
}
override fun printScopeStructure(p: Printer) {
@@ -31,6 +31,9 @@ interface KonanLibraryReader {
val isNeededForLink: Boolean get() = true
val isDefaultLink: Boolean get() = false
val manifestProperties: Properties
val moduleHeaderData: ByteArray
fun packageMetadata(fqName: String): ByteArray
fun markPackageAccessed(fqName: String)
fun moduleDescriptor(specifics: LanguageVersionSettings): ModuleDescriptor
}
@@ -71,29 +71,28 @@ class LibraryReaderImpl(var libraryFile: File, val currentAbiVersion: Int,
override val dependencies: List<String>
get() = manifestProperties.propertyList("dependencies")
val moduleHeaderData: ByteArray by lazy {
override val moduleHeaderData: ByteArray by lazy {
reader.loadSerializedModule()
}
override val isNeededForLink: Boolean
get() {
packagesAccessed.forEach {
if (!emptyPackages(moduleHeaderData).contains(it)) {
return true
}
}
return false
override var isNeededForLink: Boolean = false
private set
private val emptyPackages by lazy { emptyPackages(moduleHeaderData) }
override fun markPackageAccessed(fqName: String) {
if (!isNeededForLink // fast path
&& !emptyPackages.contains(fqName)) {
isNeededForLink = true
}
}
val packagesAccessed = mutableSetOf<String>()
fun packageMetadata(fqName: String): ByteArray {
packagesAccessed.add(fqName)
override fun packageMetadata(fqName: String): ByteArray {
return reader.loadSerializedPackageFragment(fqName)
}
override fun moduleDescriptor(specifics: LanguageVersionSettings)
= deserializeModule(specifics, {packageMetadata(it)}, moduleHeaderData, createInteropLibrary(this))
= deserializeModule(specifics, this)
}
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -25,20 +26,24 @@ import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
import org.jetbrains.kotlin.storage.StorageManager
class KonanPackageFragment(fqNameString: String,
packageLoader: (String)->KonanLinkData.PackageFragment,
storageManager: StorageManager, module: ModuleDescriptor) :
DeserializedPackageFragment(FqName(fqNameString),
storageManager, module) {
class KonanPackageFragment(
val fqNameString: String,
val reader: KonanLibraryReader,
storageManager: StorageManager, module: ModuleDescriptor
) : DeserializedPackageFragment(FqName(fqNameString), storageManager, module) {
// The proto field is lazy so that we can load only needed
// packages from the library.
val proto: KonanLinkData.PackageFragment by lazy {
packageLoader(fqNameString)
private val protoForNames: KonanLinkData.PackageFragment by lazy {
parsePackageFragment(reader.packageMetadata(fqNameString))
}
val proto: KonanLinkData.PackageFragment get() = protoForNames.also {
reader.markPackageAccessed(fqNameString)
}
private val nameResolver by lazy {
NameResolverImpl(proto.getStringTable(), proto.getNameTable())
NameResolverImpl(protoForNames.getStringTable(), protoForNames.getNameTable())
}
override val classDataFinder by lazy {
@@ -48,14 +53,23 @@ class KonanPackageFragment(fqNameString: String,
override fun computeMemberScope(): DeserializedPackageMemberScope {
val packageProto = proto.getPackage()
return DeserializedPackageMemberScope( this, packageProto,
nameResolver, /* containerSource = */ null,
return DeserializedPackageMemberScope( this, packageProto,
nameResolver, /* containerSource = */ null,
components, {loadClassNames()} )
}
private val classifierNames by lazy {
val result = mutableSetOf<Name>()
result.addAll(loadClassNames())
protoForNames.getPackage().typeAliasList.mapTo(result) { nameResolver.getName(it.name) }
result
}
fun hasTopLevelClassifier(name: Name): Boolean = name in classifierNames
private fun loadClassNames(): Collection<Name> {
val classNameList = proto.getClasses().getClassNameList()
val classNameList = protoForNames.getClasses().getClassNameList()
val names = classNameList.mapNotNull {
val classId = nameResolver.getClassId(it)
@@ -16,10 +16,8 @@
package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.InteropLibrary
import org.jetbrains.kotlin.backend.konan.KonanBuiltIns
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.library.LinkData
import org.jetbrains.kotlin.backend.konan.llvm.base64Decode
import org.jetbrains.kotlin.backend.konan.llvm.base64Encode
@@ -76,15 +74,17 @@ object NullFlexibleTypeDeserializer : FlexibleTypeDeserializer {
}
fun createKonanPackageFragmentProvider(
reader: KonanLibraryReader,
fragmentNames: List<String>,
packageLoader: (String)->KonanLinkData.PackageFragment,
storageManager: StorageManager, module: ModuleDescriptor,
configuration: DeserializationConfiguration,
interopLibrary: InteropLibrary?): PackageFragmentProvider {
configuration: DeserializationConfiguration): PackageFragmentProvider {
val packageFragments = fragmentNames.map{
KonanPackageFragment(it, packageLoader, storageManager, module)
KonanPackageFragment(it, reader, storageManager, module)
}
val interopLibrary = createInteropLibrary(reader)
val syntheticInteropPackageFragments =
interopLibrary?.createSyntheticPackages(module, packageFragments) ?: emptyList()
@@ -123,10 +123,10 @@ public fun emptyPackages(libraryData: ByteArray)
= parseModuleHeader(libraryData).emptyPackageList
internal fun deserializeModule(languageVersionSettings: LanguageVersionSettings,
packageLoader:(String)->ByteArray, library: ByteArray,
interopLibrary: InteropLibrary?): ModuleDescriptorImpl {
reader: KonanLibraryReader): ModuleDescriptorImpl {
val libraryProto = parseModuleHeader(reader.moduleHeaderData)
val libraryProto = parseModuleHeader(library)
val moduleName = libraryProto.moduleName
val storageManager = LockBasedStorageManager()
@@ -137,10 +137,10 @@ internal fun deserializeModule(languageVersionSettings: LanguageVersionSettings,
val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
val provider = createKonanPackageFragmentProvider(
libraryProto.packageFragmentNameList,
{it -> parsePackageFragment(packageLoader(it))},
storageManager,
moduleDescriptor, deserializationConfiguration, interopLibrary)
reader,
libraryProto.packageFragmentNameList,
storageManager,
moduleDescriptor, deserializationConfiguration)
moduleDescriptor.initialize(provider)