Skip to content

Commit b65a450

Browse files
committed
Cache function classes
1 parent b3f908d commit b65a450

File tree

3 files changed

+26
-21
lines changed

3 files changed

+26
-21
lines changed

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

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,8 +1104,6 @@ class Definitions {
11041104
@tu lazy val AbstractFunctionType: Array[TypeRef] = mkArityArray("scala.runtime.AbstractFunction", MaxImplementedFunctionArity, 0)
11051105
val AbstractFunctionClassPerRun: PerRun[Array[Symbol]] = new PerRun(AbstractFunctionType.map(_.symbol.asClass))
11061106
def AbstractFunctionClass(n: Int)(using Context): Symbol = AbstractFunctionClassPerRun()(using ctx)(n)
1107-
@tu private lazy val ImplementedFunctionType = mkArityArray("scala.Function", MaxImplementedFunctionArity, 0)
1108-
def FunctionClassPerRun: PerRun[Array[Symbol]] = new PerRun(ImplementedFunctionType.map(_.symbol.asClass))
11091107

11101108
val LazyHolder: PerRun[Map[Symbol, Symbol]] = new PerRun({
11111109
def holderImpl(holderType: String) = requiredClass("scala.runtime." + holderType)
@@ -1124,23 +1122,33 @@ class Definitions {
11241122

11251123
@tu lazy val TupleType: Array[TypeRef] = mkArityArray("scala.Tuple", MaxTupleArity, 1)
11261124

1125+
private class FunType(prefix: String):
1126+
private var classRefs: Array[TypeRef] = new Array(22)
1127+
def apply(n: Int): TypeRef =
1128+
while n >= classRefs.length do
1129+
val classRefs1 = new Array[TypeRef](classRefs.length * 2)
1130+
Array.copy(classRefs, 0, classRefs1, 0, classRefs.length)
1131+
classRefs = classRefs1
1132+
if classRefs(n) == null then
1133+
classRefs(n) = requiredClassRef(prefix + n.toString)
1134+
classRefs(n)
1135+
1136+
private val erasedContextFunType = FunType("scala.ErasedContextFunction")
1137+
private val contextFunType = FunType("scala.ContextFunction")
1138+
private val erasedFunType = FunType("scala.ErasedFunction")
1139+
private val funType = FunType("scala.Function")
1140+
11271141
def FunctionClass(n: Int, isContextual: Boolean = false, isErased: Boolean = false)(using Context): Symbol =
1128-
if (isContextual && isErased)
1129-
requiredClass("scala.ErasedContextFunction" + n.toString)
1130-
else if (isContextual)
1131-
requiredClass("scala.ContextFunction" + n.toString)
1132-
else if (isErased)
1133-
requiredClass("scala.ErasedFunction" + n.toString)
1134-
else if (n <= MaxImplementedFunctionArity)
1135-
FunctionClassPerRun()(n)
1136-
else
1137-
requiredClass("scala.Function" + n.toString)
1138-
1139-
@tu lazy val Function0_apply: Symbol = ImplementedFunctionType(0).symbol.requiredMethod(nme.apply)
1142+
( if isContextual && isErased then erasedContextFunType(n)
1143+
else if isContextual then contextFunType(n)
1144+
else if isErased then erasedFunType(n)
1145+
else funType(n)
1146+
).symbol.asClass
1147+
1148+
@tu lazy val Function0_apply: Symbol = FunctionClass(0).requiredMethod(nme.apply)
11401149

11411150
def FunctionType(n: Int, isContextual: Boolean = false, isErased: Boolean = false)(using Context): TypeRef =
1142-
if (n <= MaxImplementedFunctionArity && (!isContextual || ctx.erasedTypes) && !isErased) ImplementedFunctionType(n)
1143-
else FunctionClass(n, isContextual, isErased).typeRef
1151+
FunctionClass(n, isContextual && !ctx.erasedTypes, isErased).typeRef
11441152

11451153
lazy val PolyFunctionClass = requiredClass("scala.PolyFunction")
11461154
def PolyFunctionType = PolyFunctionClass.typeRef

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,7 @@ object SymbolLoaders {
219219
Stats.record("package scopes")
220220

221221
/** The scope of a package. This is different from a normal scope
222-
* in two aspects:
223-
*
224-
* 1. Names of scope entries are kept in mangled form.
225-
* 2. Some function types in the `scala` package are synthesized.
222+
* in that names of scope entries are kept in mangled form.
226223
*/
227224
final class PackageScope extends MutableScope {
228225
override def newScopeEntry(name: Name, sym: Symbol)(using Context): ScopeEntry =

tests/pos-with-compiler/lazyValsSepComp.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ import dotty.tools.dotc.core.Contexts._
1212
object Foo {
1313
val definitions: Definitions = null
1414
def defn = definitions
15-
def go = defn.FunctionClassPerRun
15+
def go = defn.ScalaBoxedClasses
1616
}

0 commit comments

Comments
 (0)