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

Skip to content

Commit afef6bd

Browse files
committed
Cache (potential) jsSuperClass tree separately
This removes the only desugarExpr call from buildClass. Since we'll stop caching buildClass going forward, this is important.
1 parent 14144ac commit afef6bd

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

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

+16-15
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) {
4545

4646
def buildClass(className: ClassName, isJSClass: Boolean, jsClassCaptures: Option[List[ParamDef]],
4747
hasClassInitializer: Boolean,
48-
superClass: Option[ClassIdent], jsSuperClass: Option[Tree], useESClass: Boolean,
48+
superClass: Option[ClassIdent], storeJSSuperClass: Option[js.Tree], useESClass: Boolean,
4949
members: List[js.Tree])(
5050
implicit moduleContext: ModuleContext,
5151
globalKnowledge: GlobalKnowledge, pos: Position): WithGlobals[List[js.Tree]] = {
5252

5353
if (!isJSClass) {
54-
assert(jsSuperClass.isEmpty, className)
54+
assert(storeJSSuperClass.isEmpty, className)
5555

5656
if (useESClass) {
5757
val parentVarWithGlobals = for (parentIdent <- superClass) yield {
@@ -70,30 +70,23 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) {
7070
// Wrap the entire class def in an accessor function
7171
import TreeDSL._
7272

73-
val genStoreJSSuperClass = jsSuperClass.map { jsSuperClass =>
74-
for (rhs <- desugarExpr(jsSuperClass, resultType = AnyType)) yield {
75-
js.VarDef(fileLevelVar(VarField.superClass).ident, Some(rhs))
76-
}
77-
}
78-
7973
val classValueIdent = fileLevelVarIdent(VarField.b, genName(className))
8074
val classValueVar = js.VarRef(classValueIdent)
8175
val createClassValueVar = genEmptyMutableLet(classValueIdent)
8276

8377
val entireClassDefWithGlobals = if (useESClass) {
84-
genJSSuperCtor(superClass, jsSuperClass).map { jsSuperClass =>
78+
genJSSuperCtor(superClass, storeJSSuperClass.isDefined).map { jsSuperClass =>
8579
List(classValueVar := js.ClassDef(Some(classValueIdent), Some(jsSuperClass), members))
8680
}
8781
} else {
8882
WithGlobals(members)
8983
}
9084

9185
val classDefStatsWithGlobals = for {
92-
optStoreJSSuperClass <- WithGlobals.option(genStoreJSSuperClass)
9386
entireClassDef <- entireClassDefWithGlobals
9487
createStaticFields <- genCreateStaticFieldsOfJSClass(className)
9588
} yield {
96-
optStoreJSSuperClass.toList ::: entireClassDef ::: createStaticFields
89+
storeJSSuperClass.toList ::: entireClassDef ::: createStaticFields
9790
}
9891

9992
jsClassCaptures.fold {
@@ -225,7 +218,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) {
225218

226219
/** Generates the JS constructor for a JS class. */
227220
def genJSConstructor(className: ClassName, superClass: Option[ClassIdent],
228-
jsSuperClass: Option[Tree], useESClass: Boolean, jsConstructorDef: JSConstructorDef)(
221+
hasJSSuperClass: Boolean, useESClass: Boolean, jsConstructorDef: JSConstructorDef)(
229222
implicit moduleContext: ModuleContext,
230223
globalKnowledge: GlobalKnowledge, pos: Position): WithGlobals[List[js.Tree]] = {
231224

@@ -240,7 +233,7 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) {
240233
} else {
241234
for {
242235
ctorFun <- ctorFunWithGlobals
243-
superCtor <- genJSSuperCtor(superClass, jsSuperClass)
236+
superCtor <- genJSSuperCtor(superClass, hasJSSuperClass)
244237
} yield {
245238
import TreeDSL._
246239

@@ -254,16 +247,24 @@ private[emitter] final class ClassEmitter(sjsGen: SJSGen) {
254247
}
255248
}
256249

257-
private def genJSSuperCtor(superClass: Option[ClassIdent], jsSuperClass: Option[Tree])(
250+
private def genJSSuperCtor(superClass: Option[ClassIdent], hasJSSuperClass: Boolean)(
258251
implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge,
259252
pos: Position): WithGlobals[js.Tree] = {
260-
if (jsSuperClass.isDefined) {
253+
if (hasJSSuperClass) {
261254
WithGlobals(fileLevelVar(VarField.superClass))
262255
} else {
263256
genJSClassConstructor(superClass.get.name, keepOnlyDangerousVarNames = true)
264257
}
265258
}
266259

260+
def genStoreJSSuperClass(jsSuperClass: Tree)(
261+
implicit moduleContext: ModuleContext, globalKnowledge: GlobalKnowledge,
262+
pos: Position): WithGlobals[js.Tree] = {
263+
for (rhs <- desugarExpr(jsSuperClass, resultType = AnyType)) yield {
264+
js.VarDef(fileLevelVar(VarField.superClass).ident, Some(rhs))
265+
}
266+
}
267+
267268
/** Generates the JavaScript constructor of a class, as a `js.Function`.
268269
*
269270
* For ECMAScript 2015, that `js.Function` must be decomposed and reformed

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,13 @@ final class Emitter(config: Emitter.Config) {
447447
(isJSClass || linkedClass.ancestors.contains(ThrowableClass))
448448
}
449449

450+
val hasJSSuperClass = linkedClass.jsSuperClass.isDefined
451+
452+
val storeJSSuperClass = linkedClass.jsSuperClass.map { jsSuperClass =>
453+
extractWithGlobals(classTreeCache.storeJSSuperClass.getOrElseUpdate(
454+
classEmitter.genStoreJSSuperClass(jsSuperClass)(moduleContext, classCache, linkedClass.pos)))
455+
}
456+
450457
// JS constructor
451458
val ctorWithGlobals = {
452459
/* The constructor depends both on the class version, and the version
@@ -468,7 +475,7 @@ final class Emitter(config: Emitter.Config) {
468475
classEmitter.genJSConstructor(
469476
className, // invalidated by overall class cache (part of ancestors)
470477
linkedClass.superClass, // invalidated by class version
471-
linkedClass.jsSuperClass, // invalidated by class version
478+
hasJSSuperClass, // invalidated by class version
472479
useESClass, // invalidated by class version
473480
jsConstructorDef // part of ctor version
474481
)(moduleContext, ctorCache, linkedClass.pos))
@@ -579,7 +586,7 @@ final class Emitter(config: Emitter.Config) {
579586
linkedClass.jsClassCaptures, // invalidated by class version
580587
hasClassInitializer, // invalidated by class version (optimizer cannot remove it)
581588
linkedClass.superClass, // invalidated by class version
582-
linkedClass.jsSuperClass, // invalidated by class version
589+
storeJSSuperClass, // invalidated by class version
583590
useESClass, // invalidated by class version (depends on kind, config and ancestry only)
584591
ctor ::: memberMethods ::: exportedMembers.flatten // all 3 invalidated directly
585592
)(moduleContext, fullClassCache, linkedClass.pos) // pos invalidated by class version
@@ -1047,6 +1054,7 @@ object Emitter {
10471054

10481055
private final class DesugaredClassCache {
10491056
val privateJSFields = new OneTimeCache[WithGlobals[List[js.Tree]]]
1057+
val storeJSSuperClass = new OneTimeCache[WithGlobals[js.Tree]]
10501058
val instanceTests = new OneTimeCache[WithGlobals[List[js.Tree]]]
10511059
val typeData = new OneTimeCache[WithGlobals[List[js.Tree]]]
10521060
val setTypeData = new OneTimeCache[js.Tree]

0 commit comments

Comments
 (0)