Skip to content

Commit 94f069e

Browse files
committed
Cache unpickled quotes witout definitions
1 parent b1a3e6d commit 94f069e

File tree

4 files changed

+67
-17
lines changed

4 files changed

+67
-17
lines changed

compiler/src/dotty/tools/dotc/quoted/MacroExpansion.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ object MacroExpansion {
1414
ctx.property(MacroExpansionPosition)
1515

1616
def context(inlinedFrom: tpd.Tree)(using Context): Context =
17-
ctx.fresh.setProperty(MacroExpansionPosition, SourcePosition(inlinedFrom.source, inlinedFrom.span)).setTypeAssigner(new Typer).withSource(inlinedFrom.source)
17+
QuotesCache.init(ctx.fresh).setProperty(MacroExpansionPosition, SourcePosition(inlinedFrom.source, inlinedFrom.span)).setTypeAssigner(new Typer).withSource(inlinedFrom.source)
1818
}
1919

compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,25 +181,43 @@ object PickledQuotes {
181181

182182
/** Unpickle TASTY bytes into it's tree */
183183
private def unpickle(pickled: String | List[String], isType: Boolean)(using Context): Tree = {
184-
val bytes = pickled match
185-
case pickled: String => TastyString.unpickle(pickled)
186-
case pickled: List[String] => TastyString.unpickle(pickled)
184+
QuotesCache.getTree(pickled) match
185+
case Some(tree) =>
186+
quotePickling.println(s"**** Using cached quote for TASTY\n$tree")
187+
tree
188+
case _ =>
189+
val bytes = pickled match
190+
case pickled: String => TastyString.unpickle(pickled)
191+
case pickled: List[String] => TastyString.unpickle(pickled)
192+
193+
quotePickling.println(s"**** unpickling quote from TASTY\n${TastyPrinter.show(bytes)}")
187194

188-
quotePickling.println(s"**** unpickling quote from TASTY\n${TastyPrinter.show(bytes)}")
195+
val mode = if (isType) UnpickleMode.TypeTree else UnpickleMode.Term
196+
val unpickler = new DottyUnpickler(bytes, mode)
197+
unpickler.enter(Set.empty)
189198

190-
val mode = if (isType) UnpickleMode.TypeTree else UnpickleMode.Term
191-
val unpickler = new DottyUnpickler(bytes, mode)
192-
unpickler.enter(Set.empty)
199+
val tree = unpickler.tree
193200

194-
val tree = unpickler.tree
201+
var cacheable = true // TODO: can we remove this?
195202

196-
// Make sure trees and positions are fully loaded
197-
new TreeTraverser {
198-
def traverse(tree: Tree)(using Context): Unit = traverseChildren(tree)
199-
}.traverse(tree)
203+
// Make sure trees and positions are fully loaded
204+
new TreeTraverser {
205+
def traverse(tree: Tree)(using Context): Unit =
206+
tree match
207+
case _: DefTree =>
208+
if !tree.symbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot)
209+
&& !tree.symbol.hasAnnotation(defn.QuotedRuntimePatterns_patternTypeAnnot)
210+
then
211+
cacheable = false
212+
case _ =>
213+
traverseChildren(tree)
214+
}.traverse(tree)
200215

201-
quotePickling.println(i"**** unpickled quote\n$tree")
202-
tree
216+
quotePickling.println(i"**** unpickled quote\n$tree")
217+
if cacheable then
218+
QuotesCache(pickled) = tree
219+
220+
tree
203221
}
204222

205223
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package dotty.tools.dotc.quoted
2+
3+
import dotty.tools.dotc.core.Contexts._
4+
import dotty.tools.dotc.util.Property
5+
import dotty.tools.dotc.reporting.trace
6+
import dotty.tools.dotc.ast.tpd
7+
8+
import scala.collection.mutable
9+
10+
object QuotesCache {
11+
import tpd._
12+
13+
/** A key to be used in a context property that caches the unpickled trees */
14+
private val QuotesCacheKey = new Property.Key[collection.mutable.Map[String | List[String], Tree]]
15+
16+
17+
/** Get the cached tree of the quote */
18+
def getTree(pickled: String | List[String])(using Context): Option[Tree] =
19+
ctx.property(QuotesCacheKey).get.get(pickled)
20+
21+
/** Update the cached tree of the quote */
22+
def update(pickled: String | List[String], tree: Tree)(using Context): Unit =
23+
ctx.property(QuotesCacheKey).get.update(pickled, tree)
24+
25+
/** Context with a cache for quote trees and tasty bytes */
26+
def init(ctx: FreshContext): ctx.type =
27+
ctx.setProperty(QuotesCacheKey, collection.mutable.Map.empty)
28+
}

staging/src/scala/quoted/staging/QuoteDriver.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package staging
44
import dotty.tools.dotc.ast.tpd
55
import dotty.tools.dotc.Driver
66
import dotty.tools.dotc.core.Contexts.{Context, ContextBase, FreshContext}
7+
import dotty.tools.dotc.quoted.QuotesCache
78
import dotty.tools.io.{AbstractFile, Directory, PlainDirectory, VirtualDirectory}
89
import dotty.tools.repl.AbstractFileClassLoader
910
import dotty.tools.dotc.reporting._
@@ -33,8 +34,11 @@ private class QuoteDriver(appClassloader: ClassLoader) extends Driver:
3334
new VirtualDirectory("<quote compilation output>")
3435
end outDir
3536

36-
val ctx0 = setup(settings.compilerArgs.toArray :+ "dummy.scala", initCtx.fresh).get._2
37-
val ctx = setCompilerSettings(ctx0.fresh.setSetting(ctx0.settings.outputDir, outDir), settings)
37+
val ctx = {
38+
val ctx0 = QuotesCache.init(initCtx.fresh)
39+
val ctx1 = setup(settings.compilerArgs.toArray :+ "dummy.scala", ctx0).get._2
40+
setCompilerSettings(ctx1.fresh.setSetting(ctx1.settings.outputDir, outDir), settings)
41+
}
3842

3943
new QuoteCompiler().newRun(ctx).compileExpr(exprBuilder) match
4044
case Right(value) =>

0 commit comments

Comments
 (0)