Skip to content

Commit 2fc88ee

Browse files
committed
Specialize String ++ Name -> Name operation
Avoid doing the concatenation in a separate string
1 parent b67b0b7 commit 2fc88ee

File tree

7 files changed

+33
-11
lines changed

7 files changed

+33
-11
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,8 +1172,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11721172

11731173
// convert a numeric with a toXXX method
11741174
def primitiveConversion(tree: Tree, numericCls: Symbol)(using Context): Tree = {
1175-
val mname = ("to" + numericCls.name).toTermName
1176-
val conversion = tree.tpe member mname
1175+
val mname = "to".concat(numericCls.name)
1176+
val conversion = tree.tpe member(mname)
11771177
if (conversion.symbol.exists)
11781178
tree.select(conversion.symbol.termRef).ensureApplied
11791179
else if (tree.tpe.widen isRef numericCls)

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,12 @@ object Contexts {
918918
private[Contexts] val comparers = new mutable.ArrayBuffer[TypeComparer]
919919
private[Contexts] var comparersInUse: Int = 0
920920

921-
private[dotc] var nameCharBuffer = new Array[Char](256)
921+
private var charArray = new Array[Char](256)
922+
923+
def sharedCharArray(len: Int): Array[Char] =
924+
while len > charArray.length do
925+
charArray = new Array[Char](charArray.length * 2)
926+
charArray
922927

923928
def reset(): Unit = {
924929
for ((_, set) <- uniqueSets) set.clear()

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,25 @@ object Decorators {
3939
* This avoids some allocation relative to `termName(s)`
4040
*/
4141
def sliceToTermName(start: Int, end: Int)(using Context): SimpleName =
42-
val base = ctx.base
4342
val len = end - start
44-
while len > base.nameCharBuffer.length do
45-
base.nameCharBuffer = new Array[Char](base.nameCharBuffer.length * 2)
46-
s.getChars(start, end, base.nameCharBuffer, 0)
47-
termName(base.nameCharBuffer, 0, len)
43+
val chars = ctx.base.sharedCharArray(len)
44+
s.getChars(start, end, chars, 0)
45+
termName(chars, 0, len)
4846

4947
def sliceToTypeName(start: Int, end: Int)(using Context): TypeName =
5048
sliceToTermName(start, end).toTypeName
5149

50+
def concat(name: Name)(using Context): SimpleName = name match
51+
case name: SimpleName =>
52+
val len = s.length + name.length
53+
var chars = ctx.base.sharedCharArray(len)
54+
s.getChars(0, s.length, chars, 0)
55+
if name.length != 0 then name.getChars(0, name.length, chars, s.length)
56+
termName(chars, 0, len)
57+
case name: TypeName => s.concat(name.toTermName)
58+
case _ => termName(s.concat(name.toString))
59+
end extension
60+
5261
/** Implements a findSymbol method on iterators of Symbols that
5362
* works like find but avoids Option, replacing None with NoSymbol.
5463
*/

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import scala.internal.Chars
88
import Chars.isOperatorPart
99
import Definitions._
1010
import nme._
11+
import Decorators.concat
1112

1213
object NameOps {
1314

@@ -138,7 +139,7 @@ object NameOps {
138139
case _ => false
139140

140141
/** Add an `extension_` in front of this name */
141-
def toExtensionName = termName("extension_" ++ name.toString)
142+
def toExtensionName(using Context): SimpleName = "extension_".concat(name)
142143

143144
/** Drop `extension_` in front of this name, if it has this prefix */
144145
def dropExtension = name match

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,13 @@ object Names {
337337
def head: Char = apply(0)
338338
def last: Char = apply(length - 1)
339339

340+
/** Copy character slice (from until end) to character array starting at `dstStart`.
341+
* @pre Destination must have enough space to hold all characters of this name.
342+
*/
343+
def getChars(from: Int, end: Int, dst: Array[Char], dstStart: Int): Unit =
344+
assert(0 <= from && from <= end && end <= length)
345+
Array.copy(chrs, start + from, dst, dstStart, end - from)
346+
340347
override def asSimpleName: SimpleName = this
341348
override def toSimpleName: SimpleName = this
342349
override final def mangle: SimpleName = encode

compiler/src/dotty/tools/dotc/typer/Deriving.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ trait Deriving {
4747
* @param reportErrors Report an error if an instance with the same name exists already
4848
*/
4949
private def addDerivedInstance(clsName: Name, info: Type, pos: SrcPos): Unit = {
50-
val instanceName = s"derived$$$clsName".toTermName
50+
val instanceName = "derived$".concat(clsName)
5151
if (ctx.denotNamed(instanceName).exists)
5252
report.error(i"duplicate type class derivation for $clsName", pos)
5353
else

compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ object ProtoTypes {
137137
extends CachedProxyType with ProtoType with ValueTypeOrProto {
138138

139139
private var myExtensionName: TermName = null
140-
def extensionName: TermName =
140+
def extensionName(using Context): TermName =
141141
if myExtensionName == null then myExtensionName = name.toExtensionName
142142
myExtensionName
143143

0 commit comments

Comments
 (0)