Browse Source

added jit stack trace support

Nicolas Cannasse 9 years ago
parent
commit
ade245d6a0
4 changed files with 111 additions and 24 deletions
  1. 74 19
      src/code.c
  2. 7 2
      src/hlmodule.h
  3. 17 1
      src/jit.c
  4. 13 2
      src/module.c

+ 74 - 19
src/code.c

@@ -343,12 +343,76 @@ const char *hl_op_name( int op ) {
 	return hl_op_names[op];
 }
 
+static char **hl_read_strings( hl_reader *r, int nstrings, int **out_lens ) {
+	int size = hl_read_i32(r);
+	hl_code *c = r->code;
+	char *sdata = (char*)hl_malloc(&c->alloc,sizeof(char) * size);
+	char **strings;
+	int *lens;
+	int i;
+	hl_read_bytes(r, sdata, size);
+	ALLOC(strings, char*, nstrings);
+	ALLOC(lens, int, nstrings);
+	for(i=0;i<nstrings;i++) {
+		int sz = UINDEX();
+		strings[i] = sdata;
+		lens[i] = sz;
+		sdata += sz;
+		if( sdata >= sdata + size || *sdata )
+			EXIT("Invalid string");
+		sdata++;
+	}
+	*out_lens = lens;
+	return strings;
+}
+
+static int *hl_read_debug_infos( hl_reader *r, int nops ) {
+	int curfile = -1, curline = 0;
+	hl_code *code = r->code;
+	int *debug = (int*)hl_malloc(&code->alloc, sizeof(int) * nops * 2);
+	int i = 0;	
+	while( i < nops ) {
+		int c = READ();
+		if( c & 1 ) {
+			c >>= 1;
+			curfile = (c << 8) | READ();
+			if( curfile >= code->ndebugfiles )
+				ERROR("Invalid debug file");
+		} else if( c & 2 ) {
+			int delta = c >> 6;
+			int count = (c >> 2) & 15;
+			if( i + count > nops )
+				ERROR("Outside range");
+			while( count-- ) {
+				debug[i<<1] = curfile;
+				debug[(i<<1)|1] = curline;
+				i++;
+			}
+			curline += delta;
+		} else if( c & 4 ) {
+			curline += c >> 3;
+			debug[i<<1] = curfile;
+			debug[(i<<1)|1] = curline;
+			i++;
+		} else {
+			unsigned char b2 = READ();
+			unsigned char b3 = READ();
+			curline = (c >> 3) | (b2 << 5) | (b3 << 13);
+			debug[i<<1] = curfile;
+			debug[(i<<1)|1] = curline;
+			i++;
+		}
+	}
+	return debug;
+}
+
 hl_code *hl_code_read( const unsigned char *data, int size ) {
 	hl_reader _r = { data, size, 0, 0, NULL };	
 	hl_reader *r = &_r;
 	hl_code *c;
 	hl_alloc alloc;
 	int i;
+	int flags;
 	hl_alloc_init(&alloc);
 	c = hl_zalloc(&alloc,sizeof(hl_code));
 	c->alloc = alloc;
@@ -360,6 +424,7 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 		printf("VER=%d\n",c->version);
 		EXIT("Unsupported version");
 	}
+	flags = UINDEX();
 	c->nints = UINDEX();
 	c->nfloats = UINDEX();
 	c->nstrings = UINDEX();
@@ -368,6 +433,7 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 	c->nnatives = UINDEX();
 	c->nfunctions = UINDEX();
 	c->entrypoint = UINDEX();	
+	c->hasdebug = flags & 1;
 	CHK_ERROR();
 	ALLOC(c->ints, int, c->nints);
 	for(i=0;i<c->nints;i++)
@@ -377,27 +443,14 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 	for(i=0;i<c->nfloats;i++)
 		c->floats[i] = hl_read_double(r);
 	CHK_ERROR();
-	{
-		int size = hl_read_i32(r);
-		char *sdata;
+	c->strings = hl_read_strings(r, c->nstrings, &c->strings_lens);
+	ALLOC(c->ustrings,uchar*,c->nstrings);
+	CHK_ERROR();
+	if( c->hasdebug ) {
+		c->ndebugfiles = UINDEX();
+		c->debugfiles = hl_read_strings(r, c->ndebugfiles, &c->debugfiles_lens);
 		CHK_ERROR();
-		sdata = (char*)hl_malloc(&c->alloc,sizeof(char) * size);
-		hl_read_bytes(r, sdata, size);
-		c->strings_data = sdata;
-		ALLOC(c->strings, char*, c->nstrings);
-		ALLOC(c->strings_lens, int, c->nstrings);
-		ALLOC(c->ustrings, uchar*, c->nstrings);
-		for(i=0;i<c->nstrings;i++) {
-			int sz = UINDEX();
-			c->strings[i] = sdata;
-			c->strings_lens[i] = sz;
-			sdata += sz;
-			if( sdata >= c->strings_data + size || *sdata )
-				EXIT("Invalid string");
-			sdata++;
-		}
 	}
-	CHK_ERROR();
 	ALLOC(c->types, hl_type, c->ntypes);
 	for(i=0;i<c->ntypes;i++) {
 		hl_read_type(r, c->types + i);
@@ -420,6 +473,8 @@ hl_code *hl_code_read( const unsigned char *data, int size ) {
 	for(i=0;i<c->nfunctions;i++) {
 		hl_read_function(r,c->functions+i);
 		CHK_ERROR();
+		if( c->hasdebug )
+			c->functions[i].debug = hl_read_debug_infos(r,c->functions[i].nops);
 	}
 	CHK_ERROR();
 	return c;

+ 7 - 2
src/hlmodule.h

@@ -44,6 +44,7 @@ typedef struct {
 	hl_type *type;
 	hl_type **regs;
 	hl_opcode *ops;
+	int *debug;
 } hl_function;
 
 typedef struct {
@@ -56,11 +57,14 @@ typedef struct {
 	int nnatives;
 	int nfunctions;
 	int entrypoint;
+	int ndebugfiles;
+	bool hasdebug;
 	int*		ints;
 	double*		floats;
 	char**		strings;
-	char*		strings_data;
 	int*		strings_lens;
+	char**		debugfiles;
+	int*		debugfiles_lens;
 	uchar**		ustrings;
 	hl_type*	types;
 	hl_type**	globals;
@@ -77,6 +81,7 @@ typedef struct {
 	void **functions_ptrs;
 	int *functions_indexes;
 	void *jit_code;
+	int **jit_debug;
 	hl_module_context ctx;
 } hl_module;
 
@@ -98,5 +103,5 @@ void hl_jit_free( jit_ctx *ctx );
 void hl_jit_init( jit_ctx *ctx, hl_module *m );
 int hl_jit_init_callback( jit_ctx *ctx );
 int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f );
-void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize );
+void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize, int ***debug );
 

+ 17 - 1
src/jit.c

@@ -249,6 +249,7 @@ struct jit_ctx {
 	hl_alloc falloc; // cleared per-function
 	hl_alloc galloc;
 	vclosure *closure_list;
+	int **debug;
 };
 
 #define jit_exit() { hl_debug_break(); exit(-1); }
@@ -319,6 +320,16 @@ static void jit_buf( jit_ctx *ctx ) {
 		ctx->startBuf = nbuf;
 		ctx->buf.b = nbuf + curpos;
 		ctx->bufSize = nsize;
+		if( ctx->m->code->hasdebug ) {
+			int **ndebug = (int**)malloc(sizeof(int**) * (nsize >> 2));
+			if( ndebug == NULL ) ASSERT(nsize);
+			if( ctx->debug ) {
+				memcpy(ndebug,ctx->debug,(curpos>>2) * sizeof(int*));
+				free(ctx->debug);
+			}
+			memset(ndebug + (curpos>>2), 0, ((nsize - curpos) >> 2) * sizeof(int*));
+			ctx->debug = ndebug;
+		}
 	}
 }
 
@@ -726,6 +737,10 @@ static void op( jit_ctx *ctx, CpuOp o, preg *a, preg *b, bool mode64 ) {
 	default:
 		ERRIF(1);
 	}
+	if( ctx->debug && o == CALL && ctx->f ) {
+		int pos = BUF_POS() >> 2;
+		ctx->debug[pos] = ctx->f->debug + (ctx->currentPos - 1) * 2;
+	}
 }
 
 static void op32( jit_ctx *ctx, CpuOp o, preg *a, preg *b ) {
@@ -2838,7 +2853,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 	return codePos;
 }
 
-void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize ) {
+void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize, int ***debug ) {
 	jlist *c;
 	int size = BUF_POS();
 	unsigned char *code;
@@ -2847,6 +2862,7 @@ void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize ) {
 	if( code == NULL ) return NULL;
 	memcpy(code,ctx->startBuf,BUF_POS());
 	*codesize = size;
+	*debug = ctx->debug;
 	// patch calls
 	c = ctx->calls;
 	while( c ) {

+ 13 - 2
src/module.c

@@ -35,7 +35,17 @@ static hl_module *cur_module;
 static void *stack_top;
 
 static uchar *module_resolve_symbol( void *addr, uchar *out, int *outSize ) {
-	return NULL;
+	int pos = ((int)(int_val)((unsigned char*)addr - (unsigned char*)cur_module->jit_code)) >> 2;
+	int *debug_addr = cur_module->jit_debug[pos];
+	int file, line;
+	int size = *outSize;
+	if( !debug_addr )
+		return NULL;
+	file = debug_addr[0];
+	line = debug_addr[1];
+	*outSize = strtou(out,*outSize,cur_module->code->debugfiles[file]);
+	*outSize += usprintf(out + *outSize, size - *outSize, USTR(" line %d"), line);
+	return out;
 }
 
 static int module_capture_stack( void **stack, int size ) {
@@ -54,6 +64,7 @@ static int module_capture_stack( void **stack, int size ) {
 			}
 		}
 	}
+	if( count ) count--;
 	return count;
 }
 
@@ -236,7 +247,7 @@ int hl_module_init( hl_module *m ) {
 		}
 		m->functions_ptrs[f->findex] = (void*)(int_val)fpos;
 	}
-	m->jit_code = hl_jit_code(ctx, m, &m->codesize);
+	m->jit_code = hl_jit_code(ctx, m, &m->codesize, &m->jit_debug);
 	for(i=0;i<m->code->nfunctions;i++) {
 		hl_function *f = m->code->functions + i;
 		m->functions_ptrs[f->findex] = ((unsigned char*)m->jit_code) + ((int_val)m->functions_ptrs[f->findex]);