From 33c5068b7902f411105544e11036837d2ba278c3 Mon Sep 17 00:00:00 2001 From: Artem Kobzar Date: Wed, 19 Apr 2023 13:10:19 +0000 Subject: [PATCH] [K/JS] Rework IR deserialization and lowering phases to consume less memory --- .../backend/generators/AdapterGenerator.kt | 2 +- .../lower/AbstractSuspendFunctionsLowering.kt | 17 +- .../AnnotationImplementationTransformer.kt | 4 +- .../lower/DefaultArgumentFunctionFactory.kt | 28 ++-- .../lower/DefaultArgumentStubGenerator.kt | 3 +- .../common/lower/LocalDeclarationsLowering.kt | 8 +- .../MethodsFromAnyGeneratorForLowerings.kt | 3 +- .../lower/SingleAbstractMethodLowering.kt | 10 +- .../AddContinuationToFunctionsLowering.kt | 6 +- .../inline/DeepCopyIrTreeWithDescriptors.kt | 6 +- .../ir/backend/js/JsCommonBackendContext.kt | 18 +-- .../kotlin/ir/backend/js/JsIntrinsics.kt | 6 +- .../ir/backend/js/JsIrBackendContext.kt | 16 +- .../backend/js/PropertyLazyInitialization.kt | 4 +- .../kotlin/ir/backend/js/compiler.kt | 1 + .../js/dce/JsUsefulDeclarationProcessor.kt | 1 - .../js/dce/UsefulDeclarationProcessor.kt | 2 +- .../js/dce/UselessDeclarationsRemover.kt | 9 +- .../backend/js/export/ExportModelGenerator.kt | 31 ++-- .../js/export/ExportModelToJsStatements.kt | 4 +- .../kotlin/ir/backend/js/ic/CacheUpdater.kt | 29 ++-- .../ir/backend/js/ic/IncrementalCache.kt | 6 +- .../backend/js/ic/IncrementalCacheArtifact.kt | 3 +- .../ir/backend/js/ic/JsIrLinkerLoader.kt | 1 + .../ir/backend/js/ic/KotlinLibraryHeader.kt | 15 +- .../backend/js/ic/KotlinSourceFileMetadata.kt | 2 +- .../js/lower/BlockDecomposerLowering.kt | 11 +- .../backend/js/lower/BridgesConstruction.kt | 11 +- .../js/lower/CallableReferenceLowering.kt | 14 +- .../js/lower/ClassReferenceLowering.kt | 22 +-- .../js/lower/CreateScriptFunctionsPhase.kt | 8 +- .../js/lower/ES6AddBoxParameterLowering.kt | 21 ++- ...tructorBoxParameterOptimizationLowering.kt | 5 +- .../js/lower/ES6ConstructorLowering.kt | 16 +- ...6PrimaryConstructorOptimizationLowering.kt | 6 +- .../ir/backend/js/lower/EnumClassLowering.kt | 18 +-- ...itlyExportedDeclarationsMarkingLowering.kt | 16 +- .../lower/InteropCallableReferenceLowering.kt | 19 ++- .../backend/js/lower/JsBridgesConstruction.kt | 2 +- .../lower/JsDefaultArgumentStubGenerator.kt | 16 +- .../backend/js/lower/JsInnerClassesSupport.kt | 4 +- .../js/lower/JsReturnableBlockLowering.kt | 2 +- ...MoveBodilessDeclarationsToSeparatePlace.kt | 8 +- .../lower/MoveOpenClassesToSeparateFiles.kt | 5 +- .../js/lower/PrivateMembersLowering.kt | 8 +- .../js/lower/PropertyReferenceLowering.kt | 3 +- .../js/lower/ScriptRemoveReceiverLowering.kt | 6 +- .../backend/js/lower/SecondaryCtorLowering.kt | 13 +- .../ir/backend/js/lower/TestGenerator.kt | 19 +-- .../EqualityAndComparisonCallsTransformer.kt | 8 +- .../calls/MethodsOfAnyCallsTransformer.kt | 2 +- .../calls/NumberOperatorCallsTransformer.kt | 1 - ...PrimitiveContainerMemberCallTransformer.kt | 4 +- .../lower/calls/ReflectionCallsTransformer.kt | 2 +- .../js/lower/cleanup/CleanupLowering.kt | 12 +- .../AbstractSuspendFunctionsLowering.kt | 41 +++-- .../coroutines/JsSuspendArityStoreLowering.kt | 8 +- .../coroutines/JsSuspendFunctionsLowering.kt | 2 +- .../lower/coroutines/StateMachineBuilder.kt | 4 +- .../IrElementToJsExpressionTransformer.kt | 9 +- .../IrElementToJsStatementTransformer.kt | 11 +- .../irToJs/IrModuleToJsTransformer.kt | 19 +-- .../transformers/irToJs/JsClassGenerator.kt | 16 +- .../irToJs/JsIntrinsicTransformers.kt | 2 +- .../irToJs/JsIrProgramFragment.kt | 2 +- .../js/transformers/irToJs/SwitchOptimizer.kt | 12 +- .../js/transformers/irToJs/jsAstUtils.kt | 63 ++++---- .../irToJs/resolveTemporaryNames.kt | 4 +- .../kotlin/ir/backend/js/utils/IrNamer.kt | 2 +- .../backend/js/utils/JsGenerationContext.kt | 6 +- .../kotlin/ir/backend/js/utils/NameTables.kt | 9 +- .../kotlin/backend/jvm/JvmIrCodegenFactory.kt | 1 + .../jetbrains/kotlin/backend/wasm/compiler.kt | 1 + .../IrDescriptorBasedFunctionFactory.kt | 17 +- .../psi2ir/generators/DeclarationGenerator.kt | 2 +- .../ir/descriptors/IrBasedDescriptors.kt | 38 +++-- .../ir/expressions/impl/IrBlockBodyImpl.kt | 3 +- .../kotlin/ir/expressions/impl/IrCallImpl.kt | 6 +- .../expressions/impl/IrConstructorCallImpl.kt | 6 +- .../impl/IrDelegatingConstructorCallImpl.kt | 6 +- .../impl/IrEnumConstructorCallImpl.kt | 6 +- .../impl/IrFunctionReferenceImpl.kt | 6 +- .../IrLocalDelegatedPropertyReferenceImpl.kt | 13 +- .../impl/IrPropertyReferenceImpl.kt | 11 +- .../impl/IrStringConcatenationImpl.kt | 3 +- .../kotlin/ir/expressions/impl/IrWhenImpl.kt | 3 +- .../CopyIrTreeWithSymbolsForFakeOverrides.kt | 5 +- .../kotlin/ir/overrides/IrOverridingUtil.kt | 20 +-- .../kotlin/ir/types/IrTypeCheckerUtils.kt | 6 +- .../kotlin/ir/types/IrTypeSubstitutor.kt | 5 +- .../kotlin/ir/types/IrTypeSystemContext.kt | 17 +- .../kotlin/ir/types/impl/IrSimpleTypeImpl.kt | 5 +- .../org/jetbrains/kotlin/ir/types/irTypes.kt | 16 +- .../kotlin/ir/util/AdditionalIrUtils.kt | 3 +- .../kotlin/ir/util/ConstantValueGenerator.kt | 3 +- .../ir/util/DeepCopyIrTreeWithSymbols.kt | 41 ++--- .../kotlin/ir/util/DeepCopyTypeRemapper.kt | 7 +- .../kotlin/ir/util/IrTypeParameterRemapper.kt | 5 +- .../jetbrains/kotlin/ir/util/IrTypeUtils.kt | 7 +- .../org/jetbrains/kotlin/ir/util/IrUtils.kt | 29 ++-- .../jetbrains/kotlin/ir/util/RemapTypes.kt | 5 +- .../kotlin/ir/util/SimpleTypeRemapper.kt | 5 +- .../kotlin/ir/util/TypeTranslator.kt | 3 +- .../ir/util/emptyArraysForMemberAccess.kt | 15 ++ .../org/jetbrains/kotlin/ir/util/overrides.kt | 3 +- .../ir/serialization.common/build.gradle.kts | 1 + .../linkage/issues/KotlinIrLinkerIssues.kt | 6 +- .../issues/UserVisibleIrModulesSupport.kt | 10 +- .../common/overrides/FakeOverrideChecker.kt | 15 +- .../BasicIrModuleDeserializer.kt | 16 +- .../common/serialization/DeclarationTable.kt | 4 +- .../common/serialization/ExpectActualTable.kt | 2 +- .../serialization/IdSignatureDeserializer.kt | 17 +- .../IncrementalCompilationSupport.kt | 2 +- .../serialization/IrBodyDeserializer.kt | 28 ++-- .../IrDeclarationDeserializer.kt | 86 +++++------ .../serialization/IrFileDeserializer.kt | 4 +- .../common/serialization/IrFileSerializer.kt | 10 +- .../serialization/IrInterningService.kt | 36 +++++ .../serialization/IrSymbolDeserializer.kt | 5 +- .../common/serialization/KotlinIrLinker.kt | 23 ++- .../jetbrains/kotlin/ir/backend/js/klib.kt | 4 +- .../js/lower/serialization/ir/JsIrLinker.kt | 3 +- .../deserializeLazyDeclarations.kt | 7 +- .../kotlin/klib/AbstractKlibIrTextTestCase.kt | 1 + .../scopes/GivenFunctionsMemberScope.kt | 2 +- .../kotlin/resolve/scopes/MemberScopeImpl.kt | 2 +- .../FunInterfaceConstructorsSyntheticScope.kt | 2 +- .../org/jetbrains/kotlin/util/scopeUtils.kt | 31 +--- .../jetbrains/kotlin/utils/CollectionUtil.kt | 49 ++++++ .../utils/MemoryOptimizedCollectionUtil.kt | 146 ++++++++++++++++++ .../org/jetbrains/kotlin/utils/collections.kt | 15 ++ .../kotlin/benchmarks/GenerateIrRuntime.kt | 2 + .../kotlin/js/test/utils/RunnerUtils.kt | 2 +- 134 files changed, 964 insertions(+), 616 deletions(-) create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/emptyArraysForMemberAccess.kt create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrInterningService.kt create mode 100644 core/util.runtime/src/org/jetbrains/kotlin/utils/CollectionUtil.kt create mode 100644 core/util.runtime/src/org/jetbrains/kotlin/utils/MemoryOptimizedCollectionUtil.kt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt index 8f822e56736..652627519e6 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt @@ -347,7 +347,7 @@ internal class AdapterGenerator( return adapterFunction.valueParameters[parameterIndex + parameterShift].toIrGetValue(startOffset, endOffset) } - adapteeFunction.valueParameters.zip(firAdaptee.valueParameters).mapIndexed { index, (valueParameter, firParameter) -> + adapteeFunction.valueParameters.zip(firAdaptee.valueParameters).forEachIndexed { index, (valueParameter, firParameter) -> when (val mappedArgument = mappedArguments?.get(firParameter)) { is ResolvedCallArgument.VarargArgument -> { val valueArgument = if (mappedArgument.arguments.isEmpty()) { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractSuspendFunctionsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractSuspendFunctionsLowering.kt index 904535719a5..43cdc3113ee 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractSuspendFunctionsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractSuspendFunctionsLowering.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.utils.* import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.name.Name @@ -141,8 +142,8 @@ abstract class AbstractSuspendFunctionsLowering(val co }.apply { parent = irFunction.parent createParameterDeclarations() - typeParameters = irFunction.typeParameters.map { typeParam -> - typeParam.copyToWithoutSuperTypes(this).apply { superTypes += typeParam.superTypes } + typeParameters = irFunction.typeParameters.memoryOptimizedMap { typeParam -> + typeParam.copyToWithoutSuperTypes(this).apply { superTypes = superTypes memoryOptimizedPlus typeParam.superTypes } } } @@ -186,11 +187,11 @@ abstract class AbstractSuspendFunctionsLowering(val co coroutineClass.declarations += this coroutineConstructors += this - valueParameters = functionParameters.mapIndexed { index, parameter -> + valueParameters = functionParameters.memoryOptimizedMapIndexed { index, parameter -> parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index) } val continuationParameter = coroutineBaseClassConstructor.valueParameters[0] - valueParameters += continuationParameter.copyTo( + valueParameters = valueParameters memoryOptimizedPlus continuationParameter.copyTo( this, DECLARATION_ORIGIN_COROUTINE_IMPL, index = valueParameters.size, type = continuationType ) @@ -235,18 +236,18 @@ abstract class AbstractSuspendFunctionsLowering(val co parent = coroutineClass coroutineClass.declarations += this - typeParameters = stateMachineFunction.typeParameters.map { parameter -> + typeParameters = stateMachineFunction.typeParameters.memoryOptimizedMap { parameter -> parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL) - .apply { superTypes += parameter.superTypes } + .apply { superTypes = superTypes memoryOptimizedPlus parameter.superTypes } } - valueParameters = stateMachineFunction.valueParameters.mapIndexed { index, parameter -> + valueParameters = stateMachineFunction.valueParameters.memoryOptimizedMapIndexed { index, parameter -> parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index) } this.createDispatchReceiverParameter() - overriddenSymbols += stateMachineFunction.symbol + overriddenSymbols = overriddenSymbols memoryOptimizedPlus stateMachineFunction.symbol } buildStateMachine(function, irFunction, argumentToPropertiesMap) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt index ace60477627..89815924151 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.ir.types.isArray import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.filterIsInstanceAnd val ANNOTATION_IMPLEMENTATION = object : IrDeclarationOriginImpl("ANNOTATION_IMPLEMENTATION", isSynthetic = true) {} @@ -156,7 +157,8 @@ abstract class AnnotationImplementationTransformer(val context: BackendContext, // (although annotations imported from Java do have) val props = declarations.filterIsInstance() if (props.isNotEmpty()) return props - return declarations.filterIsInstance().filter { it.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR } + return declarations + .filterIsInstanceAnd { it.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR } .mapNotNull { it.correspondingPropertySymbol?.owner } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentFunctionFactory.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentFunctionFactory.kt index d5b18bacbf1..534c44258e9 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentFunctionFactory.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentFunctionFactory.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.utils.* import org.jetbrains.kotlin.name.Name abstract class DefaultArgumentFunctionFactory(open val context: CommonBackendContext) { @@ -40,7 +41,7 @@ abstract class DefaultArgumentFunctionFactory(open val context: CommonBackendCon } protected fun IrFunction.copyValueParametersFrom(original: IrFunction, wrapWithNullable: Boolean = true) { - valueParameters = original.valueParameters.map { + valueParameters = original.valueParameters.memoryOptimizedMap { val newType = it.type.remapTypeParameters(original.classIfConstructor, classIfConstructor) val makeNullable = wrapWithNullable && it.defaultValue != null && (context.ir.unfoldInlineClassType(it.type) ?: it.type) !in context.irBuiltIns.primitiveIrTypes @@ -121,17 +122,18 @@ abstract class DefaultArgumentFunctionFactory(open val context: CommonBackendCon context.mapping.defaultArgumentsOriginalFunction[defaultsFunction] = declaration if (forceSetOverrideSymbols) { - (defaultsFunction as IrSimpleFunction).overriddenSymbols += declaration.overriddenSymbols.mapNotNull { - generateDefaultsFunction( - it.owner, - skipInlineMethods, - skipExternalMethods, - forceSetOverrideSymbols, - visibility, - useConstructorMarker, - it.owner.copyAnnotations(), - )?.symbol as IrSimpleFunctionSymbol? - } + (defaultsFunction as IrSimpleFunction).overriddenSymbols = + defaultsFunction.overriddenSymbols memoryOptimizedPlus declaration.overriddenSymbols.mapNotNull { + generateDefaultsFunction( + it.owner, + skipInlineMethods, + skipExternalMethods, + forceSetOverrideSymbols, + visibility, + useConstructorMarker, + it.owner.copyAnnotations(), + )?.symbol as IrSimpleFunctionSymbol? + } } } } @@ -200,7 +202,7 @@ abstract class DefaultArgumentFunctionFactory(open val context: CommonBackendCon parent = declaration.parent generateDefaultArgumentStubFrom(declaration, useConstructorMarker) // TODO some annotations are needed (e.g. @JvmStatic), others need different values (e.g. @JvmName), the rest are redundant. - annotations += copiedAnnotations + annotations = annotations memoryOptimizedPlus copiedAnnotations } } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt index db4e28a6fb4..210f2f63ba3 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.util.OperatorNameConventions +import org.jetbrains.kotlin.utils.memoryOptimizedPlus // TODO: fix expect/actual default parameters @@ -488,7 +489,7 @@ class DefaultParameterPatchOverridenSymbolsLowering( override fun transformFlat(declaration: IrDeclaration): List? { if (declaration is IrSimpleFunction) { (context.mapping.defaultArgumentsOriginalFunction[declaration] as? IrSimpleFunction)?.run { - declaration.overriddenSymbols += overriddenSymbols.mapNotNull { + declaration.overriddenSymbols = declaration.overriddenSymbols memoryOptimizedPlus overriddenSymbols.mapNotNull { (context.mapping.defaultArgumentsDispatchFunction[it.owner] as? IrSimpleFunction)?.symbol } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt index 338d420e179..ee7257c3ddb 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt @@ -35,6 +35,8 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedPlus interface VisibilityPolicy { fun forClass(declaration: IrClass, inInlineFunctionScope: Boolean): DescriptorVisibility = @@ -708,7 +710,7 @@ class LocalDeclarationsLowering( ) // Type parameters of oldDeclaration may depend on captured type parameters, so deal with that after copying. newDeclaration.typeParameters.drop(newTypeParameters.size).forEach { tp -> - tp.superTypes = tp.superTypes.map { localFunctionContext.remapType(it) } + tp.superTypes = tp.superTypes.memoryOptimizedMap { localFunctionContext.remapType(it) } } newDeclaration.parent = ownerParent @@ -721,7 +723,7 @@ class LocalDeclarationsLowering( } newDeclaration.copyAttributes(oldDeclaration) - newDeclaration.valueParameters += createTransformedValueParameters( + newDeclaration.valueParameters = newDeclaration.valueParameters memoryOptimizedPlus createTransformedValueParameters( capturedValues, localFunctionContext, oldDeclaration, newDeclaration, isExplicitLocalFunction = oldDeclaration.origin == IrDeclarationOrigin.LOCAL_FUNCTION ) @@ -831,7 +833,7 @@ class LocalDeclarationsLowering( throw AssertionError("Local class constructor can't have extension receiver: ${ir2string(oldDeclaration)}") } - newDeclaration.valueParameters += createTransformedValueParameters( + newDeclaration.valueParameters = newDeclaration.valueParameters memoryOptimizedPlus createTransformedValueParameters( capturedValues, localClassContext, oldDeclaration, newDeclaration ) newDeclaration.recordTransformedValueParameters(constructorContext) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/MethodsFromAnyGeneratorForLowerings.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/MethodsFromAnyGeneratorForLowerings.kt index 4cbb6034142..798447e4a2c 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/MethodsFromAnyGeneratorForLowerings.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/MethodsFromAnyGeneratorForLowerings.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.isArray import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.utils.memoryOptimizedMapNotNull class MethodsFromAnyGeneratorForLowerings(val context: BackendContext, val irClass: IrClass, val origin: IrDeclarationOrigin) { private fun IrClass.addSyntheticFunction(name: String, returnType: IrType) = @@ -43,7 +44,7 @@ class MethodsFromAnyGeneratorForLowerings(val context: BackendContext, val irCla companion object { fun IrClass.collectOverridenSymbols(predicate: (IrFunction) -> Boolean): List = - superTypes.mapNotNull { it.getClass()?.functions?.singleOrNull(predicate)?.symbol } + superTypes.memoryOptimizedMapNotNull { it.getClass()?.functions?.singleOrNull(predicate)?.symbol } } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SingleAbstractMethodLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SingleAbstractMethodLowering.kt index d17b207ff22..ddaeb1da27f 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SingleAbstractMethodLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/SingleAbstractMethodLowering.kt @@ -29,6 +29,9 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.util.OperatorNameConventions +import org.jetbrains.kotlin.utils.findIsInstanceAnd +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedPlus abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) : FileLoweringPass, IrElementTransformerVoidWithContext() { // SAM wrappers are cached, either in the file class (if it exists), or in a top-level enclosing class. @@ -79,8 +82,7 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) : override fun lower(irFile: IrFile) { cachedImplementations.clear() inlineCachedImplementations.clear() - enclosingContainer = irFile.declarations.filterIsInstance().find { it.isFileClass } - ?: irFile + enclosingContainer = irFile.declarations.findIsInstanceAnd { it.isFileClass } ?: irFile irFile.transformChildrenVoid() for (wrapper in cachedImplementations.values + inlineCachedImplementations.values) { @@ -177,7 +179,7 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) : setSourceRange(createFor) }.apply { createImplicitParameterDeclarationWithWrappedDescriptor() - superTypes = listOf(superType) + getAdditionalSupertypes(superType) + superTypes = listOf(superType) memoryOptimizedPlus getAdditionalSupertypes(superType) parent = enclosingContainer!! } @@ -221,7 +223,7 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) : overriddenSymbols = listOf(originalSuperMethod.symbol) dispatchReceiverParameter = subclass.thisReceiver!!.copyTo(this) extensionReceiverParameter = originalSuperMethod.extensionReceiverParameter?.copyTo(this) - valueParameters = originalSuperMethod.valueParameters.map { it.copyTo(this) } + valueParameters = originalSuperMethod.valueParameters.memoryOptimizedMap { it.copyTo(this) } body = context.createIrBuilder(symbol).irBlockBody { +irReturn( irCall( diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/coroutines/AddContinuationToFunctionsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/coroutines/AddContinuationToFunctionsLowering.kt index 773fa77d353..51dd501b345 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/coroutines/AddContinuationToFunctionsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/coroutines/AddContinuationToFunctionsLowering.kt @@ -28,6 +28,8 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedPlus /** * Replaces suspend functions with regular non-suspend functions with additional @@ -120,12 +122,12 @@ private fun IrSimpleFunction.createSuspendFunctionStub(context: CommonBackendCon val substitutionMap = makeTypeParameterSubstitutionMap(this, function) function.copyReceiverParametersFrom(this, substitutionMap) - function.overriddenSymbols += overriddenSymbols.map { + function.overriddenSymbols = function.overriddenSymbols memoryOptimizedPlus overriddenSymbols.map { factory.stageController.restrictTo(it.owner) { it.owner.getOrCreateFunctionWithContinuationStub(context).symbol } } - function.valueParameters = valueParameters.map { it.copyTo(function) } + function.valueParameters = valueParameters.memoryOptimizedMap { it.copyTo(function) } val mapping = mutableMapOf() valueParameters.forEach { mapping[it.symbol] = function.valueParameters[it.index].symbol } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/DeepCopyIrTreeWithDescriptors.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/DeepCopyIrTreeWithDescriptors.kt index b086990fa13..af663719d1b 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/DeepCopyIrTreeWithDescriptors.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/DeepCopyIrTreeWithDescriptors.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer import org.jetbrains.kotlin.ir.declarations.copyAttributes import org.jetbrains.kotlin.ir.expressions.IrConstructorCall -import org.jetbrains.kotlin.ir.expressions.IrLoop import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol @@ -21,6 +20,7 @@ import org.jetbrains.kotlin.ir.types.impl.buildSimpleType import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.utils.memoryOptimizedMap internal class DeepCopyIrTreeWithSymbolsForInliner( val typeArguments: Map?, @@ -54,7 +54,7 @@ internal class DeepCopyIrTreeWithSymbolsForInliner( arguments: List, erasedParameters: MutableSet? ) = - arguments.map { argument -> + arguments.memoryOptimizedMap { argument -> (argument as? IrTypeProjection)?.let { proj -> remapTypeAndOptionallyErase(proj.type, erasedParameters)?.let { newType -> makeTypeProjection(newType, proj.variance) @@ -112,7 +112,7 @@ internal class DeepCopyIrTreeWithSymbolsForInliner( kotlinType = null this.classifier = symbolRemapper.getReferencedClassifier(classifier) arguments = remapTypeArguments(type.arguments, erasedParameters) - annotations = type.annotations.map { it.transform(copier, null) as IrConstructorCall } + annotations = type.annotations.memoryOptimizedMap { it.transform(copier, null) as IrConstructorCall } } } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt index ab35fdbeffc..7d1165092cb 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsCommonBackendContext.kt @@ -52,7 +52,7 @@ interface JsCommonBackendContext : CommonBackendContext { } // TODO: investigate if it could be removed -internal fun BackendContext.lazy2(fn: () -> T) = lazy { irFactory.stageController.withInitialIr(fn) } +internal fun BackendContext.lazy2(fn: () -> T) = lazy(LazyThreadSafetyMode.NONE) { irFactory.stageController.withInitialIr(fn) } @OptIn(ObsoleteDescriptorBasedAPI::class) class JsCommonCoroutineSymbols( @@ -66,14 +66,14 @@ class JsCommonCoroutineSymbols( val coroutineImpl = symbolTable.referenceClass(findClass(coroutinePackage.memberScope, COROUTINE_IMPL_NAME)) - val coroutineImplLabelPropertyGetter by lazy { coroutineImpl.getPropertyGetter("state")!!.owner } - val coroutineImplLabelPropertySetter by lazy { coroutineImpl.getPropertySetter("state")!!.owner } - val coroutineImplResultSymbolGetter by lazy { coroutineImpl.getPropertyGetter("result")!!.owner } - val coroutineImplResultSymbolSetter by lazy { coroutineImpl.getPropertySetter("result")!!.owner } - val coroutineImplExceptionPropertyGetter by lazy { coroutineImpl.getPropertyGetter("exception")!!.owner } - val coroutineImplExceptionPropertySetter by lazy { coroutineImpl.getPropertySetter("exception")!!.owner } - val coroutineImplExceptionStatePropertyGetter by lazy { coroutineImpl.getPropertyGetter("exceptionState")!!.owner } - val coroutineImplExceptionStatePropertySetter by lazy { coroutineImpl.getPropertySetter("exceptionState")!!.owner } + val coroutineImplLabelPropertyGetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertyGetter("state")!!.owner } + val coroutineImplLabelPropertySetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertySetter("state")!!.owner } + val coroutineImplResultSymbolGetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertyGetter("result")!!.owner } + val coroutineImplResultSymbolSetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertySetter("result")!!.owner } + val coroutineImplExceptionPropertyGetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertyGetter("exception")!!.owner } + val coroutineImplExceptionPropertySetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertySetter("exception")!!.owner } + val coroutineImplExceptionStatePropertyGetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertyGetter("exceptionState")!!.owner } + val coroutineImplExceptionStatePropertySetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertySetter("exceptionState")!!.owner } val continuationClass = symbolTable.referenceClass( coroutinePackage.memberScope.getContributedClassifier( diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt index 4beb280805c..327026f18c2 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt @@ -185,7 +185,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC val jsNumberRangeToLong = getInternalFunction("numberRangeToLong") private val _rangeUntilFunctions = irBuiltIns.findFunctions(Name.identifier("until"), "kotlin", "ranges") - val rangeUntilFunctions by lazy { + val rangeUntilFunctions by lazy(LazyThreadSafetyMode.NONE) { _rangeUntilFunctions .filter { it.owner.extensionReceiverParameter != null && it.owner.valueParameters.size == 1 } .associateBy { it.owner.extensionReceiverParameter!!.type to it.owner.valueParameters[0].type } @@ -324,11 +324,11 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC val jsFunAnnotationSymbol = context.symbolTable.referenceClass(context.getJsInternalClass("JsFun")) val jsNameAnnotationSymbol = context.symbolTable.referenceClass(context.getJsInternalClass("JsName")) - val jsExportAnnotationSymbol by lazy { + val jsExportAnnotationSymbol by lazy(LazyThreadSafetyMode.NONE) { context.symbolTable.referenceClass(context.getJsInternalClass("JsExport")) } - val jsExportIgnoreAnnotationSymbol by lazy { + val jsExportIgnoreAnnotationSymbol by lazy(LazyThreadSafetyMode.NONE) { jsExportAnnotationSymbol.owner .findDeclaration { it.fqNameWhenAvailable == FqName("kotlin.js.JsExport.Ignore") } ?.symbol ?: error("can't find kotlin.js.JsExport.Ignore annotation") diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index 83e5b00ef1a..2cae70a3817 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.compilationException import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.linkage.partial.createPartialLinkageSupportForLowerings +import org.jetbrains.kotlin.backend.common.serialization.IrInterningService import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.config.CompilerConfiguration @@ -48,9 +49,9 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.isNullable -import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceMapNotNull import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import org.jetbrains.kotlin.utils.filterIsInstanceMapNotNull import java.util.WeakHashMap @OptIn(ObsoleteDescriptorBasedAPI::class) @@ -73,6 +74,7 @@ class JsIrBackendContext( val polyfills = JsPolyfills() val fieldToInitializer = WeakHashMap() + val globalInternationService = IrInterningService() val localClassNames = WeakHashMap() @@ -102,17 +104,17 @@ class JsIrBackendContext( val externalPackageFragment = mutableMapOf() - val additionalExportedDeclarations = mutableSetOf() + val additionalExportedDeclarations = hashSetOf() val bodilessBuiltInsPackageFragment: IrPackageFragment = IrExternalPackageFragmentImpl( DescriptorlessExternalPackageFragmentSymbol(), FqName("kotlin") ) - val packageLevelJsModules = mutableSetOf() + val packageLevelJsModules = hashSetOf() val declarationLevelJsModules = mutableListOf() - val testFunsPerFile = mutableMapOf() + val testFunsPerFile = hashMapOf() override fun createTestContainerFun(irFile: IrFile): IrSimpleFunction { return testFunsPerFile.getOrPut(irFile) { @@ -263,13 +265,13 @@ class JsIrBackendContext( private val getProgressionLastElementSymbols = irBuiltIns.findFunctions(Name.identifier("getProgressionLastElement"), "kotlin", "internal") - override val getProgressionLastElementByReturnType: Map by lazy { + override val getProgressionLastElementByReturnType: Map by lazy(LazyThreadSafetyMode.NONE) { getProgressionLastElementSymbols.associateBy { it.owner.returnType.classifierOrFail } } private val toUIntSymbols = irBuiltIns.findFunctions(Name.identifier("toUInt"), "kotlin") - override val toUIntByExtensionReceiver: Map by lazy { + override val toUIntByExtensionReceiver: Map by lazy(LazyThreadSafetyMode.NONE) { toUIntSymbols.associateBy { it.owner.extensionReceiverParameter?.type?.classifierOrFail ?: error("Expected extension receiver for ${it.owner.render()}") @@ -278,7 +280,7 @@ class JsIrBackendContext( private val toULongSymbols = irBuiltIns.findFunctions(Name.identifier("toULong"), "kotlin") - override val toULongByExtensionReceiver: Map by lazy { + override val toULongByExtensionReceiver: Map by lazy(LazyThreadSafetyMode.NONE) { toULongSymbols.associateBy { it.owner.extensionReceiverParameter?.type?.classifierOrFail ?: error("Expected extension receiver for ${it.owner.render()}") diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/PropertyLazyInitialization.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/PropertyLazyInitialization.kt index f21f233a140..db1799e3790 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/PropertyLazyInitialization.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/PropertyLazyInitialization.kt @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.symbols.IrClassSymbol class PropertyLazyInitialization(val enabled: Boolean, eagerInitialization: IrClassSymbol) { - val fileToInitializationFuns: MutableMap = mutableMapOf() - val fileToInitializerPureness: MutableMap = mutableMapOf() + val fileToInitializationFuns: MutableMap = hashMapOf() + val fileToInitializerPureness: MutableMap = hashMapOf() val eagerInitialization: IrClassSymbol = eagerInitialization } \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index 63d42ce9374..1a3ba942949 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -122,6 +122,7 @@ fun compileIr( irLinker.postProcess(inOrAfterLinkageStep = true) irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process") + irLinker.clear() allModules.forEach { module -> if (shouldGeneratePolyfills) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/JsUsefulDeclarationProcessor.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/JsUsefulDeclarationProcessor.kt index 5c88d557f9b..864fcdf5bea 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/JsUsefulDeclarationProcessor.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/JsUsefulDeclarationProcessor.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.ir.backend.js.lower.isEs6ConstructorReplacement import org.jetbrains.kotlin.ir.backend.js.utils.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.types.* diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UsefulDeclarationProcessor.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UsefulDeclarationProcessor.kt index a22de30a23c..7a8aef82149 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UsefulDeclarationProcessor.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UsefulDeclarationProcessor.kt @@ -27,7 +27,7 @@ abstract class UsefulDeclarationProcessor( protected fun getMethodOfAny(name: String): IrDeclaration = context.irBuiltIns.anyClass.owner.declarations.filterIsInstance().single { it.name.asString() == name } - protected val toStringMethod: IrDeclaration by lazy { getMethodOfAny("toString") } + protected val toStringMethod: IrDeclaration by lazy(LazyThreadSafetyMode.NONE) { getMethodOfAny("toString") } protected abstract fun isExported(declaration: IrDeclaration): Boolean protected abstract val bodyVisitor: BodyVisitorBase diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UselessDeclarationsRemover.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UselessDeclarationsRemover.kt index cd2ad7d3721..5c3cb695dc0 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UselessDeclarationsRemover.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UselessDeclarationsRemover.kt @@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.backend.js.utils.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.isAny @@ -22,6 +21,8 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.js.config.RuntimeDiagnostic +import org.jetbrains.kotlin.utils.memoryOptimizedFilter +import org.jetbrains.kotlin.utils.memoryOptimizedMap class UselessDeclarationsRemover( private val removeUnusedAssociatedObjects: Boolean, @@ -52,13 +53,13 @@ class UselessDeclarationsRemover( // Otherwise `JsClassGenerator.generateAssociatedKeyProperties` will try to reference the object factory (which is removed). // That will result in an error from the Namer. It cannot generate a name for an absent declaration. if (removeUnusedAssociatedObjects && declaration.annotations.any { !it.shouldKeepAnnotation() }) { - declaration.annotations = declaration.annotations.filter { it.shouldKeepAnnotation() } + declaration.annotations = declaration.annotations.memoryOptimizedFilter { it.shouldKeepAnnotation() } } declaration.superTypes = declaration.superTypes .flatMap { it.classOrNull?.collectUsedSuperTypes() ?: emptyList() } .distinct() - .map { it.defaultType } + .memoryOptimizedMap { it.defaultType } } private fun IrClassSymbol.collectUsedSuperTypes(): Set { @@ -68,7 +69,7 @@ class UselessDeclarationsRemover( } else { owner.superTypes .flatMap { it.takeIf { !it.isAny() }?.classOrNull?.collectUsedSuperTypes() ?: emptyList() } - .toSet() + .toHashSet() } } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt index 42750a06303..04a6925de80 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt @@ -23,9 +23,8 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.serialization.js.ModuleKind -import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.* import org.jetbrains.kotlin.utils.addToStdlib.runIf -import org.jetbrains.kotlin.utils.keysToMap private const val magicPropertyName = "__doNotUseOrImplementIt" @@ -34,7 +33,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac fun generateExport(file: IrPackageFragment): List { val namespaceFqName = file.fqName - val exports = file.declarations.flatMap { declaration -> listOfNotNull(exportDeclaration(declaration)) } + val exports = file.declarations.memoryOptimizedFlatMap { declaration -> listOfNotNull(exportDeclaration(declaration)) } return when { exports.isEmpty() -> emptyList() !generateNamespacesForPackages || namespaceFqName.isRoot -> exports @@ -46,7 +45,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac ExportedModule( context.configuration[CommonConfigurationKeys.MODULE_NAME]!!, moduleKind, - (context.externalPackageFragment.values + modules.flatMap { it.files }).flatMap { + (context.externalPackageFragment.values + modules.flatMap { it.files }).memoryOptimizedFlatMap { generateExport(it) } ) @@ -84,7 +83,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac ExportedFunction( function.getExportedIdentifier(), returnType = exportType(function.returnType), - typeParameters = function.typeParameters.map(::exportTypeParameter), + typeParameters = function.typeParameters.memoryOptimizedMap(::exportTypeParameter), isMember = parent is IrClass, isStatic = function.isStaticMethod, isAbstract = parent is IrClass && !parent.isInterface && function.modality == Modality.ABSTRACT, @@ -92,7 +91,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac ir = function, parameters = (listOfNotNull(function.extensionReceiverParameter) + function.valueParameters) .filter { it.shouldBeExported() } - .map { exportParameter(it) }, + .memoryOptimizedMap { exportParameter(it) }, ) } } @@ -102,7 +101,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac if (!constructor.isPrimary) return null val allValueParameters = listOfNotNull(constructor.extensionReceiverParameter) + constructor.valueParameters return ExportedConstructor( - parameters = allValueParameters.filterNot { it.isBoxParameter }.map { exportParameter(it) }, + parameters = allValueParameters.filterNot { it.isBoxParameter }.memoryOptimizedMap { exportParameter(it) }, visibility = constructor.visibility.toExportedVisibility() ) } @@ -219,11 +218,11 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac } private fun exportDeclarationImplicitly(klass: IrClass, superTypes: Iterable): ExportedDeclaration { - val typeParameters = klass.typeParameters.map(::exportTypeParameter) + val typeParameters = klass.typeParameters.memoryOptimizedMap(::exportTypeParameter) val superInterfaces = superTypes .filter { (it.classifierOrFail.owner as? IrDeclaration)?.isExportedImplicitlyOrExplicitly(context) ?: false } .map { exportType(it) } - .filter { it !is ExportedType.ErrorType } + .memoryOptimizedFilter { it !is ExportedType.ErrorType } val name = klass.getExportedIdentifier() val (members, nestedClasses) = exportClassDeclarations(klass, superTypes) @@ -288,7 +287,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac return exportClass( klass, superTypes, - listOf(privateConstructor) + members, + listOf(privateConstructor) memoryOptimizedPlus members, nestedClasses ) } @@ -424,17 +423,17 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac members: List, nestedClasses: List, ): ExportedDeclaration { - val typeParameters = klass.typeParameters.map(::exportTypeParameter) + val typeParameters = klass.typeParameters.memoryOptimizedMap(::exportTypeParameter) val superClasses = superTypes .filter { !it.classifierOrFail.isInterface && it.canBeUsedAsSuperTypeOfExportedClasses() } .map { exportType(it, false) } - .filter { it !is ExportedType.ErrorType } + .memoryOptimizedFilter { it !is ExportedType.ErrorType } val superInterfaces = superTypes .filter { it.shouldPresentInsideImplementsClause() } .map { exportType(it, false) } - .filter { it !is ExportedType.ErrorType } + .memoryOptimizedFilter { it !is ExportedType.ErrorType } val name = klass.getExportedIdentifier() @@ -594,7 +593,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac nonNullType.isArray() -> ExportedType.Array(exportTypeArgument(nonNullType.arguments[0])) nonNullType.isSuspendFunction() -> ExportedType.ErrorType("Suspend functions are not supported") nonNullType.isFunction() -> ExportedType.Function( - parameterTypes = nonNullType.arguments.dropLast(1).map { exportTypeArgument(it) }, + parameterTypes = nonNullType.arguments.dropLast(1).memoryOptimizedMap { exportTypeArgument(it) }, returnType = exportTypeArgument(nonNullType.arguments.last()) ) @@ -610,7 +609,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac val exportedSupertype = runIf(shouldCalculateExportedSupertypeForImplicit && isImplicitlyExported) { val transitiveExportedType = nonNullType.collectSuperTransitiveHierarchy() if (transitiveExportedType.isEmpty()) return@runIf null - transitiveExportedType.map(::exportType).reduce(ExportedType::IntersectionType) + transitiveExportedType.memoryOptimizedMap(::exportType).reduce(ExportedType::IntersectionType) } ?: ExportedType.Primitive.Any when (klass.kind) { @@ -625,7 +624,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac ClassKind.ENUM_CLASS, ClassKind.INTERFACE -> ExportedType.ClassType( name, - type.arguments.map { exportTypeArgument(it) }, + type.arguments.memoryOptimizedMap { exportTypeArgument(it) }, klass ) }.withImplicitlyExported(isImplicitlyExported, exportedSupertype) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelToJsStatements.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelToJsStatements.kt index 890f8760875..6de4b2eca12 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelToJsStatements.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelToJsStatements.kt @@ -20,14 +20,14 @@ import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.util.companionObject import org.jetbrains.kotlin.ir.util.isObject import org.jetbrains.kotlin.js.backend.ast.* -import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.filterIsInstanceAnd class ExportModelToJsStatements( private val staticContext: JsStaticContext, private val es6mode: Boolean, private val declareNewNamespace: (String) -> String, ) { - private val namespaceToRefMap = mutableMapOf() + private val namespaceToRefMap = hashMapOf() fun generateModuleExport( module: ExportedModule, diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt index 850bb171eba..67960ee4c92 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/CacheUpdater.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir.backend.js.ic import org.jetbrains.kotlin.backend.common.CommonJsKLibResolver import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig +import org.jetbrains.kotlin.backend.common.serialization.IrInterningService import org.jetbrains.kotlin.backend.common.serialization.cityHash64 import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.ir.backend.js.* @@ -19,6 +20,10 @@ import org.jetbrains.kotlin.library.KLIB_PROPERTY_DEPENDS import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.metadata.resolver.TopologicalLibraryOrder import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.utils.memoryOptimizedFilter +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize +import org.jetbrains.kotlin.utils.newHashSetWithExpectedSize import java.io.File import java.nio.file.Files import java.util.EnumSet @@ -67,6 +72,8 @@ class CacheUpdater( private val icHasher = ICHasher() + private val internationService = IrInterningService() + private val cacheRootDir = run { val configHash = icHasher.calculateConfigHash(compilerConfiguration) File(cacheDir, "version.${configHash.hash.lowBytes.toString(Character.MAX_RADIX)}") @@ -107,15 +114,15 @@ class CacheUpdater( val nameToKotlinLibrary = libraries.associateBy { it.moduleName } libraries.associateWith { - it.manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true).map { depName -> + it.manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true).memoryOptimizedMap { depName -> nameToKotlinLibrary[depName] ?: notFoundIcError("library $depName") } } } val mainModuleFriendLibraries = libraryDependencies.keys.let { libs -> - val friendPaths = mainModuleFriends.mapTo(HashSet(mainModuleFriends.size)) { File(it).canonicalPath } - libs.filter { it.libraryFile.canonicalPath in friendPaths } + val friendPaths = mainModuleFriends.mapTo(newHashSetWithExpectedSize(mainModuleFriends.size)) { File(it).canonicalPath } + libs.memoryOptimizedFilter { it.libraryFile.canonicalPath in friendPaths } } private val klibCacheDirs = libraryDependencies.keys.map { lib -> @@ -139,12 +146,12 @@ class CacheUpdater( } private val incrementalCaches = libraryDependencies.keys.zip(klibCacheDirs).associate { (lib, libraryCacheDir) -> - KotlinLibraryFile(lib) to IncrementalCache(KotlinLoadedLibraryHeader(lib), libraryCacheDir) + KotlinLibraryFile(lib) to IncrementalCache(KotlinLoadedLibraryHeader(lib, internationService), libraryCacheDir) } private val removedIncrementalCaches = buildList { if (cacheRootDir.isDirectory) { - val availableCaches = incrementalCaches.values.mapTo(HashSet(incrementalCaches.size)) { it.cacheDir } + val availableCaches = incrementalCaches.values.mapTo(newHashSetWithExpectedSize(incrementalCaches.size)) { it.cacheDir } val allDirs = Files.walk(cacheRootDir.toPath(), 1).map { it.toFile() } allDirs.filter { it != cacheRootDir && it !in availableCaches }.forEach { removedCacheDir -> add(IncrementalCache(KotlinRemovedLibraryHeader(removedCacheDir), removedCacheDir)) @@ -445,7 +452,7 @@ class CacheUpdater( // if imports have been modified, metadata for the file will be rebuilt later, // so if the imports haven't been modified, update the metadata manually if (newMetadata.importedSignaturesState == ImportedSignaturesState.NON_MODIFIED) { - val newDirectDependencies = newSignatures.associateWithTo(HashMap(newSignatures.size)) { + val newDirectDependencies = newSignatures.associateWithTo(newHashMapWithExpectedSize(newSignatures.size)) { signatureHashCalculator[it] ?: notFoundIcError("signature $it hash", libFile, srcFile) } newMetadata.directDependencies[libFile, srcFile] = newDirectDependencies @@ -690,7 +697,7 @@ class CacheUpdater( // Load declarations referenced during `context` initialization loadedIr.loadUnboundSymbols() - val dirtyFiles = dirtyFileExports.entries.associateTo(HashMap(dirtyFileExports.size)) { it.key to HashSet(it.value.keys) } + val dirtyFiles = dirtyFileExports.entries.associateTo(newHashMapWithExpectedSize(dirtyFileExports.size)) { it.key to HashSet(it.value.keys) } stopwatch.startNext("Processing IR - updating intrinsics and builtins dependencies") updater.updateStdlibIntrinsicDependencies(loadedIr, mainModuleFragment, dirtyFiles) @@ -752,12 +759,13 @@ fun rebuildCacheForDirtyFiles( mainArguments: List?, es6mode: Boolean ): Pair>> { + val internationService = IrInterningService() val emptyMetadata = object : KotlinSourceFileExports() { override val inverseDependencies = KotlinSourceFileMap>(emptyMap()) } val libFile = KotlinLibraryFile(library) - val dirtySrcFiles = dirtyFiles?.map { KotlinSourceFile(it) } ?: KotlinLoadedLibraryHeader(library).sourceFileFingerprints.keys + val dirtySrcFiles = dirtyFiles?.memoryOptimizedMap { KotlinSourceFile(it) } ?: KotlinLoadedLibraryHeader(library, internationService).sourceFileFingerprints.keys val modifiedFiles = mapOf(libFile to dirtySrcFiles.associateWith { emptyMetadata }) @@ -767,7 +775,7 @@ fun rebuildCacheForDirtyFiles( val currentIrModule = loadedIr.loadedFragments[libFile] ?: notFoundIcError("loaded fragment", libFile) val dirtyIrFiles = dirtyFiles?.let { val files = it.toSet() - currentIrModule.files.filter { irFile -> irFile.fileEntry.name in files } + currentIrModule.files.memoryOptimizedFilter { irFile -> irFile.fileEntry.name in files } } ?: currentIrModule.files val compilerWithIC = JsIrCompilerWithIC( @@ -781,8 +789,9 @@ fun rebuildCacheForDirtyFiles( // Load declarations referenced during `context` initialization loadedIr.loadUnboundSymbols() + internationService.clear() - val fragments = compilerWithIC.compile(loadedIr.loadedFragments.values, dirtyIrFiles, mainArguments).map { it() } + val fragments = compilerWithIC.compile(loadedIr.loadedFragments.values, dirtyIrFiles, mainArguments).memoryOptimizedMap { it() } return currentIrModule to dirtyIrFiles.zip(fragments) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCache.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCache.kt index 801a6fdfb5c..b3c15abfbed 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCache.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCache.kt @@ -32,13 +32,13 @@ internal class IncrementalCache(private val library: KotlinLibraryHeader, val ca private val signatureToIndexMappingFromMetadata = hashMapOf>() - private val cacheHeaderFromDisk by lazy { + private val cacheHeaderFromDisk by lazy(LazyThreadSafetyMode.NONE) { cacheHeaderFile.useCodedInputIfExists { CacheHeader.fromProtoStream(this) } } - val libraryFileFromHeader by lazy { cacheHeaderFromDisk?.libraryFile } + val libraryFileFromHeader by lazy(LazyThreadSafetyMode.NONE) { cacheHeaderFromDisk?.libraryFile } private class CacheHeader( val libraryFile: KotlinLibraryFile, @@ -149,7 +149,7 @@ internal class IncrementalCache(private val library: KotlinLibraryHeader, val ca private fun fetchSourceFileMetadata(srcFile: KotlinSourceFile, loadSignatures: Boolean) = kotlinLibrarySourceFileMetadata.getOrPut(srcFile) { val signatureToIndexMapping = signatureToIndexMappingFromMetadata.getOrPut(srcFile) { hashMapOf() } - val deserializer: IdSignatureDeserializer by lazy { + val deserializer: IdSignatureDeserializer by lazy(LazyThreadSafetyMode.NONE) { library.sourceFileDeserializers[srcFile] ?: notFoundIcError("signature deserializer", library.libraryFile, srcFile) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCacheArtifact.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCacheArtifact.kt index dfb0a96ce6d..cda8c9fb9ff 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCacheArtifact.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/IncrementalCacheArtifact.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.backend.js.ic import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrProgramFragment import org.jetbrains.kotlin.ir.backend.js.utils.serialization.serializeTo import org.jetbrains.kotlin.konan.file.use +import org.jetbrains.kotlin.utils.newHashSetWithExpectedSize import java.io.BufferedOutputStream import java.io.File @@ -54,7 +55,7 @@ internal class IncrementalCacheArtifact( private val srcCacheActions: List, private val externalModuleName: String? ) { - fun getSourceFiles() = srcCacheActions.mapTo(HashSet(srcCacheActions.size)) { it.srcFile } + fun getSourceFiles() = srcCacheActions.mapTo(newHashSetWithExpectedSize(srcCacheActions.size)) { it.srcFile } fun buildModuleArtifactAndCommitCache( moduleName: String, diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsIrLinkerLoader.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsIrLinkerLoader.kt index 590420bbf5f..2d96c0f7f18 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsIrLinkerLoader.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/JsIrLinkerLoader.kt @@ -73,6 +73,7 @@ internal data class LoadedJsIr( ExternalDependenciesGenerator(linker.symbolTable, listOf(linker)).generateUnboundSymbolsAsDependencies() linker.postProcess(inOrAfterLinkageStep = true) linker.checkNoUnboundSymbols(linker.symbolTable, "at the end of IR linkage process") + linker.clear() } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinLibraryHeader.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinLibraryHeader.kt index 1c4f68400bc..df62f475a58 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinLibraryHeader.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinLibraryHeader.kt @@ -23,7 +23,10 @@ internal interface KotlinLibraryHeader { val jsOutputName: String? } -internal class KotlinLoadedLibraryHeader(private val library: KotlinLibrary) : KotlinLibraryHeader { +internal class KotlinLoadedLibraryHeader( + private val library: KotlinLibrary, + private val internationService: IrInterningService +) : KotlinLibraryHeader { private fun parseFingerprintsFromManifest(): Map? { val manifestFingerprints = library.serializedIrFileFingerprints?.takeIf { it.size == sourceFiles.size } ?: return null return sourceFiles.withIndex().associate { it.value to manifestFingerprints[it.index].fileFingerprint } @@ -31,12 +34,12 @@ internal class KotlinLoadedLibraryHeader(private val library: KotlinLibrary) : K override val libraryFile: KotlinLibraryFile = KotlinLibraryFile(library) - override val libraryFingerprint: FingerprintHash by lazy { + override val libraryFingerprint: FingerprintHash by lazy(LazyThreadSafetyMode.NONE) { val serializedKlib = library.serializedKlibFingerprint ?: SerializedKlibFingerprint(File(libraryFile.path)) serializedKlib.klibFingerprint } - override val sourceFileDeserializers: Map by lazy { + override val sourceFileDeserializers: Map by lazy(LazyThreadSafetyMode.NONE) { buildMapUntil(sourceFiles.size) { val deserializer = IdSignatureDeserializer(IrLibraryFileFromBytes(object : IrLibraryBytesSource() { private fun err(): Nothing = icError("Not supported") @@ -46,13 +49,13 @@ internal class KotlinLoadedLibraryHeader(private val library: KotlinLibrary) : K override fun string(index: Int): ByteArray = library.string(index, it) override fun body(index: Int): ByteArray = err() override fun debugInfo(index: Int): ByteArray? = null - }), null) + }), null, internationService) put(sourceFiles[it], deserializer) } } - override val sourceFileFingerprints: Map by lazy { + override val sourceFileFingerprints: Map by lazy(LazyThreadSafetyMode.NONE) { parseFingerprintsFromManifest() ?: buildMapUntil(sourceFiles.size) { put(sourceFiles[it], SerializedIrFileFingerprint(library, it).fileFingerprint) } @@ -61,7 +64,7 @@ internal class KotlinLoadedLibraryHeader(private val library: KotlinLibrary) : K override val jsOutputName: String? get() = library.jsOutputName - private val sourceFiles by lazy { + private val sourceFiles by lazy(LazyThreadSafetyMode.NONE) { val extReg = ExtensionRegistryLite.newInstance() Array(library.fileCount()) { val fileProto = IrFile.parseFrom(library.file(it).codedInputStream, extReg) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinSourceFileMetadata.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinSourceFileMetadata.kt index 85cc7867ede..53cef51f74e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinSourceFileMetadata.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/ic/KotlinSourceFileMetadata.kt @@ -139,7 +139,7 @@ internal enum class ImportedSignaturesState { UNKNOWN, MODIFIED, NON_MODIFIED } internal class UpdatedDependenciesMetadata(oldMetadata: KotlinSourceFileMetadata) : KotlinSourceFileMetadata() { private val oldInverseDependencies = oldMetadata.inverseDependencies - private val newExportedSignatures: Set by lazy { inverseDependencies.flatSignatures() } + private val newExportedSignatures: Set by lazy(LazyThreadSafetyMode.NONE) { inverseDependencies.flatSignatures() } var importedSignaturesState = ImportedSignaturesState.UNKNOWN diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt index 25f6158856d..f67f3e0a255 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.transformStatement import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.isElseBranch +import org.jetbrains.kotlin.utils.memoryOptimizedMap import org.jetbrains.kotlin.ir.util.patchDeclarationParents import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.ir.visitors.IrElementTransformer @@ -399,7 +400,7 @@ class BlockDecomposerTransformer( } if (compositeCount == 0) { - val branches = results.map { (cond, res, orig) -> + val branches = results.memoryOptimizedMap { (cond, res, orig) -> when { isElseBranch(orig) -> IrElseBranchImpl(orig.startOffset, orig.endOffset, cond, res) else /* IrBranch */ -> IrBranchImpl(orig.startOffset, orig.endOffset, cond, res) @@ -509,7 +510,7 @@ class BlockDecomposerTransformer( val newStatements = mutableListOf() val arguments = mapArguments(expression.arguments, compositeCount, newStatements) - newStatements += expression.run { IrStringConcatenationImpl(startOffset, endOffset, type, arguments.map { it!! }) } + newStatements += expression.run { IrStringConcatenationImpl(startOffset, endOffset, type, arguments.memoryOptimizedMap { it!! }) } return JsIrBuilder.buildComposite(expression.type, newStatements) } @@ -710,7 +711,7 @@ class BlockDecomposerTransformer( val irVar = makeTempVar(aTry.type) val newTryResult = wrap(aTry.tryResult, irVar) - val newCatches = aTry.catches.map { + val newCatches = aTry.catches.memoryOptimizedMap { val newCatchBody = wrap(it.result, irVar) IrCatchImpl(it.startOffset, it.endOffset, it.catchParameter, newCatchBody) } @@ -757,7 +758,7 @@ class BlockDecomposerTransformer( if (hasComposites) { val irVar = makeTempVar(expression.type) - val newBranches = decomposedResults.map { (branch, condition, result) -> + val newBranches = decomposedResults.memoryOptimizedMap { (branch, condition, result) -> val newResult = wrap(result, irVar) when { isElseBranch(branch) -> IrElseBranchImpl(branch.startOffset, branch.endOffset, condition, newResult) @@ -771,7 +772,7 @@ class BlockDecomposerTransformer( return JsIrBuilder.buildComposite(expression.type, listOf(irVar, newWhen, JsIrBuilder.buildGetValue(irVar.symbol))) } else { - val newBranches = decomposedResults.map { (branch, condition, result) -> + val newBranches = decomposedResults.memoryOptimizedMap { (branch, condition, result) -> when { isElseBranch(branch) -> IrElseBranchImpl(branch.startOffset, branch.endOffset, condition, result) else /* IrBranch */ -> IrBranchImpl(branch.startOffset, branch.endOffset, condition, result) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt index b70388435c0..34087d65412 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.bridges.FunctionHandle import org.jetbrains.kotlin.backend.common.bridges.generateBridges -import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET @@ -23,6 +22,7 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.utils.memoryOptimizedPlus /** * Constructs bridges for inherited generic functions @@ -145,11 +145,10 @@ abstract class BridgesConstruction(val context: T) : val substitutionMap = makeTypeParameterSubstitutionMap(bridge, this) copyReceiverParametersFrom(bridge, substitutionMap) copyValueParametersFrom(bridge, substitutionMap) - annotations += bridge.annotations + annotations = annotations memoryOptimizedPlus bridge.annotations // the js function signature building process (jsFunctionSignature()) uses dfs throught overriddenSymbols for getting js name, // therefore it is very important to put bridge symbol at the beginning, it allows to get correct js function name - overriddenSymbols += bridge.symbol - overriddenSymbols += delegateTo.overriddenSymbols + overriddenSymbols = overriddenSymbols memoryOptimizedPlus bridge.symbol memoryOptimizedPlus delegateTo.overriddenSymbols } irFunction.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) { @@ -179,7 +178,7 @@ abstract class BridgesConstruction(val context: T) : val toTake = valueParameters.size - if (call.isSuspend xor irFunction.isSuspend) 1 else 0 - valueParameters.subList(0, toTake).mapIndexed { i, valueParameter -> + valueParameters.subList(0, toTake).forEachIndexed { i, valueParameter -> call.putValueArgument(i, irCastIfNeeded(irGet(valueParameter), delegateTo.valueParameters[i].type)) } @@ -203,7 +202,7 @@ abstract class BridgesConstruction(val context: T) : valueParametersToCopy = bridge.valueParameters.take(varargIndex) } } - valueParameters += valueParametersToCopy.map { p -> p.copyTo(this, type = p.type.substitute(substitutionMap)) } + valueParameters = valueParameters memoryOptimizedPlus valueParametersToCopy.map { p -> p.copyTo(this, type = p.type.substitute(substitutionMap)) } } abstract fun getBridgeOrigin(bridge: IrSimpleFunction): IrDeclarationOrigin diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt index fc5cbe19b74..c5e29e42430 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt @@ -26,6 +26,8 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.utils.memoryOptimizedMapIndexed +import org.jetbrains.kotlin.utils.memoryOptimizedPlus class CallableReferenceLowering(private val context: CommonBackendContext) : BodyLoweringPass { @@ -270,9 +272,11 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod private fun IrSimpleFunction.createLambdaInvokeMethod() { annotations = function.annotations - val valueParameterMap = function.explicitParameters.withIndex().associate { (index, param) -> - param to param.copyTo(this, index = index) - } + val valueParameterMap = function.explicitParameters + .withIndex() + .associate { (index, param) -> + param to param.copyTo(this, index = index) + } valueParameters = valueParameterMap.values.toList() body = function.moveBodyTo(this, valueParameterMap) } @@ -389,7 +393,7 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod val parameterTypes = (reference.type as IrSimpleType).arguments.map { (it as IrTypeProjection).type } val argumentTypes = parameterTypes.dropLast(1) - valueParameters = argumentTypes.mapIndexed { i, t -> + valueParameters = argumentTypes.memoryOptimizedMapIndexed { i, t -> buildValueParameter(this) { name = Name.identifier("p$i") type = t @@ -432,7 +436,7 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod val getter = nameProperty.addGetter() { returnType = stringType } - getter.overriddenSymbols += supperGetter.symbol + getter.overriddenSymbols = getter.overriddenSymbols memoryOptimizedPlus supperGetter.symbol getter.dispatchReceiverParameter = buildValueParameter(getter) { name = SpecialNames.THIS type = clazz.defaultType diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt index a317ec2222e..8f63d9558dc 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt @@ -19,8 +19,8 @@ import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.util.isFunction -import org.jetbrains.kotlin.ir.util.isThrowable +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.utils.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.* @@ -29,22 +29,22 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering private val reflectionSymbols get() = context.reflectionSymbols - private val primitiveClassProperties by lazy { + private val primitiveClassProperties by lazy(LazyThreadSafetyMode.NONE) { reflectionSymbols.primitiveClassesObject.owner.declarations.filterIsInstance() } - private val primitiveClassFunctionClass by lazy { + private val primitiveClassFunctionClass by lazy(LazyThreadSafetyMode.NONE) { reflectionSymbols.primitiveClassesObject.owner.declarations - .filterIsInstance() - .find { it.name == Name.identifier("functionClass") }!! + .findIsInstanceAnd { it.name == Name.identifier("functionClass") }!! } private fun primitiveClassProperty(name: String) = primitiveClassProperties.singleOrNull { it.name == Name.identifier(name) }?.getter ?: reflectionSymbols.primitiveClassesObject.owner.declarations - .filterIsInstance().single { it.name == Name.special("") } + .filterIsInstance() + .single { it.name == Name.special("") } - private val finalPrimitiveClasses by lazy { + private val finalPrimitiveClasses by lazy(LazyThreadSafetyMode.NONE) { mapOf( IrType::isBoolean to "booleanClass", IrType::isByte to "byteClass", @@ -67,7 +67,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering } } - private val openPrimitiveClasses by lazy { + private val openPrimitiveClasses by lazy(LazyThreadSafetyMode.NONE) { mapOf( IrType::isAny to "anyClass", IrType::isNumber to "numberClass", @@ -179,7 +179,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering startOffset = UNDEFINED_OFFSET, endOffset = UNDEFINED_OFFSET, arrayElementType = context.reflectionSymbols.kTypeClass.defaultType, - arrayElements = type.arguments.map { createKTypeProjection(it, visitedTypeParams) } + arrayElements = type.arguments.memoryOptimizedMap { createKTypeProjection(it, visitedTypeParams) } ) val isMarkedNullable = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, type.isMarkedNullable()) @@ -225,7 +225,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering startOffset = UNDEFINED_OFFSET, endOffset = UNDEFINED_OFFSET, arrayElementType = context.reflectionSymbols.kTypeClass.defaultType, - arrayElements = typeParameter.superTypes.map { createKType(it, visitedTypeParams) } + arrayElements = typeParameter.superTypes.memoryOptimizedMap { createKType(it, visitedTypeParams) } ) val variance = when (typeParameter.variance) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CreateScriptFunctionsPhase.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CreateScriptFunctionsPhase.kt index 5279d00f6a4..3cf1da43001 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CreateScriptFunctionsPhase.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CreateScriptFunctionsPhase.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.patchDeclarationParents import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.memoryOptimizedMap private object SCRIPT_FUNCTION : IrDeclarationOriginImpl("SCRIPT_FUNCTION") @@ -37,12 +38,13 @@ class CreateScriptFunctionsPhase(val context: CommonBackendContext) : FileLoweri val (startOffset, endOffset) = getFunctionBodyOffsets(irScript) val initializeStatements = irScript.statements + .asSequence() .filterIsInstance() .mapNotNull { it.backingField } .filter { it.initializer != null } .map { Pair(it, it.initializer!!.expression) } - - initializeStatements.forEach { it.first.initializer = null } + .onEach { it.first.initializer = null } + .toList() val initializeScriptFunction = createFunction(irScript, "\$initializeScript\$", context.irBuiltIns.unitType).also { it.body = it.factory.createBlockBody( @@ -51,7 +53,7 @@ class CreateScriptFunctionsPhase(val context: CommonBackendContext) : FileLoweri initializeStatements.let { if (irScript.resultProperty == null || initializeStatements.lastOrNull()?.first?.correspondingPropertySymbol != irScript.resultProperty) it else it.dropLast(1) - }.map { (field, expression) -> createIrSetField(field, expression) } + }.memoryOptimizedMap { (field, expression) -> createIrSetField(field, expression) } ) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6AddBoxParameterLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6AddBoxParameterLowering.kt index c4dfa60e016..29c63d15f3f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6AddBoxParameterLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6AddBoxParameterLowering.kt @@ -7,21 +7,28 @@ package org.jetbrains.kotlin.ir.backend.js.lower import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.ir.ValueRemapper +import org.jetbrains.kotlin.backend.common.lower.createIrBuilder +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder +import org.jetbrains.kotlin.ir.backend.js.utils.Namer import org.jetbrains.kotlin.ir.backend.js.utils.getVoid -import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.backend.js.utils.hasStrictSignature +import org.jetbrains.kotlin.ir.builders.irEqeqeqWithoutBox +import org.jetbrains.kotlin.ir.builders.irGet +import org.jetbrains.kotlin.ir.builders.irIfThen +import org.jetbrains.kotlin.ir.builders.irSet import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.builders.* -import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.symbols.IrValueSymbol -import org.jetbrains.kotlin.backend.common.lower.createIrBuilder -import org.jetbrains.kotlin.ir.backend.js.utils.Namer import org.jetbrains.kotlin.ir.types.makeNullable -import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.util.isLocal +import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.ir.util.superClass import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.utils.memoryOptimizedPlus object ES6_BOX_PARAMETER : IrDeclarationOriginImpl("ES6_BOX_PARAMETER") object ES6_BOX_PARAMETER_DEFAULT_RESOLUTION : IrStatementOriginImpl("ES6_BOX_PARAMETER_DEFAULT_RESOLUTION") @@ -52,7 +59,7 @@ class ES6AddBoxParameterToConstructorsLowering(val context: JsIrBackendContext) private fun IrConstructor.addBoxParameter() { val irClass = parentAsClass - val boxParameter = generateBoxParameter(irClass).also { valueParameters += it } + val boxParameter = generateBoxParameter(irClass).also { valueParameters = valueParameters memoryOptimizedPlus it } val body = body as? IrBlockBody ?: return val isBoxUsed = body.replaceThisWithBoxBeforeSuperCall(irClass, boxParameter.symbol) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorBoxParameterOptimizationLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorBoxParameterOptimizationLowering.kt index a2653bca6c7..68cd5476363 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorBoxParameterOptimizationLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorBoxParameterOptimizationLowering.kt @@ -22,7 +22,8 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid -import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.memoryOptimizedFilterNot class ES6ConstructorBoxParameterOptimizationLowering(private val context: JsIrBackendContext) : BodyLoweringPass { private val IrClass.needsOfBoxParameter by context.mapping.esClassWhichNeedBoxParameters @@ -36,7 +37,7 @@ class ES6ConstructorBoxParameterOptimizationLowering(private val context: JsIrBa containerFunction?.isEs6ConstructorReplacement == true && !containerFunction.parentAsClass.requiredToHaveBoxParameter() if (containerFunction != null && shouldRemoveBoxRelatedDeclarationsAndStatements && irBody is IrBlockBody) { - containerFunction.valueParameters = containerFunction.valueParameters.filter { !it.isBoxParameter } + containerFunction.valueParameters = containerFunction.valueParameters.memoryOptimizedFilterNot { it.isBoxParameter } } irBody.transformChildrenVoid(object : IrElementTransformerVoid() { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorLowering.kt index 3ee5f15398d..bcdb2f851eb 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorLowering.kt @@ -23,6 +23,10 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.runIf +import org.jetbrains.kotlin.utils.memoryOptimizedFilterNot +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedPlus +import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize object ES6_INIT_CALL : IrStatementOriginImpl("ES6_INIT_CALL") object ES6_CONSTRUCTOR_REPLACEMENT : IrDeclarationOriginImpl("ES6_CONSTRUCTOR_REPLACEMENT") @@ -62,7 +66,7 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : DeclarationTrans private fun IrConstructor.generateExportedConstructorIfNeed(factoryFunction: IrSimpleFunction): IrConstructor? { return runIf(isExported(context) && isPrimary) { apply { - valueParameters = valueParameters.filterNot { it.isBoxParameter } + valueParameters = valueParameters.memoryOptimizedFilterNot { it.isBoxParameter } (body as? IrBlockBody)?.let { val selfReplacedConstructorCall = JsIrBuilder.buildCall(factoryFunction.symbol).apply { valueParameters.forEachIndexed { i, it -> putValueArgument(i, JsIrBuilder.buildGetValue(it.symbol)) } @@ -170,9 +174,9 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : DeclarationTrans transformChildrenVoid(object : ValueRemapper(emptyMap()) { override val map: MutableMap = currentConstructor.valueParameters - .zip(constructorReplacement.valueParameters) - .associate { it.first.symbol to it.second.symbol } - .toMutableMap() + .asSequence() + .zip(constructorReplacement.valueParameters.asSequence()) + .associateTo(newHashMapWithExpectedSize(currentConstructor.valueParameters.size)) { it.first.symbol to it.second.symbol } override fun visitReturn(expression: IrReturn): IrExpression { return if (expression.returnTargetSymbol == currentConstructor.symbol) { @@ -208,7 +212,7 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : DeclarationTrans .apply { putValueArgument(0, irClass.getCurrentConstructorReference(constructorReplacement)) putValueArgument(1, expression.symbol.owner.parentAsClass.jsConstructorReference(context)) - putValueArgument(2, irAnyArray(expression.valueArguments.map { it ?: context.getVoid() })) + putValueArgument(2, irAnyArray(expression.valueArguments.memoryOptimizedMap { it ?: context.getVoid() })) putValueArgument(3, boxParameterGetter) } constructor.parentAsClass.symbol == context.irBuiltIns.anyClass -> @@ -252,6 +256,6 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : DeclarationTrans private fun IrDeclaration.excludeFromExport() { val jsExportIgnoreClass = context.intrinsics.jsExportIgnoreAnnotationSymbol.owner val jsExportIgnoreCtor = jsExportIgnoreClass.primaryConstructor ?: return - annotations += JsIrBuilder.buildConstructorCall(jsExportIgnoreCtor.symbol) + annotations = annotations memoryOptimizedPlus JsIrBuilder.buildConstructorCall(jsExportIgnoreCtor.symbol) } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6PrimaryConstructorOptimizationLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6PrimaryConstructorOptimizationLowering.kt index a19326ad0b7..6587a04016f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6PrimaryConstructorOptimizationLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6PrimaryConstructorOptimizationLowering.kt @@ -23,7 +23,8 @@ import org.jetbrains.kotlin.ir.symbols.IrValueSymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid -import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize const val CREATE_EXTERNAL_THIS_CONSTRUCTOR_PARAMETERS = 2 @@ -67,8 +68,7 @@ class ES6PrimaryConstructorOptimizationLowering(private val context: JsIrBackend body.transformChildrenVoid(object : ValueRemapper(emptyMap()) { override val map = original.valueParameters.zip(constructor.valueParameters) - .associate { it.first.symbol to it.second.symbol } - .toMutableMap() + .associateTo(newHashMapWithExpectedSize(original.valueParameters.size)) { it.first.symbol to it.second.symbol } override fun visitReturn(expression: IrReturn): IrExpression { return if (expression.returnTargetSymbol == original.symbol) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt index 3a299c34165..c20552377ba 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt @@ -12,14 +12,11 @@ import org.jetbrains.kotlin.backend.common.ir.isExpect import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlockBody import org.jetbrains.kotlin.backend.common.lower.irIfThen -import org.jetbrains.kotlin.backend.common.lower.parents import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.PRIVATE import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext -import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin -import org.jetbrains.kotlin.ir.backend.js.export.isExported import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.backend.js.utils.isInstantiableEnum import org.jetbrains.kotlin.ir.backend.js.utils.parentEnumClassOrNull @@ -36,6 +33,9 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.findIsInstanceAnd +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedPlus class EnumUsageLowering(val context: JsCommonBackendContext) : BodyLoweringPass { private var IrEnumEntry.getInstanceFun by context.mapping.enumEntryToGetInstanceFun @@ -99,7 +99,7 @@ class EnumClassConstructorLowering(val context: JsCommonBackendContext) : Declar }.apply { parent = enumClass additionalParameters.forEachIndexed { index, (name, type) -> - valueParameters += JsIrBuilder.buildValueParameter(this, name, index, type) + valueParameters = valueParameters memoryOptimizedPlus JsIrBuilder.buildValueParameter(this, name, index, type) } copyParameterDeclarationsFrom(enumConstructor) @@ -334,7 +334,7 @@ class EnumEntryInstancesBodyLowering(val context: JsCommonBackendContext) : Body val entryClass = container.constructedClass val enum = entryClass.parentAsClass if (enum.isInstantiableEnum) { - val entry = enum.declarations.filterIsInstance().find { it.correspondingClass === entryClass }!! + val entry = enum.declarations.findIsInstanceAnd { it.correspondingClass === entryClass }!! //In ES6 using `this` before superCall is unavailable, so //need to find superCall and put `instance = this` after it @@ -476,7 +476,7 @@ class EnumSyntheticFunctionsAndPropertiesLowering( declaration.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) { statements += context.createIrBuilder(declaration.symbol).irBlockBody { +irCall(enumClass.initEntryInstancesFun!!.symbol) - }.statements + originalBody.statements + }.statements memoryOptimizedPlus originalBody.statements } } } @@ -546,7 +546,7 @@ class EnumSyntheticFunctionsAndPropertiesLowering( irBranch( irEquals(irGet(nameParameter), irString(it.name.identifier)), irReturn(irCall(it.getInstanceFun!!)) ) - } + irElseBranch(irBlock { + } memoryOptimizedPlus irElseBranch(irBlock { +irCall(irClass.initEntryInstancesFun!!) +irCall(throwISESymbol) }) @@ -561,8 +561,8 @@ class EnumSyntheticFunctionsAndPropertiesLowering( } } - private fun IrBuilderWithScope.arrayOfEnumEntriesOf(enumClass: IrClass) = - irVararg(enumClass.defaultType, enumClass.enumEntries.map { irCall(it.getInstanceFun!!) }) + private fun IrBuilderWithScope.arrayOfEnumEntriesOf(enumClass: IrClass) = + irVararg(enumClass.defaultType, enumClass.enumEntries.memoryOptimizedMap { irCall(it.getInstanceFun!!) }) } private val IrClass.enumEntries: List diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ImplicitlyExportedDeclarationsMarkingLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ImplicitlyExportedDeclarationsMarkingLowering.kt index 2c6855be1e4..54feb07197a 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ImplicitlyExportedDeclarationsMarkingLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ImplicitlyExportedDeclarationsMarkingLowering.kt @@ -10,7 +10,10 @@ import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.export.isExported import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.backend.js.utils.isJsImplicitExport -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* @@ -18,6 +21,7 @@ import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.isPrimitiveArray import org.jetbrains.kotlin.ir.util.parentClassOrNull import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.utils.memoryOptimizedPlus class ImplicitlyExportedDeclarationsMarkingLowering(private val context: JsIrBackendContext) : DeclarationTransformer { private val strictImplicitExport = context.configuration.getBoolean(JSConfigurationKeys.GENERATE_STRICT_IMPLICIT_EXPORT) @@ -38,9 +42,11 @@ class ImplicitlyExportedDeclarationsMarkingLowering(private val context: JsIrBac } private fun IrClass.collectImplicitlyExportedDeclarations(): Set { - return typeParameters - .flatMap { it.superTypes }.toSet() - .flatMap { it.collectImplicitlyExportedDeclarations() }.toSet() + return typeParameters.asSequence() + .flatMap { it.superTypes } + .distinct() + .flatMap { it.collectImplicitlyExportedDeclarations() } + .toSet() } @@ -85,7 +91,7 @@ class ImplicitlyExportedDeclarationsMarkingLowering(private val context: JsIrBac private fun IrDeclaration.markWithJsImplicitExport() { val jsImplicitExportCtor = context.intrinsics.jsImplicitExportAnnotationSymbol.constructors.single() - annotations += JsIrBuilder.buildConstructorCall(jsImplicitExportCtor) + annotations = annotations memoryOptimizedPlus JsIrBuilder.buildConstructorCall(jsImplicitExportCtor) parentClassOrNull?.takeIf { it.shouldBeMarkedWithImplicitExport() }?.markWithJsImplicitExport() } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/InteropCallableReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/InteropCallableReferenceLowering.kt index 59535dd920f..86b2425a9a0 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/InteropCallableReferenceLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/InteropCallableReferenceLowering.kt @@ -32,6 +32,9 @@ import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedMapIndexed +import org.jetbrains.kotlin.utils.memoryOptimizedPlus class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass { @@ -112,16 +115,16 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo override fun lower(irFile: IrFile) { // Regular contextless lambdas are always transformed to function references - val ctorToFreeFunctionMap = mutableMapOf() + val ctorToFreeFunctionMap = hashMapOf() // Regular lambdas with captured variables are transformed to function expressions whenever possible. // However, we don't do that if the lambda captures a variable declared in a loop, at least when variable // declarations are lowered into 'var' statements in JS. See the CapturedVariablesDeclaredInLoops class. // We also don't do that if there is more than one constructor call for a single lambda. - val ctorToFunctionExpressionMap = mutableMapOf() + val ctorToFunctionExpressionMap = hashMapOf() // Suspend lambdas are transformed to factory calls - val ctorToFactoryMap = mutableMapOf() + val ctorToFactoryMap = hashMapOf() val closureUsageAnalyser = ClosureUsageAnalyser() @@ -502,7 +505,7 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo val isSuspendLambda = invokeFun.overriddenSymbols.any { it.owner.isSuspend } fun createOldToNewInvokeParametersMapping(lambdaDeclaration: IrSimpleFunction) = - invokeFun.valueParameters.associateBy({ it.symbol }, { lambdaDeclaration.valueParameters[it.index].symbol }) + invokeFun.valueParameters.associateBy({ it.symbol }) { lambdaDeclaration.valueParameters[it.index].symbol } fun lambdaInnerClasses() = lambdaClass.declarations.filter { it is IrClass || (it is IrSimpleFunction && it.dispatchReceiverParameter == null) } @@ -620,7 +623,7 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo lambdaDeclaration.parent = parent - lambdaDeclaration.valueParameters = superInvokeFun.valueParameters.mapIndexed { id, vp -> + lambdaDeclaration.valueParameters = superInvokeFun.valueParameters.memoryOptimizedMapIndexed { id, vp -> val originalValueParameter = invokeFun.valueParameters[id] vp.copyTo( irFunction = lambdaDeclaration, @@ -652,11 +655,11 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo } } - factoryDeclaration.valueParameters = constructor.valueParameters.map { it.copyTo(factoryDeclaration) } - factoryDeclaration.typeParameters = constructor.typeParameters.map { + factoryDeclaration.valueParameters = constructor.valueParameters.memoryOptimizedMap { it.copyTo(factoryDeclaration) } + factoryDeclaration.typeParameters = constructor.typeParameters.memoryOptimizedMap { it.copyToWithoutSuperTypes(factoryDeclaration).also { tp -> // TODO: make sure it is done well - tp.superTypes += it.superTypes + tp.superTypes = tp.superTypes memoryOptimizedPlus it.superTypes } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt index 7a351ebcba7..7e9ce9b57a4 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt @@ -70,7 +70,7 @@ class JsBridgesConstruction(context: JsIrBackendContext) : BridgesConstruction() + val variables = hashMapOf() - valueParameters = valueParameters.map { param -> + valueParameters = valueParameters.memoryOptimizedMap { param -> param.takeIf { it.defaultValue != null } ?.copyTo(this, isAssignable = true, origin = JsLoweredDeclarationOrigin.JS_SHADOWED_DEFAULT_PARAMETER) ?.also { new -> variables[param] = new } ?: param @@ -112,7 +116,7 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) : context.additionalExportedDeclarations.add(defaultFunStub) if (!originalFun.hasAnnotation(JsAnnotations.jsNameFqn)) { - annotations += originalFun.generateJsNameAnnotationCall() + annotations = annotations memoryOptimizedPlus originalFun.generateJsNameAnnotationCall() } } } @@ -125,7 +129,7 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) : } originalFun.annotations = irrelevantAnnotations - defaultFunStub.annotations += exportAnnotations + defaultFunStub.annotations = defaultFunStub.annotations memoryOptimizedPlus exportAnnotations originalFun.origin = JsLoweredDeclarationOrigin.JS_SHADOWED_EXPORT return listOf(originalFun, defaultFunStub) @@ -135,7 +139,7 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) : val ctx = context val irBuilder = context.createIrBuilder(symbol, UNDEFINED_OFFSET, UNDEFINED_OFFSET) - val variables = mutableMapOf().apply { + val variables = hashMapOf().apply { originalDeclaration.dispatchReceiverParameter?.let { set(it, dispatchReceiverParameter!!) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsInnerClassesSupport.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsInnerClassesSupport.kt index b0df68337dd..3707261b986 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsInnerClassesSupport.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsInnerClassesSupport.kt @@ -11,12 +11,12 @@ import org.jetbrains.kotlin.backend.common.lower.InnerClassesSupport import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.backend.js.JsMapping import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder.SYNTHESIZED_DECLARATION -import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.backend.js.utils.Namer import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor import org.jetbrains.kotlin.ir.builders.declarations.buildField import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.utils.memoryOptimizedPlus import org.jetbrains.kotlin.ir.util.copyTo import org.jetbrains.kotlin.ir.util.copyTypeParametersFrom import org.jetbrains.kotlin.ir.util.defaultType @@ -98,7 +98,7 @@ class JsInnerClassesSupport(mapping: JsMapping, private val irFactory: IrFactory newValueParameters += p.copyTo(newConstructor, index = p.index + 1) } - newConstructor.valueParameters += newValueParameters + newConstructor.valueParameters = newConstructor.valueParameters memoryOptimizedPlus newValueParameters return newConstructor } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsReturnableBlockLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsReturnableBlockLowering.kt index 025c2d9335a..475355cdcd8 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsReturnableBlockLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsReturnableBlockLowering.kt @@ -54,7 +54,7 @@ class JsReturnableBlockLowering(val context: CommonBackendContext) : BodyLowerin class JsReturnableBlockTransformer(val context: CommonBackendContext) : IrElementTransformerVoidWithContext() { private var labelCnt = 0 - private var map = mutableMapOf() + private var map = hashMapOf() private val unitType = context.irBuiltIns.unitType private val unitValue get() = IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, unitType, context.irBuiltIns.unitClass) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveBodilessDeclarationsToSeparatePlace.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveBodilessDeclarationsToSeparatePlace.kt index dbbcb439ddf..764a2c4ee3b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveBodilessDeclarationsToSeparatePlace.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveBodilessDeclarationsToSeparatePlace.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.compilationException -import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.utils.getJsModule import org.jetbrains.kotlin.ir.backend.js.utils.getJsQualifier @@ -15,10 +14,9 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.isChildOf +import org.jetbrains.kotlin.utils.memoryOptimizedPlus private val BODILESS_BUILTIN_CLASSES = listOf( "kotlin.String", @@ -73,10 +71,10 @@ class MoveBodilessDeclarationsToSeparatePlaceLowering(private val context: JsIrB override fun transformFlat(declaration: IrDeclaration): List? { val irFile = declaration.parent as? IrFile ?: return null - val externalPackageFragment by lazy { + val externalPackageFragment by lazy(LazyThreadSafetyMode.NONE) { context.externalPackageFragment.getOrPut(irFile.symbol) { IrFileImpl(fileEntry = irFile.fileEntry, fqName = irFile.fqName, symbol = IrFileSymbolImpl(), module = irFile.module).also { - it.annotations += irFile.annotations + it.annotations = it.annotations memoryOptimizedPlus irFile.annotations } } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveOpenClassesToSeparateFiles.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveOpenClassesToSeparateFiles.kt index 44ebc808a24..e65941c6774 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveOpenClassesToSeparateFiles.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveOpenClassesToSeparateFiles.kt @@ -14,13 +14,14 @@ import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl +import org.jetbrains.kotlin.utils.memoryOptimizedPlus import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat import org.jetbrains.kotlin.ir.util.transformFlat fun moveOpenClassesToSeparateFiles(moduleFragment: IrModuleFragment) { fun createFile(file: IrFile, klass: IrClass): IrFile = IrFileImpl(fileEntry = file.fileEntry, fqName = file.fqName, symbol = IrFileSymbolImpl(), module = file.module).also { - it.annotations += file.annotations + it.annotations = it.annotations memoryOptimizedPlus file.annotations it.declarations += klass klass.parent = it } @@ -55,7 +56,7 @@ fun moveOpenClassesToSeparateFiles(moduleFragment: IrModuleFragment) { return@transformFlat if (openClasses.isEmpty()) null else - listOf(file) + openClasses.map { createFile(file, it) } + openClasses.mapTo(mutableListOf(file)) { createFile(file, it) } } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrivateMembersLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrivateMembersLowering.kt index 6739ff5a83e..e2cda570a51 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrivateMembersLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PrivateMembersLowering.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.isLocal import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.memoryOptimizedPlus private val STATIC_THIS_PARAMETER = object : IrDeclarationOriginImpl("STATIC_THIS_PARAMETER") {} @@ -61,10 +62,11 @@ class PrivateMembersLowering(val context: JsIrBackendContext) : DeclarationTrans it.parent = function.parent } - staticFunction.typeParameters += function.typeParameters.map { it.deepCopyWithSymbols(staticFunction) } + staticFunction.typeParameters = + staticFunction.typeParameters memoryOptimizedPlus function.typeParameters.map { it.deepCopyWithSymbols(staticFunction) } staticFunction.extensionReceiverParameter = function.extensionReceiverParameter?.copyTo(staticFunction) - staticFunction.valueParameters += buildValueParameter(staticFunction) { + staticFunction.valueParameters = staticFunction.valueParameters memoryOptimizedPlus buildValueParameter(staticFunction) { origin = STATIC_THIS_PARAMETER name = Name.identifier("\$this") index = 0 @@ -73,7 +75,7 @@ class PrivateMembersLowering(val context: JsIrBackendContext) : DeclarationTrans function.correspondingStatic = staticFunction - staticFunction.valueParameters += function.valueParameters.map { + staticFunction.valueParameters = staticFunction.valueParameters memoryOptimizedPlus function.valueParameters.map { // TODO better way to avoid copying default value it.copyTo(staticFunction, index = it.index + 1, defaultValue = null) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PropertyReferenceLowering.kt index 47e20222c83..83d86b92920 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PropertyReferenceLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PropertyReferenceLowering.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.memoryOptimizedMap class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyLoweringPass { @@ -144,7 +145,7 @@ class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyL function.parent = factory - val unboundValueParameters = supperAccessor.valueParameters.map { it.copyTo(function) } + val unboundValueParameters = supperAccessor.valueParameters.memoryOptimizedMap { it.copyTo(function) } function.valueParameters = unboundValueParameters val arity = unboundValueParameters.size val total = arity + boundValueParameters.size diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ScriptRemoveReceiverLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ScriptRemoveReceiverLowering.kt index e237b904293..5793af61fb6 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ScriptRemoveReceiverLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ScriptRemoveReceiverLowering.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.FileLoweringPass -import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl @@ -17,6 +16,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl +import org.jetbrains.kotlin.utils.memoryOptimizedFilterNot import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -66,7 +66,7 @@ class ScriptRemoveReceiverLowering(val context: CommonBackendContext) : FileLowe val result = with(super.visitFunctionReference(expression) as IrFunctionReference) { // TODO do we really need to fix type or removing dispatchReceiver is enough? - val arguments = (type as IrSimpleType).arguments.filterNot(::isScript) + val arguments = (type as IrSimpleType).arguments.memoryOptimizedFilterNot(::isScript) val newN = arguments.size - 1 IrFunctionReferenceImpl( @@ -103,7 +103,7 @@ class ScriptRemoveReceiverLowering(val context: CommonBackendContext) : FileLowe val result = with(super.visitPropertyReference(expression) as IrPropertyReference) { // TODO do we really need to fix type or removing dispatchReceiver is enough? - val arguments = (type as IrSimpleType).arguments.filterNot(::isScript) + val arguments = (type as IrSimpleType).arguments.memoryOptimizedFilterNot(::isScript) val newN = arguments.size - 1 IrPropertyReferenceImpl( diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt index 35bd178b35d..1fb6a4a61c6 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt @@ -32,7 +32,8 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.utils.addToStdlib.runIf +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedPlus class SecondaryConstructorLowering(val context: JsIrBackendContext) : DeclarationTransformer { @@ -143,7 +144,9 @@ class SecondaryConstructorLowering(val context: JsIrBackendContext) : Declaratio ThisUsageReplaceTransformer( constructor.symbol, delegate.symbol, - oldValueParameters.zip(delegate.valueParameters).associate { (old, new) -> old.symbol to new.symbol } + oldValueParameters + .zip(delegate.valueParameters) + .associate { (old, new) -> old.symbol to new.symbol } ) ) } @@ -192,8 +195,8 @@ private fun JsIrBackendContext.buildInitDeclaration(constructor: IrConstructor, it.parent = constructor.parent it.copyTypeParametersFrom(constructor.parentAsClass) - it.valueParameters = constructor.valueParameters.map { p -> p.copyTo(it) } - it.valueParameters += JsIrBuilder.buildValueParameter(it, "\$this", constructor.valueParameters.size, type) + it.valueParameters = constructor.valueParameters.memoryOptimizedMap { p -> p.copyTo(it) } + it.valueParameters = it.valueParameters memoryOptimizedPlus JsIrBuilder.buildValueParameter(it, "\$this", constructor.valueParameters.size, type) } } @@ -214,7 +217,7 @@ private fun JsIrBackendContext.buildFactoryDeclaration(constructor: IrConstructo }.also { factory -> factory.parent = constructor.parent factory.copyTypeParametersFrom(constructor.parentAsClass) - factory.valueParameters += constructor.valueParameters.map { p -> p.copyTo(factory) } + factory.valueParameters = factory.valueParameters memoryOptimizedPlus constructor.valueParameters.map { p -> p.copyTo(factory) } factory.annotations = constructor.annotations } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TestGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TestGenerator.kt index dd5aadca0b8..e8266f12b19 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TestGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TestGenerator.kt @@ -27,6 +27,9 @@ import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.findIsInstanceAnd +import org.jetbrains.kotlin.utils.memoryOptimizedMap fun generateJsTests(context: JsIrBackendContext, moduleFragment: IrModuleFragment) { val generator = TestGenerator(context, false) @@ -40,6 +43,7 @@ class TestGenerator(val context: JsCommonBackendContext, val groupByPackage: Boo override fun lower(irFile: IrFile) { // Additional copy to prevent ConcurrentModificationException + if (irFile.declarations.isEmpty()) return ArrayList(irFile.declarations).forEach { if (it is IrClass) { generateTestCalls(it) { if (groupByPackage) suiteForPackage(irFile) else context.createTestContainerFun(irFile) } @@ -49,7 +53,7 @@ class TestGenerator(val context: JsCommonBackendContext, val groupByPackage: Boo } } - private val packageSuites = mutableMapOf() + private val packageSuites = hashMapOf() private fun suiteForPackage(irFile: IrFile) = packageSuites.getOrPut(irFile.fqName) { context.suiteFun!!.createInvocation(irFile.fqName.asString(), context.createTestContainerFun(irFile)) @@ -84,12 +88,12 @@ class TestGenerator(val context: JsCommonBackendContext, val groupByPackage: Boo private fun generateTestCalls(irClass: IrClass, parentFunction: () -> IrSimpleFunction) { if (irClass.modality == Modality.ABSTRACT || irClass.isEffectivelyExternal() || irClass.isExpect) return - val suiteFunBody by lazy { + val suiteFunBody by lazy(LazyThreadSafetyMode.NONE) { context.suiteFun!!.createInvocation(irClass.name.asString(), parentFunction(), irClass.isIgnored) } - val beforeFunctions = irClass.declarations.filterIsInstance().filter { it.isBefore } - val afterFunctions = irClass.declarations.filterIsInstance().filter { it.isAfter } + val beforeFunctions = irClass.declarations.filterIsInstanceAnd { it.isBefore } + val afterFunctions = irClass.declarations.filterIsInstanceAnd { it.isAfter } irClass.declarations.forEach { when { @@ -174,10 +178,7 @@ class TestGenerator(val context: JsCommonBackendContext, val groupByPackage: Boo if (context is JsIrBackendContext && (testFun.returnType as? IrSimpleType)?.classifier == context.intrinsics.promiseClassSymbol) { val finally = context.intrinsics.promiseClassSymbol.owner.declarations - .filterIsInstance() - .first { - it.name.asString() == "finally" - } + .findIsInstanceAnd { it.name.asString() == "finally" }!! val refType = IrSimpleTypeImpl(context.ir.symbols.functionN(0), false, emptyList(), emptyList()) @@ -190,7 +191,7 @@ class TestGenerator(val context: JsCommonBackendContext, val groupByPackage: Boo this.body = context.irFactory.createBlockBody( UNDEFINED_OFFSET, UNDEFINED_OFFSET, - afterFuns.map { + afterFuns.memoryOptimizedMap { JsIrBuilder.buildCall(it.symbol).apply { dispatchReceiver = JsIrBuilder.buildGetValue(classVal.symbol) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EqualityAndComparisonCallsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EqualityAndComparisonCallsTransformer.kt index e51a6ece8cf..d7ae5071d7a 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EqualityAndComparisonCallsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EqualityAndComparisonCallsTransformer.kt @@ -17,13 +17,14 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.atMostOne class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : CallsTransformer { private val intrinsics = context.intrinsics private val irBuiltIns = context.irBuiltIns private val icUtils = context.inlineClassesUtils - private val symbolToTransformer: SymbolToTransformer = mutableMapOf() + private val symbolToTransformer: SymbolToTransformer = hashMapOf() init { symbolToTransformer.run { @@ -178,11 +179,10 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls private fun IrType.findEqualsMethod(): IrSimpleFunction? { val klass = getClass() ?: return null if (klass.isEnumClass && klass.isExternal) return null - return klass.declarations + return klass.declarations.asSequence() .filterIsInstance() .filter { it.isEqualsInheritedFromAny() && !it.isFakeOverriddenFromAny() } - .also { assert(it.size <= 1) } - .singleOrNull() + .atMostOne() } private fun IrFunction.isMethodOfPrimitiveJSType() = diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt index 636a41e82a6..67fb02c3d36 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt @@ -23,7 +23,7 @@ class MethodsOfAnyCallsTransformer(context: JsIrBackendContext) : CallsTransform private val nameToTransformer: Map IrExpression> init { - nameToTransformer = mutableMapOf() + nameToTransformer = hashMapOf() nameToTransformer.run { put(Name.identifier("toString")) { call -> if (shouldReplaceToStringWithRuntimeCall(call)) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt index b706ce71872..674bb265f55 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl -import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.irCall diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/PrimitiveContainerMemberCallTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/PrimitiveContainerMemberCallTransformer.kt index 4db1e50e01f..24299232b77 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/PrimitiveContainerMemberCallTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/PrimitiveContainerMemberCallTransformer.kt @@ -17,7 +17,7 @@ import org.jetbrains.kotlin.ir.util.getSimpleFunction class PrimitiveContainerMemberCallTransformer(private val context: JsIrBackendContext) : CallsTransformer { private val intrinsics = context.intrinsics - private val symbolToTransformer: SymbolToTransformer = mutableMapOf() + private val symbolToTransformer: SymbolToTransformer = hashMapOf() init { symbolToTransformer.run { @@ -82,7 +82,7 @@ private val IrClassSymbol.iterator get() = getSimpleFunction("iterator")!! private val IrClassSymbol.sizeConstructor - get() = owner.declarations.filterIsInstance().first { it.valueParameters.size == 1 }.symbol + get() = owner.declarations.asSequence().filterIsInstance().first { it.valueParameters.size == 1 }.symbol private val IrClassSymbol.lengthProperty get() = getPropertyGetter("length")!! diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/ReflectionCallsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/ReflectionCallsTransformer.kt index e242b0ae20b..66d586af7b2 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/ReflectionCallsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/ReflectionCallsTransformer.kt @@ -30,7 +30,7 @@ class ReflectionCallsTransformer(private val context: JsIrBackendContext) : Call } init { - nameToTransformer = mutableMapOf() + nameToTransformer = hashMapOf() nameToTransformer.run { addWithPredicate( Name.special(Namer.KCALLABLE_GET_NAME), diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/cleanup/CleanupLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/cleanup/CleanupLowering.kt index 35cbc58c991..16a253a1c0f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/cleanup/CleanupLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/cleanup/CleanupLowering.kt @@ -63,20 +63,16 @@ private class CodeCleaner : IrElementVisitorVoid { private fun IrStatementContainer.cleanUpStatements() { var unreachable = false - val newStatements = statements.filter { + statements.removeIf { when { - unreachable -> false - it is IrExpression && it.isPure(true) -> false + unreachable -> true + it is IrExpression && it.isPure(true) -> true else -> { unreachable = it.doesNotReturn() - true + false } } } - - statements.clear() - - statements += newStatements } // Checks if it is safe to assume the statement doesn't return (e.g. throws an exception or loops infinitely) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AbstractSuspendFunctionsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AbstractSuspendFunctionsLowering.kt index b62ace31e08..5b361901332 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AbstractSuspendFunctionsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AbstractSuspendFunctionsLowering.kt @@ -33,6 +33,9 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedMapIndexed +import org.jetbrains.kotlin.utils.memoryOptimizedPlus abstract class AbstractSuspendFunctionsLowering(val context: C) : BodyLoweringPass { @@ -61,7 +64,7 @@ abstract class AbstractSuspendFunctionsLowering(val co protected open fun IrBuilderWithScope.generateDelegatedCall(expectedType: IrType, delegatingCall: IrExpression): IrExpression = delegatingCall - private val builtCoroutines = mutableMapOf() + private val builtCoroutines = hashMapOf() override fun lower(irBody: IrBody, container: IrDeclaration) { if (container is IrSimpleFunction && container.isSuspend) { @@ -153,7 +156,7 @@ abstract class AbstractSuspendFunctionsLowering(val co private fun IrBlockBodyBuilder.createCoroutineInstance(function: IrSimpleFunction, parameters: Collection, coroutine: BuiltCoroutine): IrExpression { val constructor = coroutine.coroutineConstructor - val coroutineTypeArgs = function.typeParameters.map { + val coroutineTypeArgs = function.typeParameters.memoryOptimizedMap { IrSimpleTypeImpl(it.symbol, true, emptyList(), emptyList()) } @@ -207,7 +210,8 @@ abstract class AbstractSuspendFunctionsLowering(val co private val continuationType = continuationClassSymbol.typeWith(function.returnType) // Save all arguments to fields. - private val argumentToPropertiesMap = functionParameters.associateWith { coroutineClass.addField(it.name, it.type, false) } + private val argumentToPropertiesMap = functionParameters + .associateWith { coroutineClass.addField(it.name, it.type, false) } private val coroutineBaseClass = getCoroutineBaseClass(function) private val coroutineBaseClassConstructor = coroutineBaseClass.owner.constructors.single { it.valueParameters.size == 1 } @@ -228,17 +232,20 @@ abstract class AbstractSuspendFunctionsLowering(val co }.apply { parent = function.parent createParameterDeclarations() - typeParameters = function.typeParameters.map { typeParam -> + typeParameters = function.typeParameters.memoryOptimizedMap { typeParam -> // TODO: remap types - typeParam.copyToWithoutSuperTypes(this).apply { superTypes += typeParam.superTypes } + typeParam.copyToWithoutSuperTypes(this).apply { superTypes = superTypes memoryOptimizedPlus typeParam.superTypes } } } private fun buildConstructor(): IrConstructor { if (isSuspendLambda) { - return coroutineClass.declarations.filterIsInstance().single().let { - context.mapping.capturedConstructors[it] ?: it - } + return coroutineClass.declarations + .filterIsInstance() + .single() + .let { + context.mapping.capturedConstructors[it] ?: it + } } return context.irFactory.buildConstructor { @@ -251,11 +258,11 @@ abstract class AbstractSuspendFunctionsLowering(val co parent = coroutineClass coroutineClass.addChild(this) - valueParameters = functionParameters.mapIndexed { index, parameter -> + valueParameters = functionParameters.memoryOptimizedMapIndexed { index, parameter -> parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index, defaultValue = null) } val continuationParameter = coroutineBaseClassConstructor.valueParameters[0] - valueParameters += continuationParameter.copyTo( + valueParameters = valueParameters memoryOptimizedPlus continuationParameter.copyTo( this, DECLARATION_ORIGIN_COROUTINE_IMPL, index = valueParameters.size, startOffset = function.startOffset, @@ -303,12 +310,12 @@ abstract class AbstractSuspendFunctionsLowering(val co parent = coroutineClass coroutineClass.addChild(this) - typeParameters = stateMachineFunction.typeParameters.map { parameter -> + typeParameters = stateMachineFunction.typeParameters.memoryOptimizedMap { parameter -> parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL) - .apply { superTypes += parameter.superTypes } + .apply { superTypes = superTypes memoryOptimizedPlus parameter.superTypes } } - valueParameters = stateMachineFunction.valueParameters.mapIndexed { index, parameter -> + valueParameters = stateMachineFunction.valueParameters.memoryOptimizedMapIndexed { index, parameter -> parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index) } @@ -338,14 +345,14 @@ abstract class AbstractSuspendFunctionsLowering(val co parent = coroutineClass coroutineClass.addChild(this) - typeParameters = function.typeParameters.map { parameter -> + typeParameters = function.typeParameters.memoryOptimizedMap { parameter -> parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL) - .apply { superTypes += parameter.superTypes } + .apply { superTypes = superTypes memoryOptimizedPlus parameter.superTypes } } val unboundArgs = function.valueParameters - val createValueParameters = (unboundArgs + create1CompletionParameter).mapIndexed { index, parameter -> + val createValueParameters = (unboundArgs + create1CompletionParameter).memoryOptimizedMapIndexed { index, parameter -> parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index) } @@ -441,7 +448,7 @@ abstract class AbstractSuspendFunctionsLowering(val co transformInvokeMethod(createMethod, invokeSuspendMethod) } else { - coroutineClass.superTypes += coroutineBaseClass.defaultType + coroutineClass.superTypes = coroutineClass.superTypes memoryOptimizedPlus coroutineBaseClass.defaultType } coroutineClass.addFakeOverrides(context.typeSystem, implementedMembers) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/JsSuspendArityStoreLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/JsSuspendArityStoreLowering.kt index 62868206b4e..1185f7fe0f4 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/JsSuspendArityStoreLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/JsSuspendArityStoreLowering.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.utils.filterIsInstanceAnd class JsSuspendArityStoreLowering(context: JsIrBackendContext) : DeclarationTransformer { @@ -19,11 +20,8 @@ class JsSuspendArityStoreLowering(context: JsIrBackendContext) : DeclarationTran if (declaration !is IrClass) return null declaration.declarations - .filterIsInstance() - .filter { it.isSuspend } - .let { - declaration.suspendArityStore = it - } + .filterIsInstanceAnd { it.isSuspend } + .let { declaration.suspendArityStore = it } return null } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/JsSuspendFunctionsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/JsSuspendFunctionsLowering.kt index 10f486c0210..5f8294bc935 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/JsSuspendFunctionsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/JsSuspendFunctionsLowering.kt @@ -179,7 +179,7 @@ class JsSuspendFunctionsLowering(ctx: JsCommonBackendContext) : AbstractSuspendF val liveLocals = computeLivenessAtSuspensionPoints(functionBody).values.flatten().toSet() - val localToPropertyMap = mutableMapOf() + val localToPropertyMap = hashMapOf() var localCounter = 0 // TODO: optimize by using the same property for different locals. liveLocals.forEach { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt index b1f8ccd1503..1e559bc4e1c 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt @@ -78,7 +78,7 @@ class StateMachineBuilder( private val setSuspendResultValue: (IrExpression) -> IrStatement ) : IrElementVisitorVoid { - private val loopMap = mutableMapOf() + private val loopMap = hashMapOf() private val unit = context.irBuiltIns.unitType private val anyN = context.irBuiltIns.anyNType private val nothing = context.irBuiltIns.nothingType @@ -154,7 +154,7 @@ class StateMachineBuilder( private var currentBlock = entryState.entryBlock private val catchBlockStack = mutableListOf(rootExceptionTrap) - private val tryStateMap = mutableMapOf() + private val tryStateMap = hashMapOf() private val tryLoopStack = mutableListOf() private fun buildExceptionTrapState(): SuspendState { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt index 6316091e7a6..c0f2ef18855 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt @@ -21,6 +21,9 @@ import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedPlus +import org.jetbrains.kotlin.utils.toSmartList @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer { @@ -48,7 +51,7 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer JsInvocation( expression.receiver.accept(this, data), - expression.arguments.map { it.accept(this, data) } + expression.arguments.memoryOptimizedMap { it.accept(this, data) } ) else -> compilationException( diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt index d5f1ccd0781..ac94b239c9f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs import org.jetbrains.kotlin.backend.common.ir.inlineFunction import org.jetbrains.kotlin.backend.common.ir.innerInlinedBlockOrThis -import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope import org.jetbrains.kotlin.ir.backend.js.utils.isTheLastReturnStatementIn @@ -17,9 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol -import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.isAny import org.jetbrains.kotlin.ir.util.constructedClassType import org.jetbrains.kotlin.ir.util.file @@ -27,6 +24,7 @@ import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic +import org.jetbrains.kotlin.utils.toSmartList @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer { @@ -36,7 +34,7 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer) { modules.forEach { module -> module.files.forEach { - it.accept( - backendContext.keeper, - Keeper.KeepData( - classInKeep = false, - classShouldBeKept = false - ) - ) + it.accept(backendContext.keeper, Keeper.KeepData(classInKeep = false, classShouldBeKept = false)) } } modules.forEach { module -> - module.files.forEach { StaticMembersLowering(backendContext).lower(it) } + module.files.forEach { + StaticMembersLowering(backendContext).lower(it) + } } } @@ -213,9 +210,7 @@ class IrModuleToJsTransformer( JsIrModule( data.fragment.safeName, data.fragment.externalModuleName(), - data.files.map { - generateProgramFragment(it, mode.minimizedMemberNames) - } + data.files.map { generateProgramFragment(it, mode.minimizedMemberNames) } ) } ) @@ -289,7 +284,7 @@ class IrModuleToJsTransformer( staticContext.classModels.entries.forEach { (symbol, model) -> result.classes[nameGenerator.getNameForClass(symbol.owner)] = - JsIrIcClassModel(model.superClasses.map { staticContext.getNameForClass(it.owner) }).also { + JsIrIcClassModel(model.superClasses.memoryOptimizedMap { staticContext.getNameForClass(it.owner) }).also { it.preDeclarationBlock.statements += model.preDeclarationBlock.statements it.postDeclarationBlock.statements += model.postDeclarationBlock.statements } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt index c4da4bc1d20..094079c92b4 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt @@ -22,14 +22,16 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.common.isValidES5Identifier import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.toSmartList class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationContext) { private val className = context.getNameForClass(irClass) private val classNameRef = className.makeRef() private val baseClass: IrType? = irClass.superTypes.firstOrNull { !it.classifierOrFail.isInterface } - private val classPrototypeRef by lazy { prototypeOf(classNameRef, context.staticContext) } - private val baseClassRef by lazy { // Lazy in case was not collected by namer during JsClassGenerator construction + private val classPrototypeRef by lazy(LazyThreadSafetyMode.NONE) { prototypeOf(classNameRef, context.staticContext) } + private val baseClassRef by lazy(LazyThreadSafetyMode.NONE) { // Lazy in case was not collected by namer during JsClassGenerator construction if (baseClass != null && !baseClass.isAny()) baseClass.getClassRef(context) else null } private val classBlock = JsCompositeBlock() @@ -337,7 +339,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo JsNameRef(context.getNameForStaticFunction(setMetadataFor)), listOf(ctor, name, metadataConstructor, parent, interfaces, associatedObjectKey, associatedObjects, suspendArity) .dropLastWhile { it == null } - .map { it ?: undefined } + .memoryOptimizedMap { it ?: undefined } ).makeStmt() } @@ -375,7 +377,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo .takeIf { it.size > 1 || it.singleOrNull() != baseClass } ?.mapNotNull { it.asConstructorRef() } ?.takeIf { it.isNotEmpty() } ?: return null - return JsArrayLiteral(listRef) + return JsArrayLiteral(listRef.toSmartList()) } private fun generateSuspendArity(): JsArrayLiteral? { @@ -385,7 +387,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo .distinct() .map { JsIntLiteral(it) } - return JsArrayLiteral(arity).takeIf { arity.isNotEmpty() } + return JsArrayLiteral(arity.toSmartList()).takeIf { arity.isNotEmpty() } } private fun generateAssociatedObjectKey(): JsIntLiteral? { @@ -402,7 +404,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo } } } - } + }.toSmartList() return associatedObjects .takeIf { it.isNotEmpty() } @@ -466,7 +468,7 @@ private fun IrOverridableDeclaration<*>.overridesExternal(): Boolean { private val IrClassifierSymbol.isInterface get() = (owner as? IrClass)?.isInterface == true class JsIrClassModel(val klass: IrClass) { - val superClasses = klass.superTypes.map { it.classifierOrNull as IrClassSymbol } + val superClasses = klass.superTypes.memoryOptimizedMap { it.classifierOrNull as IrClassSymbol } val preDeclarationBlock = JsCompositeBlock() val postDeclarationBlock = JsCompositeBlock() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt index 100fbea37a8..3beb8e2d89e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt @@ -33,7 +33,7 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) { init { val intrinsics = backendContext.intrinsics - transformers = mutableMapOf() + transformers = hashMapOf() transformers.apply { binOp(intrinsics.jsEqeqeq, JsBinaryOperator.REF_EQ) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIrProgramFragment.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIrProgramFragment.kt index c9bc34d4ee8..af5fd3186b5 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIrProgramFragment.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIrProgramFragment.kt @@ -67,7 +67,7 @@ class JsIrModuleHeader( val hasJsExports: Boolean, var associatedModule: JsIrModule? ) { - val externalNames: Set by lazy { nameBindings.keys - definitions } + val externalNames: Set by lazy(LazyThreadSafetyMode.NONE) { nameBindings.keys - definitions } } class JsIrProgram(private var modules: List) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/SwitchOptimizer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/SwitchOptimizer.kt index a292134c840..a64589ffb26 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/SwitchOptimizer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/SwitchOptimizer.kt @@ -154,14 +154,14 @@ class SwitchOptimizer( lastStatement } else { val jsBody = case.body.accept(stmtTransformer, context).asBlock() - var lastStatement = jsBody.statements.lastOrNull() - - if (lastStatement != null) { - lastStatement = lastStatementTransformer { lastStatement!! } - jsBody.statements[jsBody.statements.lastIndex] = lastStatement - } + val lastStatement = jsBody.statements.lastOrNull()?.let { lastStatementTransformer { it } } jsCase.statements += jsBody.statements + + if (lastStatement != null) { + jsCase.statements[jsCase.statements.lastIndex] = lastStatement + } + lastStatement } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt index 8356cf5bac3..7460d8502be 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt @@ -30,6 +30,8 @@ import org.jetbrains.kotlin.js.config.SourceMapNamesPolicy import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedPlus import java.io.FileInputStream import java.io.IOException import java.io.InputStreamReader @@ -85,18 +87,18 @@ fun objectCreate(prototype: JsExpression, context: JsStaticContext) = prototype ) -fun defineProperty(obj: JsExpression, name: String, getter: JsExpression?, setter: JsExpression?, context: JsStaticContext) = - JsInvocation( +fun defineProperty(obj: JsExpression, name: String, getter: JsExpression?, setter: JsExpression?, context: JsStaticContext): JsExpression { + val undefined by lazy(LazyThreadSafetyMode.NONE) { jsUndefined(context, context.backendContext) } + return JsInvocation( context .getNameForStaticFunction(context.backendContext.intrinsics.jsDefinePropertySymbol.owner) .makeRef(), obj, JsStringLiteral(name), - *listOf(getter, setter) - .dropLastWhile { it == null } - .map { it ?: jsUndefined(context, context.backendContext) } - .toTypedArray() + getter ?: undefined, + setter ?: undefined ) +} fun translateFunction(declaration: IrFunction, name: JsName?, context: JsGenerationContext): JsFunction { context.staticContext.backendContext.getJsCodeForFunction(declaration.symbol)?.let { function -> @@ -212,7 +214,7 @@ fun translateCall( JsNameRef(Namer.CALL_FUNCTION, qPrototype) } - return JsInvocation(callRef, jsDispatchReceiver?.let { receiver -> listOf(receiver) + arguments } ?: arguments) + return JsInvocation(callRef, jsDispatchReceiver?.let { receiver -> listOf(receiver) memoryOptimizedPlus arguments } ?: arguments) } val varargParameterIndex = function.varargParameterIndex() @@ -291,7 +293,7 @@ fun translateCall( } } } else { - JsInvocation(ref, listOfNotNull(jsExtensionReceiver) + arguments).pureIfPossible(function, context) + JsInvocation(ref, listOfNotNull(jsExtensionReceiver) memoryOptimizedPlus arguments).pureIfPossible(function, context) } } @@ -392,37 +394,36 @@ fun translateCallArguments( val varargParameterIndex = function.realOverrideTarget.varargParameterIndex() val validWithNullArgs = expression.validWithNullArgs() - val arguments = (0 until size) - .mapTo(ArrayList(size)) { index -> - expression.getValueArgument(index).checkOnNullability( - validWithNullArgs || function.valueParameters[index].isBoxParameter - ) - } - .dropLastWhile { - allowDropTailVoids && - it is IrGetField && - it.symbol.owner.correspondingPropertySymbol == context.staticContext.backendContext.intrinsics.void - } - .map { - it?.accept(transformer, context) - } - .mapIndexed { index, result -> - val isEmptyExternalVararg = validWithNullArgs && - varargParameterIndex == index && - result is JsArrayLiteral && - result.expressions.isEmpty() + val jsUndefined by lazy(LazyThreadSafetyMode.NONE) { jsUndefined(context, context.staticContext.backendContext) } - if (isEmptyExternalVararg && index == size - 1) { - null - } else result + val arguments = (0 until size) + .mapIndexedTo(ArrayList(size)) { i, _ -> + expression.getValueArgument(i).checkOnNullability(validWithNullArgs || function.valueParameters[i].isBoxParameter) + } + .mapIndexed { i, it -> + val jsArgument = when { + allowDropTailVoids && (it == null || it.isVoidGetter(context)) -> null + else -> it?.accept(transformer, context) + } + + val isEmptyExternalVararg = validWithNullArgs && + varargParameterIndex == i && + jsArgument is JsArrayLiteral && + jsArgument.expressions.isEmpty() + + jsArgument.takeIf { !isEmptyExternalVararg || i != size - 1 } } .dropLastWhile { it == null } - .map { it ?: jsUndefined(context, context.staticContext.backendContext) } + .memoryOptimizedMap { it ?: jsUndefined } check(!expression.symbol.isSuspend) { "Suspend functions should be lowered" } return arguments } +private fun IrExpression.isVoidGetter(context: JsGenerationContext): Boolean = this is IrGetField && + symbol.owner.correspondingPropertySymbol == context.staticContext.backendContext.intrinsics.void + + private fun IrExpression?.checkOnNullability(validWithNullArgs: Boolean) = also { if (it == null) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/resolveTemporaryNames.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/resolveTemporaryNames.kt index d298b516592..49c486db201 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/resolveTemporaryNames.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/resolveTemporaryNames.kt @@ -24,7 +24,7 @@ fun JsNode.resolveTemporaryNames() { private fun JsNode.resolveNames(): Map { val rootScope = computeScopes().liftUsedNames() - val replacements = mutableMapOf() + val replacements = hashMapOf() fun traverse(scope: Scope) { // Don't clash with non-temporary names declared in current scope. It's for rare cases like `_` or `Kotlin` names, // since most of local declarations are temporary. @@ -37,7 +37,7 @@ private fun JsNode.resolveNames(): Map { // Outer `foo` resolves first, so when traversing inner scope, we should take it into account. occupiedNames += scope.usedNames.asSequence().mapNotNull { if (!it.isTemporary) it.ident else replacements[it]?.ident } - val nextSuffix = mutableMapOf() + val nextSuffix = hashMapOf() for (temporaryName in scope.declaredNames.asSequence().filter { it.isTemporary }) { var resolvedName = temporaryName.ident var suffix = nextSuffix.getOrDefault(temporaryName.ident, 0) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamer.kt index 0fccae8cefe..d9f2ce0e00e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamer.kt @@ -74,7 +74,7 @@ abstract class IrNamerBase : IrNamer { } } - private val associatedObjectKeyMap = mutableMapOf() + private val associatedObjectKeyMap = hashMapOf() override fun getAssociatedObjectKey(irClass: IrClass): Int? { if (irClass.isAssociatedObjectAnnotatedAnnotation) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsGenerationContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsGenerationContext.kt index fbaa0f49a0d..7c48629d191 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsGenerationContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsGenerationContext.kt @@ -31,11 +31,11 @@ class JsGenerationContext( val currentFunction: IrFunction?, val staticContext: JsStaticContext, val localNames: LocalNameGenerator? = null, - private val nameCache: MutableMap = mutableMapOf(), + private val nameCache: MutableMap = hashMapOf(), private val useBareParameterNames: Boolean = false, ) : IrNamer by staticContext { - private val startLocationCache = mutableMapOf() - private val endLocationCache = mutableMapOf() + private val startLocationCache = hashMapOf() + private val endLocationCache = hashMapOf() fun newFile(file: IrFile, func: IrFunction? = null, localNames: LocalNameGenerator? = null): JsGenerationContext { return JsGenerationContext( diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt index b28f954df4c..59eb173a986 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt @@ -54,7 +54,7 @@ abstract class NameScope { class NameTable( val parent: NameScope = EmptyScope, val reserved: MutableSet = mutableSetOf(), - val mappedNames: MutableMap? = null + val mappedNames: MutableMap? = null, ) : NameScope() { val names = mutableMapOf() @@ -153,13 +153,10 @@ fun calculateJsFunctionSignature(declaration: IrFunction, context: JsIrBackendCo // TODO: Use better hashCode val sanitizedName = sanitizeName(declarationName, withHash = false) - return "${sanitizedName}_$signature$RESERVED_MEMBER_NAME_SUFFIX".intern() + return context.globalInternationService.string("${sanitizedName}_$signature$RESERVED_MEMBER_NAME_SUFFIX") } -fun jsFunctionSignature( - declaration: IrFunction, - context: JsIrBackendContext -): String { +fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): String { require(!declaration.isStaticMethodOfClass) require(declaration.dispatchReceiverParameter != null) diff --git a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt index 827cdd96739..6aeaf4ec167 100644 --- a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt +++ b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt @@ -262,6 +262,7 @@ open class JvmIrCodegenFactory( ) irLinker.postProcess(inOrAfterLinkageStep = true) + irLinker.clear() stubGenerator.unboundSymbolGeneration = true diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt index 41a1227aea8..3ce363c74e4 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt @@ -75,6 +75,7 @@ fun compileToLoweredIr( irLinker.postProcess(inOrAfterLinkageStep = true) irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process") + irLinker.clear() for (module in allModules) for (file in module.files) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrDescriptorBasedFunctionFactory.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrDescriptorBasedFunctionFactory.kt index be00fc17e6c..7f9ef39d5cf 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrDescriptorBasedFunctionFactory.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrDescriptorBasedFunctionFactory.kt @@ -29,6 +29,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.memoryOptimizedMap @OptIn(ObsoleteDescriptorBasedAPI::class) abstract class IrAbstractDescriptorBasedFunctionFactory { @@ -332,7 +334,7 @@ class IrDescriptorBasedFunctionFactory( classifier = symbolTable.referenceClassifier(kotlinType.constructor.declarationDescriptor ?: error("No classifier for type $kotlinType")) nullability = SimpleTypeNullability.fromHasQuestionMark(kotlinType.isMarkedNullable) - arguments = kotlinType.arguments.map { + arguments = kotlinType.arguments.memoryOptimizedMap { if (it.isStarProjection) IrStarProjectionImpl else makeTypeProjection(toIrType(it.type), it.projectionKind) } @@ -352,10 +354,11 @@ class IrDescriptorBasedFunctionFactory( private fun IrClass.addFakeOverrides() { val fakeOverrideDescriptors = - descriptor.unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.CALLABLES).asSequence() - .filterIsInstance() - .filter { it.kind === CallableMemberDescriptor.Kind.FAKE_OVERRIDE && it.dispatchReceiverParameter != null } - .filter { !DescriptorVisibilities.isPrivate(it.visibility) && it.visibility != DescriptorVisibilities.INVISIBLE_FAKE } + descriptor.unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.CALLABLES) + .filterIsInstanceAnd { + it.kind === CallableMemberDescriptor.Kind.FAKE_OVERRIDE && it.dispatchReceiverParameter != null && + !DescriptorVisibilities.isPrivate(it.visibility) && it.visibility != DescriptorVisibilities.INVISIBLE_FAKE + } fun createFakeOverrideFunction(descriptor: FunctionDescriptor, property: IrPropertySymbol?): IrSimpleFunction { val returnType = descriptor.returnType?.let { toIrType(it) } ?: error("No return type for $descriptor") @@ -369,11 +372,11 @@ class IrDescriptorBasedFunctionFactory( } newFunction.parent = this - newFunction.overriddenSymbols = descriptor.overriddenDescriptors.map { symbolTable.referenceSimpleFunction(it.original) } + newFunction.overriddenSymbols = descriptor.overriddenDescriptors.memoryOptimizedMap { symbolTable.referenceSimpleFunction(it.original) } newFunction.dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.let { newFunction.createValueParameter(it) } newFunction.extensionReceiverParameter = descriptor.extensionReceiverParameter?.let { newFunction.createValueParameter(it) } newFunction.contextReceiverParametersCount = descriptor.contextReceiverParameters.size - newFunction.valueParameters = descriptor.valueParameters.map { newFunction.createValueParameter(it) } + newFunction.valueParameters = descriptor.valueParameters.memoryOptimizedMap { newFunction.createValueParameter(it) } newFunction.correspondingPropertySymbol = property newFunction.annotations = descriptor.annotations.mapNotNull( typeTranslator.constantValueGenerator::generateAnnotationConstructorCall diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt index d65ce867569..7818692caed 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationGenerator.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.util.withScope +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt index 322542d172e..6ecd7d91a67 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBasedDescriptors.kt @@ -31,6 +31,10 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.error.ErrorUtils +import org.jetbrains.kotlin.utils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.findIsInstanceAnd +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedMapIndexed /* Descriptors that serve purely as a view into IR structures. Created each time at the borderline between IR-based and descriptor-based code (such as inliner). @@ -41,7 +45,7 @@ import org.jetbrains.kotlin.types.error.ErrorUtils abstract class IrBasedDeclarationDescriptor(val owner: T) : DeclarationDescriptor { override val annotations: Annotations by lazy { val ownerAnnotations = (owner as? IrAnnotationContainer)?.annotations ?: return@lazy Annotations.EMPTY - Annotations.create(ownerAnnotations.map { it.toAnnotationDescriptor() }) + Annotations.create(ownerAnnotations.memoryOptimizedMap { it.toAnnotationDescriptor() }) } private fun IrConstructorCall.toAnnotationDescriptor(): AnnotationDescriptor { @@ -60,7 +64,7 @@ abstract class IrBasedDeclarationDescriptor(val owner: T) : D } return AnnotationDescriptorImpl( annotationClass.defaultType.toIrBasedKotlinType(), - symbol.owner.valueParameters.map { it.name to getValueArgument(it.index) } + symbol.owner.valueParameters.memoryOptimizedMap { it.name to getValueArgument(it.index) } .filter { it.second != null } .associate { it.first to it.second!!.toConstantValue() }, source @@ -83,7 +87,7 @@ abstract class IrBasedDeclarationDescriptor(val owner: T) : D } is IrVararg -> { - val elements = elements.map { if (it is IrSpreadElement) error("$it is not expected") else it.toConstantValue() } + val elements = elements.memoryOptimizedMap { if (it is IrSpreadElement) error("$it is not expected") else it.toConstantValue() } ArrayValue(elements) { moduleDescriptor -> // TODO: substitute. moduleDescriptor.builtIns.array.defaultType @@ -263,7 +267,7 @@ open class IrBasedTypeParameterDescriptor(owner: IrTypeParameter) : TypeParamete override fun getVariance() = owner.variance - override fun getUpperBounds() = owner.superTypes.map { it.toIrBasedKotlinType() } + override fun getUpperBounds() = owner.superTypes.memoryOptimizedMap { it.toIrBasedKotlinType() } private val _typeConstructor: TypeConstructor by lazy { object : AbstractTypeConstructor(LockBasedStorageManager.NO_LOCKS) { @@ -397,7 +401,7 @@ fun IrLocalDelegatedProperty.toIrBasedDescriptor() = IrBasedVariableDescriptorWi open class IrBasedSimpleFunctionDescriptor(owner: IrSimpleFunction) : SimpleFunctionDescriptor, DescriptorWithContainerSource, IrBasedCallableDescriptor(owner) { - override fun getOverriddenDescriptors(): List = owner.overriddenSymbols.map { it.owner.toIrBasedDescriptor() } + override fun getOverriddenDescriptors(): List = owner.overriddenSymbols.memoryOptimizedMap { it.owner.toIrBasedDescriptor() } override fun getModality() = owner.modality override fun getName() = owner.name @@ -409,7 +413,7 @@ open class IrBasedSimpleFunctionDescriptor(owner: IrSimpleFunction) : SimpleFunc } override fun getExtensionReceiverParameter() = owner.extensionReceiverParameter?.toIrBasedDescriptor() as? ReceiverParameterDescriptor - override fun getTypeParameters() = owner.typeParameters.map { it.toIrBasedDescriptor() } + override fun getTypeParameters() = owner.typeParameters.memoryOptimizedMap { it.toIrBasedDescriptor() } override fun getValueParameters() = owner.valueParameters .asSequence() .mapNotNull { it.toIrBasedDescriptor() as? ValueParameterDescriptor } @@ -486,7 +490,7 @@ open class IrBasedClassConstructorDescriptor(owner: IrConstructor) : ClassConstr } override fun getTypeParameters() = - (owner.constructedClass.typeParameters + owner.typeParameters).map { it.toIrBasedDescriptor() } + (owner.constructedClass.typeParameters + owner.typeParameters).memoryOptimizedMap { it.toIrBasedDescriptor() } override fun getValueParameters() = owner.valueParameters.asSequence() .mapNotNull { it.toIrBasedDescriptor() as? ValueParameterDescriptor } @@ -594,7 +598,7 @@ open class IrBasedClassDescriptor(owner: IrClass) : ClassDescriptor, IrBasedDecl override fun getSource() = owner.source override fun getConstructors() = - owner.declarations.filterIsInstance().filter { !it.origin.isSynthetic }.map { it.toIrBasedDescriptor() }.toList() + owner.declarations.filterIsInstanceAnd { !it.origin.isSynthetic }.memoryOptimizedMap { it.toIrBasedDescriptor() } private val _defaultType: SimpleType by lazy { TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope, KotlinTypeFactory.EMPTY_REFINED_TYPE_FACTORY) @@ -607,7 +611,7 @@ open class IrBasedClassDescriptor(owner: IrClass) : ClassDescriptor, IrBasedDecl override fun getModality() = owner.modality override fun getCompanionObjectDescriptor() = - owner.declarations.filterIsInstance().firstOrNull { it.isCompanion }?.toIrBasedDescriptor() + owner.declarations.findIsInstanceAnd { it.isCompanion }?.toIrBasedDescriptor() override fun getVisibility() = owner.visibility @@ -630,7 +634,7 @@ open class IrBasedClassDescriptor(owner: IrClass) : ClassDescriptor, IrBasedDecl override fun getUnsubstitutedPrimaryConstructor() = owner.declarations.filterIsInstance().singleOrNull { it.isPrimary }?.toIrBasedDescriptor() - override fun getDeclaredTypeParameters() = owner.typeParameters.map { it.toIrBasedDescriptor() } + override fun getDeclaredTypeParameters() = owner.typeParameters.memoryOptimizedMap { it.toIrBasedDescriptor() } override fun getSealedSubclasses(): Collection { TODO("not implemented") @@ -652,7 +656,7 @@ open class IrBasedClassDescriptor(owner: IrClass) : ClassDescriptor, IrBasedDecl LazyTypeConstructor( this, ::collectTypeParameters, - { owner.superTypes.map { it.toIrBasedKotlinType() } }, + { owner.superTypes.memoryOptimizedMap { it.toIrBasedKotlinType() } }, LockBasedStorageManager.NO_LOCKS ) } @@ -780,7 +784,7 @@ open class IrBasedEnumEntryDescriptor(owner: IrEnumEntry) : ClassDescriptor, IrB ClassTypeConstructorImpl( this, emptyList(), - getCorrespondingClass().superTypes.map { it.toIrBasedKotlinType() }, + getCorrespondingClass().superTypes.memoryOptimizedMap { it.toIrBasedKotlinType() }, LockBasedStorageManager.NO_LOCKS ) } @@ -926,7 +930,7 @@ abstract class IrBasedPropertyAccessorDescriptor(owner: IrSimpleFunction) : IrBa override fun getOriginal(): IrBasedPropertyAccessorDescriptor = this - override fun getOverriddenDescriptors() = super.getOverriddenDescriptors().map { it as PropertyAccessorDescriptor } + override fun getOverriddenDescriptors() = super.getOverriddenDescriptors().memoryOptimizedMap { it as PropertyAccessorDescriptor } override fun getCorrespondingProperty(): PropertyDescriptor = owner.correspondingPropertySymbol!!.owner.toIrBasedDescriptor() @@ -934,7 +938,7 @@ abstract class IrBasedPropertyAccessorDescriptor(owner: IrSimpleFunction) : IrBa } open class IrBasedPropertyGetterDescriptor(owner: IrSimpleFunction) : IrBasedPropertyAccessorDescriptor(owner), PropertyGetterDescriptor { - override fun getOverriddenDescriptors() = super.getOverriddenDescriptors().map { it as PropertyGetterDescriptor } + override fun getOverriddenDescriptors() = super.getOverriddenDescriptors().memoryOptimizedMap { it as PropertyGetterDescriptor } override fun getOriginal(): IrBasedPropertyGetterDescriptor = this @@ -943,7 +947,7 @@ open class IrBasedPropertyGetterDescriptor(owner: IrSimpleFunction) : IrBasedPro } open class IrBasedPropertySetterDescriptor(owner: IrSimpleFunction) : IrBasedPropertyAccessorDescriptor(owner), PropertySetterDescriptor { - override fun getOverriddenDescriptors() = super.getOverriddenDescriptors().map { it as PropertySetterDescriptor } + override fun getOverriddenDescriptors() = super.getOverriddenDescriptors().memoryOptimizedMap { it as PropertySetterDescriptor } override fun getOriginal(): IrBasedPropertySetterDescriptor = this @@ -978,7 +982,7 @@ open class IrBasedTypeAliasDescriptor(owner: IrTypeAlias) : IrBasedDeclarationDe override fun isInner(): Boolean = false - override fun getDeclaredTypeParameters(): List = owner.typeParameters.map { it.toIrBasedDescriptor() } + override fun getDeclaredTypeParameters(): List = owner.typeParameters.memoryOptimizedMap { it.toIrBasedDescriptor() } override fun getName(): Name = owner.name @@ -1172,7 +1176,7 @@ private fun makeKotlinType( classifier.toIrBasedDescriptorIfPossible().defaultType.makeNullableAsSpecified(hasQuestionMark) is IrClassSymbol -> { val classDescriptor = classifier.toIrBasedDescriptorIfPossible() - val kotlinTypeArguments = arguments.mapIndexed { index, it -> + val kotlinTypeArguments = arguments.memoryOptimizedMapIndexed { index, it -> when (it) { is IrTypeProjection -> TypeProjectionImpl(it.variance, it.type.toIrBasedKotlinType()) is IrStarProjection -> StarProjectionImpl(classDescriptor.typeConstructor.parameters[index]) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockBodyImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockBodyImpl.kt index 8867c2d1288..28447261756 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockBodyImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrBlockBodyImpl.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.IrFactory import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.expressions.IrBlockBody +import org.jetbrains.kotlin.utils.SmartList class IrBlockBodyImpl( override val startOffset: Int, @@ -33,7 +34,7 @@ class IrBlockBodyImpl( this.initializer() } - override val statements: MutableList = ArrayList() + override val statements: MutableList = ArrayList(2) override val factory: IrFactory get() = IrFactoryImpl diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt index 903fba993dc..f3d9e7b8579 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt @@ -25,6 +25,8 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.util.initializeParameterArguments +import org.jetbrains.kotlin.ir.util.initializeTypeArguments import org.jetbrains.kotlin.ir.util.render class IrCallImpl( @@ -38,9 +40,9 @@ class IrCallImpl( override var superQualifierSymbol: IrClassSymbol? = null ) : IrCall() { - override val typeArguments: Array = arrayOfNulls(typeArgumentsCount) + override val typeArguments: Array = initializeTypeArguments(typeArgumentsCount) - override val valueArguments: Array = arrayOfNulls(valueArgumentsCount) + override val valueArguments: Array = initializeParameterArguments(valueArgumentsCount) override var contextReceiversCount = 0 diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrConstructorCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrConstructorCallImpl.kt index 182b6a2b55a..8d79bd14bf5 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrConstructorCallImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrConstructorCallImpl.kt @@ -13,6 +13,8 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.util.initializeParameterArguments +import org.jetbrains.kotlin.ir.util.initializeTypeArguments import org.jetbrains.kotlin.ir.util.parentAsClass class IrConstructorCallImpl( @@ -26,9 +28,9 @@ class IrConstructorCallImpl( override var origin: IrStatementOrigin? = null, override var source: SourceElement = SourceElement.NO_SOURCE ) : IrConstructorCall() { - override val typeArguments: Array = arrayOfNulls(typeArgumentsCount) + override val typeArguments: Array = initializeTypeArguments(typeArgumentsCount) - override val valueArguments: Array = arrayOfNulls(valueArgumentsCount) + override val valueArguments: Array = initializeParameterArguments(valueArgumentsCount) override var contextReceiversCount = 0 diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDelegatingConstructorCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDelegatingConstructorCallImpl.kt index ec5623fa2f0..be1f0b2fc18 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDelegatingConstructorCallImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrDelegatingConstructorCallImpl.kt @@ -24,6 +24,8 @@ import org.jetbrains.kotlin.ir.expressions.typeParametersCount import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.allTypeParameters +import org.jetbrains.kotlin.ir.util.initializeParameterArguments +import org.jetbrains.kotlin.ir.util.initializeTypeArguments class IrDelegatingConstructorCallImpl( override val startOffset: Int, @@ -35,9 +37,9 @@ class IrDelegatingConstructorCallImpl( ) : IrDelegatingConstructorCall() { override var origin: IrStatementOrigin? = null - override val typeArguments: Array = arrayOfNulls(typeArgumentsCount) + override val typeArguments: Array = initializeTypeArguments(typeArgumentsCount) - override val valueArguments: Array = arrayOfNulls(valueArgumentsCount) + override val valueArguments: Array = initializeParameterArguments(valueArgumentsCount) override var contextReceiversCount = 0 diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEnumConstructorCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEnumConstructorCallImpl.kt index 91e047a3771..b37a2df7c19 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEnumConstructorCallImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrEnumConstructorCallImpl.kt @@ -22,6 +22,8 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.util.initializeParameterArguments +import org.jetbrains.kotlin.ir.util.initializeTypeArguments class IrEnumConstructorCallImpl( override val startOffset: Int, @@ -33,9 +35,9 @@ class IrEnumConstructorCallImpl( ) : IrEnumConstructorCall() { override var origin: IrStatementOrigin? = null - override val typeArguments: Array = arrayOfNulls(typeArgumentsCount) + override val typeArguments: Array = initializeTypeArguments(typeArgumentsCount) - override val valueArguments: Array = arrayOfNulls(valueArgumentsCount) + override val valueArguments: Array = initializeParameterArguments(valueArgumentsCount) override var contextReceiversCount = 0 diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt index c84cec8593c..fea6daf53ee 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt @@ -22,6 +22,8 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionReference import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.util.initializeParameterArguments +import org.jetbrains.kotlin.ir.util.initializeTypeArguments class IrFunctionReferenceImpl( override val startOffset: Int, @@ -33,9 +35,9 @@ class IrFunctionReferenceImpl( override var reflectionTarget: IrFunctionSymbol? = symbol, override var origin: IrStatementOrigin? = null, ) : IrFunctionReference() { - override val typeArguments: Array = arrayOfNulls(typeArgumentsCount) + override val typeArguments: Array = initializeTypeArguments(typeArgumentsCount) - override val valueArguments: Array = arrayOfNulls(valueArgumentsCount) + override val valueArguments: Array = initializeParameterArguments(valueArgumentsCount) companion object { @ObsoleteDescriptorBasedAPI diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLocalDelegatedPropertyReferenceImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLocalDelegatedPropertyReferenceImpl.kt index 1758c97c3ff..7314a728bf6 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLocalDelegatedPropertyReferenceImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrLocalDelegatedPropertyReferenceImpl.kt @@ -23,6 +23,8 @@ import org.jetbrains.kotlin.ir.symbols.IrLocalDelegatedPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.util.initializeParameterArguments +import org.jetbrains.kotlin.ir.util.initializeTypeArguments class IrLocalDelegatedPropertyReferenceImpl( override val startOffset: Int, @@ -34,14 +36,7 @@ class IrLocalDelegatedPropertyReferenceImpl( override var setter: IrSimpleFunctionSymbol?, override var origin: IrStatementOrigin? = null, ) : IrLocalDelegatedPropertyReference() { - override val typeArguments: Array - get() = EMPTY_TYPE_ARGUMENTS + override val typeArguments: Array = initializeTypeArguments(0) - override val valueArguments: Array - get() = EMPTY_VALUE_ARGUMENTS - - companion object { - private val EMPTY_TYPE_ARGUMENTS = emptyArray() - private val EMPTY_VALUE_ARGUMENTS = emptyArray() - } + override val valueArguments: Array = initializeParameterArguments(0) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt index 7475d364b0b..6208aff3fad 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt @@ -23,6 +23,8 @@ import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.util.initializeParameterArguments +import org.jetbrains.kotlin.ir.util.initializeTypeArguments class IrPropertyReferenceImpl( override val startOffset: Int, @@ -35,12 +37,7 @@ class IrPropertyReferenceImpl( override var setter: IrSimpleFunctionSymbol?, override var origin: IrStatementOrigin? = null, ) : IrPropertyReference() { - override val typeArguments: Array = arrayOfNulls(typeArgumentsCount) + override val typeArguments: Array = initializeTypeArguments(typeArgumentsCount) - override val valueArguments: Array - get() = EMPTY_VALUE_ARGUMENTS - - companion object { - private val EMPTY_VALUE_ARGUMENTS = emptyArray() - } + override val valueArguments: Array = initializeParameterArguments(0) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrStringConcatenationImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrStringConcatenationImpl.kt index ff987cb7a45..3e87e4bda27 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrStringConcatenationImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrStringConcatenationImpl.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.utils.SmartList class IrStringConcatenationImpl( override val startOffset: Int, @@ -34,5 +35,5 @@ class IrStringConcatenationImpl( this.arguments.addAll(arguments) } - override val arguments: MutableList = ArrayList() + override val arguments: MutableList = ArrayList(2) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt index de93b654319..fb8e228c539 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.utils.SmartList class IrWhenImpl( override val startOffset: Int, @@ -35,7 +36,7 @@ class IrWhenImpl( this.branches.addAll(branches) } - override val branches: MutableList = ArrayList() + override val branches: MutableList = ArrayList(2) } open class IrBranchImpl( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt index 216cea8e6df..134e14d4400 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/CopyIrTreeWithSymbolsForFakeOverrides.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.types.impl.buildSimpleType import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.utils.memoryOptimizedMap // This is basically modelled after the inliner copier. class CopyIrTreeWithSymbolsForFakeOverrides( @@ -51,7 +52,7 @@ class CopyIrTreeWithSymbolsForFakeOverrides( override fun leaveScope() {} private fun remapTypeArguments(arguments: List) = - arguments.map { argument -> + arguments.memoryOptimizedMap { argument -> (argument as? IrTypeProjection)?.let { makeTypeProjection(remapType(it.type), it.variance) } ?: argument } @@ -66,7 +67,7 @@ class CopyIrTreeWithSymbolsForFakeOverrides( kotlinType = null classifier = symbolRemapper.getReferencedClassifier(type.classifier) arguments = remapTypeArguments(type.arguments) - annotations = type.annotations.map { it.transform(copier, null) as IrConstructorCall } + annotations = type.annotations.memoryOptimizedMap { it.transform(copier, null) as IrConstructorCall } } } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt index d30bbff1bf7..887149a7c5c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt @@ -17,6 +17,9 @@ import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.* import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.TypeCheckerState import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedMapNotNull abstract class FakeOverrideBuilderStrategy( private val friendModules: Map>, @@ -128,13 +131,13 @@ class IrOverridingUtil( set(value) { when (this) { is IrSimpleFunction -> this.overriddenSymbols = - value.map { it as? IrSimpleFunctionSymbol ?: error("Unexpected function overridden symbol: $it") } + value.memoryOptimizedMap { it as? IrSimpleFunctionSymbol ?: error("Unexpected function overridden symbol: $it") } is IrProperty -> { - val overriddenProperties = value.map { it as? IrPropertySymbol ?: error("Unexpected property overridden symbol: $it") } + val overriddenProperties = value.memoryOptimizedMap { it as? IrPropertySymbol ?: error("Unexpected property overridden symbol: $it") } val getter = this.getter ?: error("Property has no getter: ${render()}") - getter.overriddenSymbols = overriddenProperties.map { it.owner.getter!!.symbol } + getter.overriddenSymbols = overriddenProperties.memoryOptimizedMap { it.owner.getter!!.symbol } this.setter?.let { setter -> - setter.overriddenSymbols = overriddenProperties.mapNotNull { it.owner.setter?.symbol } + setter.overriddenSymbols = overriddenProperties.memoryOptimizedMapNotNull { it.owner.setter?.symbol } } this.overriddenSymbols = overriddenProperties } @@ -184,9 +187,8 @@ class IrOverridingUtil( val unoverriddenSuperMembers = clazz.superTypes.flatMap { superType -> val superClass = superType.getClass() ?: error("Unexpected super type: $superType") superClass.declarations - .filterIsInstance() - .filterNot { - it in overriddenMembers || it.symbol in ignoredParentSymbols || it.isStaticMember || DescriptorVisibilities.isPrivate(it.visibility) + .filterIsInstanceAnd { + it !in overriddenMembers && it.symbol !in ignoredParentSymbols && !it.isStaticMember && !DescriptorVisibilities.isPrivate(it.visibility) } .map { overriddenMember -> val fakeOverride = fakeOverrideBuilder.fakeOverrideMember(superType, overriddenMember, clazz) @@ -254,7 +256,7 @@ class IrOverridingUtil( } } - fromCurrent.overriddenSymbols = overridden.map { it.original.symbol } + fromCurrent.overriddenSymbols = overridden.memoryOptimizedMap { it.original.symbol } return bound } @@ -427,7 +429,7 @@ class IrOverridingUtil( } } - fakeOverride.overriddenSymbols = effectiveOverridden.map { it.original.symbol } + fakeOverride.overriddenSymbols = effectiveOverridden.memoryOptimizedMap { it.original.symbol } require( fakeOverride.overriddenSymbols.isNotEmpty() diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerUtils.kt index a7488a1e331..c2285aa5175 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeCheckerUtils.kt @@ -5,9 +5,9 @@ package org.jetbrains.kotlin.ir.types -import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.declarations.IrTypeParameter import org.jetbrains.kotlin.types.model.TypeConstructorMarker +import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize class IrTypeSystemContextWithAdditionalAxioms( typeSystem: IrTypeSystemContext, @@ -22,7 +22,9 @@ class IrTypeSystemContextWithAdditionalAxioms( private val firstTypeParameterConstructors = firstParameters.map { it.symbol } private val secondTypeParameterConstructors = secondParameters.map { it.symbol } - private val matchingTypeConstructors = firstTypeParameterConstructors.zip(secondTypeParameterConstructors).toMap() + private val matchingTypeConstructors = firstTypeParameterConstructors + .zip(secondTypeParameterConstructors) + .toMap(newHashMapWithExpectedSize(firstTypeParameterConstructors.size)) override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean { if (super.areEqualTypeConstructors(c1, c2)) return true diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt index 0980e228cc8..c56b925edb2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt @@ -8,9 +8,10 @@ package org.jetbrains.kotlin.ir.types import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.impl.* -import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker +import org.jetbrains.kotlin.utils.memoryOptimizedMap abstract class AbstractIrTypeSubstitutor(private val irBuiltIns: IrBuiltIns) : TypeSubstitutorMarker { @@ -39,7 +40,7 @@ abstract class AbstractIrTypeSubstitutor(private val irBuiltIns: IrBuiltIns) : T return when (irType) { is IrSimpleType -> with(irType.toBuilder()) { - arguments = irType.arguments.map { substituteTypeArgument(it) } + arguments = irType.arguments.memoryOptimizedMap { substituteTypeArgument(it) } buildSimpleType() } is IrDynamicType, diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index 3468808e53a..ffc88ed9bc6 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -32,6 +32,9 @@ import org.jetbrains.kotlin.ir.types.makeNotNull as irMakeNotNull import org.jetbrains.kotlin.ir.types.makeNullable as irMakeNullable import org.jetbrains.kotlin.ir.types.isMarkedNullable as irIsMarkedNullable import org.jetbrains.kotlin.types.model.* +import org.jetbrains.kotlin.utils.memoryOptimizedFilterIsInstance +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.compactIfPossible import org.jetbrains.kotlin.ir.types.isPrimitiveType as irTypePredicates_isPrimitiveType interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesContext, TypeSystemCommonBackendContext { @@ -268,7 +271,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon val newArguments = ArrayList(typeArguments.size) - val typeSubstitutor = IrCapturedTypeSubstitutor(typeParameters.map { it.symbol }, typeArguments, capturedTypes, irBuiltIns) + val typeSubstitutor = IrCapturedTypeSubstitutor(typeParameters.memoryOptimizedMap { it.symbol }, typeArguments, capturedTypes, irBuiltIns) for (index in typeArguments.indices) { val oldArgument = typeArguments[index] @@ -341,12 +344,12 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon isExtensionFunction: Boolean, attributes: List? ): SimpleTypeMarker { - val ourAnnotations = attributes?.filterIsInstance() + val ourAnnotations = attributes?.memoryOptimizedFilterIsInstance() require(ourAnnotations?.size == attributes?.size) return IrSimpleTypeImpl( constructor as IrClassifierSymbol, if (nullable) SimpleTypeNullability.MARKED_NULLABLE else SimpleTypeNullability.DEFINITELY_NOT_NULL, - arguments.map { it as IrTypeArgument }, + arguments.memoryOptimizedMap { it as IrTypeArgument }, ourAnnotations ?: emptyList() ) } @@ -410,7 +413,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun KotlinTypeMarker.getAttributes(): List { require(this is IrType) - return this.annotations.map { object : AnnotationMarker, IrElement by it {} } + return this.annotations.memoryOptimizedMap { object : AnnotationMarker, IrElement by it {} } } override fun KotlinTypeMarker.hasCustomAttributes(): Boolean { @@ -488,7 +491,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon getUnsubstitutedUnderlyingType()?.let { type -> // Taking only the type parameters of the class (and not its outer classes) is OK since inner classes are always top level IrTypeSubstitutor( - (this as IrType).getClass()!!.typeParameters.map { it.symbol }, + (this as IrType).getClass()!!.typeParameters.memoryOptimizedMap { it.symbol }, (this as? IrSimpleType)?.arguments.orEmpty(), irBuiltIns ).substitute(type as IrType) @@ -572,7 +575,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun substitutionSupertypePolicy(type: SimpleTypeMarker): TypeCheckerState.SupertypesPolicy { require(type is IrSimpleType) - val parameters = extractTypeParameters((type.classifier as IrClassSymbol).owner).map { it.symbol } + val parameters = extractTypeParameters((type.classifier as IrClassSymbol).owner).memoryOptimizedMap { it.symbol } val typeSubstitutor = IrTypeSubstitutor(parameters, type.arguments, irBuiltIns) return object : TypeCheckerState.SupertypesPolicy.DoCustomTransform() { @@ -610,7 +613,7 @@ fun extractTypeParameters(parent: IrDeclarationParent): List { else -> null } } - return result + return result.compactIfPossible() } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt index 34e2aa85058..fbcacb85743 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.symbols.FqNameEqualityChecker import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.utils.compactIfPossible import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.Variance @@ -110,8 +111,8 @@ fun IrSimpleTypeBuilder.buildSimpleType() = kotlinType, classifier ?: throw AssertionError("Classifier not provided"), nullability, - arguments, - annotations, + arguments.compactIfPossible(), + annotations.compactIfPossible(), abbreviation ) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt index 08da69ac17a..0c0907a1c71 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt @@ -20,6 +20,10 @@ import org.jetbrains.kotlin.ir.types.impl.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.utils.memoryOptimizedFilterNot +import org.jetbrains.kotlin.utils.memoryOptimizedMap +import org.jetbrains.kotlin.utils.memoryOptimizedMapIndexed +import org.jetbrains.kotlin.utils.memoryOptimizedPlus private fun IrType.withNullability(newNullability: Boolean): IrType = when (this) { @@ -50,10 +54,10 @@ fun IrType.addAnnotations(newAnnotations: List): IrType = else when (this) { is IrSimpleType -> toBuilder().apply { - annotations = annotations + newAnnotations + annotations = annotations memoryOptimizedPlus newAnnotations }.buildSimpleType() is IrDynamicType -> - IrDynamicTypeImpl(null, annotations + newAnnotations, Variance.INVARIANT) + IrDynamicTypeImpl(null, annotations memoryOptimizedPlus newAnnotations, Variance.INVARIANT) else -> this } @@ -62,10 +66,10 @@ fun IrType.removeAnnotations(predicate: (IrConstructorCall) -> Boolean): IrType when (this) { is IrSimpleType -> toBuilder().apply { - annotations = annotations.filterNot(predicate) + annotations = annotations.memoryOptimizedFilterNot(predicate) }.buildSimpleType() is IrDynamicType -> - IrDynamicTypeImpl(null, annotations.filterNot(predicate), Variance.INVARIANT) + IrDynamicTypeImpl(null, annotations.memoryOptimizedFilterNot(predicate), Variance.INVARIANT) else -> this } @@ -146,7 +150,7 @@ private fun makeKotlinType( arguments: List, hasQuestionMark: Boolean ): SimpleType { - val kotlinTypeArguments = arguments.mapIndexed { index, it -> + val kotlinTypeArguments = arguments.memoryOptimizedMapIndexed { index, it -> when (it) { is IrTypeProjection -> TypeProjectionImpl(it.variance, it.type.toKotlinType()) is IrStarProjection -> StarProjectionImpl((classifier.descriptor as ClassDescriptor).typeConstructor.parameters[index]) @@ -219,7 +223,7 @@ fun IrClassifierSymbol.typeWith(arguments: List): IrSimpleType = IrSimpleTypeImpl( this, SimpleTypeNullability.NOT_SPECIFIED, - arguments.map { makeTypeProjection(it, Variance.INVARIANT) }, + arguments.memoryOptimizedMap { makeTypeProjection(it, Variance.INVARIANT) }, emptyList() ) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/AdditionalIrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/AdditionalIrUtils.kt index cf47db7c87c..315e56ee4f4 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/AdditionalIrUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/AdditionalIrUtils.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.utils.filterIsInstanceAnd import java.io.File val IrConstructor.constructedClass get() = this.parent as IrClass @@ -259,7 +260,7 @@ class NaiveSourceBasedFileEntryImpl( } private fun IrClass.getPropertyDeclaration(name: String): IrProperty? { - val properties = declarations.filterIsInstance().filter { it.name.asString() == name } + val properties = declarations.filterIsInstanceAnd { it.name.asString() == name } if (properties.size > 1) { error( "More than one property with name $name in class $fqNameWhenAvailable:\n" + diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ConstantValueGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ConstantValueGenerator.kt index f2583a7b61f..6ae7aa8d246 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ConstantValueGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ConstantValueGenerator.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.types.TypeConstructorSubstitution import org.jetbrains.kotlin.types.error.ErrorClassDescriptor import org.jetbrains.kotlin.types.isError import org.jetbrains.kotlin.types.typeUtil.builtIns +import org.jetbrains.kotlin.utils.memoryOptimizedMapNotNull abstract class ConstantValueGenerator( private val moduleDescriptor: ModuleDescriptor, @@ -95,7 +96,7 @@ abstract class ConstantValueGenerator( startOffset, endOffset, constantType, arrayElementType.toIrType(), - constantValue.value.mapNotNull { + constantValue.value.memoryOptimizedMapNotNull { // For annotation arguments, the type of every subexpression can be inferred from the type of the parameter; // for arbitrary constants, we should always take the type inferred by the frontend. val newExpectedType = arrayElementType.takeIf { expectedType != null } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt index d1fc9299507..67978e87aa5 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.memoryOptimizedMap inline fun T.deepCopyWithSymbols( initialParent: IrDeclarationParent? = null, @@ -74,7 +75,7 @@ open class DeepCopyIrTreeWithSymbols( transform(this@DeepCopyIrTreeWithSymbols, null) as T protected inline fun List.transform() = - map { it.transform() } + memoryOptimizedMap { it.transform() } protected inline fun List.transformTo(destination: MutableList) = mapTo(destination) { it.transform() } @@ -132,9 +133,9 @@ open class DeepCopyIrTreeWithSymbols( declaration.statements.mapTo(scriptCopy.statements) { it.transform() } scriptCopy.earlierScripts = declaration.earlierScripts scriptCopy.earlierScriptsParameter = declaration.earlierScriptsParameter - scriptCopy.explicitCallParameters = declaration.explicitCallParameters.map { it.transform() } - scriptCopy.implicitReceiversParameters = declaration.implicitReceiversParameters.map { it.transform() } - scriptCopy.providedPropertiesParameters = declaration.providedPropertiesParameters.map { it.transform() } + scriptCopy.explicitCallParameters = declaration.explicitCallParameters.memoryOptimizedMap { it.transform() } + scriptCopy.implicitReceiversParameters = declaration.implicitReceiversParameters.memoryOptimizedMap { it.transform() } + scriptCopy.providedPropertiesParameters = declaration.providedPropertiesParameters.memoryOptimizedMap { it.transform() } } } @@ -157,10 +158,10 @@ open class DeepCopyIrTreeWithSymbols( ).apply { transformAnnotations(declaration) copyTypeParametersFrom(declaration) - superTypes = declaration.superTypes.map { + superTypes = declaration.superTypes.memoryOptimizedMap { it.remapType() } - sealedSubclasses = declaration.sealedSubclasses.map { + sealedSubclasses = declaration.sealedSubclasses.memoryOptimizedMap { symbolRemapper.getReferencedClass(it) } thisReceiver = declaration.thisReceiver?.transform() @@ -187,7 +188,7 @@ open class DeepCopyIrTreeWithSymbols( isFakeOverride = declaration.isFakeOverride, containerSource = declaration.containerSource, ).apply { - overriddenSymbols = declaration.overriddenSymbols.map { + overriddenSymbols = declaration.overriddenSymbols.memoryOptimizedMap { symbolRemapper.getReferencedFunction(it) as IrSimpleFunctionSymbol } contextReceiverParametersCount = declaration.contextReceiverParametersCount @@ -256,7 +257,7 @@ open class DeepCopyIrTreeWithSymbols( this.setter = declaration.setter?.transform()?.also { it.correspondingPropertySymbol = symbol } - this.overriddenSymbols = declaration.overriddenSymbols.map { + this.overriddenSymbols = declaration.overriddenSymbols.memoryOptimizedMap { symbolRemapper.getReferencedProperty(it) } } @@ -332,7 +333,7 @@ open class DeepCopyIrTreeWithSymbols( override fun visitTypeParameter(declaration: IrTypeParameter): IrTypeParameter = copyTypeParameter(declaration).apply { // TODO type parameter scopes? - superTypes = declaration.superTypes.map { it.remapType() } + superTypes = declaration.superTypes.memoryOptimizedMap { it.remapType() } } private fun copyTypeParameter(declaration: IrTypeParameter): IrTypeParameter = @@ -349,13 +350,13 @@ open class DeepCopyIrTreeWithSymbols( } protected fun IrTypeParametersContainer.copyTypeParametersFrom(other: IrTypeParametersContainer) { - this.typeParameters = other.typeParameters.map { + this.typeParameters = other.typeParameters.memoryOptimizedMap { copyTypeParameter(it) } typeRemapper.withinScope(this) { for ((thisTypeParameter, otherTypeParameter) in this.typeParameters.zip(other.typeParameters)) { - thisTypeParameter.superTypes = otherTypeParameter.superTypes.map { + thisTypeParameter.superTypes = otherTypeParameter.superTypes.memoryOptimizedMap { typeRemapper.remapType(it) } } @@ -403,7 +404,7 @@ open class DeepCopyIrTreeWithSymbols( override fun visitBlockBody(body: IrBlockBody): IrBlockBody = body.factory.createBlockBody( body.startOffset, body.endOffset, - body.statements.map { it.transform() } + body.statements.memoryOptimizedMap { it.transform() } ) override fun visitSyntheticBody(body: IrSyntheticBody): IrSyntheticBody = @@ -420,7 +421,7 @@ open class DeepCopyIrTreeWithSymbols( expression.startOffset, expression.endOffset, symbolRemapper.getReferencedConstructor(expression.constructor), expression.valueArguments.transform(), - expression.typeArguments.map { it.remapType() }, + expression.typeArguments.memoryOptimizedMap { it.remapType() }, expression.type.remapType() ).copyAttributes(expression) @@ -457,7 +458,7 @@ open class DeepCopyIrTreeWithSymbols( expression.type.remapType(), symbolRemapper.getReferencedReturnableBlock(expression.symbol), mapStatementOrigin(expression.origin), - expression.statements.map { it.transform() } + expression.statements.memoryOptimizedMap { it.transform() } ).copyAttributes(expression) else if (expression is IrInlinedFunctionBlock) IrInlinedFunctionBlockImpl( @@ -465,14 +466,14 @@ open class DeepCopyIrTreeWithSymbols( expression.type.remapType(), expression.inlineCall, expression.inlinedElement, mapStatementOrigin(expression.origin), - statements = expression.statements.map { it.transform() }, + statements = expression.statements.memoryOptimizedMap { it.transform() }, ).copyAttributes(expression) else IrBlockImpl( expression.startOffset, expression.endOffset, expression.type.remapType(), mapStatementOrigin(expression.origin), - expression.statements.map { it.transform() } + expression.statements.memoryOptimizedMap { it.transform() } ).copyAttributes(expression) override fun visitComposite(expression: IrComposite): IrComposite = @@ -480,14 +481,14 @@ open class DeepCopyIrTreeWithSymbols( expression.startOffset, expression.endOffset, expression.type.remapType(), mapStatementOrigin(expression.origin), - expression.statements.map { it.transform() } + expression.statements.memoryOptimizedMap { it.transform() } ).copyAttributes(expression) override fun visitStringConcatenation(expression: IrStringConcatenation): IrStringConcatenation = IrStringConcatenationImpl( expression.startOffset, expression.endOffset, expression.type.remapType(), - expression.arguments.map { it.transform() } + expression.arguments.memoryOptimizedMap { it.transform() } ).copyAttributes(expression) override fun visitGetObjectValue(expression: IrGetObjectValue): IrGetObjectValue = @@ -725,7 +726,7 @@ open class DeepCopyIrTreeWithSymbols( expression.startOffset, expression.endOffset, expression.type.remapType(), mapStatementOrigin(expression.origin), - expression.branches.map { it.transform() } + expression.branches.memoryOptimizedMap { it.transform() } ).copyAttributes(expression) override fun visitBranch(branch: IrBranch): IrBranch = @@ -782,7 +783,7 @@ open class DeepCopyIrTreeWithSymbols( aTry.startOffset, aTry.endOffset, aTry.type.remapType(), aTry.tryResult.transform(), - aTry.catches.map { it.transform() }, + aTry.catches.memoryOptimizedMap { it.transform() }, aTry.finallyExpression?.transform() ).copyAttributes(aTry) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyTypeRemapper.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyTypeRemapper.kt index fdd6db13e87..12d5ede1576 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyTypeRemapper.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyTypeRemapper.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrTypeAbbreviationImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection +import org.jetbrains.kotlin.utils.memoryOptimizedMap class DeepCopyTypeRemapper( private val symbolRemapper: SymbolRemapper @@ -32,8 +33,8 @@ class DeepCopyTypeRemapper( null, symbolRemapper.getReferencedClassifier(type.classifier), type.nullability, - type.arguments.map { remapTypeArgument(it) }, - type.annotations.map { it.transform(deepCopy, null) as IrConstructorCall }, + type.arguments.memoryOptimizedMap { remapTypeArgument(it) }, + type.annotations.memoryOptimizedMap { it.transform(deepCopy, null) as IrConstructorCall }, type.abbreviation?.remapTypeAbbreviation() ) else -> type @@ -50,7 +51,7 @@ class DeepCopyTypeRemapper( IrTypeAbbreviationImpl( symbolRemapper.getReferencedTypeAlias(typeAlias), hasQuestionMark, - arguments.map { remapTypeArgument(it) }, + arguments.memoryOptimizedMap { remapTypeArgument(it) }, annotations ) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrTypeParameterRemapper.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrTypeParameterRemapper.kt index 9995160602c..621f1af066e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrTypeParameterRemapper.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrTypeParameterRemapper.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrTypeAbbreviationImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection +import org.jetbrains.kotlin.utils.memoryOptimizedMap /** * After moving an [org.jetbrains.kotlin.ir.IrElement], some type parameter references within it may become out of scope. @@ -31,7 +32,7 @@ class IrTypeParameterRemapper( null, type.classifier.remap(), type.nullability, - type.arguments.map { it.remap() }, + type.arguments.memoryOptimizedMap { it.remap() }, type.annotations, type.abbreviation?.remap() ).apply { @@ -52,7 +53,7 @@ class IrTypeParameterRemapper( IrTypeAbbreviationImpl( typeAlias, hasQuestionMark, - arguments.map { it.remap() }, + arguments.memoryOptimizedMap { it.remap() }, annotations ).apply { annotations.forEach { it.remapTypes(this@IrTypeParameterRemapper) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt index 9c5c45cb9a2..1850fed6e59 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.DFS +import org.jetbrains.kotlin.utils.memoryOptimizedMap val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin")) private val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflect")) @@ -92,7 +93,7 @@ fun IrType.substitute(params: List, arguments: List): I fun IrType.substitute(substitutionMap: Map): IrType { if (this !is IrSimpleType || substitutionMap.isEmpty()) return this - val newAnnotations = annotations.map { it.deepCopyWithSymbols() } + val newAnnotations = annotations.memoryOptimizedMap { it.deepCopyWithSymbols() } substitutionMap[classifier]?.let { substitutedType -> // Add nullability and annotations from original type @@ -101,7 +102,7 @@ fun IrType.substitute(substitutionMap: Map): IrTy .addAnnotations(newAnnotations) } - val newArguments = arguments.map { + val newArguments = arguments.memoryOptimizedMap { when (it) { is IrTypeProjection -> makeTypeProjection(it.type.substitute(substitutionMap), it.variance) is IrStarProjection -> it @@ -127,7 +128,7 @@ private fun getImmediateSupertypes(irType: IrSimpleType): List { } return originalSupertypes .filter { it.classOrNull != null } - .map { superType -> + .memoryOptimizedMap { superType -> superType.substitute(irClass.typeParameters, arguments) as IrSimpleType } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt index db86162e52b..465a25ee1f6 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt @@ -29,8 +29,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.util.OperatorNameConventions -import org.jetbrains.kotlin.utils.DFS -import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.* import java.io.StringWriter /** @@ -731,7 +730,7 @@ fun IrClass.addSimpleDelegatingConstructor( this.visibility = superConstructor.visibility this.isPrimary = isPrimary }.also { constructor -> - constructor.valueParameters = superConstructor.valueParameters.mapIndexed { index, parameter -> + constructor.valueParameters = superConstructor.valueParameters.memoryOptimizedMapIndexed { index, parameter -> parameter.copyTo(constructor, index = index) } @@ -842,7 +841,7 @@ fun IrFunction.copyReceiverParametersFrom(from: IrFunction, substitutionMap: Map fun IrFunction.copyValueParametersFrom(from: IrFunction, substitutionMap: Map) { copyReceiverParametersFrom(from, substitutionMap) val shift = valueParameters.size - valueParameters += from.valueParameters.map { + valueParameters = valueParameters memoryOptimizedPlus from.valueParameters.map { it.copyTo(this, index = it.index + shift, type = it.type.substitute(substitutionMap)) } } @@ -866,12 +865,12 @@ fun IrTypeParametersContainer.copyTypeParameters( val oldToNewParameterMap = parameterMap.orEmpty().toMutableMap() // Any type parameter can figure in a boundary type for any other parameter. // Therefore, we first copy the parameters themselves, then set up their supertypes. - val newTypeParameters = srcTypeParameters.mapIndexed { i, sourceParameter -> + val newTypeParameters = srcTypeParameters.memoryOptimizedMapIndexed { i, sourceParameter -> sourceParameter.copyToWithoutSuperTypes(this, index = i + shift, origin = origin ?: sourceParameter.origin).also { oldToNewParameterMap[sourceParameter] = it } } - typeParameters += newTypeParameters + typeParameters = typeParameters memoryOptimizedPlus newTypeParameters srcTypeParameters.zip(newTypeParameters).forEach { (srcParameter, dstParameter) -> dstParameter.copySuperTypesFrom(srcParameter, oldToNewParameterMap) } @@ -888,13 +887,13 @@ private fun IrTypeParameter.copySuperTypesFrom(source: IrTypeParameter, srcToDst val target = this val sourceParent = source.parent as IrTypeParametersContainer val targetParent = target.parent as IrTypeParametersContainer - target.superTypes = source.superTypes.map { + target.superTypes = source.superTypes.memoryOptimizedMap { it.remapTypeParameters(sourceParent, targetParent, srcToDstParameterMap) } } fun IrAnnotationContainer.copyAnnotations(): List { - return annotations.map { it.deepCopyWithSymbols(this as? IrDeclarationParent) } + return annotations.memoryOptimizedMap { it.deepCopyWithSymbols(this as? IrDeclarationParent) } } fun IrAnnotationContainer.copyAnnotationsWhen(filter: IrConstructorCall.() -> Boolean): List { @@ -902,7 +901,7 @@ fun IrAnnotationContainer.copyAnnotationsWhen(filter: IrConstructorCall.() -> Bo } fun IrMutableAnnotationContainer.copyAnnotationsFrom(source: IrAnnotationContainer) { - annotations += source.copyAnnotations() + annotations = annotations memoryOptimizedPlus source.copyAnnotations() } fun makeTypeParameterSubstitutionMap( @@ -935,7 +934,7 @@ fun IrFunction.copyValueParametersToStatic( target.classIfConstructor ) - target.valueParameters += originalDispatchReceiver.copyTo( + target.valueParameters = target.valueParameters memoryOptimizedPlus originalDispatchReceiver.copyTo( target, origin = originalDispatchReceiver.origin, index = shift++, @@ -944,7 +943,7 @@ fun IrFunction.copyValueParametersToStatic( ) } source.extensionReceiverParameter?.let { originalExtensionReceiver -> - target.valueParameters += originalExtensionReceiver.copyTo( + target.valueParameters = target.valueParameters memoryOptimizedPlus originalExtensionReceiver.copyTo( target, origin = originalExtensionReceiver.origin, index = shift++, @@ -954,7 +953,7 @@ fun IrFunction.copyValueParametersToStatic( for (oldValueParameter in source.valueParameters) { if (oldValueParameter.index >= numValueParametersToCopy) break - target.valueParameters += oldValueParameter.copyTo( + target.valueParameters = target.valueParameters memoryOptimizedPlus oldValueParameter.copyTo( target, origin = origin, index = oldValueParameter.index + shift @@ -1002,7 +1001,7 @@ fun IrType.remapTypeParameters( IrSimpleTypeImpl( classifier.symbol, nullability, - arguments.map { + arguments.memoryOptimizedMap { when (it) { is IrTypeProjection -> makeTypeProjection( it.type.remapTypeParameters(source, target, srcToDstParameterMap), @@ -1218,7 +1217,7 @@ fun IrFactory.createStaticFunctionWithReceivers( fun remap(type: IrType): IrType = type.remapTypeParameters(oldFunction, this, typeParameterMap) - typeParameters.forEach { it.superTypes = it.superTypes.map(::remap) } + typeParameters.forEach { it.superTypes = it.superTypes.memoryOptimizedMap(::remap) } annotations = oldFunction.annotations @@ -1321,7 +1320,7 @@ private fun IrSimpleFunction.copyAndRenameConflictingTypeParametersFrom( newParameter.copySuperTypesFrom(oldParameter, parameterMap) } - typeParameters = typeParameters + newParameters + typeParameters = typeParameters memoryOptimizedPlus newParameters return newParameters } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RemapTypes.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RemapTypes.kt index 3294b394385..391bfe7edda 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RemapTypes.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RemapTypes.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.utils.memoryOptimizedMap // Modify IrElement in place, applying typeRemapper to all the IrType fields. fun IrElement.remapTypes(typeRemapper: TypeRemapper) { @@ -24,7 +25,7 @@ private class RemapTypesHelper(private val typeRemapper: TypeRemapper) : IrEleme } override fun visitClass(declaration: IrClass) { - declaration.superTypes = declaration.superTypes.map { typeRemapper.remapType(it) } + declaration.superTypes = declaration.superTypes.memoryOptimizedMap { typeRemapper.remapType(it) } super.visitClass(declaration) } @@ -35,7 +36,7 @@ private class RemapTypesHelper(private val typeRemapper: TypeRemapper) : IrEleme } override fun visitTypeParameter(declaration: IrTypeParameter) { - declaration.superTypes = declaration.superTypes.map { typeRemapper.remapType(it) } + declaration.superTypes = declaration.superTypes.memoryOptimizedMap { typeRemapper.remapType(it) } super.visitTypeParameter(declaration) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SimpleTypeRemapper.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SimpleTypeRemapper.kt index e19e3062bbb..3c32f28fdd7 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SimpleTypeRemapper.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SimpleTypeRemapper.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrTypeAbbreviationImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection +import org.jetbrains.kotlin.utils.memoryOptimizedMap class SimpleTypeRemapper( private val symbolRemapper: SymbolRemapper @@ -26,7 +27,7 @@ class SimpleTypeRemapper( type else { val symbol = symbolRemapper.getReferencedClassifier(type.classifier) - val arguments = type.arguments.map { remapTypeArgument(it) } + val arguments = type.arguments.memoryOptimizedMap { remapTypeArgument(it) } if (symbol == type.classifier && arguments == type.arguments) type else { @@ -51,7 +52,7 @@ class SimpleTypeRemapper( IrTypeAbbreviationImpl( symbolRemapper.getReferencedTypeAlias(typeAlias), hasQuestionMark, - arguments.map { remapTypeArgument(it) }, + arguments.memoryOptimizedMap { remapTypeArgument(it) }, annotations ) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt index 325c4c14f8e..d9877371b5e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.types.impl.* import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes +import org.jetbrains.kotlin.utils.memoryOptimizedMap import org.jetbrains.kotlin.utils.threadLocal import java.util.* @@ -305,7 +306,7 @@ abstract class TypeTranslator( } private fun translateTypeArguments(arguments: List) = - arguments.map { + arguments.memoryOptimizedMap { if (it.isStarProjection) IrStarProjectionImpl else diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/emptyArraysForMemberAccess.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/emptyArraysForMemberAccess.kt new file mode 100644 index 00000000000..8c048d5d563 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/emptyArraysForMemberAccess.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.ir.util + +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.types.IrType + +private val EMPTY_TYPE_ARRAY = arrayOfNulls(0) +private val EMPTY_EXPRESSION_ARRAY = arrayOfNulls(0) + +fun initializeTypeArguments(size: Int) = if (size == 0) EMPTY_TYPE_ARRAY else arrayOfNulls(size) +fun initializeParameterArguments(size: Int) = if (size == 0) EMPTY_EXPRESSION_ARRAY else arrayOfNulls(size) \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/overrides.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/overrides.kt index 9f9785576d1..a27ff47141e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/overrides.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/overrides.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal +import org.jetbrains.kotlin.utils.memoryOptimizedMap @ObsoleteDescriptorBasedAPI fun SymbolTable.declareSimpleFunctionWithOverrides( @@ -49,7 +50,7 @@ fun generateOverriddenFunctionSymbols( declaration: IrSimpleFunction, symbolTable: ReferenceSymbolTable ) { - declaration.overriddenSymbols = declaration.descriptor.overriddenDescriptors.map { + declaration.overriddenSymbols = declaration.descriptor.overriddenDescriptors.memoryOptimizedMap { symbolTable.referenceSimpleFunction(it.original) } } diff --git a/compiler/ir/serialization.common/build.gradle.kts b/compiler/ir/serialization.common/build.gradle.kts index 4a4d78edecc..431ca7fad47 100644 --- a/compiler/ir/serialization.common/build.gradle.kts +++ b/compiler/ir/serialization.common/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { api(project(":compiler:util")) implementation(project(":compiler:psi")) compileOnly(commonDependency("org.jetbrains.kotlin:kotlin-reflect")) { isTransitive = false } + compileOnly(commonDependency("org.jetbrains.intellij.deps.fastutil:intellij-deps-fastutil")) compileOnly(intellijCore()) } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/KotlinIrLinkerIssues.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/KotlinIrLinkerIssues.kt index b2b725e1408..fb2c852ffd5 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/KotlinIrLinkerIssues.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/KotlinIrLinkerIssues.kt @@ -228,14 +228,14 @@ private fun StringBuilder.appendProjectDependencies( return } - val incomingDependencyIdToDependencies: MutableMap> = mutableMapOf() + val incomingDependencyIdToDependencies: MutableMap> = hashMapOf() allModules.values.forEach { module -> module.requestedVersionsByIncomingDependencies.keys.forEach { incomingDependencyId -> incomingDependencyIdToDependencies.getOrPut(incomingDependencyId) { mutableListOf() } += module } } - val renderedModules: MutableSet = mutableSetOf() + val renderedModules: MutableSet = hashSetOf() var everDependenciesOmitted = false fun renderModules(modules: Collection, parentData: Data?) { @@ -346,7 +346,7 @@ private fun findPotentiallyConflictingOutgoingDependencies( ) // Reverse dependency index. - val outgoingDependenciesIndex: MutableMap> = mutableMapOf() + val outgoingDependenciesIndex: MutableMap> = hashMapOf() allModules.values.forEach { module -> module.requestedVersionsByIncomingDependencies.forEach { (incomingDependencyId, requestedVersion) -> diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/UserVisibleIrModulesSupport.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/UserVisibleIrModulesSupport.kt index 61ebad754bb..7ed2ff92b2d 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/UserVisibleIrModulesSupport.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/UserVisibleIrModulesSupport.kt @@ -88,10 +88,10 @@ open class UserVisibleIrModulesSupport(externalDependenciesLoader: ExternalDepen selectedVersion = ResolvedDependencyVersion.EMPTY, // Assumption: As we don't know for sure which modules the source code module depends on directly and which modules // it depends on transitively, so let's assume it depends on all modules directly. - requestedVersionsByIncomingDependencies = mutableMapOf( + requestedVersionsByIncomingDependencies = hashMapOf( ResolvedDependencyId.DEFAULT_SOURCE_CODE_MODULE_ID to ResolvedDependencyVersion.EMPTY ), - artifactPaths = mutableSetOf() + artifactPaths = hashSetOf() ) val outgoingDependencyIds = deserializer.moduleDependencies.map { getUserVisibleModuleId(it) } @@ -108,7 +108,7 @@ open class UserVisibleIrModulesSupport(externalDependenciesLoader: ExternalDepen */ protected fun mergedModules(deserializers: Collection): MutableMap { val externalDependencyModulesByNames: Map = - mutableMapOf().apply { + hashMapOf().apply { externalDependencyModules.forEach { externalDependency -> externalDependency.id.uniqueNames.forEach { uniqueName -> this[uniqueName] = externalDependency @@ -122,7 +122,7 @@ open class UserVisibleIrModulesSupport(externalDependenciesLoader: ExternalDepen // The build system may express a group of modules where one module is a library KLIB and one or more modules // are just C-interop KLIBs as a single module with multiple artifacts. We need to expand them so that every particular // module/artifact will be represented as an individual [ResolvedDependency] instance. - val artifactPathsToOriginModules: MutableMap = mutableMapOf() + val artifactPathsToOriginModules: MutableMap = hashMapOf() externalDependencyModules.forEach { originModule -> originModule.artifactPaths.forEach { artifactPath -> artifactPathsToOriginModules[artifactPath] = originModule } } @@ -180,7 +180,7 @@ open class UserVisibleIrModulesSupport(externalDependenciesLoader: ExternalDepen } } - return (externalDependencyModules + providedModules).associateByTo(mutableMapOf()) { it.id } + return (externalDependencyModules + providedModules).associateByTo(hashMapOf()) { it.id } } protected data class ModuleWithUninitializedDependencies( diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt index f19fc26ed40..dc1007aeddc 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered +import org.jetbrains.kotlin.utils.filterIsInstanceAnd class FakeOverrideChecker( private val irMangler: KotlinMangler.IrMangler, @@ -39,25 +40,25 @@ class FakeOverrideChecker( val descriptorFakeOverrides = classDescriptor.unsubstitutedMemberScope .getDescriptorsFiltered(DescriptorKindFilter.CALLABLES) + .asSequence() .filterIsInstance() .filter { it.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE } .filterNot { it.visibility == DescriptorVisibilities.PRIVATE || it.visibility == DescriptorVisibilities.INVISIBLE_FAKE } val descriptorSignatures = descriptorFakeOverrides .map { with(descriptorMangler) { it.signatureString(compatibleMode) } } - .sorted() + .toMutableList() + .apply { sort() } - val irFakeOverrides = clazz.declarations + val irFakeOverrides = clazz.declarations.asSequence() .filterIsInstance() .filter { it.isFakeOverride } - - irFakeOverrides.forEach { - checkOverriddenSymbols(it) - } + .onEach { checkOverriddenSymbols(it) } val irSignatures = irFakeOverrides .map { with(irMangler) { it.signatureString(compatibleMode) } } - .sorted() + .toMutableList() + .apply { sort() } // We can't have equality here because dependency libraries could have // been compiled with -friend-modules. diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt index 4d60faf44de..5750cd628f5 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt @@ -27,14 +27,18 @@ abstract class BasicIrModuleDeserializer( override val klib: IrLibrary, override val strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, - private val containsErrorCode: Boolean = false + private val containsErrorCode: Boolean = false, + private val shouldSaveDeserializationState: Boolean = true, ) : IrModuleDeserializer(moduleDescriptor, libraryAbiVersion) { private val fileToDeserializerMap = mutableMapOf() private val moduleDeserializationState = ModuleDeserializationState() - protected val moduleReversedFileIndex = mutableMapOf() + protected var fileDeserializationStates: List = emptyList() + get() = if (!shouldSaveDeserializationState) error("File deserialization state are not cached inside the instance because `shouldSaveDeserializationState` was set as `false`") else field + + protected val moduleReversedFileIndex = hashMapOf() override val moduleDependencies by lazy { moduleDescriptor.allDependencyModules @@ -46,8 +50,6 @@ abstract class BasicIrModuleDeserializer( return fileToDeserializerMap.values.filterNot { strategyResolver(it.file.fileEntry.name).onDemand } } - protected lateinit var fileDeserializationStates: List - override fun init(delegate: IrModuleDeserializer) { val fileCount = klib.fileCount() @@ -64,7 +66,9 @@ abstract class BasicIrModuleDeserializer( moduleFragment.files.add(file) } - this.fileDeserializationStates = fileDeserializationStates + if (shouldSaveDeserializationState) { + this.fileDeserializationStates = fileDeserializationStates + } fileToDeserializerMap.values.forEach { it.symbolDeserializer.deserializeExpectActualMapping() } } @@ -128,7 +132,7 @@ abstract class BasicIrModuleDeserializer( fileStrategy.needBodies, allowErrorNodes, fileStrategy.inlineBodies, - moduleDeserializer + moduleDeserializer, ) fileToDeserializerMap[file] = fileDeserializationState.fileDeserializer diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt index ea16cfac901..8271591b786 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt @@ -32,7 +32,7 @@ abstract class GlobalDeclarationTable( ) { val publicIdSignatureComputer = PublicIdSignatureComputer(mangler) - protected val table = mutableMapOf() + protected val table = hashMapOf() constructor(mangler: KotlinMangler.IrMangler) : this(mangler, IdSignatureClashTracker.DEFAULT_TRACKER) @@ -53,7 +53,7 @@ abstract class GlobalDeclarationTable( } open class DeclarationTable(globalTable: GlobalDeclarationTable) { - protected val table = mutableMapOf() + protected val table = hashMapOf() protected open val globalDeclarationTable: GlobalDeclarationTable = globalTable // TODO: we need to disentangle signature construction with declaration tables. open val signaturer: IdSignatureSerializer = IdSignatureSerializer(globalTable.publicIdSignatureComputer, this) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt index 630972d4c8d..5312ecb4369 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt @@ -62,7 +62,7 @@ class ExpectActualTable(val expectDescriptorToSymbol: MutableMap { - val rightHandSide = mutableMapOf() + val rightHandSide = hashMapOf() this.acceptVoid(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt index 141295ff5bf..ce614b36a61 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt @@ -5,9 +5,9 @@ package org.jetbrains.kotlin.backend.common.serialization -import org.jetbrains.kotlin.ir.symbols.IrFileSymbol import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IdSignature.FileSignature +import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature import org.jetbrains.kotlin.backend.common.serialization.proto.CommonIdSignature as ProtoCommonIdSignature import org.jetbrains.kotlin.backend.common.serialization.proto.CompositeSignature as ProtoCompositeSignature @@ -18,7 +18,8 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.LocalSignature as class IdSignatureDeserializer( private val libraryFile: IrLibraryFile, - private val fileSignature: FileSignature? + private val fileSignature: FileSignature?, + private val internationService: IrInterningService ) { private fun loadSignatureProto(index: Int): ProtoIdSignature { @@ -35,8 +36,8 @@ class IdSignatureDeserializer( } private fun deserializePublicIdSignature(proto: ProtoCommonIdSignature): IdSignature.CommonSignature { - val pkg = libraryFile.deserializeFqName(proto.packageFqNameList) - val cls = libraryFile.deserializeFqName(proto.declarationFqNameList) + val pkg = internationService.string(libraryFile.deserializeFqName(proto.packageFqNameList)) + val cls = internationService.string(libraryFile.deserializeFqName(proto.declarationFqNameList)) val memberId = if (proto.hasMemberUniqId()) proto.memberUniqId else null return IdSignature.CommonSignature(pkg, cls, memberId, proto.flags) @@ -49,8 +50,9 @@ class IdSignatureDeserializer( val hash = proto.accessorHashId val mask = proto.flags + val declarationFqName = internationService.string("${propertySignature.declarationFqName}.$name") val accessorSignature = - IdSignature.CommonSignature(propertySignature.packageFqName, "${propertySignature.declarationFqName}.$name", hash, mask) + IdSignature.CommonSignature(propertySignature.packageFqName, declarationFqName, hash, mask) return IdSignature.AccessorSignature(propertySignature, accessorSignature) } @@ -70,7 +72,7 @@ class IdSignatureDeserializer( } private fun deserializeLocalIdSignature(proto: ProtoLocalSignature): IdSignature.LocalSignature { - val localFqn = libraryFile.deserializeFqName(proto.localFqNameList) + val localFqn = internationService.string(libraryFile.deserializeFqName(proto.localFqNameList)) val localHash = if (proto.hasLocalHash()) proto.localHash else null val description = if (proto.hasDebugInfo()) libraryFile.debugInfo(proto.debugInfo) else null return IdSignature.LocalSignature(localFqn, localHash, description) @@ -93,6 +95,7 @@ class IdSignatureDeserializer( } fun signatureToIndexMapping(): Map { - return signatureCache.entries.associate { it.value to it.key } + if (signatureCache.isEmpty()) return emptyMap() + return signatureCache.entries.associateTo(newHashMapWithExpectedSize(signatureCache.size)) { it.value to it.key } } } \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt index f20922d2b2e..2a85957def8 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt @@ -105,7 +105,7 @@ class CurrentModuleWithICDeserializer( icReaderFactory: (IrLibrary) -> IrModuleDeserializer) : IrModuleDeserializer(delegate.moduleDescriptor, KotlinAbiVersion.CURRENT) { - private val dirtyDeclarations = mutableMapOf() + private val dirtyDeclarations = hashMapOf() private val icKlib = ICKotlinLibrary(icData) private val icDeserializer: IrModuleDeserializer = icReaderFactory(icKlib) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt index 6441303e4d0..d54bc4d4466 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrBodyDeserializer.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.* +import org.jetbrains.kotlin.utils.memoryOptimizedMap import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlock as ProtoBlock import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlockBody as ProtoBlockBody @@ -81,7 +82,7 @@ class IrBodyDeserializer( private val declarationDeserializer: IrDeclarationDeserializer ) { - private val fileLoops = mutableMapOf() + private val fileLoops = hashMapOf() private fun deserializeLoopHeader(loopIndex: Int, loopBuilder: () -> IrLoop): IrLoop = fileLoops.getOrPut(loopIndex, loopBuilder) @@ -90,14 +91,7 @@ class IrBodyDeserializer( proto: ProtoBlockBody, start: Int, end: Int ): IrBlockBody { - - val statements = mutableListOf() - - val statementProtos = proto.statementList - statementProtos.forEach { - statements.add(deserializeStatement(it) as IrStatement) - } - + val statements = proto.statementList.memoryOptimizedMap { deserializeStatement(it) as IrStatement } return irFactory.createBlockBody(start, end, statements) } @@ -163,14 +157,14 @@ class IrBodyDeserializer( private fun deserializeMemberAccessCommon(access: IrMemberAccessExpression<*>, proto: ProtoMemberAccessCommon) { - proto.valueArgumentList.mapIndexed { i, arg -> + proto.valueArgumentList.forEachIndexed { i, arg -> if (arg.hasExpression()) { val expr = deserializeExpression(arg.expression) access.putValueArgument(i, expr) } } - proto.typeArgumentList.mapIndexed { i, arg -> + proto.typeArgumentList.forEachIndexed { i, arg -> access.putTypeArgument(i, declarationDeserializer.deserializeNullableIrType(arg)) } @@ -211,16 +205,16 @@ class IrBodyDeserializer( val klass = constructorCall.symbol.owner.parentAsClass - val typeParameters = extractTypeParameters(klass) + val typeParameters = extractTypeParameters(klass).ifEmpty { + return IrSimpleTypeBuilder().apply { classifier = klass.symbol }.buildSimpleType() + } val typeArguments = ArrayList(typeParameters.size) val typeParameterSymbols = ArrayList(typeParameters.size) val rawType = with(IrSimpleTypeBuilder()) { - arguments = typeParameters.run { - mapTo(ArrayList(size)) { - classifier = it.symbol - buildTypeProjection() - } + arguments = typeParameters.memoryOptimizedMap { + classifier = it.symbol + buildTypeProjection() } classifier = klass.symbol buildSimpleType() diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt index 4223ca1103d..5228cb4aba3 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.types.impl.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.* import kotlin.collections.set import org.jetbrains.kotlin.backend.common.serialization.proto.IrAnonymousInit as ProtoAnonymousInit import org.jetbrains.kotlin.backend.common.serialization.proto.IrClass as ProtoClass @@ -52,9 +53,9 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.IrInlineClassRepr import org.jetbrains.kotlin.backend.common.serialization.proto.IrLocalDelegatedProperty as ProtoLocalDelegatedProperty import org.jetbrains.kotlin.backend.common.serialization.proto.IrMultiFieldValueClassRepresentation as ProtoIrMultiFieldValueClassRepresentation import org.jetbrains.kotlin.backend.common.serialization.proto.IrProperty as ProtoProperty -import org.jetbrains.kotlin.backend.common.serialization.proto.IrSimpleTypeNullability as ProtoSimpleTypeNullablity import org.jetbrains.kotlin.backend.common.serialization.proto.IrSimpleType as ProtoSimpleType import org.jetbrains.kotlin.backend.common.serialization.proto.IrSimpleTypeLegacy as ProtoSimpleTypeLegacy +import org.jetbrains.kotlin.backend.common.serialization.proto.IrSimpleTypeNullability as ProtoSimpleTypeNullablity import org.jetbrains.kotlin.backend.common.serialization.proto.IrStatement as ProtoStatement import org.jetbrains.kotlin.backend.common.serialization.proto.IrType as ProtoType import org.jetbrains.kotlin.backend.common.serialization.proto.IrTypeAbbreviation as ProtoTypeAbbreviation @@ -76,27 +77,27 @@ class IrDeclarationDeserializer( private val platformFakeOverrideClassFilter: FakeOverrideClassFilter, private val fakeOverrideBuilder: FakeOverrideBuilder, private val compatibilityMode: CompatibilityMode, - private val partialLinkageEnabled: Boolean + private val partialLinkageEnabled: Boolean, + private val internationService: IrInterningService, ) { private val bodyDeserializer = IrBodyDeserializer(builtIns, allowErrorNodes, irFactory, libraryFile, this) + private fun deserializeString(index: Int): String { + return libraryFile.string(index) + } + private fun deserializeName(index: Int): Name { - val name = libraryFile.string(index) - return Name.guessByFirstCharacter(name) + return internationService.name(Name.guessByFirstCharacter(deserializeString(index))) } - private val irTypeCache = mutableMapOf() - - private fun loadTypeProto(index: Int): ProtoType { - return libraryFile.type(index) - } + private val irTypeCache = hashMapOf() fun deserializeNullableIrType(index: Int): IrType? = if (index == -1) null else deserializeIrType(index) fun deserializeIrType(index: Int): IrType { return irTypeCache.getOrPut(index) { - val typeData = loadTypeProto(index) + val typeData = libraryFile.type(index) deserializeIrTypeData(typeData) } } @@ -110,9 +111,7 @@ class IrDeclarationDeserializer( } internal fun deserializeAnnotations(annotations: List): List { - return annotations.map { - bodyDeserializer.deserializeAnnotation(it) - } + return annotations.memoryOptimizedMap { bodyDeserializer.deserializeAnnotation(it) } } private fun deserializeSimpleTypeNullability(proto: ProtoSimpleTypeNullablity) = when (proto) { @@ -125,8 +124,9 @@ class IrDeclarationDeserializer( val symbol = deserializeIrSymbolAndRemap(proto.classifier) .checkSymbolType(fallbackSymbolKind = /* just the first possible option */ CLASS_SYMBOL) - val arguments = proto.argumentList.map { deserializeIrTypeArgument(it) } + val arguments = proto.argumentList.memoryOptimizedMap { deserializeIrTypeArgument(it) } val annotations = deserializeAnnotations(proto.annotationList) + val abbreviation = if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null return IrSimpleTypeImpl( null, @@ -134,7 +134,7 @@ class IrDeclarationDeserializer( deserializeSimpleTypeNullability(proto.nullability), arguments, annotations, - if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null + abbreviation ) } @@ -142,8 +142,9 @@ class IrDeclarationDeserializer( val symbol = deserializeIrSymbolAndRemap(proto.classifier) .checkSymbolType(fallbackSymbolKind = /* just the first possible option */ CLASS_SYMBOL) - val arguments = proto.argumentList.map { deserializeIrTypeArgument(it) } + val arguments = proto.argumentList.memoryOptimizedMap { deserializeIrTypeArgument(it) } val annotations = deserializeAnnotations(proto.annotationList) + val abbreviation = if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null return IrSimpleTypeImpl( null, @@ -151,7 +152,7 @@ class IrDeclarationDeserializer( SimpleTypeNullability.fromHasQuestionMark(proto.hasQuestionMark), arguments, annotations, - if (proto.hasAbbreviation()) deserializeTypeAbbreviation(proto.abbreviation) else null + abbreviation ) } @@ -159,13 +160,19 @@ class IrDeclarationDeserializer( IrTypeAbbreviationImpl( deserializeIrSymbolAndRemap(proto.typeAlias).checkSymbolType(TYPEALIAS_SYMBOL), proto.hasQuestionMark, - proto.argumentList.map { deserializeIrTypeArgument(it) }, + proto.argumentList.memoryOptimizedMap { deserializeIrTypeArgument(it) }, deserializeAnnotations(proto.annotationList) ) + private val SIMPLE_DYNAMIC_TYPE = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT) + private fun deserializeDynamicType(proto: ProtoDynamicType): IrDynamicType { - val annotations = deserializeAnnotations(proto.annotationList) - return IrDynamicTypeImpl(null, annotations, Variance.INVARIANT) + return if (proto.annotationCount == 0) { + SIMPLE_DYNAMIC_TYPE + } else { + val annotations = deserializeAnnotations(proto.annotationList) + IrDynamicTypeImpl(null, annotations, Variance.INVARIANT) + } } private fun deserializeErrorType(proto: ProtoErrorType): IrErrorType { @@ -205,7 +212,7 @@ class IrDeclarationDeserializer( } // Delegating symbol maps to it's delegate only inside the declaration the symbol belongs to. - private val delegatedSymbolMap = mutableMapOf() + private val delegatedSymbolMap = hashMapOf() internal fun deserializeIrSymbol(code: Long): IrSymbol { return symbolDeserializer.deserializeIrSymbol(code) @@ -367,7 +374,7 @@ class IrDeclarationDeserializer( }.usingParent { typeParameters = deserializeTypeParameters(proto.typeParameterList, true) - superTypes = proto.superTypeList.map { deserializeIrType(it) } + superTypes = proto.superTypeList.memoryOptimizedMap { deserializeIrType(it) } withExternalValue(isExternal) { val oldDeclarations = declarations.toSet() @@ -389,8 +396,8 @@ class IrDeclarationDeserializer( else -> computeMissingInlineClassRepresentationForCompatibility(this) } - // It has been desided not to deserialize the list of sealed subclasses because of KT-54028 - // sealedSubclasses = proto.sealedSubclassList.map { deserializeIrSymbol(it).checkSymbolType(CLASS_SYMBOL) } + // It has been decided not to deserialize the list of sealed subclasses because of KT-54028 + // sealedSubclasses = proto.sealedSubclassList.memoryOptimizedMap { deserializeIrSymbol(it).checkSymbolType(CLASS_SYMBOL) } fakeOverrideBuilder.enqueueClass(this, signature, compatibilityMode) } @@ -403,9 +410,9 @@ class IrDeclarationDeserializer( ) private fun deserializeMultiFieldValueClassRepresentation(proto: ProtoIrMultiFieldValueClassRepresentation): MultiFieldValueClassRepresentation { - val names = proto.underlyingPropertyNameList.map { deserializeName(it) } - val types = proto.underlyingPropertyTypeList.map { deserializeIrType(it) as IrSimpleType } - return MultiFieldValueClassRepresentation(names zip types) + val names = proto.underlyingPropertyNameList.memoryOptimizedMap { deserializeName(it) } + val types = proto.underlyingPropertyTypeList.memoryOptimizedMap { deserializeIrType(it) as IrSimpleType } + return MultiFieldValueClassRepresentation(names memoryOptimizedZip types) } private fun computeMissingInlineClassRepresentationForCompatibility(irClass: IrClass): InlineClassRepresentation { @@ -447,30 +454,17 @@ class IrDeclarationDeserializer( private fun deserializeTypeParameters(protos: List, isGlobal: Boolean): List { // NOTE: fun , T : Any> Array.filterNotNullTo(destination: C): C - val result = ArrayList(protos.size) - for (index in protos.indices) { - val proto = protos[index] - result.add(deserializeIrTypeParameter(proto, index, isGlobal)) + return protos.memoryOptimizedMapIndexed { index, proto -> + deserializeIrTypeParameter(proto, index, isGlobal).apply { + superTypes = proto.superTypeList.memoryOptimizedMap { deserializeIrType(it) } + } } - - for (i in protos.indices) { - result[i].superTypes = protos[i].superTypeList.map { deserializeIrType(it) } - } - - return result } private fun deserializeValueParameters(protos: List): List { - val result = ArrayList(protos.size) - - for (i in protos.indices) { - result.add(deserializeIrValueParameter(protos[i], i)) - } - - return result + return protos.memoryOptimizedMapIndexed { index, proto -> deserializeIrValueParameter(proto, index) } } - /** * In `declarations-only` mode in case of private property/function with inferred anonymous private type like this * class C { @@ -609,7 +603,7 @@ class IrDeclarationDeserializer( flags.isFakeOverride ) }.apply { - overriddenSymbols = proto.overriddenList.map { deserializeIrSymbolAndRemap(it).checkSymbolType(FUNCTION_SYMBOL) } + overriddenSymbols = proto.overriddenList.memoryOptimizedMap { deserializeIrSymbolAndRemap(it).checkSymbolType(FUNCTION_SYMBOL) } } } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt index 532bf4b04b5..9af04d304cf 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt @@ -74,6 +74,7 @@ class FileDeserializationState( ::addIdSignature, linker::handleExpectActualMapping, symbolProcessor = linker.symbolProcessor, + internationService = linker.internationService ) { idSignature, symbolKind -> linker.deserializeOrReturnUnboundIrSymbolIfPartialLinkageEnabled(idSignature, symbolKind, moduleDeserializer) } @@ -91,7 +92,8 @@ class FileDeserializationState( linker.fakeOverrideBuilder.platformSpecificClassFilter, linker.fakeOverrideBuilder, compatibilityMode = moduleDeserializer.compatibilityMode, - linker.partialLinkageSupport.isEnabled + linker.partialLinkageSupport.isEnabled, + internationService = linker.internationService ) val fileDeserializer = IrFileDeserializer(file, fileReader, fileProto, symbolDeserializer, declarationDeserializer) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt index a37aa8f20bd..e15833fa52d 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.library.impl.IrMemoryDeclarationWriter import org.jetbrains.kotlin.library.impl.IrMemoryStringWriter import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.filterIsInstanceAnd import java.io.File import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature import org.jetbrains.kotlin.backend.common.serialization.proto.Actual as ProtoActual @@ -125,7 +126,7 @@ open class IrFileSerializer( private val normalizeAbsolutePaths: Boolean = false, private val sourceBaseDirs: Collection ) { - private val loopIndex = mutableMapOf() + private val loopIndex = hashMapOf() private var currentLoopIndex = 0 // For every actual we keep a corresponding expects' uniqIds. @@ -134,10 +135,10 @@ open class IrFileSerializer( // The same type can be used multiple times in a file // so use this index to store type data only once. - private val protoTypeMap = mutableMapOf() + private val protoTypeMap = hashMapOf() protected val protoTypeArray = arrayListOf() - private val protoStringMap = mutableMapOf() + private val protoStringMap = hashMapOf() protected val protoStringArray = arrayListOf() // The same signature could be used multiple times in a file @@ -1444,8 +1445,7 @@ open class IrFileSerializer( // Make sure that all top level properties are initialized on library's load. file.declarations - .filterIsInstance() - .filter { it.backingField?.initializer != null && keepOrderOfProperties(it) } + .filterIsInstanceAnd { it.backingField?.initializer != null && keepOrderOfProperties(it) } .forEach { val fieldSymbol = it.backingField?.symbol ?: error("Not found ID ${it.render()}") proto.addExplicitlyExportedToCompiler(serializeIrSymbol(fieldSymbol)) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrInterningService.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrInterningService.kt new file mode 100644 index 00000000000..959731ab937 --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrInterningService.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.common.serialization + +import org.jetbrains.kotlin.name.Name +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet + +/** + * The interface provide an API for interning [String] and [Name] values + * to save memory by eliminating duplicates of instances of those classes + */ +class IrInterningService { + /** + * We use here an open-addressing map, because it consumes at least twice lesser memory than with bucket-based implementation: + * - Open-addressing (cost per entry): ref to key + ref to value + * - Bucket-based (cost per entry): hash code + ref to key + ref to value + ref to the next node + class header with memory alignment + */ + private val strings by lazy { ObjectOpenHashSet() } + private val names by lazy { ObjectOpenHashSet() } + + fun string(string: String): String { + return strings.addOrGet(string) + } + + fun name(name: Name): Name { + return names.addOrGet(name) + } + + fun clear() { + strings.clear() + names.clear() + } +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt index 7831e99f22d..249b2552a13 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt @@ -25,11 +25,12 @@ class IrSymbolDeserializer( val actuals: List, val enqueueLocalTopLevelDeclaration: (IdSignature) -> Unit, val handleExpectActualMapping: (IdSignature, IrSymbol) -> IrSymbol, + internationService: IrInterningService, val symbolProcessor: IrSymbolDeserializer.(IrSymbol, IdSignature) -> IrSymbol = { s, _ -> s }, fileSignature: IdSignature.FileSignature = IdSignature.FileSignature(fileSymbol), val deserializePublicSymbol: (IdSignature, BinarySymbolData.SymbolKind) -> IrSymbol ) { - val deserializedSymbols: MutableMap = mutableMapOf() + val deserializedSymbols: MutableMap = hashMapOf() fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol { return deserializedSymbols.getOrPut(idSig) { @@ -84,7 +85,7 @@ class IrSymbolDeserializer( } } - val signatureDeserializer = IdSignatureDeserializer(libraryFile, fileSignature) + val signatureDeserializer = IdSignatureDeserializer(libraryFile, fileSignature, internationService) fun deserializeIdSignature(index: Int): IdSignature { return signatureDeserializer.deserializeIdSignature(index) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index 3fbe9b2a653..a7836fb1eed 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -15,7 +15,10 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.builders.TranslationPluginContext -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.* @@ -32,22 +35,23 @@ abstract class KotlinIrLinker( private val exportedDependencies: List, val symbolProcessor: IrSymbolDeserializer.(IrSymbol, IdSignature) -> IrSymbol = { s, _ -> s }, ) : IrDeserializer, FileLocalAwareLinker { + val internationService = IrInterningService() // Kotlin-MPP related data. Consider some refactoring val expectIdSignatureToActualIdSignature = mutableMapOf() - val topLevelActualIdSignatureToModuleDeserializer = mutableMapOf() - internal val expectSymbols = mutableMapOf() - internal val actualSymbols = mutableMapOf() + val topLevelActualIdSignatureToModuleDeserializer = hashMapOf() + internal val expectSymbols = hashMapOf() + internal val actualSymbols = hashMapOf() - val modulesWithReachableTopLevels = mutableSetOf() + val modulesWithReachableTopLevels = hashSetOf() - protected val deserializersForModules = mutableMapOf() + protected val deserializersForModules = hashMapOf() abstract val fakeOverrideBuilder: FakeOverrideBuilder abstract val translationPluginContext: TranslationPluginContext? - private val triedToDeserializeDeclarationForSymbol = mutableSetOf() + private val triedToDeserializeDeclarationForSymbol = hashSetOf() private lateinit var linkerExtensions: Collection @@ -204,6 +208,10 @@ abstract class KotlinIrLinker( deserializersForModules.values.forEach { it.init() } } + fun clear() { + internationService.clear() + } + override fun postProcess(inOrAfterLinkageStep: Boolean) { // TODO: Expect/actual actualization should be fixed to cope with the situation when either expect or actual symbol is unbound. finalizeExpectActualLinker() @@ -224,7 +232,6 @@ abstract class KotlinIrLinker( deserializersForModules.values.asSequence().map { it.moduleFragment } } } - // TODO: fix IrPluginContext to make it not produce additional external reference // symbolTable.noUnboundLeft("unbound after fake overrides:") } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 3cc7f2438a2..1bfd29e3679 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -49,7 +49,6 @@ import org.jetbrains.kotlin.js.analyze.AbstractTopDownAnalyzerFacadeForWeb import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy import org.jetbrains.kotlin.js.config.JSConfigurationKeys -import org.jetbrains.kotlin.konan.file.ZipFileSystemAccessor import org.jetbrains.kotlin.konan.properties.Properties import org.jetbrains.kotlin.konan.properties.propertyList import org.jetbrains.kotlin.library.* @@ -74,6 +73,7 @@ import org.jetbrains.kotlin.util.DummyLogger import org.jetbrains.kotlin.util.Logger import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.addToStdlib.ifTrue +import org.jetbrains.kotlin.utils.memoryOptimizedFilter import java.io.File val KotlinLibrary.moduleName: String @@ -494,7 +494,7 @@ class ModulesStructure( val friendDependencies = allDependencies.run { val friendAbsolutePaths = friendDependenciesPaths.map { File(it).canonicalPath } - filter { + memoryOptimizedFilter { it.libraryFile.absolutePath in friendAbsolutePaths } } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt index 038bdaddd02..7242365213d 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt @@ -68,10 +68,11 @@ class JsIrLinker( } private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) : - BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion, allowErrorCode) + BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategyResolver, libraryAbiVersion, allowErrorCode, false) override fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection): IrModuleDeserializer { val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies) + icData?.let { return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it.icData) { lib -> JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategyResolver, KotlinAbiVersion.CURRENT, it.containsErrorCode) diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt index 445b960c237..3a9f633faeb 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/backend/jvm/serialization/deserializeLazyDeclarations.kt @@ -45,6 +45,7 @@ fun deserializeFromByteArray( toplevelParent: IrClass, typeSystemContext: IrTypeSystemContext, ) { + val internationService = IrInterningService() val irProto = JvmIr.ClassOrFile.parseFrom(byteArray.codedInputStream) val irLibraryFile = IrLibraryFileFromAnnotation( irProto.typeList, @@ -66,7 +67,8 @@ fun deserializeFromByteArray( fileSignature = dummyFileSignature, /* TODO */ actuals = emptyList(), enqueueLocalTopLevelDeclaration = {}, // just link to it in symbolTable - handleExpectActualMapping = { _, symbol -> symbol } // no expect declarations + handleExpectActualMapping = { _, symbol -> symbol }, // no expect declarations + internationService = internationService ) { idSignature, symbolKind -> referencePublicSymbol(symbolTable, idSignature, symbolKind) } @@ -86,7 +88,8 @@ fun deserializeFromByteArray( DefaultFakeOverrideClassFilter, fakeOverrideBuilder, compatibilityMode = CompatibilityMode.CURRENT, - partialLinkageEnabled = false + partialLinkageEnabled = false, + internationService = internationService ) for (declarationProto in irProto.declarationList) { deserializer.deserializeDeclaration(declarationProto, setParent = false) diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibIrTextTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibIrTextTestCase.kt index 63bce3733b5..749abca1460 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibIrTextTestCase.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/klib/AbstractKlibIrTextTestCase.kt @@ -231,6 +231,7 @@ abstract class AbstractKlibIrTextTestCase : CodegenTestCase() { irLinker.init(null, emptyList()) ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies() irLinker.postProcess(inOrAfterLinkageStep = true) + irLinker.clear() return testModule } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/GivenFunctionsMemberScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/GivenFunctionsMemberScope.kt index 009e2661867..aef178992c8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/GivenFunctionsMemberScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/GivenFunctionsMemberScope.kt @@ -23,7 +23,7 @@ import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.getValue -import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.filterIsInstanceAnd import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.compact import java.util.* diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt index 9203618811a..4061cab00ee 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt @@ -22,9 +22,9 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceMapTo import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.alwaysTrue +import org.jetbrains.kotlin.utils.filterIsInstanceMapTo abstract class MemberScopeImpl : MemberScope { override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = null diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/synthetic/FunInterfaceConstructorsSyntheticScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/synthetic/FunInterfaceConstructorsSyntheticScope.kt index 14936736692..a4188dd16e7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/synthetic/FunInterfaceConstructorsSyntheticScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/synthetic/FunInterfaceConstructorsSyntheticScope.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.resolve.sam.* import org.jetbrains.kotlin.resolve.scopes.SyntheticScope import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.storage.StorageManager -import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceMapNotNull +import org.jetbrains.kotlin.utils.filterIsInstanceMapNotNull class FunInterfaceConstructorsScopeProvider( storageManager: StorageManager, diff --git a/core/descriptors/src/org/jetbrains/kotlin/util/scopeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/util/scopeUtils.kt index c987e56023e..8df187e0e3c 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/util/scopeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/util/scopeUtils.kt @@ -20,7 +20,7 @@ import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.utils.SmartList -import java.util.* +import org.jetbrains.kotlin.utils.filterIsInstanceAndTo /** * Concatenates the contents of this collection with the given collection, avoiding allocations if possible. @@ -105,31 +105,6 @@ inline fun getFirstClassifierDiscriminateHeade return result } -inline fun Iterable<*>.filterIsInstanceAnd(predicate: (R) -> Boolean): Collection = - filterIsInstanceAndTo(SmartList(), predicate) - -inline fun > Iterable<*>.filterIsInstanceAndTo(destination: C, predicate: (R) -> Boolean): C { - for (element in this) if (element is R && predicate(element)) destination.add(element) - return destination +inline fun Iterable<*>.filterIsInstanceAnd(predicate: (R) -> Boolean): List { + return filterIsInstanceAndTo(SmartList(), predicate) } - -inline fun > Iterable<*>.filterIsInstanceMapTo(destination: C, transform: (T) -> R): C { - for (element in this) if (element is T) { - destination.add(transform(element)) - } - return destination -} - -inline fun Iterable<*>.filterIsInstanceMapNotNull(transform: (T) -> R?): Collection = - filterIsInstanceMapNotNullTo(SmartList(), transform) - -inline fun > Iterable<*>.filterIsInstanceMapNotNullTo(destination: C, transform: (T) -> R?): C { - for (element in this) if (element is T) { - val result = transform(element) - if (result != null) { - destination.add(result) - } - } - return destination -} - diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/CollectionUtil.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/CollectionUtil.kt new file mode 100644 index 00000000000..d7aa7cb0052 --- /dev/null +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/CollectionUtil.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.utils + +inline fun > Iterable<*>.filterIsInstanceAndTo(destination: C, predicate: (R) -> Boolean): C { + for (element in this) { + if (element is R && predicate(element)) { + destination.add(element) + } + } + return destination +} + +inline fun > Iterable<*>.filterIsInstanceMapTo(destination: C, transform: (T) -> R): C { + for (element in this) { + if (element is T) { + destination.add(transform(element)) + } + } + return destination +} + +inline fun Collection<*>.filterIsInstanceMapNotNull(transform: (T) -> R?): Collection { + if (isEmpty()) return emptyList() + return filterIsInstanceMapNotNullTo(SmartList(), transform) +} + +inline fun Collection<*>.filterIsInstanceAnd(predicate: (R) -> Boolean): List { + if (isEmpty()) return emptyList() + return filterIsInstanceAndTo(SmartList(), predicate) +} + +inline fun > Iterable<*>.filterIsInstanceMapNotNullTo( + destination: C, + transform: (T) -> R? +): C { + for (element in this) { + if (element is T) { + val result = transform(element) + if (result != null) { + destination.add(result) + } + } + } + return destination +} diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/MemoryOptimizedCollectionUtil.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/MemoryOptimizedCollectionUtil.kt new file mode 100644 index 00000000000..96c342bf88e --- /dev/null +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/MemoryOptimizedCollectionUtil.kt @@ -0,0 +1,146 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.utils + +import java.util.* +import kotlin.math.min + +/** + * A memory-optimized version of [Iterable.map]. + * @see Iterable.map + */ +inline fun Collection.memoryOptimizedMap(transform: (T) -> R): List { + return mapTo(ArrayList(size), transform).compactIfPossible() +} + +/** + * A memory-optimized version of [Iterable.mapIndexed]. + * @see Iterable.mapIndexed + */ +inline fun Collection.memoryOptimizedMapIndexed(transform: (index: Int, T) -> R): List { + return mapIndexedTo(ArrayList(size), transform).compactIfPossible() +} + +/** + * A memory-optimized version of [Iterable.mapNotNull]. + * @see Iterable.mapNotNull + */ +inline fun Collection.memoryOptimizedMapNotNull(transform: (T) -> R?): List { + return mapNotNullTo(ArrayList(), transform).compactIfPossible() +} + +/** + * A memory-optimized version of [Iterable.flatMap]. + * @see Iterable.flatMap + */ +inline fun Collection.memoryOptimizedFlatMap(transform: (T) -> Iterable): List { + return flatMapTo(ArrayList(), transform).compactIfPossible() +} + +/** + * A memory-optimized version of [Iterable.filter]. + * @see Iterable.filter + */ +inline fun Collection.memoryOptimizedFilter(predicate: (T) -> Boolean): List { + return filterTo(ArrayList(), predicate).compactIfPossible() +} + +/** + * A memory-optimized version of [Iterable.filterNot]. + * @see Iterable.filterNot + */ +inline fun Collection.memoryOptimizedFilterNot(predicate: (T) -> Boolean): List { + return filterNotTo(ArrayList(), predicate).compactIfPossible() +} + +/** + * A memory-optimized version of [Iterable.filterIsInstance]. + * @see Iterable.filterIsInstance + */ +inline fun Collection<*>.memoryOptimizedFilterIsInstance(): List { + return filterIsInstanceTo(ArrayList()).compactIfPossible() +} + +/** + * A memory-optimized version of [Iterable.plus]. + * @see Iterable.plus + */ +infix fun List.memoryOptimizedPlus(elements: List): List = + when (val resultSize = size + elements.size) { + 0 -> emptyList() + 1 -> Collections.singletonList(if (isEmpty()) elements.first() else first()) + else -> ArrayList(resultSize).also { + it.addAll(this) + it.addAll(elements) + } + } + +/** + * A memory-optimized version of [Iterable.plus]. + * @see Iterable.plus + */ +infix fun List.memoryOptimizedPlus(element: T): List = + when (size) { + 0 -> Collections.singletonList(element) + else -> ArrayList(size + 1).also { + it.addAll(this) + it.add(element) + } + } + +/** + * A memory-optimized version of [Iterable.zip]. + * @see Iterable.zip + */ +infix fun Collection.memoryOptimizedZip(other: Collection): List> { + return when { + isEmpty() || other.isEmpty() -> emptyList() + min(size, other.size) == 1 -> listOf(first() to other.first()) + else -> zip(other) { t1, t2 -> t1 to t2 } + } +} + +/** + * [Sequence] variant of [org.jetbrains.kotlin.backend.common.atMostOne] + * So, when: + * - there is no element then `null` will be returned + * - there is a single element then the element will be returned + * - there is more than one element then the error will be thrown + * @see org.jetbrains.kotlin.backend.common.atMostOne + */ +fun Sequence.atMostOne(): T? { + val iterator = iterator() + + if (!iterator.hasNext()) return null + + val single = iterator.next() + + if (iterator.hasNext()) { + throw IllegalArgumentException("Sequence has more than one element.") + } + + return single +} + +/** + * The variant of [org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd] extension function but to find the first element + * which is an instance of type [T] and satisfies [predicate] condition + * @see org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd + */ +inline fun Iterable<*>.findIsInstanceAnd(predicate: (T) -> Boolean): T? { + for (element in this) { + if (element is T && predicate(element)) { + return element + } + } + return null +} + +/** + * The same as [Collection.toMutableList] extension function, but it returns a SmartList which is better with in sense of memory consumption + * @see Collection.toMutableList + */ +fun Collection.toSmartList(): List = SmartList(this) \ No newline at end of file diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/collections.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/collections.kt index 0263bdac6ca..8deedaa1a99 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/utils/collections.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/collections.kt @@ -86,6 +86,21 @@ fun ArrayList.compact(): List = else -> apply { trimToSize() } } + +/** + * The same as [org.jetbrains.kotlin.utils.compact] extension function, but it could be used with the + * immutable list type (without [java.util.ArrayList.trimToSize] for the collections with more than 1 element) + * @see org.jetbrains.kotlin.utils.compact + */ +fun List.compactIfPossible(): List = + when (size) { + 0 -> emptyList() + 1 -> listOf(first()) + else -> apply { + if (this is ArrayList<*>) trimToSize() + } + } + fun List.indexOfFirst(startFrom: Int, predicate: (T) -> Boolean): Int { for (index in startFrom..lastIndex) { if (predicate(this[index])) return index diff --git a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt index 2fa13c4f7df..bc818bdbb68 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt @@ -560,6 +560,7 @@ class GenerateIrRuntime { .generateUnboundSymbolsAsDependencies() jsLinker.postProcess(inOrAfterLinkageStep = true) + jsLinker.clear() moduleFragment.patchDeclarationParents() @@ -586,6 +587,7 @@ class GenerateIrRuntime { .generateUnboundSymbolsAsDependencies() jsLinker.postProcess(inOrAfterLinkageStep = true) + jsLinker.clear() moduleFragment.patchDeclarationParents() diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/RunnerUtils.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/RunnerUtils.kt index 7dc59d13c1e..779eeae405c 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/RunnerUtils.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/RunnerUtils.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.* import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator.Companion.getMainModule -import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd +import org.jetbrains.kotlin.utils.filterIsInstanceAnd import java.io.File const val MODULE_EMULATION_FILE = "${JsEnvironmentConfigurator.TEST_DATA_DIR_PATH}/moduleEmulation.js"