Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DAML profiler: Evaluate arguments before open event #6234

Merged
merged 1 commit into from
Jun 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import java.util.ArrayList
final class Profile {
import Profile._
private val start: Long = System.nanoTime()
private val events: ArrayList[Event] = new ArrayList()
private[lf] val events: ArrayList[Event] = new ArrayList()
var name: String = "DAML Engine profile"

def addOpenEvent(label: AnyRef) = {
Expand All @@ -39,7 +39,7 @@ final class Profile {
object Profile {
// NOTE(MH): See the documenation of [[Profile]] above for why we use
// [[AnyRef]] for the labels.
private final case class Event(val open: Boolean, val rawLabel: AnyRef, val time: Long) {
private[lf] final case class Event(val open: Boolean, val rawLabel: AnyRef, val time: Long) {
def label: String = {
import com.daml.lf.speedy.SExpr._
rawLabel match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -699,14 +699,9 @@ object Speedy {
}
// Now the correct number of arguments is ensured. What kind of prim do we have?
prim match {
case PClosure(label, body, frame) =>
// Maybe push a continuation for the profiler
if (label != null) {
machine.profile.addOpenEvent(label)
machine.pushKont(KLeaveClosure(label))
}
case closure: PClosure =>
// Push a continuation to execute the function body when the arguments have been evaluated
machine.pushKont(KFun(body, frame, actuals))
machine.pushKont(KFun(closure, actuals))

case PBuiltin(builtin) =>
// Push a continuation to execute the builtin when the arguments have been evaluated
Expand All @@ -731,16 +726,22 @@ object Speedy {
}

/** The function-closure and arguments have been evaluated. Now execute the body. */
final case class KFun(body: SExpr, frame: Frame, actuals: util.ArrayList[SValue])
final case class KFun(closure: PClosure, actuals: util.ArrayList[SValue])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Embedding the PClosure in the KFun, instead of it's components.

extends Kont
with SomeArrayEquals {
def execute(v: SValue, machine: Machine) = {
actuals.add(v)
// Set frame/actuals to allow access to the function arguments and closure free-varables.
machine.frame = frame
machine.frame = closure.frame
machine.actuals = actuals
// Maybe push a continuation for the profiler
val label = closure.label
if (label != null) {
machine.profile.addOpenEvent(label)
machine.pushKont(KLeaveClosure(label))
}
// Start evaluating the body of the closure.
machine.ctrl = body
machine.ctrl = closure.expr
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,21 @@ class SpeedyTest extends WordSpec with Matchers {
}

}

"profiler" should {
"evaluate arguments before open event" in {
val events = profile(e"""
let f: Int64 -> Int64 = \(x: Int64) -> ADD_INT64 x 1 in
let g: Int64 -> Int64 = \(x: Int64) -> ADD_INT64 x 2 in
f (g 1)
""")
events should have size 4
events.get(0) should matchPattern { case Profile.Event(true, "g", _) => }
events.get(1) should matchPattern { case Profile.Event(false, "g", _) => }
events.get(2) should matchPattern { case Profile.Event(true, "f", _) => }
events.get(3) should matchPattern { case Profile.Event(false, "f", _) => }
}
}
}

object SpeedyTest {
Expand All @@ -311,6 +326,19 @@ object SpeedyTest {
}
}

private def profile(e: Expr): java.util.ArrayList[Profile.Event] = {
val packages = PureCompiledPackages(Map.empty, profiling = Compiler.FullProfile).right.get
val machine = Speedy.Machine.fromExpr(
expr = e,
compiledPackages = packages,
scenario = false,
submissionTime = Time.Timestamp.now(),
initialSeeding = InitialSeeding.NoSeed,
)
machine.run()
machine.profile.events
}

@SuppressWarnings(Array("org.wartremover.warts.Any"))
private implicit def resultEq: Equality[Either[SError, SValue]] = {
case (Right(v1: SValue), Right(v2: SValue)) => svalue.Equality.areEqual(v1, v2)
Expand Down