Refactor deserialization initialization in built-ins and JS
BuiltinsPackageFragment was only designed to work with a single instance alive. Because of this, it was creating deserialization subsystem upon initialization. This was not working perfectly in JS where it was used, because multiple storage managers, class caches and other components were created for each package, leading to different concurrency errors and performance hits. Also in the near future another package fragment will be needed to represent the built-in package "kotlin.reflect"
This commit is contained in:
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil;
|
||||
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -107,7 +108,7 @@ public abstract class Config {
|
||||
return moduleId;
|
||||
}
|
||||
|
||||
public abstract boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report);
|
||||
public abstract boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report);
|
||||
|
||||
protected abstract void init(@NotNull List<JetFile> sourceFilesInLibraries, @NotNull List<KotlinJavascriptMetadata> metadata);
|
||||
|
||||
@@ -117,10 +118,10 @@ public abstract class Config {
|
||||
if (moduleDescriptors != null) return moduleDescriptors;
|
||||
|
||||
moduleDescriptors = new SmartList<ModuleDescriptorImpl>();
|
||||
for(KotlinJavascriptMetadata metadataEntry : metadata) {
|
||||
for (KotlinJavascriptMetadata metadataEntry : metadata) {
|
||||
moduleDescriptors.add(createModuleDescriptor(metadataEntry));
|
||||
}
|
||||
for(ModuleDescriptorImpl module : moduleDescriptors) {
|
||||
for (ModuleDescriptorImpl module : moduleDescriptors) {
|
||||
setDependencies(module, moduleDescriptors);
|
||||
module.seal();
|
||||
}
|
||||
@@ -149,18 +150,19 @@ public abstract class Config {
|
||||
private static ModuleDescriptorImpl createModuleDescriptor(KotlinJavascriptMetadata metadata) {
|
||||
ModuleDescriptorImpl moduleDescriptor = TopDownAnalyzerFacadeForJS.createJsModule("<" + metadata.getModuleName() + ">");
|
||||
|
||||
List<PackageFragmentProvider> providers = KotlinJavascriptSerializationUtil
|
||||
.getPackageFragmentProviders(moduleDescriptor, metadata.getBody());
|
||||
CompositePackageFragmentProvider compositePackageFragmentProvider = new CompositePackageFragmentProvider(providers);
|
||||
PackageFragmentProvider provider =
|
||||
KotlinJavascriptSerializationUtil.createPackageFragmentProvider(moduleDescriptor, metadata.getBody());
|
||||
|
||||
moduleDescriptor.initialize(compositePackageFragmentProvider);
|
||||
moduleDescriptor.initialize(
|
||||
provider != null ? provider : new CompositePackageFragmentProvider(Collections.<PackageFragmentProvider>emptyList())
|
||||
);
|
||||
moduleDescriptor.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule());
|
||||
|
||||
return moduleDescriptor;
|
||||
}
|
||||
|
||||
private static void setDependencies(ModuleDescriptorImpl module, List<ModuleDescriptorImpl> modules) {
|
||||
for(ModuleDescriptorImpl moduleItem : modules) {
|
||||
for (ModuleDescriptorImpl moduleItem : modules) {
|
||||
module.addDependencyOnModule(moduleItem);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-13
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.serialization.js
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import org.jetbrains.kotlin.builtins.BuiltInsSerializationUtil
|
||||
import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment
|
||||
import org.jetbrains.kotlin.builtins.createBuiltInPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -44,29 +44,26 @@ public object KotlinJavascriptSerializationUtil {
|
||||
private val PACKAGE_FILE_SUFFIX = "/.kotlin_package"
|
||||
|
||||
platformStatic
|
||||
public fun getPackageFragmentProviders(moduleDescriptor: ModuleDescriptor, metadata: ByteArray): List<PackageFragmentProvider> {
|
||||
public fun createPackageFragmentProvider(moduleDescriptor: ModuleDescriptor, metadata: ByteArray): PackageFragmentProvider? {
|
||||
val gzipInputStream = GZIPInputStream(ByteArrayInputStream(metadata))
|
||||
val content = JsProtoBuf.Library.parseFrom(gzipInputStream)
|
||||
gzipInputStream.close()
|
||||
|
||||
val contentMap: MutableMap<String, ByteArray> = hashMapOf()
|
||||
for(index in 0..content.getEntryCount()-1) {
|
||||
for (index in content.getEntryCount().indices) {
|
||||
val entry = content.getEntry(index)
|
||||
contentMap[entry.getPath()] = entry.getContent().toByteArray()
|
||||
}
|
||||
|
||||
val packages = getPackages(contentMap)
|
||||
val packageFqNames = getPackages(contentMap).map { FqName(it) }.toSet()
|
||||
if (packageFqNames.isEmpty()) return null
|
||||
|
||||
val load = { path: String -> if (!contentMap.containsKey(path)) null else ByteArrayInputStream(contentMap.get(path)) }
|
||||
|
||||
val providers = arrayListOf<PackageFragmentProvider>()
|
||||
for (packageName in packages) {
|
||||
val fqName = FqName(packageName)
|
||||
val packageFragment = BuiltinsPackageFragment(fqName, LockBasedStorageManager(), moduleDescriptor, FlexibleTypeCapabilitiesDeserializer.Dynamic, load)
|
||||
providers.add(packageFragment.provider)
|
||||
return createBuiltInPackageFragmentProvider(
|
||||
LockBasedStorageManager(), moduleDescriptor, packageFqNames, FlexibleTypeCapabilitiesDeserializer.Dynamic
|
||||
) {
|
||||
path ->
|
||||
if (!contentMap.containsKey(path)) null else ByteArrayInputStream(contentMap.get(path))
|
||||
}
|
||||
|
||||
return providers
|
||||
}
|
||||
|
||||
public fun contentMapToByteArray(contentMap: Map<String, ByteArray>): ByteArray {
|
||||
|
||||
Reference in New Issue
Block a user