Skip to content

Commit 2ec7a6f

Browse files
authored
Merge pull request #9866 from dotty-staging/optimize-backend
Some Optimizations in Backend
2 parents 7ee3a20 + b0cfccc commit 2ec7a6f

14 files changed

+68
-57
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
3939
import coreBTypes._
4040
import BCodeBodyBuilder._
4141

42-
private val primitives = new DottyPrimitives(ctx)
42+
protected val primitives: DottyPrimitives
4343

4444
/*
4545
* Functionality to build the body of ASM MethodNode, except for `synchronized` and `try` expressions.
@@ -1021,9 +1021,15 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
10211021
}
10221022
}
10231023

1024-
def genLoadArguments(args: List[Tree], btpes: List[BType]): Unit = {
1025-
(args zip btpes) foreach { case (arg, btpe) => genLoad(arg, btpe) }
1026-
}
1024+
def genLoadArguments(args: List[Tree], btpes: List[BType]): Unit =
1025+
args match
1026+
case arg :: args1 =>
1027+
btpes match
1028+
case btpe :: btpes1 =>
1029+
genLoad(arg, btpe)
1030+
genLoadArguments(args1, btpes1)
1031+
case _ =>
1032+
case _ =>
10271033

10281034
def genLoadModule(tree: Tree): BType = {
10291035
val module = (

compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ trait BCodeIdiomatic {
3535
lazy val majorVersion: Int = (classfileVersion & 0xFF)
3636
lazy val emitStackMapFrame = (majorVersion >= 50)
3737

38-
val extraProc: Int = GenBCodeOps.mkFlags(
39-
asm.ClassWriter.COMPUTE_MAXS,
40-
if (emitStackMapFrame) asm.ClassWriter.COMPUTE_FRAMES else 0
41-
)
38+
val extraProc: Int =
39+
import GenBCodeOps.addFlagIf
40+
asm.ClassWriter.COMPUTE_MAXS
41+
.addFlagIf(emitStackMapFrame, asm.ClassWriter.COMPUTE_FRAMES)
4242

4343
lazy val JavaStringBuilderClassName = jlStringBuilderRef.internalName
4444

compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ trait BCodeSkelBuilder extends BCodeHelpers {
535535
}
536536
def lineNumber(tree: Tree): Unit = {
537537
if (!emitLines || !tree.span.exists) return;
538-
val nr = ctx.source.atSpan(tree.span).line + 1
538+
val nr = ctx.source.offsetToLine(tree.span.point) + 1
539539
if (nr != lastEmittedLineNr) {
540540
lastEmittedLineNr = nr
541541
lastInsn match {
@@ -690,12 +690,12 @@ trait BCodeSkelBuilder extends BCodeHelpers {
690690

691691
val isNative = methSymbol.hasAnnotation(NativeAttr)
692692
val isAbstractMethod = (methSymbol.is(Deferred) || (methSymbol.owner.isInterface && ((methSymbol.is(Deferred)) || methSymbol.isClassConstructor)))
693-
val flags = GenBCodeOps.mkFlags(
694-
javaFlags(methSymbol),
695-
if (isAbstractMethod) asm.Opcodes.ACC_ABSTRACT else 0,
696-
if (false /*methSymbol.isStrictFP*/) asm.Opcodes.ACC_STRICT else 0,
697-
if (isNative) asm.Opcodes.ACC_NATIVE else 0 // native methods of objects are generated in mirror classes
698-
)
693+
val flags =
694+
import GenBCodeOps.addFlagIf
695+
javaFlags(methSymbol)
696+
.addFlagIf(isAbstractMethod, asm.Opcodes.ACC_ABSTRACT)
697+
.addFlagIf(false /*methSymbol.isStrictFP*/, asm.Opcodes.ACC_STRICT)
698+
.addFlagIf(isNative, asm.Opcodes.ACC_NATIVE) // native methods of objects are generated in mirror classes
699699

700700
// TODO needed? for(ann <- m.symbol.annotations) { ann.symbol.initialize }
701701
initJMethod(flags, params.map(p => p.symbol.annotations))

compiler/src/dotty/tools/backend/jvm/BTypes.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -649,14 +649,13 @@ abstract class BTypes {
649649

650650
def innerClassAttributeEntry: Option[InnerClassEntry] = info.nestedInfo map {
651651
case NestedInfo(_, outerName, innerName, isStaticNestedClass) =>
652+
import GenBCodeOps.addFlagIf
652653
InnerClassEntry(
653654
internalName,
654655
outerName.orNull,
655656
innerName.orNull,
656-
GenBCodeOps.mkFlags(
657-
info.flags,
658-
if (isStaticNestedClass) asm.Opcodes.ACC_STATIC else 0
659-
) & ClassBType.INNER_CLASSES_FLAGS
657+
info.flags.addFlagIf(isStaticNestedClass, asm.Opcodes.ACC_STATIC)
658+
& ClassBType.INNER_CLASSES_FLAGS
660659
)
661660
}
662661

compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -304,39 +304,36 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes {
304304
val finalFlag = sym.is(Final) && !toDenot(sym).isClassConstructor && !sym.is(Mutable) && !sym.enclosingClass.is(Trait)
305305

306306
import asm.Opcodes._
307-
GenBCodeOps.mkFlags(
308-
if (privateFlag) ACC_PRIVATE else ACC_PUBLIC,
309-
if (sym.is(Deferred) || sym.isOneOf(AbstractOrTrait)) ACC_ABSTRACT else 0,
310-
if (sym.isInterface) ACC_INTERFACE else 0,
311-
312-
if (finalFlag &&
307+
import GenBCodeOps.addFlagIf
308+
0 .addFlagIf(privateFlag, ACC_PRIVATE)
309+
.addFlagIf(!privateFlag, ACC_PUBLIC)
310+
.addFlagIf(sym.is(Deferred) || sym.isOneOf(AbstractOrTrait), ACC_ABSTRACT)
311+
.addFlagIf(sym.isInterface, ACC_INTERFACE)
312+
.addFlagIf(finalFlag
313313
// Primitives are "abstract final" to prohibit instantiation
314314
// without having to provide any implementations, but that is an
315315
// illegal combination of modifiers at the bytecode level so
316316
// suppress final if abstract if present.
317-
!sym.isOneOf(AbstractOrTrait) &&
317+
&& !sym.isOneOf(AbstractOrTrait)
318318
// Mixin forwarders are bridges and can be final, but final bridges confuse some frameworks
319-
!sym.is(Bridge))
320-
ACC_FINAL else 0,
321-
322-
if (sym.isStaticMember) ACC_STATIC else 0,
323-
if (sym.is(Bridge)) ACC_BRIDGE | ACC_SYNTHETIC else 0,
324-
if (sym.is(Artifact)) ACC_SYNTHETIC else 0,
325-
if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
326-
if (sym.isAllOf(JavaEnumTrait)) ACC_ENUM else 0,
327-
if (sym.is(JavaVarargs)) ACC_VARARGS else 0,
328-
if (sym.is(Synchronized)) ACC_SYNCHRONIZED else 0,
329-
if (sym.isDeprecated) ACC_DEPRECATED else 0,
330-
if (sym.is(Enum)) ACC_ENUM else 0
331-
)
319+
&& !sym.is(Bridge), ACC_FINAL)
320+
.addFlagIf(sym.isStaticMember, ACC_STATIC)
321+
.addFlagIf(sym.is(Bridge), ACC_BRIDGE | ACC_SYNTHETIC)
322+
.addFlagIf(sym.is(Artifact), ACC_SYNTHETIC)
323+
.addFlagIf(sym.isClass && !sym.isInterface, ACC_SUPER)
324+
.addFlagIf(sym.isAllOf(JavaEnumTrait), ACC_ENUM)
325+
.addFlagIf(sym.is(JavaVarargs), ACC_VARARGS)
326+
.addFlagIf(sym.is(Synchronized), ACC_SYNCHRONIZED)
327+
.addFlagIf(sym.isDeprecated, ACC_DEPRECATED)
328+
.addFlagIf(sym.is(Enum), ACC_ENUM)
332329
}
333330

334331
def javaFieldFlags(sym: Symbol) = {
335332
import asm.Opcodes._
336-
javaFlags(sym) | GenBCodeOps.mkFlags(
337-
if (sym.hasAnnotation(TransientAttr)) ACC_TRANSIENT else 0,
338-
if (sym.hasAnnotation(VolatileAttr)) ACC_VOLATILE else 0,
339-
if (sym.is(Mutable)) 0 else ACC_FINAL
340-
)
333+
import GenBCodeOps.addFlagIf
334+
javaFlags(sym)
335+
.addFlagIf(sym.hasAnnotation(TransientAttr), ACC_TRANSIENT)
336+
.addFlagIf(sym.hasAnnotation(VolatileAttr), ACC_VOLATILE)
337+
.addFlagIf(!sym.is(Mutable), ACC_FINAL)
341338
}
342339
}

compiler/src/dotty/tools/backend/jvm/GenBCode.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,13 @@ class GenBCode extends Phase {
5050
myOutput
5151
}
5252

53+
private var myPrimitives: DottyPrimitives = null
54+
5355
def run(using Context): Unit =
54-
GenBCodePipeline(
55-
DottyBackendInterface(outputDir, superCallsMap)
56+
if myPrimitives == null then myPrimitives = new DottyPrimitives(ctx)
57+
new GenBCodePipeline(
58+
DottyBackendInterface(outputDir, superCallsMap),
59+
myPrimitives
5660
).run(ctx.compilationUnit.tpdTree)
5761

5862

@@ -74,7 +78,7 @@ object GenBCode {
7478
val name: String = "genBCode"
7579
}
7680

77-
class GenBCodePipeline(val int: DottyBackendInterface)(using Context) extends BCodeSyncAndTry {
81+
class GenBCodePipeline(val int: DottyBackendInterface, val primitives: DottyPrimitives)(using Context) extends BCodeSyncAndTry {
7882
import DottyBackendInterface.symExtensions
7983

8084
private var tree: Tree = _

compiler/src/dotty/tools/backend/jvm/GenBCodeOps.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import scala.tools.asm
77
object GenBCodeOps extends GenBCodeOps
88

99
class GenBCodeOps {
10-
def mkFlags(args: Int*) = args.foldLeft(0)(_ | _)
10+
extension (flags: Int)
11+
def addFlagIf(cond: Boolean, flag: Int): Int = if cond then flags | flag else flags
1112

1213
final val PublicStatic = asm.Opcodes.ACC_PUBLIC | asm.Opcodes.ACC_STATIC
1314
final val PublicStaticFinal = asm.Opcodes.ACC_PUBLIC | asm.Opcodes.ACC_STATIC | asm.Opcodes.ACC_FINAL

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,9 +596,9 @@ object desugar {
596596
(ordinalMethLit(ordinal) :: enumLabelLit(className.toString) :: Nil, scaffolding)
597597
else (Nil, Nil)
598598
def copyMeths = {
599-
val hasRepeatedParam = constrVparamss.exists(_.exists {
599+
val hasRepeatedParam = constrVparamss.nestedExists {
600600
case ValDef(_, tpt, _) => isRepeated(tpt)
601-
})
601+
}
602602
if (mods.is(Abstract) || hasRepeatedParam) Nil // cannot have default arguments for repeated parameters, hence copy method is not issued
603603
else {
604604
def copyDefault(vparam: ValDef) =

compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ object DesugarEnums {
297297
case parent => parent.isType && typeHasRef(parent)
298298
}
299299

300-
vparamss.exists(_.exists(valDefHasRef)) || parents.exists(parentHasRef)
300+
vparamss.nestedExists(valDefHasRef) || parents.exists(parentHasRef)
301301
}
302302

303303
/** A pair consisting of

compiler/src/dotty/tools/dotc/core/Decorators.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,16 @@ object Decorators {
195195
}
196196

197197
extension [T, U](xss: List[List[T]])
198-
def nestedMap(f: T => U): List[List[U]] =
199-
xss.map(_.map(f))
198+
def nestedMap(f: T => U): List[List[U]] = xss match
199+
case xs :: xss1 => xs.map(f) :: xss1.nestedMap(f)
200+
case nil => Nil
200201
def nestedMapConserve(f: T => U): List[List[U]] =
201202
xss.mapconserve(_.mapconserve(f))
202203
def nestedZipWithConserve(yss: List[List[U]])(f: (T, U) => T): List[List[T]] =
203204
xss.zipWithConserve(yss)((xs, ys) => xs.zipWithConserve(ys)(f))
205+
def nestedExists(p: T => Boolean): Boolean = xss match
206+
case xs :: xss1 => xs.exists(p) || xss1.nestedExists(p)
207+
case nil => false
204208
end extension
205209

206210
extension (text: Text)

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ object SymDenotations {
899899
else if is(NoDefaultParams) then false
900900
else
901901
val result =
902-
rawParamss.exists(_.exists(_.is(HasDefault)))
902+
rawParamss.nestedExists(_.is(HasDefault))
903903
|| allOverriddenSymbols.exists(_.hasDefaultParams)
904904
setFlag(if result then HasDefaultParams else NoDefaultParams)
905905
result

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3847,7 +3847,7 @@ object Parsers {
38473847
val problem = tree match
38483848
case tree: MemberDef if !(tree.mods.flags & ModifierFlags).isEmpty =>
38493849
i"refinement cannot be ${(tree.mods.flags & ModifierFlags).flagStrings().mkString("`", "`, `", "`")}"
3850-
case tree: DefDef if tree.vparamss.exists(_.exists(!_.rhs.isEmpty)) =>
3850+
case tree: DefDef if tree.vparamss.nestedExists(!_.rhs.isEmpty) =>
38513851
i"refinement cannot have default arguments"
38523852
case tree: ValOrDefDef =>
38533853
if tree.rhs.isEmpty then ""

compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
237237

238238
/** Is there a repeated parameter in some parameter list? */
239239
private def hasRepeatedParams(sym: Symbol)(using Context): Boolean =
240-
sym.info.paramInfoss.flatten.exists(_.isRepeatedParam)
240+
sym.info.paramInfoss.nestedExists(_.isRepeatedParam)
241241

242242
/** Is this the type of a method that has a repeated parameter type as
243243
* its last parameter in the last parameter list?

compiler/src/dotty/tools/dotc/util/SourcePosition.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ extends SrcPos, interfaces.SourcePosition, Showable {
2525

2626
def point: Int = span.point
2727

28-
def line: Int = if (source.content().length != 0) source.offsetToLine(point) else -1
28+
def line: Int = if (source.length != 0) source.offsetToLine(point) else -1
2929

3030
/** Extracts the lines from the underlying source file as `Array[Char]`*/
3131
def linesSlice: Array[Char] =

0 commit comments

Comments
 (0)