Skip to content

Commit

Permalink
Extend hooking of interpreter to support the interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisJefferson committed Sep 4, 2018
1 parent 84d38cb commit f7fbe46
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 75 deletions.
18 changes: 14 additions & 4 deletions src/hookintrprtr.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ extern void (*OriginalPrintExprFuncsForHook[256])(Expr expr);

struct InterpreterHooks {
void (*visitStat)(Stat stat);
void (*visitInterpretedStat)(Int line, Int pos);
void (*enterFunction)(Obj func);
void (*leaveFunction)(Obj func);
void (*registerStat)(Stat stat);
void (*registerInterpretedStat)(Int line, Int pos);
const char * hookName;
};

Expand Down Expand Up @@ -122,17 +124,17 @@ void DeactivatePrintHooks(struct PrintHooks * hook);
** variable to avoid race conditions.
*/

#define GAP_HOOK_LOOP(member, argument) \
#define GAP_HOOK_LOOP(member, ...) \
do { \
Int i; \
Int i; \
struct InterpreterHooks * hook; \
for (i = 0; i < HookCount; ++i) { \
hook = activeHooks[i]; \
if (hook && hook->member) { \
(hook->member)(argument); \
(hook->member)(__VA_ARGS__); \
} \
} \
} while(0)
} while (0)

static inline void VisitStatIfHooked(Stat stat)
{
Expand All @@ -155,6 +157,14 @@ static inline void RegisterStatWithHook(Stat func)
GAP_HOOK_LOOP(registerStat, func);
}

static inline void InterpreterHook(Int file, Int line, Int skipped)
{
GAP_HOOK_LOOP(registerInterpretedStat, file, line);
if (!skipped) {
GAP_HOOK_LOOP(visitInterpretedStat, file, line);
}
}


/****************************************************************************
**
Expand Down
2 changes: 1 addition & 1 deletion src/modules.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
**
*/

#define GAP_KERNEL_MAJOR_VERSION 3
#define GAP_KERNEL_MAJOR_VERSION 4
#define GAP_KERNEL_MINOR_VERSION 0
#define GAP_KERNEL_API_VERSION \
((GAP_KERNEL_MAJOR_VERSION)*1000 + (GAP_KERNEL_MINOR_VERSION))
Expand Down
192 changes: 122 additions & 70 deletions src/profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,88 +365,113 @@ static inline Int8 getTicks(void)
}
}


static inline void printOutput(UInt line, int nameid, int exec, int visited)
{
Int8 ticks = 0, newticks = 0;

if (profileState.lastOutputted.line != line ||
profileState.lastOutputted.fileID != nameid ||
profileState.lastOutputtedExec != exec) {

if (profileState.OutputRepeats) {
newticks = getTicks();

ticks = newticks - profileState.lastOutputtedTime;

// Basic sanity check
if (ticks < 0)
ticks = 0;
if ((profileState.minimumProfileTick == 0) ||
(ticks > profileState.minimumProfileTick) || (!visited)) {
int ticksDone;
if (profileState.minimumProfileTick == 0) {
ticksDone = ticks;
}
else {
ticksDone = (ticks / profileState.minimumProfileTick) *
profileState.minimumProfileTick;
}
ticks -= ticksDone;
outputFilenameIdIfRequired(nameid);
fprintf(profileState.Stream,
"{\"Type\":\"%c\",\"Ticks\":%d,\"Line\":%d,"
"\"FileId\":%d}\n",
exec ? 'E' : 'R', ticksDone, (int)line, (int)nameid);
profileState.lastOutputtedTime = newticks;
profileState.lastNotOutputted.line = -1;
profileState.lastOutputted.line = line;
profileState.lastOutputted.fileID = nameid;
profileState.lastOutputtedExec = exec;
}
else {
profileState.lastNotOutputted.line = line;
profileState.lastNotOutputted.fileID = nameid;
}
}
else {
outputFilenameIdIfRequired(nameid);
fprintf(profileState.Stream,
"{\"Type\":\"%c\",\"Line\":%d,\"FileId\":%d}\n",
exec ? 'E' : 'R', (int)line, (int)nameid);
profileState.lastOutputted.line = line;
profileState.lastOutputted.fileID = nameid;
profileState.lastOutputtedExec = exec;
profileState.lastNotOutputted.line = -1;
}
}
}

// exec : are we executing this statement
// visit: Was this statement previously visited (that is, executed)
static inline void outputStat(Stat stat, int exec, int visited)
{
UInt line;
int nameid;
UInt line;
int nameid;

CheckLeaveFunctionsAfterLongjmp();
// Explicitly skip these two cases, as they are often specially handled
// and also aren't really interesting statements (something else will
// be executed whenever they are).
if (TNUM_STAT(stat) == T_TRUE_EXPR || TNUM_STAT(stat) == T_FALSE_EXPR) {
return;
}

Int8 ticks = 0, newticks = 0;
CheckLeaveFunctionsAfterLongjmp();

// Explicitly skip these two cases, as they are often specially handled
// and also aren't really interesting statements (something else will
// be executed whenever they are).
if (TNUM_STAT(stat) == T_TRUE_EXPR || TNUM_STAT(stat) == T_FALSE_EXPR) {
return;
}
// Catch the case we arrive here and profiling is already disabled
if (!profileState_Active) {
return;
}

// Catch the case we arrive here and profiling is already disabled
if (!profileState_Active) {
return;
}
nameid = getFilenameIdOfCurrentFunction();
outputFilenameIdIfRequired(nameid);

nameid = getFilenameIdOfCurrentFunction();
outputFilenameIdIfRequired(nameid);
// Statement not attached to a file
if (nameid == 0) {
return;
}

// Statement not attached to a file
if (nameid == 0) {
return;
}
line = LINE_STAT(stat);
printOutput(line, nameid, exec, visited);
}

line = LINE_STAT(stat);
if (profileState.lastOutputted.line != line ||
profileState.lastOutputted.fileID != nameid ||
profileState.lastOutputtedExec != exec)
{
static inline void outputInterpretedStat(Int file, Int line, Int exec)
{
CheckLeaveFunctionsAfterLongjmp();

if (profileState.OutputRepeats) {
newticks = getTicks();
// Catch the case we arrive here and profiling is already disabled
if (!profileState_Active) {
return;
}

ticks = newticks - profileState.lastOutputtedTime;
outputFilenameIdIfRequired(file);

// Basic sanity check
if (ticks < 0)
ticks = 0;
if ((profileState.minimumProfileTick == 0) ||
(ticks > profileState.minimumProfileTick) || (!visited)) {
int ticksDone;
if (profileState.minimumProfileTick == 0) {
ticksDone = ticks;
}
else {
ticksDone = (ticks / profileState.minimumProfileTick) *
profileState.minimumProfileTick;
}
ticks -= ticksDone;
outputFilenameIdIfRequired(nameid);
fprintf(
profileState.Stream,
"{\"Type\":\"%c\",\"Ticks\":%d,\"Line\":%d,\"FileId\":%d}\n",
exec ? 'E' : 'R', ticksDone, (int)line, (int)nameid);
profileState.lastOutputtedTime = newticks;
profileState.lastNotOutputted.line = -1;
profileState.lastOutputted.line = line;
profileState.lastOutputted.fileID = nameid;
profileState.lastOutputtedExec = exec;
}
else {
profileState.lastNotOutputted.line = line;
profileState.lastNotOutputted.fileID = nameid;
}
}
else {
outputFilenameIdIfRequired(nameid);
fprintf(profileState.Stream, "{\"Type\":\"%c\",\"Line\":%d,\"FileId\":%d}\n",
exec ? 'E' : 'R', (int)line, (int)nameid);
profileState.lastOutputted.line = line;
profileState.lastOutputted.fileID = nameid;
profileState.lastOutputtedExec = exec;
profileState.lastNotOutputted.line = -1;
// Statement not attached to a file
if (file == 0) {
return;
}
}

printOutput(line, file, exec, 0);
}

void visitStat(Stat stat)
Expand All @@ -469,6 +494,18 @@ void visitStat(Stat stat)
}
}

void visitInterpretedStat(Int file, Int line)
{
#ifdef HPCGAP
if (profileState.profiledThread != TLS(threadID))
return;
#endif

HashLock(&profileState);
outputInterpretedStat(file, line, 1);
HashUnlock(&profileState);
}

/****************************************************************************
**
** Activating and deacivating profiling, either at startup or by user request
Expand Down Expand Up @@ -502,10 +539,25 @@ void registerStat(Stat stat)
HashUnlock(&profileState);
}

void registerInterpretedStat(Int file, Int line)
{
int active;
HashLock(&profileState);
active = profileState_Active;
if (active) {
outputInterpretedStat(file, line, 0);
}
HashUnlock(&profileState);
}


struct InterpreterHooks profileHooks = {
visitStat, enterFunction, leaveFunction, registerStat,
"line-by-line profiling"};
struct InterpreterHooks profileHooks = { visitStat,
visitInterpretedStat,
enterFunction,
leaveFunction,
registerStat,
registerInterpretedStat,
"line-by-line profiling" };


void enableAtStartup(char * filename, Int repeats, TickMethod tickMethod)
Expand Down

0 comments on commit f7fbe46

Please sign in to comment.