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
//! Counters a profiling harness fills in and a profiling build of the engine
//! writes to.
//!
//! Invariant: a normal build never touches anything here, and nothing in the
//! engine ever reads one of these to decide what to do. They exist so a harness
//! that installs a counting global allocator can attribute time and allocations
//! to the bytecode instruction that caused them - which needs a place both the
//! binary that owns the allocator and the crate that runs the instruction can
//! reach, and that place has to be the crate they both already depend on.
//!
//! The stage tables are written only by a build with `inillucent-storage`'s
//! `opcode-probe` feature on, which is off by default and is never on in a
//! shipped build.
//!
//! **The per-opcode tables went with the machine they profiled (task-1946, M3).**
//! `OPCODE_SLOTS`, `OPCODE_RUNS`, `OPCODE_NANOS`, `OPCODE_ALLOCATIONS` and
//! `reset_opcodes` attributed time and allocations to a bytecode instruction,
//! and there is no bytecode engine: `inillucent-vm` was deleted with the rest of
//! the old one. Nothing had written one of them since.
use AtomicU64;
/// How many heap allocations the process has made, when something is counting.
///
/// The harness that installs a counting allocator increments this; every other
/// build leaves it at zero, which reads as "nobody is counting" rather than as
/// "no allocations happened", because a profile is only compared against itself.
pub static ALLOCATIONS: AtomicU64 = new;
/// How many named stages the tables below have room for.
pub const STAGE_SLOTS: usize = 16;
/// How many nanoseconds each named stage has spent.
///
/// A stage is whatever a profiling build decided to bracket - the halves of a
/// page edit, say. The names live with the code that records them, because a
/// number here means nothing without the bracket that produced it.
pub static STAGE_NANOS: = ;
/// How many times each named stage ran.
pub static STAGE_RUNS: = ;
/// How many heap allocations each named stage made.
pub static STAGE_ALLOCATIONS: = ;
/// Adds one run of a stage, with the allocations it made.
/// Adds one run of a stage.
/// How many rounds a seeded property loop should run.
///
/// Answers `full` on every ordinary build. Under Miri it answers a hundredth of
/// it, floored at five hundred, because the interpreter executes every
/// instruction and a two-hundred-thousand-round loop that takes milliseconds
/// natively takes hours there - so a Miri run either samples or never finishes,
/// and never finishing is the same as not running it.
///
/// The properties these loops check - no input panics, every value round-trips
/// canonically - are checked against Miri's much stricter memory model at any
/// sample size, and the full sample still runs everywhere else.