8000 Do not cache overall class · scala-js/scala-js@79ea629 · GitHub
[go: up one dir, main page]

Skip to content

Commit 79ea629

Browse files
committed
Do not cache overall class
This reduces some memory overhead for negligible performance cost.
1 parent ea5a7c4 commit 79ea629

File tree

2 files changed

+33
-28
lines changed

2 files changed

+33
-28
lines changed

linker/shared/src/main/scala/org/scalajs/linker/backend/emitter/Emitter.scala

Lines changed: 26 additions & 24 deletions
< 2364 td data-grid-cell-id="diff-cc66873dd084b73e1e8f3b9179881f68ed00ed75362c5e96ecd2a26c3dce45b5-1012-1012-2" data-line-anchor="diff-cc66873dd084b73e1e8f3b9179881f68ed00ed75362c5e96ecd2a26c3dce45b5R1012" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-additionLine-bgColor, var(--diffBlob-addition-bgColor-line));padding-right:24px" tabindex="-1" valign="top" class="focusable-grid-cell diff-text-cell right-side-diff-cell left-side">+
(compute, true)
Original file line numberDiff line numberDiff line change
@@ -616,9 +616,9 @@ final class Emitter[E >: Null <: js.Transformed.Value](
616616
}
617617

618618
val fullClass = extractChanged {
619-
val fullClassCache = classCache.getFullClassCache()
619+
val fullClassChangeTracker = classCache.getFullClassChangeTracker()
620620

621-
fullClassCache.getOrElseUpdate(linkedClass.version, ctorWithGlobals,
621+
fullClassChangeTracker.trackChanged(linkedClass.version, ctorWithGlobals,
622622
memberMethodsWithGlobals, exportedMembersWithGlobals, {
623623
for {
624624
ctor <- ctorWithGlobals
@@ -635,7 +635,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
635635
storeJSSuperClass.map(js.Transformed(_)), // invalidated by class version
636636
useESClass, // invalidated by class version (depends on kind, config and ancestry only)
637637
membersAsTrees, // invalidated directly
638-
)(moduleContext, fullClassCache, linkedClass.pos) // pos invalidated by class version
638+
)(moduleContext, fullClassChangeTracker, linkedClass.pos) // pos invalidated by class version
639639
} yield {
640640
// Avoid a nested post transform if we just got the original members back.
641641
if (clazz eq membersAsTrees) {
@@ -849,7 +849,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
849849
private[this] val _exportedMembersCache =
850850
mutable.Map.empty[Int, MethodCache[E]]
851851

852-
private[this] var _fullClassCache: Option[FullClassCache] = None
852+
private[this] var _fullClassChangeTracker: Option[FullClassChangeTracker] = None
853853

854854
override def invalidate(): Unit = {
855855
/* Do not invalidate contained methods, as they have their own
@@ -865,7 +865,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
865865
_methodCaches.foreach(_.valuesIterator.foreach(_.startRun()))
866866
_memberMethodCache.valuesIterator.foreach(_.startRun())
867867
_constructorCache.foreach(_.startRun())
868-
_fullClassCache.foreach(_.startRun())
868+
_fullClassChangeTracker.foreach(_.startRun())
869869
}
870870

871871
def getCache(version: Version): (DesugaredClassCache[E], Boolean) = {
@@ -904,10 +904,10 @@ final class Emitter[E >: Null <: js.Transformed.Value](
904904
def getExportedMemberCache(idx: Int): MethodCache[E] =
905905
_exportedMembersCache.getOrElseUpdate(idx, new MethodCache)
906906

907-
def getFullClassCache(): FullClassCache = {
908-
_fullClassCache.getOrElse {
909-
val cache = new FullClassCache
910-
_fullClassCache = Some(cache)
907+
def getFullClassChangeTracker(): FullClassChangeTracker = {
908+
_fullClassChangeTracker.getOrElse {
909+
val cache = new FullClassChangeTracker
910+
_fullClassChangeTracker = Some(cache)
911911
cache
912912
}
913913
}
@@ -921,8 +921,8 @@ final class Emitter[E >: Null <: js.Transformed.Value](
921921

922922
_exportedMembersCache.filterInPlace((_, c) => c.cleanAfterRun())
923923

924-
if (_fullClassCache.exists(!_.cleanAfterRun()))
925-
_fullClassCache = None
924+
if (_fullClassChangeTracker.exists(!_.cleanAfterRun()))
925+
_fullClassChangeTracker = None
926926

927927
if (!_cacheUsed)
928928
invalidate()
@@ -967,26 +967,24 @@ final class Emitter[E >: Null <: js.Transformed.Value](
967967
}
968968
}
969969

970-
private class FullClassCache extends knowledgeGuardian.KnowledgeAccessor {
971-
private[this] var _tree: WithGlobals[List[E]] = null
970+
private class FullClassChangeTracker extends knowledgeGuardian.KnowledgeAccessor {
972971
private[this] var _lastVersion: Version = Version.Unversioned
973972
private[this] var _lastCtor: WithGlobals[E] = null
974973
private[this] var _lastMemberMethods: List[WithGlobals[E]] = null
975974
private[this] var _lastExportedMembers: List[WithGlobals[E]] = null
976-
private[this] var _cacheUsed = false
975+
private[this] var _trackerUsed = false
977976

978977
override def invalidate(): Unit = {
979978
super.invalidate()
980-
_tree = null
981979
_lastVersion = Version.Unversioned
982980
_lastCtor = null
983981
_lastMemberMethods = null
984982
_lastExportedMembers = null
985983
}
986984

987-
def startRun(): Unit = _cacheUsed = false
985+
def startRun(): Unit = _trackerUsed = false
988986

989-
def getOrElseUpdate(version: Version, ctor: WithGlobals[E],
987+
def trackChanged(version: Version, ctor: WithGlobals[E],
990988
memberMethods: List[WithGlobals[E]], exportedMembers: List[WithGlobals[E]],
991989
compute: => WithGlobals[List[E]]): (WithGlobals[List[E]], Boolean) = {
992990

@@ -998,28 +996,32 @@ final class Emitter[E >: Null <: js.Transformed.Value](
998996
}
999997
}
1000998

1001-
_cacheUsed = true
999+
_trackerUsed = true
10021000

1003-
if (_tree == null || !version.sameVersion(_lastVersion) || (_lastCtor ne ctor) ||
1001+
if (!version.sameVersion(_lastVersion) || (_lastCtor ne ctor) ||
10041002
!allSame(_lastMemberMethods, memberMethods) ||
10051003
!allSame(_lastExportedMembers, exportedMembers)) {
1004+
// Input has changed or we were invalidated.
1005+
// Clean knowledge tracking and re-track dependencies.
10061006
invalidate()
1007-
_tree = compute
10081007
_lastVersion = version
10091008
_lastCtor = ctor
10101009
_lastMemberMethods = memberMethods
10111010
_lastExportedMembers = exportedMembers
1012-
(_tree, true)
1011+
1012
10131013
} else {
1014-
(_tree, false)
1014+
// Input has not changed and we were not invalidated.
1015+
// --> nothing has changed (we recompute to save memory).
1016+
(compute, false)
10151017
}
10161018
}
10171019

10181020
def cleanAfterRun(): Boolean = {
1019-
if (!_cacheUsed)
1021+
if (!_trackerUsed)
10201022
invalidate()
10211023

1022-
_cacheUsed
1024+
_trackerUsed
10231025
}
10241026
}
10251027

linker/shared/src/test/scala/org/scalajs/linker/EmitterTest.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,18 +208,21 @@ class EmitterTest {
208208

209209
// Post transforms
210210

211-
val Seq(postTransforms1, _, _) =
211+
val Seq(postTransforms1, nestedPostTransforms1, _) =
212212
lines1.assertContainsMatch(EmitterPostTransformStatsMessage).map(_.toInt)
213213

214-
val Seq(postTransforms2, _, _) =
214+
val Seq(postTransforms2, nestedPostTransforms2, _) =
215215
lines2.assertContainsMatch(EmitterPostTransformStatsMessage).map(_.toInt)
216216

217-
// At the time of writing this test, postTransformsTotal1 reports 216
217+
// At the time of writing this test, postTransforms1 reports 216
218218
assertTrue(
219219
s"Not enough post transforms (got $postTransforms1); extraction must have gone wrong",
220220
postTransforms1 > 200)
221221

222-
assertEquals("Second run must not have any post transforms", 0, postTransforms2)
222+
assertEquals("Second run must only have nested post transforms",
223+
nestedPostTransforms2, postTransforms2)
224+
assertEquals("Both runs must have the same number of nested post transforms",
225+
nestedPostTransforms1, nestedPostTransforms2)
223226
}
224227
}
225228
}

0 commit comments

Comments
 (0)
0