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

Skip to content

Commit c131ea7

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 ea5a7c4 commit c131ea7

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
@@ -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+
(compute, true)
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

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