Przeglądaj źródła

display object and method name in JIT stack traces

Nicolas Cannasse 9 lat temu
rodzic
commit
ecd2c946b4
5 zmienionych plików z 73 dodań i 18 usunięć
  1. 1 1
      src/hlc_main.c
  2. 3 0
      src/hlmodule.h
  3. 34 13
      src/jit.c
  4. 34 4
      src/module.c
  5. 1 0
      src/opcodes.h

+ 1 - 1
src/hlc_main.c

@@ -56,7 +56,7 @@ static uchar *hlc_resolve_symbol( void *addr, uchar *out, int *outSize ) {
 		line.FileName = USTR("\\?");
 		line.LineNumber = 0;
 		SymGetLineFromAddrW64(stack_process_handle, (DWORD64)(int_val)addr, &offset, &line);
-		*outSize = usprintf(out,*outSize,USTR("%s(%s) line %d"),data.sym.Name,wcsrchr(line.FileName,'\\')+1,(int)line.LineNumber);
+		*outSize = usprintf(out,*outSize,USTR("%s(%s:%d)"),data.sym.Name,wcsrchr(line.FileName,'\\')+1,(int)line.LineNumber);
 		return out;
 	}
 #endif

+ 3 - 0
src/hlmodule.h

@@ -45,6 +45,9 @@ typedef struct {
 	hl_type **regs;
 	hl_opcode *ops;
 	int *debug;
+
+	hl_type_obj *obj;
+	const uchar *field;
 } hl_function;
 
 typedef struct {

+ 34 - 13
src/jit.c

@@ -2076,6 +2076,29 @@ static double uint_to_double( unsigned int v ) {
 	return v;
 }
 
+static vclosure *alloc_static_closure( jit_ctx *ctx, int fid, hl_runtime_obj *obj, int field ) {
+	hl_module *m = ctx->m;
+	vclosure *c = hl_malloc(&m->ctx.alloc,sizeof(vclosure));
+	int fidx = m->functions_indexes[fid];
+	c->hasValue = 0;
+	if( fidx >= m->code->nfunctions ) {
+		// native
+		c->t = m->code->natives[fidx - m->code->nfunctions].t;
+		c->fun = m->functions_ptrs[fid];
+		c->value = NULL;
+	} else {
+		c->t = m->code->functions[fidx].type;
+		c->fun = (void*)(int_val)fid;
+		c->value = ctx->closure_list;
+		ctx->closure_list = c;
+		if( obj ) {
+			m->code->functions[fidx].obj = obj->t->obj;
+			m->code->functions[fidx].field = obj->t->obj->fields[field - (obj->parent?obj->parent->nfields:0)].name;
+		}
+	}
+	return c;
+}
+
 static void make_dyn_cast( jit_ctx *ctx, vreg *dst, vreg *v ) {
 	int size;
 	preg p;
@@ -2577,24 +2600,22 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			break;
 		case OStaticClosure:
 			{
-				// todo : share duplicates ?
-				vclosure *c = hl_malloc(&m->ctx.alloc,sizeof(vclosure));
+				vclosure *c = alloc_static_closure(ctx,o->p2,NULL,0);
 				preg *r = alloc_reg(ctx, RCPU);
-				c->t = dst->t;
-				c->hasValue = 0;
-				if( ctx->m->functions_indexes[o->p2] >= ctx->m->code->nfunctions ) {
-					// native
-					c->fun = ctx->m->functions_ptrs[o->p2];
-					c->value = NULL;
-				} else {
-					c->fun = (void*)(int_val)o->p2;
-					c->value = ctx->closure_list;
-					ctx->closure_list = c;
-				}
 				op64(ctx, MOV, r, pconst64(&p,(int_val)c));
 				store(ctx,dst,r,true);
 			}
 			break;
+		case OSetMethod:
+			{
+				hl_runtime_obj *rt = hl_get_obj_rt(dst->t);
+				vclosure *c = alloc_static_closure(ctx,o->p3,rt,o->p2);
+				preg *r = alloc_reg(ctx, RCPU);
+				preg *ro = alloc_cpu(ctx, dst, true);
+				op64(ctx, MOV, r, pconst64(&p,(int_val)c));
+				op64(ctx, MOV, pmem(&p,(CpuReg)ro->id, rt->fields_indexes[o->p2]), r);
+			}
+			break;
 		case OField:
 			{
 				switch( ra->t->kind ) {

+ 34 - 4
src/module.c

@@ -35,16 +35,37 @@ static hl_module *cur_module;
 static void *stack_top;
 
 static uchar *module_resolve_symbol( void *addr, uchar *out, int *outSize ) {
-	int pos = ((int)(int_val)((unsigned char*)addr - (unsigned char*)cur_module->jit_code)) >> JIT_CALL_PRECISION;
-	int *debug_addr = cur_module->jit_debug[pos];
+	int code_pos = ((int)(int_val)((unsigned char*)addr - (unsigned char*)cur_module->jit_code)) >> JIT_CALL_PRECISION;
+	int *debug_addr = cur_module->jit_debug[code_pos];
 	int file, line;
 	int size = *outSize;
+	int pos = 0;
+	hl_function *fdebug;
 	if( !debug_addr )
 		return NULL;
+	{
+		// resolve function from its debug addr
+		int min = 0;
+		int max = cur_module->code->nfunctions;
+		while( min < max ) {
+			int mid = (min + max) >> 1;
+			hl_function *f = cur_module->code->functions + mid;
+			if( debug_addr < f->debug )
+				max = mid;
+			else
+				min = mid + 1;
+		}
+		fdebug = cur_module->code->functions + (((min + max) >> 1) - 1);
+	}
 	file = debug_addr[0];
 	line = debug_addr[1];
-	*outSize = hl_from_utf8(out,*outSize,cur_module->code->debugfiles[file]);
-	*outSize += usprintf(out + *outSize, size - *outSize, USTR(" line %d"), line);
+	if( fdebug->obj )
+		pos += usprintf(out,size - pos,USTR("%s.%s("),fdebug->obj->name,fdebug->field);
+	else
+		pos += usprintf(out,size - pos,USTR("fun$%d("),fdebug->findex);
+	pos += hl_from_utf8(out + pos,size - pos,cur_module->code->debugfiles[file]);
+	pos += usprintf(out + pos, size - pos, USTR(":%d)"), line);
+	*outSize = pos;
 	return out;
 }
 
@@ -224,6 +245,15 @@ int hl_module_init( hl_module *m ) {
 		case HOBJ:
 			t->obj->m = &m->ctx;
 			t->obj->global_value = ((int)t->obj->global_value) ? (void**)(m->globals_data + m->globals_indexes[(int)t->obj->global_value-1]) : NULL;
+			{
+				int j;
+				for(j=0;j<t->obj->nproto;j++) {
+					hl_obj_proto *p = t->obj->proto + j;
+					hl_function *f = m->code->functions + m->functions_indexes[p->findex];
+					f->obj = t->obj;
+					f->field = p->name;
+				}
+			}
 			break;
 		case HENUM:
 			hl_init_enum(t->tenum);

+ 1 - 0
src/opcodes.h

@@ -79,6 +79,7 @@ OP_BEGIN
 	OP(OSetThis,2)
 	OP(ODynGet,3)
 	OP(ODynSet,3)
+	OP(OSetMethod,3)
 
 	OP(OJTrue,2)
 	OP(OJFalse,2)