forked from Fundament-Software/Alicorn0
-
Notifications
You must be signed in to change notification settings - Fork 0
/
profile.lua
117 lines (112 loc) · 3.02 KB
/
profile.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
local evaluator = require "./evaluator"
local profile, profile_n, profile_samples
local function start()
profile = require("jit.profile")
profile_n = 0
profile_samples = {}
profile.start("li10", function(thread, samples, vmstate)
local stack_n = 0
local stack = {}
-- luajit's profiler loops from 0 to 100
-- hopefully 1000 will be enough for us for a while
for i = 0, 1000 do
local d = debug.getinfo(thread, i, "Sfln")
if not d then
break
end
local infer = d.func == evaluator.infer
local check = d.func == evaluator.check
local term, context, goal, inferred_type
if infer or check then
_, term = debug.getlocal(thread, i, 1)
_, context = debug.getlocal(thread, i, 2)
end
if check then
_, goal = debug.getlocal(thread, i, 3)
--_, inferred_type = debug.getlocal(thread, i, 5)
end
stack_n = stack_n + 1
stack[stack_n] = {
i = i,
name = d.name,
namewhat = d.namewhat,
source = d.source,
short_src = d.short_src,
linedefined = d.linedefined,
lastlinedefined = d.lastlinedefined,
what = d.what,
currentline = d.currentline,
func = d.func,
infer = infer,
check = check,
term = term,
context = context,
goal = goal,
inferred_type = inferred_type,
}
end
profile_n = profile_n + 1
profile_samples[profile_n] = {
stack_n = stack_n,
stack = stack,
samples = samples,
vmstate = vmstate,
}
end)
end
local function stop()
profile.stop()
end
local function dump(profile_file)
local profile_out = io.open(profile_file, "w")
if not profile_out then
error("opening profile file failed!")
end
for n, sample in ipairs(profile_samples) do
profile_out:write("sample: ", n, "\n")
local t = false
for _, d in ipairs(sample.stack) do
local depth = sample.stack_n - d.i
profile_out:write(
string.format("%d %s %s %s: %s:%d\n", depth, d.what, d.namewhat, d.name, d.source, d.currentline)
)
if not t and (d.infer or d.check) then
profile_out:write(d.context:format_names())
profile_out:write(d.term:pretty_print(d.context), "\n")
profile_out:write(d.term:default_print(), "\n")
if d.check then
profile_out:write(d.goal:pretty_print(d.context), "\n")
profile_out:write(d.goal:default_print(), "\n")
--profile_out:write(d.inferred_type:pretty_print(d.context), "\n")
--profile_out:write(d.inferred_type:default_print(), "\n")
end
t = true
end
end
end
profile_out:close()
end
local function dump_flame(profile_file)
local profile_out = io.open(profile_file, "w")
if not profile_out then
error("opening profile file failed!")
end
for _, sample in ipairs(profile_samples) do
local s = sample.stack
for i = sample.stack_n, 1, -1 do
local d = s[i]
profile_out:write(string.format("%s %s %s: %s:%d", d.what, d.namewhat, d.name, d.source, d.currentline))
if i > 1 then
profile_out:write(";")
end
end
profile_out:write(" ", sample.samples, "\n")
end
profile_out:close()
end
return {
start = start,
stop = stop,
dump = dump,
dump_flame = dump_flame,
}