Skip to content

Commit 302c62d

Browse files
committed
Address some review comments; add opencensus support; add pprof support
1 parent bd95b4d commit 302c62d

File tree

11 files changed

+854
-262
lines changed

11 files changed

+854
-262
lines changed

go.mod

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,25 @@ module github.com/luthersystems/elps
33
go 1.13
44

55
require (
6-
github.com/BurntSushi/toml v0.3.1 // indirect
76
github.com/chzyer/logex v1.1.10 // indirect
87
github.com/chzyer/readline v0.0.0-20160726135117-62c6fe619375
98
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect
109
github.com/davecgh/go-spew v1.1.1 // indirect
1110
github.com/fsnotify/fsnotify v1.4.7 // indirect
11+
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
1212
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce // indirect
1313
github.com/inconshreveable/mousetrap v1.0.0 // indirect
1414
github.com/magiconair/properties v1.8.0 // indirect
1515
github.com/mitchellh/go-homedir v0.0.0-20180523094522-3864e76763d9
1616
github.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675 // indirect
1717
github.com/pelletier/go-toml v1.1.0 // indirect
18-
github.com/pmezard/go-difflib v1.0.0 // indirect
1918
github.com/prataprc/goparsec v0.0.0-20180208125142-3db61e7995f1
2019
github.com/spf13/afero v1.1.0 // indirect
2120
github.com/spf13/cast v1.2.0 // indirect
2221
github.com/spf13/cobra v0.0.3
2322
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec // indirect
2423
github.com/spf13/pflag v1.0.1 // indirect
2524
github.com/spf13/viper v1.0.2
26-
github.com/stretchr/testify v1.2.2
27-
golang.org/x/sys v0.0.0-20180525142821-c11f84a56e43 // indirect
28-
golang.org/x/text v0.3.0 // indirect
29-
gopkg.in/yaml.v2 v2.2.1 // indirect
25+
github.com/stretchr/testify v1.4.0
26+
go.opencensus.io v0.22.3
3027
)

go.sum

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
12
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
23
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
34
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
@@ -6,10 +7,21 @@ github.com/chzyer/readline v0.0.0-20160726135117-62c6fe619375 h1:JVe1zduaiPlSLOu
67
github.com/chzyer/readline v0.0.0-20160726135117-62c6fe619375/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
78
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
89
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
10+
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
11+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
912
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1013
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1114
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
1215
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
16+
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4=
17+
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU=
18+
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
19+
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
20+
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
21+
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
22+
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
23+
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
24+
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
1325
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno=
1426
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
1527
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
@@ -38,13 +50,45 @@ github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
3850
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
3951
github.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso=
4052
github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
41-
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
42-
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
43-
golang.org/x/sys v0.0.0-20180525142821-c11f84a56e43 h1:PvnWIWTbA7gsEBkKjt0HV9hckYfcqYv8s/ju7ArZ0do=
44-
golang.org/x/sys v0.0.0-20180525142821-c11f84a56e43/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
53+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
54+
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
55+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
56+
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
57+
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
58+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
59+
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
60+
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
61+
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
62+
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
63+
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
64+
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
65+
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
66+
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
67+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
68+
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
69+
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
70+
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
71+
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
72+
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
73+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
74+
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd h1:r7DufRZuZbWB7j439YfAzP8RPDa9unLkpwQKUYbIMPI=
75+
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4576
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
4677
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
78+
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
79+
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
80+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
81+
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
82+
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
83+
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
84+
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
85+
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
86+
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
87+
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
88+
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
89+
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
4790
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
4891
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
49-
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
50-
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
92+
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
93+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
94+
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

lisp/profiler.go

Lines changed: 0 additions & 247 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
11
package lisp
22

3-
import (
4-
"errors"
5-
"fmt"
6-
"github.com/luthersystems/elps/parser/token"
7-
"os"
8-
"regexp"
9-
"runtime"
10-
"sync"
11-
"time"
12-
)
13-
14-
153
const ElpsVersion = "1.7"
16-
var builtinRegex = regexp.MustCompile("\\<(?:builtin|special)-[a-z]+ \\`\\`(.*)\\'\\'\\>")
174

185
// Interface for a profiler
196
type Profiler interface {
@@ -31,237 +18,3 @@ type Profiler interface {
3118
End(function *LVal)
3219
}
3320

34-
// A profiler implementation that builds Callgrind files.
35-
// Heavily influenced by how XDebug works for PHP. Not because
36-
// I like PHP but because XDebug is very light
37-
// The resulting files can be opened in KCacheGrind or QCacheGrind.
38-
type profiler struct {
39-
sync.Mutex
40-
writer *os.File
41-
runtime *Runtime
42-
enabled bool
43-
startTime time.Time
44-
refs map[string]int
45-
sourceCache map[int]*token.Location
46-
refCounter int
47-
callRefs map[int32]*callRef
48-
}
49-
50-
// Returns a new Callgrind processor
51-
func NewProfiler(runtime *Runtime) Profiler {
52-
p := new(profiler)
53-
p.runtime = runtime
54-
runtime.Profiler = p
55-
return p
56-
}
57-
58-
// Represents something that got called
59-
type callRef struct {
60-
start time.Time
61-
prev *callRef
62-
name string
63-
children []*callRef
64-
duration time.Duration
65-
file string
66-
line int
67-
}
68-
69-
func (p *profiler) IsEnabled() bool {
70-
return p.enabled
71-
}
72-
73-
func (p *profiler) Enable() error {
74-
p.Lock()
75-
defer p.Unlock()
76-
if p.enabled {
77-
return errors.New("Profiler already enabled")
78-
}
79-
if p.writer == nil {
80-
return errors.New("No output set in profiler")
81-
}
82-
fmt.Fprintf(p.writer, "version: 1\ncreator: elps %s (Go %s)\n", ElpsVersion, runtime.Version());
83-
fmt.Fprintf(p.writer, "cmd: %s\npart: 1\npositions: line\n\n", "TODO");
84-
fmt.Fprintf(p.writer, "events: Time_(ns) Memory_(bytes)\n\n");
85-
p.callRefs = make(map[int32]*callRef)
86-
p.startTime = time.Now()
87-
p.refs = make(map[string]int)
88-
p.refCounter = 0
89-
p.enabled = true
90-
return nil
91-
}
92-
93-
func (p *profiler) SetFile(filename string) error {
94-
p.Lock()
95-
defer p.Unlock()
96-
if p.enabled {
97-
return errors.New("Profiler already enabled")
98-
}
99-
pointer, err := os.Create(filename)
100-
if err != nil {
101-
return err
102-
}
103-
p.writer = pointer
104-
return nil
105-
}
106-
107-
func (p *profiler) Complete() error {
108-
p.Lock()
109-
defer p.Unlock()
110-
duration := time.Now().Sub(p.startTime)
111-
ms := &runtime.MemStats{}
112-
runtime.ReadMemStats(ms)
113-
fmt.Fprintf(p.writer, "summary %d %d\n\n", duration.Nanoseconds(), ms.TotalAlloc)
114-
return p.writer.Close()
115-
}
116-
117-
func (p *profiler) getRef(name string) string {
118-
if ref, ok := p.refs[name]; ok {
119-
return fmt.Sprintf("(%d)", ref)
120-
}
121-
p.refCounter++
122-
p.refs[name] = p.refCounter
123-
return fmt.Sprintf("(%d) %s", p.refCounter, name)
124-
}
125-
126-
func (p *profiler) Start(function *LVal) {
127-
if !p.enabled {
128-
return
129-
}
130-
switch function.Type {
131-
case LInt, LString, LFloat, LBytes, LError, LArray, LQuote, LNative, LQSymbol, LSortMap:
132-
// We don't need to profile these types. We could, but we're not that LISP :D
133-
return
134-
case LFun, LSymbol, LSExpr:
135-
// Mark the time and point of entry. It feels like we're building the call stack in Runtime
136-
// again, but we're not - it's called, not callers.
137-
_, _, name := p.getFunctionParameters(function)
138-
p.incrementCallRef(name, function.Source)
139-
default:
140-
panic(fmt.Sprintf("Missing type %d", function.Type))
141-
}
142-
}
143-
144-
// Generates a call ref so the same item can be located again
145-
func (p *profiler) incrementCallRef(name string, loc *token.Location) *callRef {
146-
p.Lock()
147-
defer p.Unlock()
148-
var thread *int32
149-
thread = &([]int32{1}[0]);
150-
frameRef := new(callRef)
151-
frameRef.name = name
152-
frameRef.children = make([]*callRef, 0)
153-
if loc != nil {
154-
frameRef.file = loc.File
155-
frameRef.line = loc.Line
156-
}
157-
if current, ok := p.callRefs[*thread]; ok && current != nil {
158-
frameRef.prev = current
159-
frameRef.prev.children = append(frameRef.prev.children, frameRef)
160-
}
161-
frameRef.start = time.Now()
162-
p.callRefs[*thread] = frameRef
163-
return frameRef
164-
}
165-
166-
// Finds a call ref for the current scope
167-
func (p *profiler) getCallRefAndDecrement() *callRef {
168-
var thread *int32
169-
//C.GetGoId(thread)
170-
thread = &([]int32{1}[0]);
171-
if current, ok := p.callRefs[*thread]; ok {
172-
p.callRefs[*thread] = current.prev
173-
return current
174-
}
175-
panic(fmt.Sprintf("Unset thread ref %d", *thread))
176-
}
177-
178-
// Gets a canonical version of the function name suitable for viewing in KCacheGrind
179-
func (p *profiler) getFunNameFromFID(in string) string {
180-
// Most of the time we can just look this up in FunNames
181-
if name, ok := p.runtime.Package.FunNames[in]; ok {
182-
return name
183-
}
184-
// but sometimes something doesn't match - so we'll try to regexp it out
185-
if !builtinRegex.MatchString(in) {
186-
return in
187-
}
188-
return builtinRegex.FindStringSubmatch(in)[1]
189-
}
190-
191-
// Gets file parameters from the LVal
192-
func (p *profiler) getFunctionParameters(function *LVal) (string, int, string) {
193-
var source string
194-
line := 0
195-
if function.Source == nil {
196-
if cell := function.Cells[0]; cell != nil && cell.Source != nil {
197-
source = cell.Source.File
198-
line = cell.Source.Line
199-
} else {
200-
source = "no-source"
201-
}
202-
} else {
203-
source = function.Source.File
204-
line = function.Source.Line
205-
}
206-
fName := fmt.Sprintf("%s:%s", function.FunData().Package, p.getFunNameFromFID(function.FunData().FID))
207-
return source, line, fName
208-
}
209-
210-
func (p *profiler) End(function *LVal) {
211-
if !p.enabled {
212-
return
213-
}
214-
p.Lock()
215-
defer p.Unlock()
216-
switch function.Type {
217-
case LInt, LString, LFloat, LBytes, LError, LArray, LQuote, LNative, LQSymbol, LSortMap:
218-
// Again, we can ignore these as we never put them on the stack
219-
return
220-
case LFun, LSymbol, LSExpr:
221-
source, line, fName := p.getFunctionParameters(function)
222-
// Write what function we've been observing and where to find it
223-
fmt.Fprintf(p.writer, "fl=%s\n", p.getRef(source))
224-
fmt.Fprintf(p.writer, "fn=%s\n", p.getRef(fName))
225-
// TODO track memory
226-
memory := 0
227-
ref := p.getCallRefAndDecrement()
228-
ref.duration = time.Since(ref.start)
229-
if ref.duration == 0 {
230-
ref.duration = 1
231-
}
232-
// Cache the location - we won't be able to get it again when we build the maps for
233-
// things that call this.
234-
if ref.line == 0 && function.Source != nil {
235-
ref.line = function.Source.Line
236-
ref.file = function.Source.File
237-
}
238-
// Output timing and line ref
239-
fmt.Fprintf(p.writer, "%d %d %d\n", line, ref.duration, memory)
240-
// Output the things we called
241-
for _, entry := range ref.children {
242-
fmt.Fprintf(p.writer, "cfl=%s\n", p.getRef(entry.file))
243-
fmt.Fprintf(p.writer, "cfn=%s\n", p.getRef(entry.name))
244-
fmt.Fprint(p.writer, "calls=1 0 0\n")
245-
fmt.Fprintf(p.writer, "%d %d %d\n", entry.line, entry.duration, memory)
246-
}
247-
// and end the entry
248-
fmt.Fprint(p.writer, "\n")
249-
// if we're a top level caller we need to generate a file entry
250-
if len(p.runtime.Stack.Frames) == 0 {
251-
// just show the file
252-
fmt.Fprintf(p.writer, "fl=%s\n", p.getRef(source))
253-
fmt.Fprintf(p.writer, "%d %d %d\n", line, ref.duration, memory)
254-
// and call ourselves
255-
fmt.Fprintf(p.writer, "cfl=%s\n", p.getRef(source))
256-
fmt.Fprintf(p.writer, "cfn=%s\n", p.getRef(fName))
257-
fmt.Fprintf(p.writer, "%d %d %d\n", line, ref.duration, memory)
258-
fmt.Fprint(p.writer, "calls=1 0 0\n")
259-
// and end the entry
260-
fmt.Fprint(p.writer, "\n")
261-
}
262-
default:
263-
panic(fmt.Sprintf("Missing type %d", function.Type))
264-
}
265-
}
266-
267-

0 commit comments

Comments
 (0)