Skip to content

Commit d4a5515

Browse files
committed
Reduce allocations for pickling
- Avoid boxing overheads in NameBuffer and TreeBuffer - Avoid repeated re-allocations in updateMapWithDeltas
1 parent 783bf65 commit d4a5515

File tree

3 files changed

+52
-40
lines changed

3 files changed

+52
-40
lines changed

compiler/src/dotty/tools/dotc/core/tasty/NameBuffer.scala

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package tasty
66
import dotty.tools.tasty.TastyBuffer
77
import TastyBuffer._
88

9-
import collection.mutable
9+
import collection.mutable.ArrayBuffer
1010
import Names.{Name, chrs, SimpleName, DerivedName, TypeName}
1111
import NameKinds._
1212
import NameOps._
@@ -16,42 +16,43 @@ import NameTags.{SIGNED, TARGETSIGNED}
1616
class NameBuffer extends TastyBuffer(10000) {
1717
import NameBuffer._
1818

19-
private val nameRefs = new mutable.LinkedHashMap[Name, NameRef]
19+
private val nameRefs = new util.EqHashMap[Name, NameRef]
20+
private val nameBuf = new ArrayBuffer[Name]
2021

21-
def nameIndex(name: Name): NameRef = {
22+
def nameIndex(name: Name): NameRef =
2223
val name1 = name.toTermName
23-
nameRefs.get(name1) match {
24-
case Some(ref) =>
25-
ref
26-
case None =>
27-
name1 match {
28-
case SignedName(original, Signature(params, result), target) =>
29-
nameIndex(original)
30-
if !original.matchesTargetName(target) then nameIndex(target)
31-
nameIndex(result)
32-
params.foreach {
33-
case param: TypeName =>
34-
nameIndex(param)
35-
case _ =>
36-
}
37-
case AnyQualifiedName(prefix, name) =>
38-
nameIndex(prefix); nameIndex(name)
39-
case AnyUniqueName(original, separator, num) =>
40-
nameIndex(separator)
41-
if (!original.isEmpty) nameIndex(original)
42-
case DerivedName(original, _) =>
43-
nameIndex(original)
44-
case _ =>
45-
}
46-
val ref = NameRef(nameRefs.size)
47-
nameRefs(name1) = ref
48-
ref
49-
}
50-
}
24+
val ref: NameRef | Null = nameRefs.lookup(name1)
25+
if ref != null then ref.uncheckedNN
26+
else
27+
name1 match
28+
case SignedName(original, Signature(params, result), target) =>
29+
nameIndex(original)
30+
if !original.matchesTargetName(target) then nameIndex(target)
31+
nameIndex(result)
32+
params.foreach {
33+
case param: TypeName =>
34+
nameIndex(param)
35+
case _ =>
36+
}
37+
case AnyQualifiedName(prefix, name) =>
38+
nameIndex(prefix); nameIndex(name)
39+
case AnyUniqueName(original, separator, num) =>
40+
nameIndex(separator)
41+
if (!original.isEmpty) nameIndex(original)
42+
case DerivedName(original, _) =>
43+
nameIndex(original)
44+
case _ =>
45+
val ref1 = NameRef(nameRefs.size)
46+
nameRefs(name1) = ref1
47+
nameBuf += name1
48+
ref1
5149

52-
private def withLength(op: => Unit, lengthWidth: Int = 1): Unit = {
50+
private inline def withLength(inline op: Unit, lengthWidth: Int = 1): Unit = {
5351
val lengthAddr = currentAddr
54-
for (i <- 0 until lengthWidth) writeByte(0)
52+
var i = 0
53+
while i < lengthWidth do
54+
writeByte(0)
55+
i += 1
5556
op
5657
val length = currentAddr.index - lengthAddr.index - lengthWidth
5758
putNat(lengthAddr, length, lengthWidth)
@@ -111,11 +112,11 @@ class NameBuffer extends TastyBuffer(10000) {
111112

112113
override def assemble(): Unit = {
113114
var i = 0
114-
for ((name, ref) <- nameRefs) {
115+
for name <- nameBuf do
116+
val ref = nameRefs(name)
115117
assert(ref.index == i)
116118
i += 1
117119
pickleNameContents(name)
118-
}
119120
}
120121
}
121122

compiler/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,11 @@ class TreeBuffer extends TastyBuffer(50000) {
109109

110110
/** Adjust all offsets according to previously computed deltas */
111111
private def adjustOffsets(): Unit =
112-
for (i <- 0 until numOffsets) {
112+
var i = 0
113+
while i < numOffsets do
113114
val corrected = adjustedOffset(i)
114115
fillAddr(offset(i), corrected)
115-
}
116+
i += 1
116117

117118
/** Adjust deltas to also take account references that will shrink (and thereby
118119
* generate additional zeroes that can be skipped) due to previously
@@ -122,12 +123,11 @@ class TreeBuffer extends TastyBuffer(50000) {
122123
val delta1 = new Array[Int](delta.length)
123124
var lastDelta = 0
124125
var i = 0
125-
while (i < numOffsets) {
126+
while i < numOffsets do
126127
val corrected = adjustedOffset(i)
127128
lastDelta += AddrWidth - TastyBuffer.natSize(corrected.index)
128129
delta1(i) = lastDelta
129130
i += 1
130-
}
131131
val saved =
132132
if (numOffsets == 0) 0
133133
else delta1(numOffsets - 1) - delta(numOffsets - 1)

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,18 @@ class TreePickler(pickler: TastyPickler) {
816816
buf.compactify()
817817

818818
def updateMapWithDeltas(mp: MutableSymbolMap[Addr]) =
819-
for (key <- mp.keysIterator.toBuffer[Symbol]) mp(key) = adjusted(mp(key))
819+
val keys = new Array[Symbol](mp.size)
820+
val it = mp.keysIterator
821+
var i = 0
822+
while i < keys.length do
823+
keys(i) = it.next
824+
i += 1
825+
assert(!it.hasNext)
826+
i = 0
827+
while i < keys.length do
828+
val key = keys(i)
829+
mp(key) = adjusted(mp(key))
830+
i += 1
820831

821832
updateMapWithDeltas(symRefs)
822833
}

0 commit comments

Comments
 (0)