@@ -5,37 +5,57 @@ const VERSIONS = Dict(
55)
66
77# TODO : Add any new types as they're added
8- const SUPPORTED_TYPES = Set {Type} ((
9- BenchmarkGroup,
10- Parameters,
11- TagFilter,
12- Trial,
13- TrialEstimate,
14- TrialJudgement,
15- TrialRatio,
16- LinuxPerf. Stats,
17- LinuxPerf. ThreadStats,
18- LinuxPerf. Counter,
19- LinuxPerf. EventType
20- ))
21- const LOWERED_TO_SUPPORTED_TYPES = Dict {Symbol,Type} (
22- Base. typename (x). name => x for x in SUPPORTED_TYPES
8+ const SUPPORTED_TYPES = Dict {Symbol,Type} (
9+ Base. typename (x). name => x for x in [
10+ BenchmarkGroup,
11+ Parameters,
12+ TagFilter,
13+ Trial,
14+ TrialEstimate,
15+ TrialJudgement,
16+ TrialRatio,
17+ ]
2318)
2419# n.b. Benchmark type not included here, since it is gensym'd
2520
26- function JSON. lower (x:: Union{SUPPORTED_TYPES...} )
21+ function JSON. lower (x:: Union{values( SUPPORTED_TYPES) ...} )
2722 d = Dict {String,Any} ()
2823 T = typeof (x)
2924 for i in 1 : nfields (x)
3025 name = String (fieldname (T, i))
3126 field = getfield (x, i)
3227 ft = typeof (field)
33- value = ( ft in SUPPORTED_TYPES) ? JSON. lower (field) : field
28+ value = ft <: get ( SUPPORTED_TYPES, nameof (ft), Union{} ) ? JSON. lower (field) : field
3429 d[name] = value
3530 end
3631 return [string (nameof (typeof (x))), d]
3732end
3833
34+ # Recovers LinuxPerf.Stats from serialized form
35+ function _convert (:: Type{Union{Nothing,LinuxPerf.Stats}} , d)
36+ if isnothing (d)
37+ return nothing
38+ end
39+ return LinuxPerf. Stats (_convert .(LinuxPerf. ThreadStats, d[" threads" ]))
40+ end
41+ function _convert (:: Type{LinuxPerf.ThreadStats} , d:: Dict{String} )
42+ return LinuxPerf. ThreadStats (
43+ d[" pid" ],
44+ [
45+ [_convert (LinuxPerf. Counter, counter) for counter in group] for
46+ group in d[" groups" ]
47+ ],
48+ )
49+ end
50+ function _convert (:: Type{LinuxPerf.Counter} , d:: Dict{String} )
51+ return LinuxPerf. Counter (
52+ _convert (LinuxPerf. EventType, d[" event" ]), d[" value" ], d[" enabled" ], d[" running" ]
53+ )
54+ end
55+ function _convert (:: Type{LinuxPerf.EventType} , d:: Dict{String} )
56+ return LinuxPerf. EventType (d[" category" ], d[" event" ])
57+ end
58+
3959# a minimal 'eval' function, mirroring KeyTypes, but being slightly more lenient
4060safeeval (@nospecialize x) = x
4161safeeval (x:: QuoteNode ) = x. value
@@ -45,25 +65,22 @@ function safeeval(x::Expr)
4565 x. head === :tuple && return ((safeeval (a) for a in x. args). .. ,)
4666 return x
4767end
48- recover (:: Nothing ) = nothing
4968function recover (x:: Vector )
5069 length (x) == 2 || throw (ArgumentError (" Expecting a vector of length 2" ))
5170 typename = x[1 ]:: String
5271 fields = x[2 ]:: Dict
5372 startswith (typename, " BenchmarkTools." ) &&
5473 (typename = typename[(sizeof (" BenchmarkTools." ) + 1 ): end ])
55- T = LOWERED_TO_SUPPORTED_TYPES [Symbol (typename)]
74+ T = SUPPORTED_TYPES [Symbol (typename)]
5675 fc = fieldcount (T)
5776 xs = Vector {Any} (undef, fc)
5877 for i in 1 : fc
5978 ft = fieldtype (T, i)
6079 fn = String (fieldname (T, i))
61- if ft == Union{Nothing, LinuxPerf. Stats} || ft in SUPPORTED_TYPES
80+ if ft == Union{Nothing,LinuxPerf. Stats}
81+ xsi = _convert (ft, fields[fn])
82+ elseif ft <: get (SUPPORTED_TYPES, nameof (ft), Union{})
6283 xsi = recover (fields[fn])
63- elseif ft == Vector{LinuxPerf. ThreadStats}
64- xsi = recover .(fields[fn])
65- elseif ft == Vector{Vector{LinuxPerf. Counter}}
66- xsi = [[recover (c) for c in t] for t in fields[fn]]
6784 else
6885 xsi = convert (ft, fields[fn])
6986 end
@@ -124,7 +141,7 @@ function save(io::IO, args...)
124141 " in the order it appears in the input."
125142 )
126143 continue
127- elseif typeof (arg) ∉ SUPPORTED_TYPES
144+ elseif ! (arg isa get ( SUPPORTED_TYPES, nameof ( typeof (arg)), Union{}))
128145 throw (ArgumentError (" Only BenchmarkTools types can be serialized." ))
129146 end
130147 push! (goodargs, arg)
0 commit comments