Skip to content

Commit

Permalink
Add statistic counters and averages
Browse files Browse the repository at this point in the history
  • Loading branch information
jart committed Nov 21, 2022
1 parent be5f418 commit 1e38765
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 3 deletions.
7 changes: 6 additions & 1 deletion blink/instruction.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "blink/macros.h"
#include "blink/memory.h"
#include "blink/modrm.h"
#include "blink/stats.h"
#include "blink/x86.h"

static bool IsOpcodeEqual(struct XedDecodedInst *xedd, u8 *a) {
Expand All @@ -44,6 +45,7 @@ static bool IsOpcodeEqual(struct XedDecodedInst *xedd, u8 *a) {

static void ReadInstruction(struct Machine *m, u8 *p, unsigned n) {
struct XedDecodedInst xedd[1];
STATISTIC(instructions_decoded++);
if (!DecodeInstruction(xedd, p, n, m->mode)) {
memcpy(m->xedd, xedd, kInstructionBytes);
} else {
Expand All @@ -55,6 +57,7 @@ static void LoadInstructionSlow(struct Machine *m, u64 ip) {
unsigned i;
u8 *addr;
u8 copy[15], *toil;
STATISTIC(page_overlaps++);
i = 4096 - (ip & 4095);
addr = ResolveAddress(m, ip);
if ((toil = FindReal(m, ip + i))) {
Expand All @@ -81,7 +84,9 @@ void LoadInstruction(struct Machine *m) {
m->opcache->codehost = ResolveAddress(m, m->opcache->codevirt);
addr = m->opcache->codehost + (ip & 4095);
}
if (!IsOpcodeEqual(m->xedd, addr)) {
if (IsOpcodeEqual(m->xedd, addr)) {
STATISTIC(instructions_cached++);
} else {
ReadInstruction(m, addr, 15);
}
} else {
Expand Down
14 changes: 12 additions & 2 deletions blink/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "blink/memory.h"
#include "blink/pml4t.h"
#include "blink/real.h"
#include "blink/stats.h"

void SetReadAddr(struct Machine *m, i64 addr, u32 size) {
if (size) {
Expand Down Expand Up @@ -64,12 +65,14 @@ u64 FindPage(struct Machine *m, i64 virt) {
virt &= -4096;
for (i = 1; i < ARRAYLEN(m->tlb); ++i) {
if (m->tlb[i].virt == virt && ((res = m->tlb[i].entry) & PAGE_V)) {
STATISTIC(++tlb_hits_2);
bubble = m->tlb[i - 1];
m->tlb[i - 1] = m->tlb[i];
m->tlb[i] = bubble;
return res;
}
}
STATISTIC(++tlb_misses);
level = 39;
entry = m->system->cr3;
do {
Expand All @@ -94,6 +97,7 @@ u8 *FindReal(struct Machine *m, i64 virt) {
u64 entry;
if (m->mode != XED_MODE_REAL) {
if (m->tlb[0].virt == (virt & -4096) && (m->tlb[0].entry & PAGE_V)) {
STATISTIC(++tlb_hits_1);
return m->system->real.p + (m->tlb[0].entry & PAGE_TA) + (virt & 4095);
}
if (-0x800000000000 <= virt && virt < 0x800000000000) {
Expand Down Expand Up @@ -171,7 +175,10 @@ void VirtualRecvWrite(struct Machine *m, i64 addr, void *src, u64 n) {
u8 *ReserveAddress(struct Machine *m, i64 v, size_t n) {
u8 *r;
unassert(n <= sizeof(m->opcache->stash));
if ((v & 4095) + n <= 4096) return ResolveAddress(m, v);
if ((v & 4095) + n <= 4096) {
return ResolveAddress(m, v);
}
STATISTIC(++page_overlaps);
m->opcache->stashaddr = v;
m->opcache->stashsize = n;
r = m->opcache->stash;
Expand All @@ -184,7 +191,10 @@ u8 *AccessRam(struct Machine *m, i64 v, size_t n, void *p[2], u8 *tmp,
u8 *a, *b;
unsigned k;
unassert(n <= 4096);
if ((v & 4095) + n <= 4096) return ResolveAddress(m, v);
if ((v & 4095) + n <= 4096) {
return ResolveAddress(m, v);
}
STATISTIC(++page_overlaps);
k = 4096;
k -= v & 4095;
unassert(k <= 4096);
Expand Down
42 changes: 42 additions & 0 deletions blink/stats.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "blink/log.h"
#include "blink/stats.h"

#define DEFINE_AVERAGE(S) struct Average S;
#define DEFINE_COUNTER(S) long S;
#include "blink/stats.inc"
#undef DEFINE_AVERAGE
#undef DEFINE_COUNTER

#define APPEND(...) o += snprintf(b + o, n - o, __VA_ARGS__)

void PrintStats(void) {
#ifndef NDEBUG
char b[2048];
int n = sizeof(b);
int o = 0;
b[0] = 0;
#define DEFINE_COUNTER(S) APPEND("%-32s = %ld\n", #S, S);
#define DEFINE_AVERAGE(S) APPEND("%-32s = %.6g\n", #S, S.a);
#include "blink/stats.inc"
#undef S
WriteErrorString(b);
#endif
}
49 changes: 49 additions & 0 deletions blink/stats.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ifndef BLINK_STATS_H_
#define BLINK_STATS_H_
#include "blink/tsan.h"

#ifndef NDEBUG
// we don't care about the accuracy of statistics across threads. some
// hardware architectures don't even seem to have atomic addition ops.
#define STATISTIC(x) \
do { \
IGNORE_RACES_START(); \
x; \
IGNORE_RACES_END(); \
} while (0)
#else
#define STATISTIC(x) (void)0
#endif

#define AVERAGE(S, x) S.a += ((x)-S.a) / ++S.i

#ifndef NDEBUG
#ifdef __GNUC__
#define GET_COUNTER(S) \
({ \
IGNORE_RACES_START(); \
long S_ = S; \
IGNORE_RACES_END(); \
S_; \
})
#else
#define GET_COUNTER(S) (S)
#endif
#else
#define GET_COUNTER(S) 0L
#endif

#define DEFINE_COUNTER(S) extern long S;
#define DEFINE_AVERAGE(S) extern struct Average S;
#include "blink/stats.inc"
#undef DEFINE_COUNTER
#undef DEFINE_AVERAGE

struct Average {
double a;
long i;
};

void PrintStats(void);

#endif /* BLINK_STATS_H_ */
7 changes: 7 additions & 0 deletions blink/stats.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
DEFINE_COUNTER(instructions_cached)
DEFINE_COUNTER(instructions_decoded)
DEFINE_COUNTER(instructions_dispatched)
DEFINE_COUNTER(page_overlaps)
DEFINE_COUNTER(tlb_hits_1)
DEFINE_COUNTER(tlb_hits_2)
DEFINE_COUNTER(tlb_misses)

0 comments on commit 1e38765

Please sign in to comment.