8000 Separate IRFileCache into super-stable / stable API · sueka/scala-js@a9930ba · GitHub
[go: up one dir, main page]

Skip to content

Commit a9930ba

Browse files
committed
Separate IRFileCache into super-stable / stable API
Note that the super-stable part currently still references some classes from irio which is to become stable only. We'll fix this in the next commit.
1 parent 295742d commit a9930ba

File tree

6 files changed

+93
-53
lines changed

6 files changed

+93
-53
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Scala.js (https://www.scala-js.org/)
3+
*
4+
* Copyright EPFL.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (https://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package org.scalajs.linker
14+
15+
import scala.concurrent._
16+
17+
import org.scalajs.linker.irio._
18+
import org.scalajs.linker.standard.StandardIRFileCache
19+
20+
/** Centralized Scala.js IR cache.
21+
*
22+
* Caches all Scala.js IR used in a given JVM. It supports creating of multiple
23+
* sub-caches ([[IRFileCache.Cache]]) that track individual file sets.
24+
* The global cache is fully thread-safe. However, the sub-caches are not.
25+
*/
26+
abstract class IRFileCache private[linker] () {
27+
/** Create a new sub-cache.
28+
*
29+
* Users should call [[IRFileCache.Cache.free]] once they are done to allow
30+
* for more aggressive GC.
31+
*/
32+
def newCache: IRFileCache.Cache
33+
34+
/** Approximate statistics about the cache usage */
35+
def stats: IRFileCache.Stats
36+
37+
/** Reset statistics */
38+
def clearStats(): Unit
39+
}
40+
41+
object IRFileCache {
42+
def apply(): IRFileCache = new StandardIRFileCache()
43+
44+
/** A cache to use for individual runs. Not threadsafe */
45+
abstract class Cache private[linker] () {
46+
/** Extract and cache IR.
47+
*
48+
* The returned value is valid until the next invocation of [[cached]] or
49+
* [[free]].
50+
*
51+
* @note Updating any of the underlying files in the container during the
52+
* lifetime of a returned [[irio.VirtualScalaJSIRFile]] yields
53+
* unspecified behavior.
54+
*/
55+
def cached(files: Seq[ScalaJSIRContainer])(
56+
implicit ec: ExecutionContext): Future[Seq[VirtualScalaJSIRFile]]
57+
58+
/** Should be called if this cache is not used anymore.
59+
*
60+
* Frees resources in the global cache, if they are not used anymore.
61+
* The cache may be reused after calling [[free]] (but this is not any
62+
* faster than calling [[IRFileCache.newCache]], modulo the object
63+
* allocation).
64+
*/
65+
def free(): Unit
66+
}
67+
68+
/** Statistics about an individual run. */
69+
abstract class Stats private[linker] {
70+
/** Descriptive line to display in logs */
71+
def logLine: String
72+
}
73+
}

linker/shared/src/main/scala/org/scalajs/linker/irio/IRFileCache.scala renamed to linker/shared/src/main/scala/org/scalajs/linker/standard/StandardIRFileCache.scala

Lines changed: 16 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* additional information regarding copyright ownership.
1111
*/
1212

13-
package org.scalajs.linker.irio
13+
package org.scalajs.linker.standard
1414

1515
import scala.annotation.tailrec
1616
import scala.concurrent._
@@ -24,19 +24,16 @@ import java.util.concurrent.atomic.AtomicInteger
2424
import org.scalajs.ir.EntryPointsInfo
2525
import org.scalajs.ir.Trees.ClassDef
2626

27-
/** Centralized Scala.js IR cache.
28-
*
29-
* Caches all Scala.js IR used in a given JVM. It supports creating of multiple
30-
* sub-caches ([[IRFileCache.Cache]]) that track individual file sets.
31-
* The global cache is fully thread-safe. However, the sub-caches are not.
32-
*/
33-
final class IRFileCache {
27+
import org.scalajs.linker.irio._
28+
import org.scalajs.linker.IRFileCache
29+
30+
final class StandardIRFileCache extends IRFileCache {
3431
/* General implementation comment: We always synchronize before doing I/O
3532
* (instead of using a calculate and CAS pattern). This is since we assume
3633
* that paying the cost for synchronization is lower than I/O.
3734
*/
3835

39-
import IRFileCache._
36+
import StandardIRFileCache.Stats
4037

4138
/** Holds the cached IR */
4239
private[this] val globalCache = new ConcurrentHashMap[String, PersistedFiles]
@@ -46,27 +43,18 @@ final class IRFileCache {
4643
private[this] val statsInvalidated = new AtomicInteger(0)
4744
private[this] val statsTreesRead = new AtomicInteger(0)
4845

49-
/** Create a new sub-cache.
50-
*
51-
* Users should call [[IRFileCache.Cache.free]] once they are done to allow
52-
* for more aggressive GC.
53-
*/
54-
def newCache: Cache = new CacheImpl
46+
def newCache: IRFileCache.Cache = new CacheImpl
5547

56-
/** Approximate statistics about the cache usage */
57-
def stats: IRFileCache.Stats = {
58-
new IRFileCache.Stats(statsReused.get, statsInvalidated.get,
59-
statsTreesRead.get)
60-
}
48+
def stats: Stats =
49+
new Stats(statsReused.get, statsInvalidated.get, statsTreesRead.get)
6150

62-
/** Reset statistics */
6351
def clearStats(): Unit = {
6452
statsReused.set(0)
6553
statsInvalidated.set(0)
6654
statsTreesRead.set(0)
6755
}
6856

69-
private final class CacheImpl extends Cache {
57+
private final class CacheImpl extends IRFileCache.Cache {
7058
private[this] var localCache: Seq[PersistedFiles] = _
7159

7260
def cached(files: Seq[ScalaJSIRContainer])(
@@ -274,33 +262,12 @@ final class IRFileCache {
274262
}
275263
}
276264

277-
object IRFileCache {
278-
/** A cache to use for individual runs. Not threadsafe */
279-
sealed trait Cache {
280-
/** Extract and cache IR.
281-
*
282-
* The returned value is valid until the next invocation of [[cached]] or
283-
* [[free]].
284-
*
285-
* @note Updating any of the underlying files in the container during the
286-
* lifetime of a returned [[VirtualScalaJSIRFile]] yields
287-
* unspecified behavior.
288-
*/
289-
def cached(files: Seq[ScalaJSIRContainer])(
290-
implicit ec: ExecutionContext): Future[Seq[VirtualScalaJSIRFile]]
291-
292-
/** Should be called if this cache is not used anymore.
293-
*
294-
* Frees resources in the global cache, if they are not used anymore.
295-
* The cache may be reused after calling [[free]] (but this is not any
296-
* faster than calling [[IRFileCache.newCache]], modulo the object
297-
* allocation).
298-
*/
299-
def free(): Unit
300-
}
301-
302-
final class Stats(val reused: Int, val invalidated: Int, val treesRead: Int) {
303-
/** Descriptive line to display in logs */
265+
object StandardIRFileCache {
266+
final class Stats private[StandardIRFileCache] (
267+
val reused: Int,
268+
val invalidated: Int,
269+
val treesRead: Int
270+
) extends IRFileCache.Stats {
304271
def logLine: String = {
305272
s"reused: $reused -- " +
306273
s"invalidated: $invalidated -- " +

linker/shared/src/test/scala/org/scalajs/linker/testutils/TestIRRepo.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ final class TestIRRepo(stdlibPath: String) {
4343
import scala.concurrent.ExecutionContext.Implicits.global
4444
import TestIRRepo.InfoLoader
4545

46-
private val globalIRCache = new IRFileCache
46+
private val globalIRCache = IRFileCache()
4747

4848
val stdlibIRFiles: Future[Seq[VirtualScalaJSIRFile]] = {
4949
Platform.loadJar(stdlibPath).flatMap(

partest/src/main/scala/scala/tools/nsc/MainGenericRunner.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class MainGenericRunner {
9898
val sjsCode = {
9999
val file = Jimfs.newFileSystem().getPath("partest.js")
100100

101-
val cache = (new IRFileCache).newCache
101+
val cache = IRFileCache().newCache
102102
val result = FileScalaJSIRContainer
103103
.fromClasspath(command.settings.classpathURLs.map(urlToPath _))
104104
.flatMap(cache.cached _)

sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPluginInternal.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ private[sbtplugin] object ScalaJSPluginInternal {
5050
import ScalaJSPlugin.logIRCacheStats
5151

5252
/** The global Scala.js IR cache */
53-
val globalIRCache: IRFileCache = new IRFileCache()
53+
val globalIRCache: IRFileCache = IRFileCache()
5454

5555
@tailrec
5656
final private def registerResource[T <: AnyRef](

test-suite-linker/src/main/scala/org/scalajs/bootstrap/TestSuiteLinker.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ object QuickLinker {
4242
.withSourceMapURI(relURI(smPath))
4343
.withJSFileURI(relURI(outputPath))
4444

45-
val cache = (new IRFileCache).newCache
45+
val cache = IRFileCache().newCache
4646

4747
NodeScalaJSIRContainer.fromClasspath(cp.toSeq)
4848
.flatMap(cache.cached _)

0 commit comments

Comments
 (0)
0