Skip to content

Commit

Permalink
Add control to speedy compiler to choose if stack-trace support occur…
Browse files Browse the repository at this point in the history
…s at runtime. (digital-asset#6070)


Choices for `stacktracing` are `NoStackTrace` / `FullStackTrace`.

Adapt code so the selection is made by the original caller:
- `engine`
- `scenario-service`
- `repl-service`
- `daml-script` runner
etc

Currently, all callers pass `FullStackTrace` (the existing behaviour), except for the
exploration dev-code: `daml-lf/interpreter/perf/src/main/scala/com/daml/lf/explore`.

The idea is that once this control is in place, we can discuss if we can change how we
might expose it to the user, and/or perhaps change the default behaviour to have
`stacktracing` disabled.

changelog_begin
changelog_end
  • Loading branch information
nickchapman-da authored May 22, 2020
1 parent f845bca commit 44d0128
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ class ReplService(
respObs: StreamObserver[LoadPackageResponse]): Unit = {
val (pkgId, pkg) = Decode.decodeArchiveFromInputStream(req.getPackage.newInput)
packages = packages + (pkgId -> pkg)
compiledDefinitions = compiledDefinitions ++ Compiler(packages, Compiler.NoProfile)
compiledDefinitions = compiledDefinitions ++ Compiler(
packages,
Compiler.FullStackTrace,
Compiler.NoProfile)
.unsafeCompilePackage(pkgId)
respObs.onNext(LoadPackageResponse.newBuilder.build)
respObs.onCompleted()
Expand Down Expand Up @@ -219,9 +222,14 @@ class ReplService(
}

val allPkgs = packages + (homePackageId -> pkg)
val defs = Compiler(allPkgs, Compiler.NoProfile).unsafeCompilePackage(homePackageId)
val defs = Compiler(allPkgs, Compiler.FullStackTrace, Compiler.NoProfile)
.unsafeCompilePackage(homePackageId)
val compiledPackages =
PureCompiledPackages(allPkgs, compiledDefinitions ++ defs, Compiler.NoProfile)
PureCompiledPackages(
allPkgs,
compiledDefinitions ++ defs,
Compiler.FullStackTrace,
Compiler.NoProfile)
val runner = new Runner(
compiledPackages,
Script.Action(scriptExpr, ScriptIds(scriptPackageId)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ class Context(val contextId: Context.ContextId) {
// if any change we recompile everything
extPackages --= unloadPackages
extPackages ++= newPackages
extDefns = assert(Compiler.compilePackages(extPackages, Compiler.NoProfile))
extDefns =
assert(Compiler.compilePackages(extPackages, Compiler.FullStackTrace, Compiler.NoProfile))
modDefns = HashMap.empty
modules.values
} else {
Expand All @@ -118,7 +119,7 @@ class Context(val contextId: Context.ContextId) {
}

val pkgs = allPackages
val compiler = Compiler(pkgs, Compiler.NoProfile)
val compiler = Compiler(pkgs, Compiler.FullStackTrace, Compiler.NoProfile)

modulesToCompile.foreach { mod =>
if (!omitValidation)
Expand Down Expand Up @@ -152,7 +153,8 @@ class Context(val contextId: Context.ContextId) {
Speedy.Machine
.build(
sexpr = defn,
compiledPackages = PureCompiledPackages(allPackages, defns, Compiler.NoProfile),
compiledPackages =
PureCompiledPackages(allPackages, defns, Compiler.FullStackTrace, Compiler.NoProfile),
submissionTime,
initialSeeding,
Set.empty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ final class ConcurrentCompiledPackages extends MutableCompiledPackages {
def getDefinition(dref: speedy.SExpr.SDefinitionRef): Option[speedy.SExpr] =
Option(_defns.get(dref))

def stackTraceMode = speedy.Compiler.FullStackTrace
def profilingMode = speedy.Compiler.NoProfile

/** Might ask for a package if the package you're trying to add references it.
Expand Down Expand Up @@ -83,7 +84,7 @@ final class ConcurrentCompiledPackages extends MutableCompiledPackages {
// Compile the speedy definitions for this package.
val defns =
speedy
.Compiler(packages orElse state.packages, profilingMode)
.Compiler(packages orElse state.packages, stackTraceMode, profilingMode)
.unsafeCompilePackage(pkgId)
defns.foreach {
case (defnId, defn) => _defns.put(defnId, defn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ object PlaySpeedy {

def main(args0: List[String]) = {
val config: Config = parseArgs(args0)
val compiler: Compiler = Compiler(Map.empty, Compiler.NoProfile)
val compiler: Compiler = Compiler(Map.empty, Compiler.FullStackTrace, Compiler.NoProfile)

val names: List[String] = config.names match {
case Nil => examples.toList.map(_._1)
Expand Down Expand Up @@ -66,7 +66,7 @@ object PlaySpeedy {

def makeMachine(sexpr: SExpr): Machine = {
val compiledPackages: CompiledPackages =
PureCompiledPackages(Map.empty, Compiler.NoProfile).right.get
PureCompiledPackages(Map.empty, Compiler.NoStackTrace, Compiler.NoProfile).right.get
Machine.fromSExpr(
sexpr,
compiledPackages,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,29 @@ object PlaySpeedy {
def parseArgs(args0: List[String]): Config = {
var funcName: String = "triangle"
var argValue: Long = 10
var stacktracing: Compiler.StackTraceMode = Compiler.NoStackTrace
def loop(args: List[String]): Unit = args match {
case Nil => {}
case "-h" :: _ => usage()
case "--help" :: _ => usage()
case "--arg" :: x :: args =>
argValue = x.toLong
loop(args)
case "--stacktracing" :: args =>
stacktracing = Compiler.FullStackTrace
loop(args)
case x :: args =>
funcName = x
loop(args)
}
loop(args0)
Config(funcName, argValue)
Config(funcName, argValue, stacktracing)
}

final case class Config(
funcName: String,
argValue: Long,
stacktracing: Compiler.StackTraceMode,
)

def main(args0: List[String]) = {
Expand All @@ -68,8 +73,11 @@ object PlaySpeedy {
case (pkgId, pkgArchive) => Decode.readArchivePayloadAndVersion(pkgId, pkgArchive)._1
}.toMap

println("Compiling packages...")
val compiledPackages: CompiledPackages = PureCompiledPackages(packagesMap).right.get
println(s"Compiling packages... ${config.stacktracing}")
val compiledPackages: CompiledPackages = PureCompiledPackages(
packagesMap,
config.stacktracing
).right.get

val machine: Machine = {
println(s"Setup machine for: ${config.funcName}(${config.argValue})")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,22 @@ trait CompiledPackages {
def definitions: PartialFunction[SDefinitionRef, SExpr] =
Function.unlift(this.getDefinition)

def stackTraceMode: Compiler.StackTraceMode
def profilingMode: Compiler.ProfilingMode

def compiler: Compiler = Compiler(packages, profilingMode)
def compiler: Compiler = Compiler(packages, stackTraceMode, profilingMode)
}

final class PureCompiledPackages private (
packages: Map[PackageId, Package],
defns: Map[SDefinitionRef, SExpr],
stacktracing: Compiler.StackTraceMode,
profiling: Compiler.ProfilingMode,
) extends CompiledPackages {
override def packageIds: Set[PackageId] = packages.keySet
override def getPackage(pkgId: PackageId): Option[Package] = packages.get(pkgId)
override def getDefinition(dref: SDefinitionRef): Option[SExpr] = defns.get(dref)
override def stackTraceMode = stacktracing
override def profilingMode = profiling
}

Expand All @@ -44,16 +47,18 @@ object PureCompiledPackages {
private[lf] def apply(
packages: Map[PackageId, Package],
defns: Map[SDefinitionRef, SExpr],
stacktracing: Compiler.StackTraceMode,
profiling: Compiler.ProfilingMode
): PureCompiledPackages =
new PureCompiledPackages(packages, defns, profiling)
new PureCompiledPackages(packages, defns, stacktracing, profiling)

def apply(
packages: Map[PackageId, Package],
stacktracing: Compiler.StackTraceMode = Compiler.FullStackTrace,
profiling: Compiler.ProfilingMode = Compiler.NoProfile,
): Either[String, PureCompiledPackages] =
Compiler
.compilePackages(packages, profiling)
.map(new PureCompiledPackages(packages, _, profiling))
.compilePackages(packages, stacktracing, profiling)
.map(new PureCompiledPackages(packages, _, stacktracing, profiling))

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ private[lf] object Compiler {
case object NoProfile extends ProfilingMode
case object FullProfile extends ProfilingMode

sealed abstract class StackTraceMode extends Product with Serializable
case object NoStackTrace extends StackTraceMode
case object FullStackTrace extends StackTraceMode

private val SEGetTime = SEBuiltin(SBGetTime)

private def SBCompareNumeric(b: SBuiltin) =
Expand All @@ -62,10 +66,11 @@ private[lf] object Compiler {
*/
def compilePackages(
packages: Map[PackageId, Package],
stacktracing: StackTraceMode,
profiling: ProfilingMode,
validation: Boolean = true,
): Either[String, Map[SDefinitionRef, SExpr]] = {
val compiler = Compiler(packages, profiling)
val compiler = Compiler(packages, stacktracing, profiling)
try {
Right(
packages.keys.foldLeft(Map.empty[SDefinitionRef, SExpr])(
Expand All @@ -82,10 +87,19 @@ private[lf] object Compiler {

private[lf] final case class Compiler(
packages: PackageId PartialFunction Package,
stacktracing: Compiler.StackTraceMode,
profiling: Compiler.ProfilingMode) {

import Compiler._

// Stack-trace support is disabled by avoiding the construction of SELocation nodes.
def maybeSELocation(loc: Location, sexp: SExpr): SExpr = {
stacktracing match {
case NoStackTrace => sexp
case FullStackTrace => SELocation(loc, sexp)
}
}

private val logger = LoggerFactory.getLogger(this.getClass)

private abstract class VarRef { def name: Name }
Expand Down Expand Up @@ -620,13 +634,13 @@ private[lf] final case class Compiler(
}

case ELocation(loc, EScenario(scen)) =>
SELocation(loc, translateScenario(scen, Some(loc)))
maybeSELocation(loc, translateScenario(scen, Some(loc)))

case EScenario(scen) =>
translateScenario(scen, None)

case ELocation(loc, e) =>
SELocation(loc, translate(e))
maybeSELocation(loc, translate(e))

case EToAny(ty, e) =>
SEApp(SEBuiltin(SBToAny(ty)), Array(translate(e)))
Expand Down Expand Up @@ -968,12 +982,6 @@ private[lf] final case class Compiler(
f(())
}

def stripLocation(e: SExpr): SExpr =
e match {
case SELocation(_, e2) => stripLocation(e2)
case _ => e
}

/** Convert abstractions in a speedy expression into
* explicit closure creations.
* This step computes the free variables in an abstraction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,8 @@ class OrderingSpec
private val txSeed = crypto.Hash.hashPrivateKey("SBuiltinTest")
private def initMachine(expr: SExpr) = Speedy.Machine fromSExpr (
sexpr = expr,
compiledPackages = PureCompiledPackages(Map.empty, Map.empty, Compiler.NoProfile),
compiledPackages =
PureCompiledPackages(Map.empty, Map.empty, Compiler.FullStackTrace, Compiler.NoProfile),
submissionTime = Time.Timestamp.now(),
seeding = InitialSeeding.TransactionSeed(txSeed),
globalCids = Set.empty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ object Repl {
profiling: Compiler.ProfilingMode) {
private val build = Speedy.Machine
.newBuilder(
PureCompiledPackages(packages, profiling).right.get,
PureCompiledPackages(packages, Compiler.FullStackTrace, profiling).right.get,
Time.Timestamp.MinValue,
nextSeed())
.fold(err => sys.error(err.toString), identity)
Expand Down Expand Up @@ -389,7 +389,8 @@ object Repl {
}

def speedyCompile(state: State, args: Seq[String]): Unit = {
val defs = assertRight(Compiler.compilePackages(state.packages, Compiler.NoProfile))
val defs = assertRight(
Compiler.compilePackages(state.packages, Compiler.FullStackTrace, Compiler.NoProfile))
defs.get(idToRef(state, args(0))) match {
case None =>
println("Error: definition '" + args(0) + "' not found. Try :list."); usage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ class CollectAuthorityState {
val packagesMap = packages.all.map {
case (pkgId, pkgArchive) => Decode.readArchivePayloadAndVersion(pkgId, pkgArchive)._1
}.toMap
val stacktracing = Compiler.FullStackTrace

// NOTE(MH): We use a static seed to get reproducible runs.
val seeding = crypto.Hash.secureRandom(crypto.Hash.hashPrivateKey("scenario-perf"))
buildMachine = Speedy.Machine
.newBuilder(
PureCompiledPackages(packagesMap).right.get,
PureCompiledPackages(packagesMap, stacktracing).right.get,
Time.Timestamp.MinValue,
seeding(),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ class Runner(
override def packages = compiledPackages.packages
def packageIds = compiledPackages.packageIds
override def definitions = fromLedgerValue.orElse(compiledPackages.definitions)
override def stackTraceMode = Compiler.FullStackTrace
override def profilingMode = Compiler.NoProfile
}
}
Expand Down

0 comments on commit 44d0128

Please sign in to comment.