Skip to content

Commit

Permalink
Add a call stack simulation to help build stats.
Browse files Browse the repository at this point in the history
  • Loading branch information
jnthn committed Jul 4, 2017
1 parent e713c78 commit d151a2a
Showing 1 changed file with 96 additions and 0 deletions.
96 changes: 96 additions & 0 deletions src/spesh/stats.c
@@ -1,12 +1,82 @@
#include "moar.h"

/* Logs are linear recordings marked with frame correlation IDs. We need to
* simulate the call stack as part of the analysis. This models a frame on
* the call stack and the stack respectively. */
typedef struct SimStackFrame {
/* Spesh stats for the stack frame. */
MVMSpeshStats *ss;

/* Correlation ID. */
MVMuint32 cid;
} SimStackFrame;
typedef struct SimStack {
/* Array of frames. */
SimStackFrame *frames;

/* Current frame index and allocated space. */
MVMuint32 used;
MVMuint32 limit;
} SimStack;

/* Gets the statistics for a static frame, creating them if needed. */
MVMSpeshStats * stats_for(MVMThreadContext *tc, MVMStaticFrame *sf) {
if (!sf->body.spesh_stats)
sf->body.spesh_stats = MVM_calloc(1, sizeof(MVMSpeshStats));
return sf->body.spesh_stats;
}

/* Initializes the stack simulation. */
void sim_stack_init(MVMThreadContext *tc, SimStack *sims) {
sims->used = 0;
sims->limit = 32;
sims->frames = MVM_malloc(sims->limit * sizeof(SimStackFrame));
}

/* Pushes an entry onto the stack frame model. */
void sim_stack_push(MVMThreadContext *tc, SimStack *sims, MVMSpeshStats *ss, MVMuint32 cid) {
SimStackFrame *frame;
if (sims->used == sims->limit) {
sims->limit *= 2;
sims->frames = MVM_realloc(sims->frames, sims->limit * sizeof(SimStackFrame));
}
frame = &(sims->frames[sims->used++]);
frame->ss = ss;
frame->cid = cid;
printf("push %d\n", cid);
}

/* Pops the top frame from the sim stack. */
void sim_stack_pop(MVMThreadContext *tc, SimStack *sims) {
if (sims->used == 0)
MVM_panic(1, "Spesh stats: cannot pop an empty simulation stack");
sims->used--;
printf("pop %d\n", sims->frames[sims->used].cid);
}

/* Gets the simulation stack frame for the specified correlation ID. If it is
* not on the top, searches to see if it's further down. If it is, then pops
* off the top to reach it. If it's not found at all, returns NULL and does
* nothing to the simulation stack. */
SimStackFrame * sim_stack_find(MVMThreadContext *tc, SimStack *sims, MVMuint32 cid) {
MVMuint32 found_at = sims->used;
while (found_at != 0) {
found_at--;
if (sims->frames[found_at].cid == cid) {
MVMint32 i;
for (i = found_at + 1; found_at < sims->used; i++)
sim_stack_pop(tc, sims);
return &(sims->frames[found_at]);
}
}
return NULL;
}

/* Destroys the stack simulation. */
void sim_stack_destroy(MVMThreadContext *tc, SimStack *sims) {
MVM_free(sims->frames);
}

/* Gets the stats by callsite, adding it if it's missing. */
MVMuint32 by_callsite_idx(MVMThreadContext *tc, MVMSpeshStats *ss, MVMCallsite *cs) {
/* See if we already have it. */
Expand All @@ -31,6 +101,8 @@ MVMuint32 by_callsite_idx(MVMThreadContext *tc, MVMSpeshStats *ss, MVMCallsite *
void MVM_spesh_stats_update(MVMThreadContext *tc, MVMSpeshLog *sl, MVMObject *sf_updated) {
MVMuint32 i;
MVMuint32 n = sl->body.used;
SimStack sims;
sim_stack_init(tc, &sims);
for (i = 0; i < n; i++) {
MVMSpeshLogEntry *e = &(sl->body.entries[i]);
switch (e->kind) {
Expand All @@ -44,10 +116,34 @@ void MVM_spesh_stats_update(MVMThreadContext *tc, MVMSpeshLog *sl, MVMObject *sf
ss->hits++;
callsite_idx = by_callsite_idx(tc, ss, e->entry.cs);
ss->by_callsite[callsite_idx].hits++;
sim_stack_push(tc, &sims, ss, e->id);
break;
}
case MVM_SPESH_LOG_PARAMETER: {
SimStackFrame *simf = sim_stack_find(tc, &sims, e->id);
/* TODO Add to parameters logging */
break;
}
case MVM_SPESH_LOG_PARAMETER_DECONT: {
SimStackFrame *simf = sim_stack_find(tc, &sims, e->id);
/* TODO Add to parameters logging */
break;
}
case MVM_SPESH_LOG_TYPE:
case MVM_SPESH_LOG_INVOKE:
case MVM_SPESH_LOG_OSR: {
SimStackFrame *simf = sim_stack_find(tc, &sims, e->id);
/* TODO Stash entry for later association */
break;
}
case MVM_SPESH_LOG_STATIC: {
SimStackFrame *simf = sim_stack_find(tc, &sims, e->id);
/* TODO Log static value */
break;
}
}
}
sim_stack_destroy(tc, &sims);
}

void MVM_spesh_stats_gc_mark(MVMThreadContext *tc, MVMSpeshStats *ss, MVMGCWorklist *worklist) {
Expand Down

0 comments on commit d151a2a

Please sign in to comment.