aboutsummaryrefslogtreecommitdiff
path: root/goodfile
blob: cf93b869641130eecd6c4e55e133ee3a4a277bdd (plain)
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
118
119
120
121
Build.dependencies({"git", "make", "rustc", "cargo"})

Build.metric(
  "nightly version",
  string.gsub(Build.check_output({"rustc", "--version"}).stdout, '^%s*(.*)%s*$', '%1')
)

Step.start("crate")
Step.push("build")
Build.run({"cargo", "build"}) -- `run` automatically records stdout and stderr to log files named after the command
Step.advance("test")
Build.run({"cargo", "test"}, {name="test stdlib/fmt"}) -- artifacts are stored under `name` if that's present
Build.run({"cargo", "test", "--no-default-features"}, {name="test nostdlib/nofmt"})
Build.run({"cargo", "test", "--no-default-features", "--features", "fmt"}, {name="test nostdlib/fmt"})

Step.start("ffi")
Step.push("build")
Build.run({"cargo", "+nightly", "build", "-Z", "build-std", "--release", "--no-default-features", "--target", Build.environment.vars.native_rust_triple}, {cwd="ffi/"})

Step.advance("validate")
sopath = "ffi/target/" .. Build.environment.vars.native_rust_triple .. "/release/libyaxpeax_x86_ffi_long_mode.so"
Build.run({"ls", sopath})
Build.metric(
  "libyaxpeax_x86_ffi_long_mode.so size (bytes)",
  Build.environment.size(sopath)
)
Build.artifact(sopath)

-- now run some perf numbers...
Step.start("perf")
Build.run({"git", "clone", "https://github.com/iximeow/disas-bench.git", "disas-bench"})
Build.run({"git", "submodule", "update", "--recursive", "--init"}, {cwd="disas-bench"})
Build.run({"git", "remote", "add", "dev", "../../.."}, {cwd="disas-bench/libs/yaxpeax"})
Build.run({"git", "fetch", "-a", "dev"}, {cwd="disas-bench/libs/yaxpeax"})
Build.run({"git", "checkout", Build.sha}, {cwd="disas-bench/libs/yaxpeax"})
Step.push("build")
Build.run({"make", "make-bench-yaxpeax"}, {cwd="disas-bench/bench/yaxpeax"})

Build.metric(
  "bench-yaxpeax-fmt size (bytes)",
  Build.environment.size("disas-bench/bench/yaxpeax/bench-yaxpeax-fmt")
)

Build.metric(
  "bench-yaxpeax-no-fmt size (bytes)",
  Build.environment.size("disas-bench/bench/yaxpeax/bench-yaxpeax-no-fmt")
)

-- fmt
Step.advance("fmt")
bench_start = Build.now_ms()

Build.run({"./bench-yaxpeax-fmt", "20", "0x400", "0x2460400", "../../input/xul.dll"}, {cwd="disas-bench/bench/yaxpeax"})

bench_end = Build.now_ms()
Build.metric("fmt runtime (ms)", bench_end - bench_start)

-- no-fmt
Step.advance("no-fmt")
bench_start = Build.now_ms()

Build.run({"./bench-yaxpeax-no-fmt", "20", "0x400", "0x2460400", "../../input/xul.dll"}, {cwd="disas-bench/bench/yaxpeax"})

bench_end = Build.now_ms()
Build.metric("no-fmt runtime (ms)", bench_end - bench_start)

-- perf

if Build.environment.has("perf") then
  perf_setting = Build.check_output({"cat", "/proc/sys/kernel/perf_event_paranoid"})
  -- TODO: roll this up into some perf tools in the lua env. for now, if perf
  -- event paranoid is >2 then we'll probably just fail the build trying and
  -- failing to run perf.
  perf_out = Build.check_output({"perf", "stat", "-x", ";", "-e", "cycles,instructions", "./bench-yaxpeax-no-fmt", "20", "0x400", "0x2460400", "../../input/xul.dll"}, {cwd="disas-bench/bench/yaxpeax"})

  measurements = {}

  for count, unit, name in perf_out.stderr:gmatch("([^;]*);([^;]*);([^;]*)[^\n]*\n?") do
    measurements[name] = tonumber(count)
  end

  insts, good, bad, ms = perf_out.stdout:match("Disassembled (%d*) instructions %((%d*) valid, (%d*) bad%), (%d*) ms")

  measurements["decoded"] = tonumber(insts)
  measurements["elapsed_ms"] = tonumber(ms)

  local instructions_name = "instructions:u"
  local cycles_name = "cycles:u"
  if measurements[instructions_name] == nil then
    instructions_name = "instructions"
    cycles_name = "cycles"
  end

  ipc = measurements[instructions_name] / measurements[cycles_name]
  Build.metric("no-fmt IPC", string.format("%.3f", ipc))
  inst_per_decode = measurements[instructions_name] / measurements["decoded"]
  Build.metric("no-fmt instructions/decode", string.format("%.1f", inst_per_decode))
  ms_per_decode = measurements["elapsed_ms"] / measurements["decoded"]
  Build.metric("no-fmt ns/decode", string.format("%.2f", ms_per_decode * 1000000))


  perf_out = Build.check_output({"perf", "stat", "-x", ";", "-e", "cycles,instructions", "./bench-yaxpeax-fmt", "20", "0x400", "0x2460400", "../../input/xul.dll"}, {cwd="disas-bench/bench/yaxpeax"})

  measurements = {}

  for count, unit, name in perf_out.stderr:gmatch("([^;]*);([^;]*);([^;]*)[^\n]*\n?") do
    measurements[name] = tonumber(count)
  end

  insts, good, bad, ms = perf_out.stdout:match("Disassembled (%d*) instructions %((%d*) valid, (%d*) bad%), (%d*) ms")

  measurements["decoded"] = tonumber(insts)
  measurements["elapsed_ms"] = tonumber(ms)

  ipc = measurements[instructions_name] / measurements[cycles_name]
  Build.metric("fmt IPC", string.format("%.3f", ipc))
  inst_per_decode = measurements[instructions_name] / measurements["decoded"]
  Build.metric("fmt instructions/decode+display", string.format("%.1f", inst_per_decode))
  ms_per_decode = measurements["elapsed_ms"] / measurements["decoded"]
  Build.metric("fmt ns/decode+display", string.format("%.2f", ms_per_decode * 1000000))
end