Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove profiling limit on files with <= 2^16 lines #1913

Merged
merged 1 commit into from
Nov 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 43 additions & 51 deletions src/code.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,53 +135,69 @@ Obj FuncGET_FILENAME_CACHE(Obj self)
return CopyObj(FilenameCache, 1);
}

Obj FILENAME_STAT(Stat stat)
{
Obj filename;
UInt filenameid = FILENAMEID_STAT(stat);
if (filenameid == 0)
filename = NEW_STRING(0);
else
filename = ELM_LIST(FilenameCache, filenameid);
return filename;
}
// filename

Obj GET_FILENAME_BODY(Obj body)
{
return BODY_HEADER(body)->filename;
Obj val = BODY_HEADER(body)->filename_or_id;
if (IS_INTOBJ(val)) {
UInt gapnameid = INT_INTOBJ(val);
val = ELM_LIST(FilenameCache, gapnameid);
}

return val;
}

void SET_FILENAME_BODY(Obj body, Obj val)
{
GAP_ASSERT(IS_STRING_REP(val));
MakeImmutableString(val);
BODY_HEADER(body)->filename = val;
BODY_HEADER(body)->filename_or_id = val;
}

// gapnameid

UInt GET_GAPNAMEID_BODY(Obj body)
{
Obj gapnameid = BODY_HEADER(body)->filename_or_id;
return IS_POS_INTOBJ(gapnameid) ? INT_INTOBJ(gapnameid) : 0;
}

void SET_GAPNAMEID_BODY(Obj body, UInt val)
{
BODY_HEADER(body)->filename_or_id = INTOBJ_INT(val);
}

// location

Obj GET_LOCATION_BODY(Obj body)
{
Obj location = BODY_HEADER(body)->location;
Obj location = BODY_HEADER(body)->startline_or_location;
return IS_STRING_REP(location) ? location : 0;
}

void SET_LOCATION_BODY(Obj body, Obj val)
{
GAP_ASSERT(IS_STRING_REP(val));
MakeImmutableString(val);
BODY_HEADER(body)->location = val;
BODY_HEADER(body)->startline_or_location = val;
}

// startline

UInt GET_STARTLINE_BODY(Obj body)
{
Obj line = BODY_HEADER(body)->startline;
Obj line = BODY_HEADER(body)->startline_or_location;
return IS_POS_INTOBJ(line) ? INT_INTOBJ(line) : 0;
}

void SET_STARTLINE_BODY(Obj body, UInt val)
{
BODY_HEADER(body)->startline = val ? INTOBJ_INT(val) : 0;
BODY_HEADER(body)->startline_or_location = val ? INTOBJ_INT(val) : 0;
}

// endline

UInt GET_ENDLINE_BODY(Obj body)
{
Obj line = BODY_HEADER(body)->endline;
Expand All @@ -193,27 +209,6 @@ void SET_ENDLINE_BODY(Obj body, UInt val)
BODY_HEADER(body)->endline = val ? INTOBJ_INT(val) : 0;
}

/****************************************************************************
**
** Fill in filename and line of a statement, checking we do not overflow
** the space we have for storing information
*/
static StatHeader fillFilenameLine(Int fileid, Int line, Int size, Int type)
{
if (fileid < 0 || fileid >= (1 << 15)) {
fileid = (1 << 15) - 1;
ReportFileNumberOverflowOccured();
}
if (line < 0 || line >= (1 << 16)) {
line = (1 << 16) - 1;
ReportLineNumberOverflowOccured();
}

StatHeader header = { 0, fileid, line, size, type };
return header;
}



/****************************************************************************
**
Expand All @@ -230,8 +225,7 @@ static StatHeader fillFilenameLine(Int fileid, Int line, Int size, Int type)
static Stat NewStatWithProf (
UInt type,
UInt size,
UInt line,
UInt file)
UInt line)
{
Stat stat; /* result */

Expand All @@ -252,7 +246,9 @@ static Stat NewStatWithProf (
STATE(PtrBody) = (Stat*)PTR_BAG(body);

/* enter type and size */
*STAT_HEADER(stat) = fillFilenameLine(file, line, size, type);
STAT_HEADER(stat)->line = line;
STAT_HEADER(stat)->size = size;
STAT_HEADER(stat)->type = type;
RegisterStatWithHook(stat);
/* return the new statement */
return stat;
Expand All @@ -262,8 +258,8 @@ Stat NewStat (
UInt type,
UInt size)
{
SetupGapname(STATE(Input));
return NewStatWithProf(type, size, STATE(Input)->number, STATE(Input)->gapnameid);
assert(STATE(Input)->gapnameid != 0);
return NewStatWithProf(type, size, STATE(Input)->number);
}


Expand Down Expand Up @@ -794,8 +790,7 @@ void CodeFuncExprBegin (

/* record where we are reading from */
SetupGapname(STATE(Input));
Obj filename = ELM_LIST(FilenameCache, STATE(Input)->gapnameid);
SET_FILENAME_BODY(body, filename);
SET_GAPNAMEID_BODY(body, STATE(Input)->gapnameid);
SET_STARTLINE_BODY(body, startLine);
/* Pr("Coding begin at %s:%d ",(Int)(STATE(Input)->name),STATE(Input)->number);
Pr(" Body id %d\n",(Int)(body),0L); */
Expand Down Expand Up @@ -858,12 +853,9 @@ void CodeFuncExprEnd (

/* stuff the first statements into the first statement sequence */
/* Making sure to preserve the line number and file name */
*STAT_HEADER(OFFSET_FIRST_STAT)
= fillFilenameLine(
FILENAMEID_STAT(OFFSET_FIRST_STAT),
LINE_STAT(OFFSET_FIRST_STAT),
nr*sizeof(Stat),
T_SEQ_STAT+nr-1);
STAT_HEADER(OFFSET_FIRST_STAT)->line = LINE_STAT(OFFSET_FIRST_STAT);
STAT_HEADER(OFFSET_FIRST_STAT)->size = nr*sizeof(Stat);
STAT_HEADER(OFFSET_FIRST_STAT)->type = T_SEQ_STAT+nr-1;
for ( i = 1; i <= nr; i++ ) {
stat1 = PopStat();
ADDR_STAT(OFFSET_FIRST_STAT)[nr-i] = stat1;
Expand Down Expand Up @@ -1441,7 +1433,7 @@ void CodeReturnVoidWhichIsNotProfiled ( void )

/* allocate the return-statement, without profile information */

stat = NewStatWithProf( T_RETURN_VOID, 0 * sizeof(Expr), 0, 0 );
stat = NewStatWithProf( T_RETURN_VOID, 0 * sizeof(Expr), 0 );

/* push the return-statement */
PushStat( stat );
Expand Down
45 changes: 19 additions & 26 deletions src/code.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
*/
typedef struct {
unsigned int visited : 1;
unsigned int fileid : 15;
unsigned int line : 16;
unsigned int line : 31;
unsigned int size : 24;
unsigned int type : 8;
} StatHeader;
Expand All @@ -45,7 +44,7 @@ typedef struct {

/****************************************************************************
**
** Function headers
** Function body headers
**
** 'FILENAME_BODY' is a string containing the file of a function
** 'STARTLINE_BODY' is the line number where a function starts.
Expand All @@ -61,11 +60,19 @@ typedef struct {
*/

typedef struct {
Obj filename;
union {
Obj startline;
Obj location;
};
// if non-zero, this is either a string containing the name of the
// file of a function, or an immediate integer containing the index
// of the filename inside FilenameCache
Obj filename_or_id;

// if non-zero, this is either an immediate integer encoding the
// line number where a function starts, or string describing the
// location of a function. Typically this will be the name of a C
// function implementing it.
Obj startline_or_location;

// if non-zero, this is an immediate integer encoding the line
// number where a function ends
Obj endline;
} BodyHeader;

Expand All @@ -77,6 +84,10 @@ static inline BodyHeader *BODY_HEADER(Obj body)

Obj GET_FILENAME_BODY(Obj body);
void SET_FILENAME_BODY(Obj body, Obj val);

UInt GET_GAPNAMEID_BODY(Obj body);
void SET_GAPNAMEID_BODY(Obj body, UInt val);

Obj GET_LOCATION_BODY(Obj body);
void SET_LOCATION_BODY(Obj body, Obj val);

Expand Down Expand Up @@ -249,24 +260,6 @@ enum STAT_TNUM {
*/
#define LINE_STAT(stat) (STAT_HEADER(stat)->line)

/****************************************************************************
**
*F FILENAMEID_STAT(<stat>) . . . . . . . . . . . . file name of a statement
**
** 'FILENAMEID_STAT' returns the file the statement <stat> was read from.
** This should be looked up in the FilenameCache variable
*/
#define FILENAMEID_STAT(stat) (STAT_HEADER(stat)->fileid)

/****************************************************************************
**
*F FILENAME_STAT(<stat>) . . . . . . . . . . . . . file name of a statement
**
** 'FILENAME_STAT' returns a gap string containing the file where the statement
** <stat> was read from.
*/
Obj FILENAME_STAT(Stat stat);

/****************************************************************************
**
*F VISITED_STAT(<stat>) . . . . . . . . . . . if statement has even been run
Expand Down
42 changes: 22 additions & 20 deletions src/gap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,8 @@ Obj FuncCURRENT_STATEMENT_LOCATION(Obj self, Obj context)
if (IsKernelFunction(func)) {
return Fail;
}
if (call < OFFSET_FIRST_STAT || call > SIZE_BAG(BODY_FUNC(func)) - sizeof(StatHeader)) {
Obj body = BODY_FUNC(func);
if (call < OFFSET_FIRST_STAT || call > SIZE_BAG(body) - sizeof(StatHeader)) {
return Fail;
}

Expand All @@ -1052,7 +1053,7 @@ Obj FuncCURRENT_STATEMENT_LOCATION(Obj self, Obj context)
if ((FIRST_STAT_TNUM <= type && type <= LAST_STAT_TNUM) ||
(FIRST_EXPR_TNUM <= type && type <= LAST_EXPR_TNUM)) {
Int line = LINE_STAT(call);
Obj filename = FILENAME_STAT(call);
Obj filename = GET_FILENAME_BODY(body);
retlist = NEW_PLIST(T_PLIST, 2);
SET_LEN_PLIST(retlist, 2);
SET_ELM_PLIST(retlist, 1, filename);
Expand All @@ -1073,28 +1074,29 @@ Obj FuncPRINT_CURRENT_STATEMENT(Obj self, Obj context)
Stat call = STAT_LVARS(context);
if (IsKernelFunction(func)) {
Pr("<compiled statement> ", 0L, 0L);
return 0;
}
else if (call < OFFSET_FIRST_STAT || call > SIZE_BAG(BODY_FUNC(func)) - sizeof(StatHeader)) {
Obj body = BODY_FUNC(func);
if (call < OFFSET_FIRST_STAT || call > SIZE_BAG(body) - sizeof(StatHeader)) {
Pr("<corrupted statement> ", 0L, 0L);
return 0;
}
else {
Obj currLVars = STATE(CurrLVars);
SWITCH_TO_OLD_LVARS(context);
GAP_ASSERT(call == BRK_CALL_TO());

Int type = TNUM_STAT(call);
if (FIRST_STAT_TNUM <= type && type <= LAST_STAT_TNUM) {
PrintStat(call);
Pr(" at %s:%d", (UInt)CSTR_STRING(FILENAME_STAT(call)),
LINE_STAT(call));
}
else if (FIRST_EXPR_TNUM <= type && type <= LAST_EXPR_TNUM) {
PrintExpr(call);
Pr(" at %s:%d", (UInt)CSTR_STRING(FILENAME_STAT(call)),
LINE_STAT(call));
}
SWITCH_TO_OLD_LVARS(currLVars);

Obj currLVars = STATE(CurrLVars);
SWITCH_TO_OLD_LVARS(context);
GAP_ASSERT(call == BRK_CALL_TO());

Int type = TNUM_STAT(call);
Obj filename = GET_FILENAME_BODY(body);
if (FIRST_STAT_TNUM <= type && type <= LAST_STAT_TNUM) {
PrintStat(call);
Pr(" at %s:%d", (UInt)CSTR_STRING(filename), LINE_STAT(call));
}
else if (FIRST_EXPR_TNUM <= type && type <= LAST_EXPR_TNUM) {
PrintExpr(call);
Pr(" at %s:%d", (UInt)CSTR_STRING(filename), LINE_STAT(call));
}
SWITCH_TO_OLD_LVARS(currLVars);
return 0;
}

Expand Down
Loading