Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 49479e4

Browse files
committed
Do not cache overall class
This reduces some memory overhead for negligible performance cost. Residual (post link memory) benchmarks for the test suite: Baseline: 1.13 GB, new 1.01 GB
1 parent 3fc4295 commit 49479e4

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

+26-24
Original file line numberDiff line numberDiff line change
@@ -620,9 +620,9 @@ final class Emitter[E >: Null <: js.Transformed.Value](
620620
}
621621

622622
val fullClass = extractChanged {
623-
val fullClassCache = classCache.getFullClassCache()
623+
val fullClassChangeTracker = classCache.getFullClassChangeTracker()
624624

625-
fullClassCache.getOrElseUpdate(linkedClass.version, ctorWithGlobals,
625+
fullClassChangeTracker.trackChanged(linkedClass.version, ctorWithGlobals,
626626
memberMethodsWithGlobals, exportedMembersWithGlobals, {
627627
for {
628628
ctor <- ctorWithGlobals
@@ -639,7 +639,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
639639
storeJSSuperClass.map(js.Transformed(_)), // invalidated by class version
640640
useESClass, // invalidated by class version (depends on kind, config and ancestry only)
641641
membersAsTrees // invalidated directly
642-
)(moduleContext, fullClassCache, linkedClass.pos) // pos invalidated by class version
642+
)(moduleContext, fullClassChangeTracker, linkedClass.pos) // pos invalidated by class version
643643
} yield {
644644
// Avoid a nested post transform if we just got the original members back.
645645
if (clazz eq membersAsTrees) {
@@ -863,7 +863,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
863863
private[this] val _exportedMembersCache =
864864
mutable.Map.empty[Int, MethodCache[E]]
865865

866-
private[this] var _fullClassCache: Option[FullClassCache] = None
866+
private[this] var _fullClassChangeTracker: Option[FullClassChangeTracker] = None
867867

868868
override def invalidate(): Unit = {
869869
/* Do not invalidate contained methods, as they have their own
@@ -879,7 +879,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
879879
_methodCaches.foreach(_.valuesIterator.foreach(_.startRun()))
880880
_memberMethodCache.valuesIterator.foreach(_.startRun())
881881
_constructorCache.foreach(_.startRun())
882-
_fullClassCache.foreach(_.startRun())
882+
_fullClassChangeTracker.foreach(_.startRun())
883883
}
884884

885885
def getCache(version: Version): (DesugaredClassCache[E], Boolean) = {
@@ -918,10 +918,10 @@ final class Emitter[E >: Null <: js.Transformed.Value](
918918
def getExportedMemberCache(idx: Int): MethodCache[E] =
919919
_exportedMembersCache.getOrElseUpdate(idx, new MethodCache)
920920

921-
def getFullClassCache(): FullClassCache = {
922-
_fullClassCache.getOrElse {
923-
val cache = new FullClassCache
924-
_fullClassCache = Some(cache)
921+
def getFullClassChangeTracker(): FullClassChangeTracker = {
922+
_fullClassChangeTracker.getOrElse {
923+
val cache = new FullClassChangeTracker
924+
_fullClassChangeTracker = Some(cache)
925925
cache
926926
}
927927
}
@@ -935,8 +935,8 @@ final class Emitter[E >: Null <: js.Transformed.Value](
935935

936936
_exportedMembersCache.filterInPlace((_, c) => c.cleanAfterRun())
937937

938-
if (_fullClassCache.exists(!_.cleanAfterRun()))
939-
_fullClassCache = None
938+
if (_fullClassChangeTracker.exists(!_.cleanAfterRun()))
939+
_fullClassChangeTracker = None
940940

941941
if (!_cacheUsed)
942942
invalidate()
@@ -981,26 +981,24 @@ final class Emitter[E >: Null <: js.Transformed.Value](
981981
}
982982
}
983983

984-
private class FullClassCache extends knowledgeGuardian.KnowledgeAccessor {
985-
private[this] var _tree: WithGlobals[List[E]] = null
984+
private class FullClassChangeTracker extends knowledgeGuardian.KnowledgeAccessor {
986985
private[this] var _lastVersion: Version = Version.Unversioned
987986
private[this] var _lastCtor: WithGlobals[E] = null
988987
private[this] var _lastMemberMethods: List[WithGlobals[E]] = null
989988
private[this] var _lastExportedMembers: List[WithGlobals[E]] = null
990-
private[this] var _cacheUsed = false
989+
private[this] var _trackerUsed = false
991990

992991
override def invalidate(): Unit = {
993992
super.invalidate()
994-
_tree = null
995993
_lastVersion = Version.Unversioned
996994
_lastCtor = null
997995
_lastMemberMethods = null
998996
_lastExportedMembers = null
999997
}
1000998

1001-
def startRun(): Unit = _cacheUsed = false
999+
def startRun(): Unit = _trackerUsed = false
10021000

1003-
def getOrElseUpdate(version: Version, ctor: WithGlobals[E],
1001+
def trackChanged(version: Version, ctor: WithGlobals[E],
10041002
memberMethods: List[WithGlobals[E]], exportedMembers: List[WithGlobals[E]],
10051003
compute: => WithGlobals[List[E]]): (WithGlobals[List[E]], Boolean) = {
10061004

@@ -1012,28 +1010,32 @@ final class Emitter[E >: Null <: js.Transformed.Value](
10121010
}
10131011
}
10141012

1015-
_cacheUsed = true
1013+
_trackerUsed = true
10161014

1017-
if (_tree == null || !version.sameVersion(_lastVersion) || (_lastCtor ne ctor) ||
1015+
if (!version.sameVersion(_lastVersion) || (_lastCtor ne ctor) ||
10181016
!allSame(_lastMemberMethods, memberMethods) ||
10191017
!allSame(_lastExportedMembers, exportedMembers)) {
1018+
// Input has changed or we were invalidated.
1019+
// Clean knowledge tracking and re-track dependencies.
10201020
invalidate()
1021-
_tree = compute
10221021
_lastVersion = version
10231022
_lastCtor = ctor
10241023
_lastMemberMethods = memberMethods
10251024
_lastExportedMembers = exportedMembers
1026-
(_tree, true)
1025+
1026+
(compute, true)
10271027
} else {
1028-
(_tree, false)
1028+
// Input has not changed and we were not invalidated.
1029+
// --> nothing has changed (we recompute to save memory).
1030+
(compute, false)
10291031
}
10301032
}
10311033

10321034
def cleanAfterRun(): Boolean = {
1033-
if (!_cacheUsed)
1035+
if (!_trackerUsed)
10341036
invalidate()
10351037

1036-
_cacheUsed
1038+
_trackerUsed
10371039
}
10381040
}
10391041

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

+7-4
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)