@@ -1144,35 +1144,38 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11441144 expand(tree, tree.tpe.widen)
11451145 }
11461146
1147- inline val MapRecursionLimit = 10
1148-
11491147 extension (trees : List [Tree ])
11501148
1151- /** A map that expands to a recursive function. It's equivalent to
1149+ /** Equivalent (but faster) to
11521150 *
11531151 * flatten(trees.mapConserve(op))
11541152 *
1155- * and falls back to it after `MaxRecursionLimit` recursions.
1156- * Before that it uses a simpler method that uses stackspace
1157- * instead of heap.
1158- * Note `op` is duplicated in the generated code, so it should be
1159- * kept small.
1153+ * assuming that `trees` does not contain `Thicket`s to start with.
11601154 */
1161- inline def mapInline (inline op : Tree => Tree ): List [Tree ] =
1162- def recur (trees : List [Tree ], count : Int ): List [Tree ] =
1163- if count > MapRecursionLimit then
1164- // use a slower implementation that avoids stack overflows
1165- flatten(trees.mapConserve(op))
1166- else trees match
1167- case tree :: rest =>
1168- val tree1 = op(tree)
1169- val rest1 = recur(rest, count + 1 )
1170- if (tree1 eq tree) && (rest1 eq rest) then trees
1171- else tree1 match
1172- case Thicket (elems1) => elems1 ::: rest1
1173- case _ => tree1 :: rest1
1174- case nil => nil
1175- recur(trees, 0 )
1155+ inline def flattenedMapConserve (inline f : Tree => Tree ): List [Tree ] =
1156+ @ tailrec
1157+ def loop (mapped : ListBuffer [Tree ] | Null , unchanged : List [Tree ], pending : List [Tree ]): List [Tree ] =
1158+ if pending.isEmpty then
1159+ if mapped == null then unchanged
1160+ else mapped.prependToList(unchanged)
1161+ else
1162+ val head0 = pending.head
1163+ val head1 = f(head0)
1164+
1165+ if head1 eq head0 then
1166+ loop(mapped, unchanged, pending.tail)
1167+ else
1168+ val buf = if mapped == null then new ListBuffer [Tree ] else mapped
1169+ var xc = unchanged
1170+ while xc ne pending do
1171+ buf += xc.head
1172+ xc = xc.tail
1173+ head1 match
1174+ case Thicket (elems1) => buf ++= elems1
1175+ case _ => buf += head1
1176+ val tail0 = pending.tail
1177+ loop(buf, tail0, tail0)
1178+ loop(null , trees, trees)
11761179
11771180 /** Transform statements while maintaining import contexts and expression contexts
11781181 * in the same way as Typer does. The code addresses additional concerns:
0 commit comments