@@ -112,7 +112,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
112
112
}
113
113
114
114
private def emitInternal (moduleSet : ModuleSet ,
115
- logger : Logger ): WithGlobals [Map [ModuleID , List [E ]]] = {
115
+ logger : Logger ): WithGlobals [Map [ModuleID , ( List [E ], Boolean ) ]] = {
116
116
// Reset caching stats.
117
117
statsClassesReused = 0
118
118
statsClassesInvalidated = 0
@@ -172,7 +172,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
172
172
*/
173
173
@ tailrec
174
174
private def emitAvoidGlobalClash (moduleSet : ModuleSet ,
175
- logger : Logger , secondAttempt : Boolean ): WithGlobals [Map [ModuleID , List [E ]]] = {
175
+ logger : Logger , secondAttempt : Boolean ): WithGlobals [Map [ModuleID , ( List [E ], Boolean ) ]] = {
176
176
val result = emitOnce(moduleSet, logger)
177
177
178
178
val mentionedDangerousGlobalRefs =
@@ -197,7 +197,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
197
197
}
198
198
199
199
private def emitOnce (moduleSet : ModuleSet ,
200
- logger : Logger ): WithGlobals [Map [ModuleID , List [E ]]] = {
200
+ logger : Logger ): WithGlobals [Map [ModuleID , ( List [E ], Boolean ) ]] = {
201
201
// Genreate classes first so we can measure time separately.
202
202
val generatedClasses = logger.time(" Emitter: Generate Classes" ) {
203
203
moduleSet.modules.map { module =>
@@ -215,18 +215,26 @@ final class Emitter[E >: Null <: js.Transformed.Value](
215
215
216
216
val moduleTrees = logger.time(" Emitter: Write trees" ) {
217
217
moduleSet.modules.map { module =>
218
+ var changed = false
219
+ def extractChangedAndWithGlobals [T ](x : (WithGlobals [T ], Boolean )): T = {
220
+ changed ||= x._2
221
+ extractWithGlobals(x._1)
222
+ }
223
+
218
224
val moduleContext = ModuleContext .fromModule(module)
219
225
val moduleCache = state.moduleCaches.getOrElseUpdate(module.id, new ModuleCache )
220
226
221
227
val moduleClasses = generatedClasses(module.id)
222
228
223
- val moduleImports = extractWithGlobals {
229
+ changed ||= moduleClasses.exists(_.changed)
230
+
231
+ val moduleImports = extractChangedAndWithGlobals {
224
232
moduleCache.getOrComputeImports(module.externalDependencies, module.internalDependencies) {
225
233
genModuleImports(module).map(postTransform(_, 0 ))
226
234
}
227
235
}
228
236
229
- val topLevelExports = extractWithGlobals {
237
+ val topLevelExports = extractChangedAndWithGlobals {
230
238
/* We cache top level exports all together, rather than individually,
231
239
* since typically there are few.
232
240
*/
@@ -236,7 +244,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
236
244
}
237
245
}
238
246
239
- val moduleInitializers = extractWithGlobals {
247
+ val moduleInitializers = extractChangedAndWithGlobals {
240
248
val initializers = module.initializers.toList
241
249
moduleCache.getOrComputeInitializers(initializers) {
242
250
WithGlobals .list(initializers.map { initializer =>
@@ -327,7 +335,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
327
335
trackedGlobalRefs = unionPreserveEmpty(trackedGlobalRefs, genClass.trackedGlobalRefs)
328
336
}
329
337
330
- module.id -> allTrees
338
+ module.id -> ( allTrees, changed)
331
339
}
332
340
}
333
341
@@ -385,8 +393,14 @@ final class Emitter[E >: Null <: js.Transformed.Value](
385
393
val classCache = classCaches.getOrElseUpdate(
386
394
new ClassID (linkedClass.ancestors, moduleContext), new ClassCache )
387
395
396
+ var changed = false
397
+ def extractChanged [T ](x : (T , Boolean )): T = {
398
+ changed ||= x._2
399
+ x._1
400
+ }
401
+
388
402
val classTreeCache =
389
- classCache.getCache(linkedClass.version)
403
+ extractChanged( classCache.getCache(linkedClass.version) )
390
404
391
405
val kind = linkedClass.kind
392
406
@@ -399,6 +413,9 @@ final class Emitter[E >: Null <: js.Transformed.Value](
399
413
withGlobals.value
400
414
}
401
415
416
+ def extractWithGlobalsAndChanged [T ](x : (WithGlobals [T ], Boolean )): T =
417
+ extractWithGlobals(extractChanged(x))
418
+
402
419
// Main part
403
420
404
421
val main = List .newBuilder[E ]
@@ -429,7 +446,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
429
446
val methodCache =
430
447
classCache.getStaticLikeMethodCache(namespace, methodDef.methodName)
431
448
432
- main += extractWithGlobals (methodCache.getOrElseUpdate(methodDef.version,
449
+ main += extractWithGlobalsAndChanged (methodCache.getOrElseUpdate(methodDef.version,
433
450
classEmitter.genStaticLikeMethod(className, methodDef)(moduleContext, methodCache).map(postTransform(_, 0 ))))
434
451
}
435
452
}
@@ -482,7 +499,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
482
499
}
483
500
484
501
// JS constructor
485
- val ctorWithGlobals = {
502
+ val ctorWithGlobals = extractChanged {
486
503
/* The constructor depends both on the class version, and the version
487
504
* of the inlineable init, if there is one.
488
505
*
@@ -567,13 +584,13 @@ final class Emitter[E >: Null <: js.Transformed.Value](
567
584
classCache.getMemberMethodCache(method.methodName)
568
585
569
586
val version = Version .combine(isJSClassVersion, method.version)
570
- methodCache.getOrElseUpdate(version,
587
+ extractChanged( methodCache.getOrElseUpdate(version,
571
588
classEmitter.genMemberMethod(
572
589
className, // invalidated by overall class cache
573
590
isJSClass, // invalidated by isJSClassVersion
574
591
useESClass, // invalidated by isJSClassVersion
575
592
method, // invalidated by method.version
576
- )(moduleContext, methodCache).map(postTransform(_, memberIndent)))
593
+ )(moduleContext, methodCache).map(postTransform(_, memberIndent))))
577
594
}
578
595
579
596
// Exported Members
@@ -582,13 +599,13 @@ final class Emitter[E >: Null <: js.Transformed.Value](
582
599
} yield {
583
600
val memberCache = classCache.getExportedMemberCache(idx)
584
601
val version = Version .combine(isJSClassVersion, member.version)
585
- memberCache.getOrElseUpdate(version,
602
+ extractChanged( memberCache.getOrElseUpdate(version,
586
603
classEmitter.genExportedMember(
587
604
className, // invalidated by overall class cache
588
605
isJSClass, // invalidated by isJSClassVersion
589
606
useESClass, // invalidated by isJSClassVersion
590
607
member // invalidated by version
591
- )(moduleContext, memberCache).map(postTransform(_, memberIndent)))
608
+ )(moduleContext, memberCache).map(postTransform(_, memberIndent))))
592
609
}
593
610
594
611
val hasClassInitializer : Boolean = {
@@ -598,7 +615,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
598
615
}
599
616
}
600
617
601
- val fullClass = {
618
+ val fullClass = extractChanged {
602
619
val fullClassCache = classCache.getFullClassCache()
603
620
604
621
fullClassCache.getOrElseUpdate(linkedClass.version, ctorWithGlobals,
@@ -701,7 +718,8 @@ final class Emitter[E >: Null <: js.Transformed.Value](
701
718
main.result(),
702
719
staticFields,
703
720
staticInitialization,
704
- trackedGlobalRefs
721
+ trackedGlobalRefs,
722
+ changed
705
723
)
706
724
}
707
725
@@ -738,28 +756,33 @@ final class Emitter[E >: Null <: js.Transformed.Value](
738
756
}
739
757
740
758
def getOrComputeImports (externalDependencies : Set [String ], internalDependencies : Set [ModuleID ])(
741
- compute : => WithGlobals [E ]): WithGlobals [E ] = {
759
+ compute : => WithGlobals [E ]): ( WithGlobals [E ], Boolean ) = {
742
760
743
761
_cacheUsed = true
744
762
745
763
if (externalDependencies != _lastExternalDependencies || internalDependencies != _lastInternalDependencies) {
746
764
_importsCache = compute
747
765
_lastExternalDependencies = externalDependencies
748
766
_lastInternalDependencies = internalDependencies
767
+ (_importsCache, true )
768
+ } else {
769
+ (_importsCache, false )
749
770
}
750
- _importsCache
771
+
751
772
}
752
773
753
774
def getOrComputeTopLevelExports (topLevelExports : List [LinkedTopLevelExport ])(
754
- compute : => WithGlobals [E ]): WithGlobals [E ] = {
775
+ compute : => WithGlobals [E ]): ( WithGlobals [E ], Boolean ) = {
755
776
756
777
_cacheUsed = true
757
778
758
779
if (! sameTopLevelExports(topLevelExports, _lastTopLevelExports)) {
759
780
_topLevelExportsCache = compute
760
781
_lastTopLevelExports = topLevelExports
782
+ (_topLevelExportsCache, true )
783
+ } else {
784
+ (_topLevelExportsCache, false )
761
785
}
762
- _topLevelExportsCache
763
786
}
764
787
765
788
private def sameTopLevelExports (tles1 : List [LinkedTopLevelExport ], tles2 : List [LinkedTopLevelExport ]): Boolean = {
@@ -790,15 +813,17 @@ final class Emitter[E >: Null <: js.Transformed.Value](
790
813
}
791
814
792
815
def getOrComputeInitializers (initializers : List [ModuleInitializer .Initializer ])(
793
- compute : => WithGlobals [E ]): WithGlobals [E ] = {
816
+ compute : => WithGlobals [E ]): ( WithGlobals [E ], Boolean ) = {
794
817
795
818
_cacheUsed = true
796
819
797
820
if (initializers != _lastInitializers) {
798
821
_initializersCache = compute
799
822
_lastInitializers = initializers
823
+ (_initializersCache, true )
824
+ } else {
825
+ (_initializersCache, false )
800
826
}
801
- _initializersCache
802
827
}
803
828
804
829
def cleanAfterRun (): Boolean = {
@@ -843,17 +868,18 @@ final class Emitter[E >: Null <: js.Transformed.Value](
843
868
_fullClassCache.foreach(_.startRun())
844
869
}
845
870
846
- def getCache (version : Version ): DesugaredClassCache [E ] = {
871
+ def getCache (version : Version ): (DesugaredClassCache [E ], Boolean ) = {
872
+ _cacheUsed = true
847
873
if (_cache == null || ! _lastVersion.sameVersion(version)) {
848
874
invalidate()
849
875
statsClassesInvalidated += 1
850
876
_lastVersion = version
851
877
_cache = new DesugaredClassCache [E ]
878
+ (_cache, true )
852
879
} else {
853
880
statsClassesReused += 1
881
+ (_cache, false )
854
882
}
855
- _cacheUsed = true
856
- _cache
857
883
}
858
884
859
885
def getMemberMethodCache (
@@ -919,17 +945,18 @@ final class Emitter[E >: Null <: js.Transformed.Value](
919
945
def startRun (): Unit = _cacheUsed = false
920
946
921
947
def getOrElseUpdate (version : Version ,
922
- v : => WithGlobals [T ]): WithGlobals [T ] = {
948
+ v : => WithGlobals [T ]): (WithGlobals [T ], Boolean ) = {
949
+ _cacheUsed = true
923
950
if (_tree == null || ! _lastVersion.sameVersion(version)) {
924
951
invalidate()
925
952
statsMethodsInvalidated += 1
926
953
_tree = v
927
954
_lastVersion = version
955
+ (_tree, true )
928
956
} else {
929
957
statsMethodsReused += 1
958
+ (_tree, false )
930
959
}
931
- _cacheUsed = true
932
- _tree
933
960
}
934
961
935
962
def cleanAfterRun (): Boolean = {
@@ -961,7 +988,7 @@ final class Emitter[E >: Null <: js.Transformed.Value](
961
988
962
989
def getOrElseUpdate (version : Version , ctor : WithGlobals [E ],
963
990
memberMethods : List [WithGlobals [E ]], exportedMembers : List [WithGlobals [E ]],
964
- compute : => WithGlobals [List [E ]]): WithGlobals [List [E ]] = {
991
+ compute : => WithGlobals [List [E ]]): ( WithGlobals [List [E ]], Boolean ) = {
965
992
966
993
@ tailrec
967
994
def allSame [A <: AnyRef ](xs : List [A ], ys : List [A ]): Boolean = {
@@ -971,6 +998,8 @@ final class Emitter[E >: Null <: js.Transformed.Value](
971
998
}
972
999
}
973
1000
1001
+ _cacheUsed = true
1002
+
974
1003
if (_tree == null || ! version.sameVersion(_lastVersion) || (_lastCtor ne ctor) ||
975
1004
! allSame(_lastMemberMethods, memberMethods) ||
976
1005
! allSame(_lastExportedMembers, exportedMembers)) {
@@ -980,10 +1009,10 @@ final class Emitter[E >: Null <: js.Transformed.Value](
980
1009
_lastCtor = ctor
981
1010
_lastMemberMethods = memberMethods
982
1011
_lastExportedMembers = exportedMembers
1012
+ (_tree, true )
1013
+ } else {
1014
+ (_tree, false )
983
1015
}
984
-
985
- _cacheUsed = true
986
- _tree
987
1016
}
988
1017
989
1018
def cleanAfterRun (): Boolean = {
@@ -1017,7 +1046,7 @@ object Emitter {
1017
1046
/** Result of an emitter run. */
1018
1047
final class Result [E ] private [Emitter ](
1019
1048
val header : String ,
1020
- val body : Map [ModuleID , List [E ]],
1049
+ val body : Map [ModuleID , ( List [E ], Boolean ) ],
1021
1050
val footer : String ,
1022
1051
val topLevelVarDecls : List [String ],
1023
1052
val globalRefs : Set [String ]
@@ -1108,7 +1137,8 @@ object Emitter {
1108
1137
val main : List [E ],
1109
1138
val staticFields : E ,
1110
1139
val staticInitialization : E ,
1111
- val trackedGlobalRefs : Set [String ]
1140
+ val trackedGlobalRefs : Set [String ],
1141
+ val changed : Boolean
1112
1142
)
1113
1143
1114
1144
private final class OneTimeCache [A >: Null ] {
0 commit comments