Skip to content

Commit 940b2f1

Browse files
committed
Specialize more to avoid closure creation
1 parent a1f7c7d commit 940b2f1

File tree

1 file changed

+42
-42
lines changed

1 file changed

+42
-42
lines changed

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

+42-42
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,7 @@ class ClassfileParser(
235235
getOwner(jflags), preName.name, sflags, completer,
236236
getPrivateWithin(jflags), coord = start)
237237

238-
val isVarargs = sflags.is(Flags.Method) && (jflags & JAVA_ACC_VARARGS) != 0
239-
completer.attrCompleter = parseAttributes(member, isVarargs)
238+
completer.attrCompleter = parseAttributes(member)
240239

241240
getScope(jflags).enter(member)
242241

@@ -291,7 +290,7 @@ class ClassfileParser(
291290
val isVarargs = denot.is(Flags.Method) && (jflags & JAVA_ACC_VARARGS) != 0
292291
denot.info = sigToType(sig, isVarargs = isVarargs)
293292
if (isConstructor) normalizeConstructorParams()
294-
denot.info = translateTempPoly(attrCompleter.complete(denot.info))
293+
denot.info = translateTempPoly(attrCompleter.complete(denot.info, isVarargs))
295294
if (isConstructor) normalizeConstructorInfo()
296295

297296
if (ctx.explicitNulls) denot.info = JavaNullInterop.nullifyMember(denot.symbol, denot.info, isEnum)
@@ -628,36 +627,49 @@ class ClassfileParser(
628627
None // ignore malformed annotations
629628
}
630629

631-
abstract class AttributeCompleter {
630+
class AttributeCompleter(sym: Symbol) {
631+
var codeAttribute: Boolean = false
632+
var sig: String = null
632633
var constant: Constant = null
633634
var exceptions: List[NameOrString] = Nil
634-
def complete(tp: Type)(using Context): Type
635-
}
635+
var annotations: List[Annotation] = Nil
636+
def complete(tp: Type, isVarargs: Boolean = false)(using Context): Type = {
637+
// flag test will trigger completion and cycles, thus have to be lazy
638+
if (codeAttribute && sym.owner.isAllOf(Flags.JavaInterface)) {
639+
sym.resetFlag(Flags.Deferred)
640+
sym.owner.resetFlag(Flags.PureInterface)
641+
report.log(s"$sym in ${sym.owner} is a java 8+ default method.")
642+
}
636643

637-
// invariant: `in` and `ctx` should not be captured inside the result function
638-
def parseAttributes(sym: Symbol, isVarargs: Boolean = false)(using ctx: Context, in: DataReader): AttributeCompleter = {
639-
var typeUpdate: Option[Context ?=> Type] = None
640-
var delayedWork: List[Context ?=> Unit] = Nil
641-
val res = new AttributeCompleter {
642-
def complete(tp: Type)(using Context): Type = {
643-
val updatedType =
644-
if typeUpdate.isEmpty then tp
645-
else typeUpdate.get
646-
647-
val newType =
648-
if this.constant != null then
649-
val ct = convertTo(this.constant, updatedType)
650-
if ct != null then ConstantType(ct) else updatedType
651-
else updatedType
652-
653-
exceptions.foreach { ex =>
654-
val cls = getClassSymbol(ex.name)
655-
sym.addAnnotation(ThrowsAnnotation(cls.asClass))
644+
val updatedType =
645+
if sig == null then tp
646+
else {
647+
val newType = sigToType(sig, sym, isVarargs)
648+
if (ctx.debug && ctx.verbose)
649+
println("" + sym + "; signature = " + sig + " type = " + newType)
650+
newType
656651
}
657-
delayedWork.foreach(_.apply)
658-
cook.apply(newType)
652+
653+
val newType =
654+
if this.constant != null then
655+
val ct = convertTo(this.constant, updatedType)
656+
if ct != null then ConstantType(ct) else updatedType
657+
else updatedType
658+
659+
annotations.foreach(annot => sym.addAnnotation(annot))
660+
661+
exceptions.foreach { ex =>
662+
val cls = getClassSymbol(ex.name)
663+
sym.addAnnotation(ThrowsAnnotation(cls.asClass))
659664
}
665+
666+
cook.apply(newType)
660667
}
668+
}
669+
670+
// invariant: `in` and `ctx` should not be captured inside the result function
671+
def parseAttributes(sym: Symbol)(using ctx: Context, in: DataReader): AttributeCompleter = {
672+
val res = new AttributeCompleter(sym)
661673

662674
def parseAttribute(): Unit = {
663675
val attrName = pool.getName(in.nextChar).name.toTypeName
@@ -666,12 +678,7 @@ class ClassfileParser(
666678
attrName match {
667679
case tpnme.SignatureATTR =>
668680
val sig = pool.getExternalName(in.nextChar)
669-
typeUpdate = Some {
670-
val newType = sigToType(sig.value, sym, isVarargs)
671-
if (ctx.debug && ctx.verbose)
672-
println("" + sym + "; signature = " + sig + " type = " + newType)
673-
newType
674-
}
681+
res.sig = sig.value
675682

676683
case tpnme.SyntheticATTR =>
677684
sym.setFlag(Flags.SyntheticArtifact)
@@ -682,7 +689,7 @@ class ClassfileParser(
682689
case tpnme.DeprecatedATTR =>
683690
val msg = Literal(Constant("see corresponding Javadoc for more information."))
684691
val since = Literal(Constant(""))
685-
delayedWork ::= sym.addAnnotation(Annotation(defn.DeprecatedAnnot, msg, since))
692+
res.annotations ::= Annotation(defn.DeprecatedAnnot, msg, since)
686693

687694
case tpnme.ConstantValueATTR =>
688695
val c = pool.getConstant(in.nextChar)
@@ -708,14 +715,7 @@ class ClassfileParser(
708715

709716
case tpnme.CodeATTR =>
710717
in.skip(attrLen)
711-
// flag test will trigger completion and cycles, thus have to be lazy
712-
delayedWork ::= {
713-
if (sym.owner.isAllOf(Flags.JavaInterface)) {
714-
sym.resetFlag(Flags.Deferred)
715-
sym.owner.resetFlag(Flags.PureInterface)
716-
report.log(s"$sym in ${sym.owner} is a java 8+ default method.")
717-
}
718-
}
718+
res.codeAttribute = true
719719

720720
case _ =>
721721
}

0 commit comments

Comments
 (0)