Skip to content

Commit

Permalink
Add profile hooks into interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisJefferson committed Sep 21, 2018
1 parent 0669ae4 commit 353883c
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/gapstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ typedef struct GAPState {
UInt SymbolStartPos;
UInt SymbolStartLine;

// Used for recording the first line of the fragment of code currently
// begin interpreted, so the current line is outputted when profiling
UInt InterpreterStartLine;

const Char * Prompt;

Char * In;
Expand Down
32 changes: 30 additions & 2 deletions src/intrprtr.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "funcs.h"
#include "gapstate.h"
#include "gvars.h"
#include "hookintrprtr.h"
#include "integer.h"
#include "io.h"
#include "lists.h"
Expand Down Expand Up @@ -82,8 +83,32 @@
*/
/* TL: UInt IntrCoding; */

// INTERPRETER_PROFILE_HOOK deals with profiling of immediately executed
// code.
// If STATE(IntrCoding) is true, profiling is handled by the AST
// generation and execution. Otherwise, we always mark the line as
// read, and mark as executed if STATE(IntrReturning) and STATE(IntrIgnoring)
// are both false.
#define INTERPRETER_PROFILE_HOOK() \
if (!STATE(IntrCoding)) { \
InterpreterHook(GetInputFilenameID(), STATE(InterpreterStartLine), \
STATE(IntrReturning) || STATE(IntrIgnoring)); \
} \
STATE(InterpreterStartLine) = 0;


// Put the profiling hook into SKIP_IF_RETURNING, as this is run in
// (nearly) every part of the interpreter, avoid lots of extra code.
#define SKIP_IF_RETURNING() \
INTERPRETER_PROFILE_HOOK(); \
SKIP_IF_RETURNING_NO_PROFILE_HOOK();

// Need to
#define SKIP_IF_RETURNING_NO_PROFILE_HOOK() \
if (STATE(IntrReturning) > 0) { \
return; \
}

#define SKIP_IF_RETURNING() if ( STATE(IntrReturning) > 0 ) { return; }
#define SKIP_IF_IGNORING() if ( STATE(IntrIgnoring) > 0 ) { return; }


Expand Down Expand Up @@ -377,7 +402,7 @@ void IntrFuncCallEnd (
UInt i; /* loop variable */

/* ignore or code */
SKIP_IF_RETURNING();
SKIP_IF_RETURNING_NO_PROFILE_HOOK();
SKIP_IF_IGNORING();
if ( STATE(IntrCoding) > 0 ) {
CodeFuncCallEnd( funccall, options, nr );
Expand Down Expand Up @@ -609,6 +634,9 @@ Int IntrIfEndBody (
{
UInt i; /* loop variable */

/* explicitly check interpreter hooks, as not using SKIP_IF_RETURNING */
INTERPRETER_PROFILE_HOOK();

/* ignore or code */
if ( STATE(IntrReturning) > 0 ) { return 0; }
if ( STATE(IntrIgnoring) > 0 ) { STATE(IntrIgnoring)--; return 0; }
Expand Down
15 changes: 13 additions & 2 deletions src/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,21 @@
** terminated by the character '\0'. Because 'line' holds only part of the
** line for very long lines the last character need not be a <newline>.
**
** 'stream' is non-zero if the input points to a stream.
**
** 'sline' contains the next line from the stream as GAP string.
**
** The following variables are used to store the state of the interpreter
** and stream when another input file is opened:
**
** 'ptr' points to the current character within that line. This is not used
** for the current input file, where 'In' points to the current character.
**
** 'number' is the number of the current line, is used in error messages.
**
** 'stream' is none zero if the input points to a stream.
** 'interpreterStartLine' is the number of the line where the fragment of
** code currently being interpreted started. This is used for profiling
**
** 'sline' contains the next line from the stream as GAP string.
**
*/
typedef struct {
Expand All @@ -72,6 +79,7 @@ typedef struct {
Char line[32768];
Char * ptr;
UInt symbol;
Int interpreterStartLine;
Int number;
Obj stream;
UInt isstringstream;
Expand Down Expand Up @@ -537,6 +545,7 @@ UInt OpenInputStream(Obj stream, UInt echo)
GAP_ASSERT(IS_CHAR_PUSHBACK_EMPTY());
IO()->Input->ptr = STATE(In);
IO()->Input->symbol = STATE(Symbol);
IO()->Input->interpreterStartLine = STATE(InterpreterStartLine);
}

/* enter the file identifier and the file name */
Expand All @@ -561,6 +570,7 @@ UInt OpenInputStream(Obj stream, UInt echo)
STATE(In) = IO()->Input->line;
STATE(In)[0] = STATE(In)[1] = '\0';
STATE(Symbol) = S_ILLEGAL;
STATE(InterpreterStartLine) = 0;
IO()->Input->number = 1;

/* indicate success */
Expand Down Expand Up @@ -602,6 +612,7 @@ UInt CloseInput ( void )
IO()->Input = IO()->InputStack[sp - 1];
STATE(In) = IO()->Input->ptr;
STATE(Symbol) = IO()->Input->symbol;
STATE(InterpreterStartLine) = IO()->Input->interpreterStartLine;

/* indicate success */
return 1;
Expand Down
4 changes: 4 additions & 0 deletions src/scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ void Match (
{
Char errmsg [256];

if (STATE(InterpreterStartLine) == 0) {
STATE(InterpreterStartLine) = STATE(SymbolStartLine);
}

// if 'STATE(Symbol)' is the expected symbol match it away
if ( symbol == STATE(Symbol) ) {
STATE(Symbol) = NextSymbol();
Expand Down

0 comments on commit 353883c

Please sign in to comment.