Add spans

This commit is contained in:
Anton Medvedev
2024-04-13 10:08:10 +02:00
parent 2be09b2554
commit 3dc373ec9a
6 changed files with 63 additions and 0 deletions
+29
View File
@@ -50,6 +50,11 @@ func Compile(tree *parser.Tree, config *conf.Config) (program *Program, err erro
}
}
var span *Span
if len(c.spans) > 0 {
span = c.spans[0]
}
program = NewProgram(
tree.Source,
tree.Node,
@@ -60,6 +65,7 @@ func Compile(tree *parser.Tree, config *conf.Config) (program *Program, err erro
c.arguments,
c.functions,
c.debugInfo,
span,
)
return
}
@@ -76,6 +82,7 @@ type compiler struct {
functionsIndex map[string]int
debugInfo map[string]string
nodes []ast.Node
spans []*Span
chains [][]int
arguments []int
}
@@ -193,6 +200,28 @@ func (c *compiler) compile(node ast.Node) {
c.nodes = c.nodes[:len(c.nodes)-1]
}()
if c.config != nil && c.config.Profile {
span := &Span{
Name: reflect.TypeOf(node).String(),
Expression: node.String(),
}
if len(c.spans) > 0 {
prev := c.spans[len(c.spans)-1]
prev.Children = append(prev.Children, span)
}
c.spans = append(c.spans, span)
defer func() {
if len(c.spans) > 1 {
c.spans = c.spans[:len(c.spans)-1]
}
}()
c.emit(OpProfileStart, c.addConstant(span))
defer func() {
c.emit(OpProfileEnd, c.addConstant(span))
}()
}
switch n := node.(type) {
case *ast.NilNode:
c.NilNode(n)
+1
View File
@@ -20,6 +20,7 @@ type Config struct {
ExpectAny bool
Optimize bool
Strict bool
Profile bool
ConstFns map[string]reflect.Value
Visitors []ast.Visitor
Functions FunctionsTable
+2
View File
@@ -81,6 +81,8 @@ const (
OpGroupBy
OpSortBy
OpSort
OpProfileStart
OpProfileEnd
OpBegin
OpEnd // This opcode must be at the end of this list.
)
+9
View File
@@ -27,6 +27,7 @@ type Program struct {
variables int
functions []Function
debugInfo map[string]string
span *Span
}
// NewProgram returns a new Program. It's used by the compiler.
@@ -40,6 +41,7 @@ func NewProgram(
arguments []int,
functions []Function,
debugInfo map[string]string,
span *Span,
) *Program {
return &Program{
source: source,
@@ -51,6 +53,7 @@ func NewProgram(
Arguments: arguments,
functions: functions,
debugInfo: debugInfo,
span: span,
}
}
@@ -360,6 +363,12 @@ func (program *Program) DisassembleWriter(w io.Writer) {
case OpSort:
code("OpSort")
case OpProfileStart:
code("OpProfileStart")
case OpProfileEnd:
code("OpProfileEnd")
case OpBegin:
code("OpBegin")
+13
View File
@@ -2,6 +2,7 @@ package vm
import (
"reflect"
"time"
)
type (
@@ -25,3 +26,15 @@ type Scope struct {
}
type groupBy = map[any][]any
type Span struct {
Name string `json:"name"`
Expression string `json:"expression"`
Duration int64 `json:"duration"`
Children []*Span `json:"children"`
start time.Time
}
func GetSpan(program *Program) *Span {
return program.span
}
+9
View File
@@ -8,6 +8,7 @@ import (
"regexp"
"sort"
"strings"
"time"
"github.com/expr-lang/expr/builtin"
"github.com/expr-lang/expr/file"
@@ -523,6 +524,14 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
vm.memGrow(uint(scope.Len))
vm.push(sortable.Array)
case OpProfileStart:
span := program.Constants[arg].(*Span)
span.start = time.Now()
case OpProfileEnd:
span := program.Constants[arg].(*Span)
span.Duration += time.Since(span.start).Nanoseconds()
case OpBegin:
a := vm.pop()
array := reflect.ValueOf(a)