Skip to content

Commit f425dea

Browse files
dimonchik0036Space Team
authored andcommitted
[CLI] JvmDependenciesIndexImpl: add lock to make it thread safe
Can be rewritten to multi-thread implementation in the feature ^KT-56550
1 parent 15dfe6c commit f425dea

File tree

1 file changed

+32
-35
lines changed

1 file changed

+32
-35
lines changed

compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/index/JvmDependenciesIndexImpl.kt

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
/*
2-
* Copyright 2010-2016 JetBrains s.r.o.
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
2+
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
154
*/
165

176
package org.jetbrains.kotlin.cli.jvm.index
@@ -23,13 +12,16 @@ import com.intellij.openapi.vfs.VirtualFile
2312
import gnu.trove.THashMap
2413
import org.jetbrains.kotlin.name.ClassId
2514
import org.jetbrains.kotlin.name.FqName
26-
import org.jetbrains.kotlin.utils.IntArrayList
2715
import java.util.*
16+
import java.util.concurrent.locks.ReentrantLock
17+
import kotlin.concurrent.withLock
2818

2919
// speeds up finding files/classes in classpath/java source roots
30-
// NOT THREADSAFE, needs to be adapted/removed if we want compiler to be multithreaded
20+
// TODO: KT-58327 needs to be adapted/removed if we want compiler to be multithreaded
3121
// the main idea of this class is for each package to store roots which contains it to avoid excessive file system traversal
3222
class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex {
23+
private val lock = ReentrantLock()
24+
3325
//these fields are computed based on _roots passed to constructor which are filled in later
3426
private val roots: List<JavaRoot> by lazy { _roots.toList() }
3527

@@ -74,8 +66,10 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex {
7466
acceptedRootTypes: Set<JavaRoot.RootType>,
7567
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
7668
) {
77-
search(TraverseRequest(packageFqName, acceptedRootTypes)) { dir, rootType ->
78-
if (continueSearch(dir, rootType)) null else Unit
69+
lock.withLock {
70+
search(TraverseRequest(packageFqName, acceptedRootTypes)) { dir, rootType ->
71+
if (continueSearch(dir, rootType)) null else Unit
72+
}
7973
}
8074
}
8175

@@ -85,26 +79,29 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>) : JvmDependenciesIndex {
8579
acceptedRootTypes: Set<JavaRoot.RootType>,
8680
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
8781
): T? {
88-
// make a decision based on information saved from last class search
89-
if (lastClassSearch?.first?.classId != classId) {
90-
return search(FindClassRequest(classId, acceptedRootTypes), findClassGivenDirectory)
91-
}
82+
lock.withLock {
83+
// TODO: KT-58327 probably should be changed to thread local to fix fast-path
84+
// make a decision based on information saved from last class search
85+
if (lastClassSearch?.first?.classId != classId) {
86+
return search(FindClassRequest(classId, acceptedRootTypes), findClassGivenDirectory)
87+
}
9288

93-
val (cachedRequest, cachedResult) = lastClassSearch!!
94-
return when (cachedResult) {
95-
is SearchResult.NotFound -> {
96-
val limitedRootTypes = acceptedRootTypes - cachedRequest.acceptedRootTypes
97-
if (limitedRootTypes.isEmpty()) {
98-
null
99-
} else {
100-
search(FindClassRequest(classId, limitedRootTypes), findClassGivenDirectory)
89+
val (cachedRequest, cachedResult) = lastClassSearch!!
90+
return when (cachedResult) {
91+
is SearchResult.NotFound -> {
92+
val limitedRootTypes = acceptedRootTypes - cachedRequest.acceptedRootTypes
93+
if (limitedRootTypes.isEmpty()) {
94+
null
95+
} else {
96+
search(FindClassRequest(classId, limitedRootTypes), findClassGivenDirectory)
97+
}
10198
}
102-
}
103-
is SearchResult.Found -> {
104-
if (cachedRequest.acceptedRootTypes == acceptedRootTypes) {
105-
findClassGivenDirectory(cachedResult.packageDirectory, cachedResult.root.type)
106-
} else {
107-
search(FindClassRequest(classId, acceptedRootTypes), findClassGivenDirectory)
99+
is SearchResult.Found -> {
100+
if (cachedRequest.acceptedRootTypes == acceptedRootTypes) {
101+
findClassGivenDirectory(cachedResult.packageDirectory, cachedResult.root.type)
102+
} else {
103+
search(FindClassRequest(classId, acceptedRootTypes), findClassGivenDirectory)
104+
}
108105
}
109106
}
110107
}

0 commit comments

Comments
 (0)