Skip to content

Commit e4a3318

Browse files
committed
Add multi-thread to ObjcExportHeaderGenerator when processing packageFragments
KT-82436
1 parent f32be28 commit e4a3318

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

native/objcexport-header-generator/impl/k1/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
1414
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
1515
import org.jetbrains.kotlin.descriptors.SourceFile
1616
import org.jetbrains.kotlin.resolve.scopes.MemberScope
17+
import java.util.concurrent.Executors
18+
import java.util.concurrent.TimeUnit
19+
import java.util.Collections.synchronizedList
1720

1821
abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor(
1922
val moduleDescriptors: List<ModuleDescriptor>,
@@ -22,6 +25,7 @@ abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor(
2225
val objcGenerics: Boolean,
2326
val objcExportBlockExplicitParameterNames: Boolean,
2427
problemCollector: ObjCExportProblemCollector,
28+
val threadsCount: Int = Runtime.getRuntime().availableProcessors()
2529
) {
2630
private val stubs = mutableListOf<ObjCExportStub>()
2731

@@ -117,31 +121,49 @@ abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor(
117121
.flatMap { it.getPackageFragments() }
118122
.makePackagesOrderStable()
119123

124+
val classesToTranslate = synchronizedList(mutableListOf<ClassDescriptor>())
125+
126+
val executor = if (threadsCount > 1) {
127+
Executors.newFixedThreadPool(threadsCount)
128+
} else {
129+
null
130+
}
131+
132+
120133
packageFragments.forEach { packageFragment ->
121-
packageFragment.getMemberScope().getContributedDescriptors()
134+
val memberScope = packageFragment.getMemberScope()
135+
136+
val task = {
137+
memberScope.getContributedDescriptors()
122138
.asSequence()
123139
.filterIsInstance<CallableMemberDescriptor>()
124140
.filter { mapper.shouldBeExposed(it) }
125141
.forEach {
126142
val classDescriptor = getClassIfCategory(it)
127143
if (classDescriptor == null) {
128-
topLevel.getOrPut(it.findSourceFile(), { mutableListOf() }) += it
144+
synchronized(topLevel) {
145+
topLevel.getOrPut(it.findSourceFile(), { mutableListOf() }) += it
146+
}
129147
} else {
130148
// If a class is hidden from Objective-C API then it is meaningless
131149
// to export its extensions.
132150
if (!classDescriptor.isHiddenFromObjC()) {
133-
extensions.getOrPut(classDescriptor, { mutableListOf() }) += it
151+
synchronized(extensions) {
152+
extensions.getOrPut(classDescriptor, { mutableListOf() }) += it
153+
}
134154
}
135155
}
136156
}
137-
}
157+
}
138158

139-
val classesToTranslate = mutableListOf<ClassDescriptor>()
159+
executor?.submit(task) ?: task()
140160

141-
packageFragments.forEach { packageFragment ->
142-
packageFragment.getMemberScope().collectClasses(classesToTranslate)
161+
memberScope.collectClasses(classesToTranslate)
143162
}
144163

164+
executor?.shutdown()
165+
executor?.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)
166+
145167
classesToTranslate.makeClassesOrderStable().forEach { translateClass(it) }
146168

147169
extensions.makeCategoriesOrderStable().forEach { (classDescriptor, declarations) ->

0 commit comments

Comments
 (0)