From 9e86ef12cf955258f8c40082f8c8b850630b742f Mon Sep 17 00:00:00 2001 From: pcpa Date: Fri, 18 Jan 2013 18:05:57 -0200 Subject: [PATCH] Add the new jit_name call to mark function boundaries * check/3to2.tst, check/add.tst, check/allocai.tst, check/bp.tst, check/call.tst, check/ccall.c, check/clobber.tst, check/divi.tst, check/fib.tst, check/ldsti.tst, check/ldstr-c.tst, check/ldstr.tst, check/ldstxi-c.tst, check/ldstxi.tst, check/ldstxr-c.tst, check/ldstxr.tst, check/lightning.c, check/rpn.tst, check/stack.tst, check/varargs.tst, include/lightning.h, include/lightning/jit_private.h, lib/jit_arm.c, lib/jit_disasm.c, lib/jit_mips.c, lib/jit_note.c, lib/jit_ppc.c, lib/jit_print.c, lib/jit_x86.c, lib/lightning.c: Extend the "jit_note" abstraction with the new "jit_name" call, that receives a string argument, and should usually be called to mark boundaries of functions of code generating jit (that is, it is not expected that the language generating jit map its functions to jit functions). --- ChangeLog | 16 ++ check/3to2.tst | 3 + check/add.tst | 2 + check/allocai.tst | 3 + check/bp.tst | 2 + check/call.tst | 10 + check/ccall.c | 9 +- check/clobber.tst | 3 - check/divi.tst | 3 + check/fib.tst | 2 + check/ldsti.tst | 3 - check/ldstr-c.tst | 3 - check/ldstr.tst | 3 - check/ldstxi-c.tst | 3 - check/ldstxi.tst | 3 - check/ldstxr-c.tst | 3 - check/ldstxr.tst | 3 - check/lightning.c | 33 ++-- check/rpn.tst | 3 + check/stack.tst | 6 + check/varargs.tst | 3 - include/lightning.h | 3 + include/lightning/jit_private.h | 17 +- lib/jit_arm.c | 2 +- lib/jit_disasm.c | 30 +-- lib/jit_mips.c | 2 +- lib/jit_note.c | 316 ++++++++++++++++++++++---------- lib/jit_ppc.c | 2 +- lib/jit_print.c | 7 +- lib/jit_x86.c | 2 +- lib/lightning.c | 42 +---- 31 files changed, 339 insertions(+), 203 deletions(-) diff --git a/ChangeLog b/ChangeLog index 41b04989a..5e960428a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2013-01-18 Paulo Andrade + + * check/3to2.tst, check/add.tst, check/allocai.tst, check/bp.tst, + check/call.tst, check/ccall.c, check/clobber.tst, check/divi.tst, + check/fib.tst, check/ldsti.tst, check/ldstr-c.tst, check/ldstr.tst, + check/ldstxi-c.tst, check/ldstxi.tst, check/ldstxr-c.tst, + check/ldstxr.tst, check/lightning.c, check/rpn.tst, check/stack.tst, + check/varargs.tst, include/lightning.h, + include/lightning/jit_private.h, lib/jit_arm.c, lib/jit_disasm.c, + lib/jit_mips.c, lib/jit_note.c, lib/jit_ppc.c, lib/jit_print.c, + lib/jit_x86.c, lib/lightning.c: Extend the "jit_note" abstraction + with the new "jit_name" call, that receives a string argument, and + should usually be called to mark boundaries of functions of code + generating jit (that is, it is not expected that the language + generating jit map its functions to jit functions). + 2013-01-17 Paulo Andrade * check/add.tst, check/allocai.tst, check/bp.tst, check/divi.tst, diff --git a/check/3to2.tst b/check/3to2.tst index 1e4a30eff..563cf85ec 100644 --- a/check/3to2.tst +++ b/check/3to2.tst @@ -8,6 +8,7 @@ ifmt: jmpi main #define def_test_double(a, b, c) \ + name test_double_##a##_##b##_##c \ test_double_##a##_##b##_##c: \ prolog \ arg_d $d0 \ @@ -30,6 +31,7 @@ test_double_##a##_##b##_##c: \ finishi @printf #define def_test_int(a, b, c) \ + name test_int_##a##_##b##_##c \ test_int_##a##_##b##_##c: \ prolog \ arg $i0 \ @@ -80,6 +82,7 @@ def_test_int(v0, r0, v0) def_test_int(v0, v0, r0) + name main main: prolog diff --git a/check/add.tst b/check/add.tst index 5ef50a312..9fc054d9f 100644 --- a/check/add.tst +++ b/check/add.tst @@ -5,6 +5,7 @@ fmt: .code jmpi main + name test test: prolog arg $i0 @@ -15,6 +16,7 @@ test: retr %r0 epilog + name main main: prolog prepare diff --git a/check/allocai.tst b/check/allocai.tst index bcfe3c4b6..c20cad0c7 100644 --- a/check/allocai.tst +++ b/check/allocai.tst @@ -19,6 +19,7 @@ identity (int arg) return arg; } */ + name identify identify: prolog arg $i @@ -31,6 +32,7 @@ identify: retr %v0 epilog + name identity_func identity_func: prolog arg $i @@ -74,6 +76,7 @@ branch: retr %v1 epilog + name main main: prolog prepare diff --git a/check/bp.tst b/check/bp.tst index e312e550e..b05bdd0df 100644 --- a/check/bp.tst +++ b/check/bp.tst @@ -5,6 +5,7 @@ fmt: .code jmpi main + name rfibs rfibs: prolog arg $in @@ -28,6 +29,7 @@ out: reti 1 epilog + name main main: prolog prepare diff --git a/check/call.tst b/check/call.tst index 50fcc059e..21068b6e8 100644 --- a/check/call.tst +++ b/check/call.tst @@ -1,4 +1,5 @@ #define def_wi(i) \ + name _w##i \ _w##i: \ prolog \ arg $arg##i \ @@ -6,6 +7,7 @@ _w##i: \ retr %r0 \ epilog #define def_wf(f) \ + name _w##f \ _w##f: \ prolog \ arg##f $arg##f \ @@ -14,6 +16,7 @@ _w##f: \ retr %r0 \ epilog #define def_fi(f, i) \ + name f##i \ f##i: \ prolog \ arg $arg##i \ @@ -22,6 +25,7 @@ f##i: \ retr##f %f0 \ epilog #define def_f(f) \ + name f##f \ f##f: \ prolog \ arg##f $arg##f \ @@ -29,6 +33,8 @@ f##f: \ retr##f %f0 \ epilog #define def_ff(f, g) \ + name f##g \ + name f##g \ f##g: \ prolog \ arg##g $arg##g \ @@ -79,6 +85,7 @@ bstr: def_ff(_f, _d) def_ff(_d, _f) + name main main: prolog @@ -234,6 +241,7 @@ f##g##n: ret epilog + name backward backward: prolog prepare @@ -242,6 +250,7 @@ backward: ret epilog + name forward forward: prolog prepare @@ -252,6 +261,7 @@ forward: ret epilog + name iforward iforward: prolog prepare diff --git a/check/ccall.c b/check/ccall.c index 201bc2ed7..ac44cb66a 100644 --- a/check/ccall.c +++ b/check/ccall.c @@ -704,7 +704,8 @@ main(int argc, char *argv[]) #define strfy(n) #n #define defi(T, N) \ - n##T##N = jit_note(strfy(n##T##N), 0); \ + n##T##N = jit_name(strfy(n##T##N)); \ + jit_note("ccall.c", __LINE__); \ jit_prolog(); \ arg##N(); \ get##N(,T,JIT_R) \ @@ -712,7 +713,8 @@ main(int argc, char *argv[]) jit_retr(JIT_R0); \ jit_epilog(); #define deff(T, N) \ - n##T##N = jit_note(strfy(n##T##N), 0); \ + n##T##N = jit_name(strfy(n##T##N)); \ + jit_note("ccall.c", __LINE__); \ jit_prolog(); \ arg##N(T); \ get##N(T,T,JIT_F); \ @@ -752,7 +754,8 @@ main(int argc, char *argv[]) #undef def jit_patch(jmpi_main); - jit_note("main", 0); + jit_name("main"); + jit_note("ccall.c", __LINE__); jit_prolog(); #define push0(T) /**/ diff --git a/check/clobber.tst b/check/clobber.tst index bdadda522..0f8fc4a2c 100644 --- a/check/clobber.tst +++ b/check/clobber.tst @@ -819,9 +819,6 @@ ok: .c "ok\n" .code - jmpi main - -main: prolog alu(__LINE__, add) diff --git a/check/divi.tst b/check/divi.tst index c54a4360f..9c03ed899 100644 --- a/check/divi.tst +++ b/check/divi.tst @@ -11,6 +11,7 @@ x: jmpi main #define generate_divider(operand) \ + name divider_##operand \ divider_##operand: \ prolog \ arg $i \ @@ -22,6 +23,7 @@ generate_divider(8) generate_divider(32768) #define generate_test_divider(divisor) \ + name test_divider_##divisor \ test_divider_##divisor: \ prolog \ allocai 4 $loc \ @@ -62,6 +64,7 @@ done_##divisor: \ generate_test_divider(8) generate_test_divider(32768) + name main main: prolog prepare diff --git a/check/fib.tst b/check/fib.tst index 0bb441f8d..6831632e9 100644 --- a/check/fib.tst +++ b/check/fib.tst @@ -5,6 +5,7 @@ format: .code jmpi main + name nfibs nfibs: prolog arg $in @@ -23,6 +24,7 @@ ref: retr %r1 // RET = R1 epilog + name main main: prolog arg $argc diff --git a/check/ldsti.tst b/check/ldsti.tst index 59d598ba9..362cb8446 100644 --- a/check/ldsti.tst +++ b/check/ldsti.tst @@ -76,9 +76,6 @@ L##x##C: LDST0(R2, F0) .code - jmpi main - -main: prolog /* Simple test to simplify validating encodings before diff --git a/check/ldstr-c.tst b/check/ldstr-c.tst index 7f85cdaf6..6ddc86e15 100644 --- a/check/ldstr-c.tst +++ b/check/ldstr-c.tst @@ -83,9 +83,6 @@ Lu##x##C: LDST0(V2, R2) .code - jmpi main - -main: prolog /* Simple test to simplify validating encodings before diff --git a/check/ldstr.tst b/check/ldstr.tst index 1eb03d670..1ed26b1dc 100644 --- a/check/ldstr.tst +++ b/check/ldstr.tst @@ -95,9 +95,6 @@ L##x##C: LDST0(V2, R2, F0) .code - jmpi main - -main: prolog /* Simple test to simplify validating encodings before diff --git a/check/ldstxi-c.tst b/check/ldstxi-c.tst index 9491bf101..1ad016895 100644 --- a/check/ldstxi-c.tst +++ b/check/ldstxi-c.tst @@ -93,9 +93,6 @@ Lu##x##C: LDST0(R2, R1) .code - jmpi main - -main: prolog /* Simple test to simplify validating encodings before diff --git a/check/ldstxi.tst b/check/ldstxi.tst index 4aa0cc77b..574521af8 100644 --- a/check/ldstxi.tst +++ b/check/ldstxi.tst @@ -83,9 +83,6 @@ L##x##C: LDST0(V2, R2, F0) .code - jmpi main - -main: prolog /* Simple test to simplify validating encodings before diff --git a/check/ldstxr-c.tst b/check/ldstxr-c.tst index 13056bca2..cd770a64d 100644 --- a/check/ldstxr-c.tst +++ b/check/ldstxr-c.tst @@ -105,9 +105,6 @@ Lu##x##C##1: LDST0(R0, R2, V2) .code - jmpi main - -main: prolog /* Simple test to simplify validating encodings before diff --git a/check/ldstxr.tst b/check/ldstxr.tst index 95c18915d..14620dc73 100644 --- a/check/ldstxr.tst +++ b/check/ldstxr.tst @@ -120,9 +120,6 @@ L##x##C: LDST0(R0, R1, R2, F5) .code - jmpi main - -main: prolog /* Simple test to simplify validating encodings before diff --git a/check/lightning.c b/check/lightning.c index dc3179226..13abbfbd4 100644 --- a/check/lightning.c +++ b/check/lightning.c @@ -207,7 +207,6 @@ struct label { char *name; void *value; label_kind_t kind; - int line; }; typedef enum { @@ -243,6 +242,7 @@ static void call_forward(void *value, label_t *label); static void make_arg(void *value); static jit_pointer_t get_arg(void); static long get_imm(void); +static void name(void); static void prolog(void); static void ellipsis(void); static void allocai(void); static void arg(void); @@ -502,7 +502,7 @@ static void *xmalloc(size_t size); static void *xrealloc(void *pointer, size_t size); static void *xcalloc(size_t nmemb, size_t size); -static label_t *new_label(label_kind_t kind, char *name, void *value, int line); +static label_t *new_label(label_kind_t kind, char *name, void *value); static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value); static int bcmp_symbols(const void *left, const void *right); static int qcmp_symbols(const void *left, const void *right); @@ -534,6 +534,7 @@ static char *data; static size_t data_offset, data_length; static instr_t instr_vector[] = { #define entry(value) { NULL, #value, value } + entry(name), entry(prolog), entry(ellipsis), entry(allocai), entry(arg), @@ -1211,7 +1212,13 @@ name(void) \ } \ jit_##name(value); \ } +static void +name(void) { + int ch = skipws(); + (void)identifier(ch); + jit_name(parser.string); +} entry(prolog) entry(ellipsis) void allocai(void) { @@ -1809,7 +1816,7 @@ get_label(skip_t skip) } if ((label = get_label_by_name(parser.string)) == NULL) label = new_label(label_kind_code_forward, - parser.string, jit_forward(), 0); + parser.string, jit_forward()); return (label); } @@ -2250,7 +2257,7 @@ dynamic(void) value = dlsym(RTLD_DEFAULT, parser.string + 1); if ((string = dlerror())) error("%s", string); - label = new_label(label_kind_dynamic, parser.string, value, 0); + label = new_label(label_kind_dynamic, parser.string, value); } parser.type = type_p; parser.value.p = label->value; @@ -3449,7 +3456,6 @@ static void parse(void) { int ch; - label_kind_t kind; token_t token; instr_t *instr; label_t *label; @@ -3463,26 +3469,26 @@ parse(void) if ((label = get_label_by_name(parser.string))) { if (label->kind == label_kind_code_forward) { label->kind = label_kind_code; - label->line = parser.line; jit_link(label->value); - jit_note(parser.string, parser.line); + jit_note(parser.name, parser.line); } else error("label %s: redefined", parser.string); } else { if (parser.parsing == PARSING_DATA) { - kind = label_kind_data; value = data + data_offset; + label = new_label(label_kind_data, + parser.string, value); } else if (parser.parsing == PARSING_CODE) { - kind = label_kind_code; value = jit_label(); + jit_note(parser.name, parser.line); + label = new_label(label_kind_code, + parser.string, value); } else error("label not in .code or .data"); - label = new_label(kind, parser.string, value, - parser.line); } break; } @@ -3578,7 +3584,7 @@ xcalloc(size_t nmemb, size_t size) } static label_t * -new_label(label_kind_t kind, char *name, void *value, int line) +new_label(label_kind_t kind, char *name, void *value) { label_t *label; @@ -3586,11 +3592,8 @@ new_label(label_kind_t kind, char *name, void *value, int line) label->kind = kind; label->name = strdup(name); label->value = value; - label->line = line; put_hash(labels, (entry_t *)label); label_offset++; - if (label->kind == label_kind_code) - jit_note(name, line); return (label); } diff --git a/check/rpn.tst b/check/rpn.tst index 939e0a5c2..62ef8d672 100644 --- a/check/rpn.tst +++ b/check/rpn.tst @@ -12,6 +12,7 @@ newline: .code jmpi main + name c2f c2f: prolog arg $in @@ -56,6 +57,7 @@ c2f: retr %r0 epilog + name f2c f2c: prolog arg $in @@ -103,6 +105,7 @@ f2c: epilog //----------------------------------------------------------------------- + name main main: prolog diff --git a/check/stack.tst b/check/stack.tst index 3870953c5..be63dc3c6 100644 --- a/check/stack.tst +++ b/check/stack.tst @@ -11,6 +11,7 @@ #define szof_d 8 #define FILL(T) \ + name fill##T \ fill##T: \ prolog \ arg $argp \ @@ -30,6 +31,7 @@ fill##T##done: \ ret \ epilog #define FILLF(T) \ + name fill##T \ fill##T: \ prolog \ arg $argp \ @@ -153,12 +155,14 @@ N##T##V: /* bottom function */ #define DEF0(T) \ + name test##T##_0 \ test##T##_0: \ prolog \ ret \ epilog #define DEFN(N, M, T) \ + name test##T##_##N \ test##T##_##N: \ prolog \ arg $argp \ @@ -210,6 +214,7 @@ test##T##_##N##_done: \ /* top function */ #define DEFX(T) \ + name test##T##_17 \ test##T##_17: \ prolog \ /* heap buffer in %v1 */ \ @@ -302,6 +307,7 @@ ok: DEF(_f) DEF(_d) + name main main: prolog diff --git a/check/varargs.tst b/check/varargs.tst index 65c81a4a4..ee826f5c4 100644 --- a/check/varargs.tst +++ b/check/varargs.tst @@ -20,9 +20,6 @@ buff: .size 256 .code - jmpi main - -main: prolog /* diff --git a/include/lightning.h b/include/lightning.h index 442a8a8d4..52ff539fa 100644 --- a/include/lightning.h +++ b/include/lightning.h @@ -102,6 +102,8 @@ typedef enum { #define jit_data(u,v,w) _jit_data(_jit,u,v,w) jit_code_data, jit_code_save, jit_code_load, +#define jit_name(u) _jit_name(_jit,u) + jit_code_name, #define jit_note(u, v) _jit_note(_jit, u, v) #define jit_label() _jit_label(_jit) #define jit_forward() _jit_forward(_jit) @@ -741,6 +743,7 @@ extern jit_state_t *jit_new_state(void); extern jit_pointer_t _jit_address(jit_state_t*, jit_node_t*); extern jit_node_t *_jit_data(jit_state_t*, jit_pointer_t, jit_word_t, jit_int32_t); +extern jit_node_t *_jit_name(jit_state_t*, char*); extern jit_node_t *_jit_note(jit_state_t*, char*, int); extern jit_node_t *_jit_label(jit_state_t*); extern jit_node_t *_jit_forward(jit_state_t*); diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h index 854e32563..c32f0b48a 100644 --- a/include/lightning/jit_private.h +++ b/include/lightning/jit_private.h @@ -152,6 +152,7 @@ jit_regset_scan1(jit_regset_t, jit_int32_t); */ typedef union jit_data jit_data_t; typedef struct jit_note jit_note_t; +typedef struct jit_line jit_line_t; typedef struct jit_block jit_block_t; typedef struct jit_value jit_value_t; typedef struct jit_function jit_function_t; @@ -180,7 +181,15 @@ union jit_data { }; struct jit_note { + jit_uint8_t *code; char *name; + jit_line_t *lines; + jit_word_t length; + jit_word_t size; /* of code */ +}; + +struct jit_line { + char *file; jit_int32_t *linenos; jit_int32_t *offsets; jit_word_t length; @@ -420,10 +429,10 @@ extern void jit_finish_debug(void); extern void jit_init_note(void); extern void jit_finish_note(void); -#define jit_set_note(u, v, w) _jit_set_note(_jit, u, v, w) -extern void _jit_set_note(jit_state_t*, char*, int, jit_int32_t); -#define jit_get_note(u, v, w) _jit_get_note(_jit, u, v, w) -extern jit_bool_t _jit_get_note(jit_state_t*,jit_uint8_t*,char**,int*); +#define jit_set_note(n,u,v,w) _jit_set_note(_jit, n, u, v, w) +extern void _jit_set_note(jit_state_t*, jit_note_t*, char*, int, jit_int32_t); +#define jit_get_note(n,u,v,w) _jit_get_note(_jit, n, u, v, w) +extern jit_bool_t _jit_get_note(jit_state_t*,jit_uint8_t*,char**,char**,int*); #define jit_annotate() _jit_annotate(_jit) extern void _jit_annotate(jit_state_t*); diff --git a/lib/jit_arm.c b/lib/jit_arm.c index 7b467b12c..db4d514b0 100644 --- a/lib/jit_arm.c +++ b/lib/jit_arm.c @@ -1028,7 +1028,7 @@ _jit_emit(jit_state_t *_jit) value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { - case jit_code_note: + case jit_code_note: case jit_code_name: node->u.w = _jit->pc.w; break; case jit_code_label: diff --git a/lib/jit_disasm.c b/lib/jit_disasm.c index 602d96b18..07252fc36 100644 --- a/lib/jit_disasm.c +++ b/lib/jit_disasm.c @@ -195,6 +195,7 @@ static void disasm_print_address(bfd_vma addr, struct disassemble_info *info) { char *name; + char *file; int line; char buffer[address_buffer_length]; @@ -205,12 +206,11 @@ disasm_print_address(bfd_vma addr, struct disassemble_info *info) # define jit_pointer_p(u) \ ((u) >= _jit->code.ptr && (u) < _jit->pc.uc) if (jit_pointer_p((jit_uint8_t *)(jit_word_t)addr)) { - if (jit_get_note((jit_uint8_t *)(jit_word_t)addr, &name, &line)) { - if (line) - (*info->fprintf_func)(info->stream, " %s:%d", name, line); - else - (*info->fprintf_func)(info->stream, " %s", name); - } + if (jit_get_note((jit_uint8_t *)(jit_word_t)addr, &name, &file, &line)) + (*info->fprintf_func)(info->stream, " %s:%s:%d", + name ? name : "", + file ? file : "", + line); } # undef jit_pointer_p # undef _jit @@ -259,6 +259,7 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) { int bytes; char *name, *old_name; + char *file, *old_file; int line, old_line; #if __arm__ jit_int32_t offset; @@ -276,7 +277,7 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) disasm_info.buffer = code; disasm_info.buffer_vma = (jit_uword_t)code; disasm_info.buffer_length = length; - old_name = NULL; + old_file = old_name = NULL; old_line = 0; disasm_jit = _jit; while (pc < end) { @@ -310,15 +311,14 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) } } #endif - if (jit_get_note((jit_uint8_t *)(jit_word_t)pc, &name, &line) && - (name != old_name || line != old_line)) { - if (line) - (*disasm_info.fprintf_func)(disasm_stream, "# %s:%d\n", - name, line); - else - (*disasm_info.fprintf_func)(disasm_stream, "# %s\n", - name); + if (jit_get_note((jit_uint8_t *)(jit_word_t)pc, &name, &file, &line) && + (name != old_name || file != old_file || line != old_line)) { + (*disasm_info.fprintf_func)(disasm_stream, "# %s:%s:%d\n", + name ? name : "", + file ? file : "", + line); old_name = name; + old_file = file; old_line = line; } diff --git a/lib/jit_mips.c b/lib/jit_mips.c index 94c4ff3b7..f5cbdf53d 100644 --- a/lib/jit_mips.c +++ b/lib/jit_mips.c @@ -777,7 +777,7 @@ _jit_emit(jit_state_t *_jit) value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { - case jit_code_note: + case jit_code_note: case jit_code_name: node->u.w = _jit->pc.w; break; case jit_code_label: diff --git a/lib/jit_note.c b/lib/jit_note.c index 648ecac54..08b535d25 100644 --- a/lib/jit_note.c +++ b/lib/jit_note.c @@ -21,14 +21,15 @@ /* * Prototypes */ -#define new_note(u, v, w, x) _new_note(_jit, u, v, w, x) -static void _new_note(jit_state_t*,jit_int32_t,char*,jit_int32_t,jit_int32_t); -#define note_insert_index(u) _note_insert_index(_jit, u) -static jit_int32_t _note_insert_index(jit_state_t*,jit_int32_t); +#define new_note(u, v) _new_note(_jit, u, v) +static jit_note_t *_new_note(jit_state_t *, jit_uint8_t*, char*); +static void new_line(jit_int32_t,jit_note_t*,char*,jit_int32_t,jit_int32_t); #define note_search_index(u) _note_search_index(_jit, u) -static jit_int32_t _note_search_index(jit_state_t*,jit_int32_t); -static jit_int32_t offset_insert_index(jit_note_t*,jit_int32_t); -static jit_int32_t offset_search_index(jit_note_t*,jit_int32_t); +static jit_int32_t _note_search_index(jit_state_t*, jit_uint8_t*); +static jit_int32_t line_insert_index(jit_note_t*,jit_int32_t); +static jit_int32_t line_search_index(jit_note_t*,jit_int32_t); +static jit_int32_t offset_insert_index(jit_line_t*,jit_int32_t); +static jit_int32_t offset_search_index(jit_line_t*,jit_int32_t); /* * Implementation @@ -43,127 +44,204 @@ jit_finish_note(void) { } -void -_jit_set_note(jit_state_t *_jit, - char *name, int lineno, jit_int32_t offset) +jit_node_t * +_jit_name(jit_state_t *_jit, char *name) { + jit_node_t *node; + + node = jit_new_node(jit_code_name); + if (name) + node->v.n = jit_data(name, strlen(name) + 1, 1); + else + node->v.p = NULL; + if (_jit->note.head == NULL) + _jit->note.head = _jit->note.tail = node; + else { + _jit->note.tail->link = node; + _jit->note.tail = node; + } + + return (node); +} + +jit_node_t * +_jit_note(jit_state_t *_jit, char *name, int line) +{ + jit_node_t *node; + + node = jit_new_node(jit_code_note); + if (name) + node->v.n = jit_data(name, strlen(name) + 1, 1); + else + node->v.p = NULL; + node->w.w = line; + if (_jit->note.head == NULL) + _jit->note.head = _jit->note.tail = node; + else { + _jit->note.tail->link = node; + _jit->note.tail = node; + } + + return (node); +} + +void +_jit_annotate(jit_state_t *_jit) +{ + jit_node_t *node; jit_note_t *note; + + note = NULL; + for (node = _jit->note.head; node; node = node->link) { + if (node->code == jit_code_name) + note = new_note(node->u.p, node->v.p ? node->v.n->u.p : NULL); + else if (node->v.p) { + if (note == NULL) + note = new_note(node->u.p, NULL); + jit_set_note(note, node->v.n->u.p, node->w.w, + (jit_uint8_t *)node->u.p - note->code); + } + } + /* last note */ + if (note) + note->size = _jit->pc.uc - note->code; +} + +void +_jit_set_note(jit_state_t *_jit, jit_note_t *note, + char *file, int lineno, jit_int32_t offset) +{ + jit_line_t *line; jit_int32_t index; - index = note_insert_index(offset); - if (index >= _jit->note.length || _jit->note.ptr[index].name != name) - new_note(index, name, lineno, offset); + index = line_insert_index(note, offset); + if (index >= note->length || note->lines[index].file != file) + new_line(index, note, file, lineno, offset); else { - note = _jit->note.ptr + index; - index = offset_insert_index(note, offset); - if (note->offsets[index] == offset) { + line = note->lines + index; + index = offset_insert_index(line, offset); + if (line->offsets[index] == offset) { /* common case if no code was generated for several source lines */ - if (note->linenos[index] < lineno) - note->linenos[index] = lineno; + if (line->linenos[index] < lineno) + line->linenos[index] = lineno; } - else if (note->linenos[index] == lineno) { + else if (line->linenos[index] == lineno) { /* common case of extending entry */ - if (note->offsets[index] > offset) - note->offsets[index] = offset; + if (line->offsets[index] > offset) + line->offsets[index] = offset; } else { /* line or offset changed */ - if ((note->length & 15) == 0) { - note->linenos = realloc(note->linenos, (note->length + 17) * + if ((line->length & 15) == 0) { + line->linenos = realloc(line->linenos, (line->length + 17) * sizeof(jit_int32_t)); - note->offsets = realloc(note->offsets, (note->length + 17) * + line->offsets = realloc(line->offsets, (line->length + 17) * sizeof(jit_int32_t)); } if (index < note->length) { - memmove(note->linenos + index + 1, note->linenos + index, - sizeof(jit_int32_t) * (note->length - index)); - memmove(note->offsets + index + 1, note->offsets + index, - sizeof(jit_int32_t) * (note->length - index)); + memmove(line->linenos + index + 1, line->linenos + index, + sizeof(jit_int32_t) * (line->length - index)); + memmove(line->offsets + index + 1, line->offsets + index, + sizeof(jit_int32_t) * (line->length - index)); } - note->linenos[index] = lineno; - note->offsets[index] = offset; - ++note->length; + line->linenos[index] = lineno; + line->offsets[index] = offset; + ++line->length; } } } jit_bool_t _jit_get_note(jit_state_t *_jit, jit_uint8_t *code, - char **name, jit_int32_t *lineno) + char **name, char **file, jit_int32_t *lineno) { jit_note_t *note; + jit_line_t *line; jit_int32_t index; jit_int32_t offset; - if (code < _jit->code.ptr || code >= _jit->pc.uc) - return (0); - offset = code - _jit->code.ptr; - if ((index = note_search_index(offset)) >= _jit->note.length) - return (0); - if (index == 0 && offset < _jit->note.ptr[0].offsets[0]) + if ((index = note_search_index(code)) >= _jit->note.length) return (0); note = _jit->note.ptr + index; - if ((index = offset_search_index(note, offset)) >= note->length) + if (code < note->code || code >= note->code + note->size) + return (0); + offset = code - note->code; + if ((index = line_search_index(note, offset)) >= note->length) + return (0); + if (index == 0 && offset < note->lines[0].offsets[0]) + return (0); + line = note->lines + index; + if ((index = offset_search_index(line, offset)) >= line->length) return (0); if (name) *name = note->name; + if (file) + *file = line->file; if (lineno) - *lineno = note->linenos[index]; + *lineno = line->linenos[index]; return (1); } -static void -_new_note(jit_state_t *_jit, jit_int32_t index, - char *name, jit_int32_t lineno, jit_int32_t offset) +static jit_note_t * +_new_note(jit_state_t *_jit, jit_uint8_t *code, char *name) { jit_note_t *note; + jit_note_t *prev; - if (_jit->note.ptr == NULL) - _jit->note.ptr = malloc(16 * sizeof(jit_note_t)); - else if ((_jit->note.length & 15) == 0) - _jit->note.ptr = realloc(_jit->note.ptr, - (_jit->note.length + 17) * sizeof(jit_note_t)); - - if (index < _jit->note.length) - memmove(_jit->note.ptr + index + 1, _jit->note.ptr + index, - sizeof(jit_note_t) * (_jit->note.length - index)); - note = _jit->note.ptr + index; - ++_jit->note.length; - - note->name = name; - note->length = 1; - note->linenos = malloc(16 * sizeof(jit_int32_t)); - note->linenos[0] = lineno; - note->offsets = malloc(16 * sizeof(jit_int32_t)); - note->offsets[0] = offset; -} - -static jit_int32_t -_note_insert_index(jit_state_t *_jit, jit_int32_t offset) -{ - jit_int32_t bot; - jit_int32_t top; - jit_int32_t index; - jit_note_t *notes; - - bot = 0; - top = _jit->note.length; - if ((notes = _jit->note.ptr) == NULL) - return (0); - for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { - if (offset < *notes[index].offsets) - top = index; - else - bot = index + 1; + if (_jit->note.ptr == NULL) { + prev = NULL; + _jit->note.ptr = malloc(sizeof(jit_note_t) * 8); } + else { + prev = _jit->note.ptr + _jit->note.length - 1; + if ((_jit->note.length & 7) == 7) + _jit->note.ptr = realloc(_jit->note.ptr, sizeof(jit_note_t) * + (_jit->note.length + 9)); + } + if (prev) { + assert(code >= prev->code); + prev->size = code - prev->code; + } + note = _jit->note.ptr + _jit->note.length; + ++_jit->note.length; + note->code = code; + note->name = name; + note->lines = NULL; + note->length = note->size = 0; - return ((bot + top) >> 1); + return (note); +} + +static void +new_line(jit_int32_t index, jit_note_t *note, + char *file, jit_int32_t lineno, jit_int32_t offset) +{ + jit_line_t *line; + + if (note->lines == NULL) + note->lines = malloc(16 * sizeof(jit_line_t)); + else if ((note->length & 15) == 15) + note->lines = realloc(note->lines, + (note->length + 17) * sizeof(jit_line_t)); + + if (index < note->length) + memmove(note->lines + index + 1, note->lines + index, + sizeof(jit_line_t) * (note->length - index)); + line = note->lines + index; + ++note->length; + + line->file = file; + line->length = 1; + line->linenos = malloc(16 * sizeof(jit_int32_t)); + line->linenos[0] = lineno; + line->offsets = malloc(16 * sizeof(jit_int32_t)); + line->offsets[0] = offset; } static jit_int32_t -_note_search_index(jit_state_t *_jit, jit_int32_t offset) +_note_search_index(jit_state_t *_jit, jit_uint8_t *code) { jit_int32_t bot; jit_int32_t top; @@ -172,15 +250,12 @@ _note_search_index(jit_state_t *_jit, jit_int32_t offset) bot = 0; top = _jit->note.length; - if ((notes = _jit->note.ptr) == NULL) - return (0); + notes = _jit->note.ptr; for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { - if (offset < *notes[index].offsets) + if (code < notes[index].code) top = index; - /* offset should be already verified to be in range */ - else if (index == _jit->note.length - 1 || - (offset >= *notes[index].offsets && - offset < *notes[index + 1].offsets)) + else if (code >= notes[index].code && + code - notes[index].code <= notes[index].size) break; else bot = index + 1; @@ -190,7 +265,56 @@ _note_search_index(jit_state_t *_jit, jit_int32_t offset) } static jit_int32_t -offset_insert_index(jit_note_t *note, jit_int32_t offset) +line_insert_index(jit_note_t *note, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_line_t *lines; + + bot = 0; + top = note->length; + if ((lines = note->lines) == NULL) + return (0); + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < *lines[index].offsets) + top = index; + else + bot = index + 1; + } + + return ((bot + top) >> 1); +} + +static jit_int32_t +line_search_index(jit_note_t *note, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_line_t *lines; + + bot = 0; + top = note->length; + if ((lines = note->lines) == NULL) + return (0); + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < *lines[index].offsets) + top = index; + /* offset should be already verified to be in range */ + else if (index == note->length - 1 || + (offset >= *lines[index].offsets && + offset < *lines[index + 1].offsets)) + break; + else + bot = index + 1; + } + + return (index); +} + +static jit_int32_t +offset_insert_index(jit_line_t *line, jit_int32_t offset) { jit_int32_t bot; jit_int32_t top; @@ -198,8 +322,8 @@ offset_insert_index(jit_note_t *note, jit_int32_t offset) jit_int32_t *offsets; bot = 0; - top = note->length; - offsets = note->offsets; + top = line->length; + offsets = line->offsets; for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { if (offset < offsets[index]) top = index; @@ -211,7 +335,7 @@ offset_insert_index(jit_note_t *note, jit_int32_t offset) } static jit_int32_t -offset_search_index(jit_note_t *note, jit_int32_t offset) +offset_search_index(jit_line_t *line, jit_int32_t offset) { jit_int32_t bot; jit_int32_t top; @@ -219,13 +343,13 @@ offset_search_index(jit_note_t *note, jit_int32_t offset) jit_int32_t *offsets; bot = 0; - top = note->length; - offsets = note->offsets; + top = line->length; + offsets = line->offsets; for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { if (offset < offsets[index]) top = index; /* offset should be already verified to be in range */ - else if (index == note->length - 1 || + else if (index == line->length - 1 || (offset >= offsets[index] && offset < offsets[index + 1])) break; else diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c index 44b01e5ac..443fcac02 100644 --- a/lib/jit_ppc.c +++ b/lib/jit_ppc.c @@ -800,7 +800,7 @@ _jit_emit(jit_state_t *_jit) value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { - case jit_code_note: + case jit_code_note: case jit_code_name: node->u.w = _jit->pc.w; break; case jit_code_label: diff --git a/lib/jit_print.c b/lib/jit_print.c index 8d5404593..fe4b16509 100644 --- a/lib/jit_print.c +++ b/lib/jit_print.c @@ -37,7 +37,7 @@ static char *code_name[] = { "data", "save", "load", - "#note", + "#name", "#note", "label", "prolog", "arg", @@ -375,6 +375,11 @@ _jit_print(jit_state_t *_jit) else print_flt(node->w.d); continue; + case jit_code_name: + print_chr(' '); + if (node->v.p) + print_str(node->v.n->u.p); + break; case jit_code_note: print_chr(' '); if (node->v.p) diff --git a/lib/jit_x86.c b/lib/jit_x86.c index 99063d919..3d9f0487f 100644 --- a/lib/jit_x86.c +++ b/lib/jit_x86.c @@ -1128,7 +1128,7 @@ _jit_emit(jit_state_t *_jit) value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { - case jit_code_note: + case jit_code_note: case jit_code_name: node->u.w = _jit->pc.w; break; case jit_code_label: diff --git a/lib/lightning.c b/lib/lightning.c index baad60886..9b20a1e44 100644 --- a/lib/lightning.c +++ b/lib/lightning.c @@ -321,7 +321,8 @@ jit_pointer_t _jit_address(jit_state_t *_jit, jit_node_t *node) { assert(_jit->done); - assert(node && node->code == jit_code_note); + assert(node && + (node->code == jit_code_note || node->code == jit_code_name)); return ((jit_pointer_t)node->u.w); } @@ -415,29 +416,6 @@ _jit_data(jit_state_t *_jit, jit_pointer_t data, return (node); } -jit_node_t * -_jit_note(jit_state_t *_jit, char *name, int line) -{ - jit_node_t *node; - - node = new_node(jit_code_note); - if (name) - node->v.n = jit_data(name, strlen(name) + 1, 1); - else - node->v.p = NULL; - node->w.w = line; - - (void)link_node(node); - if (_jit->note.head == NULL) - _jit->note.head = _jit->note.tail = node; - else { - _jit->note.tail->link = node; - _jit->note.tail = node; - } - - return (node); -} - static void _new_pool(jit_state_t *_jit) { @@ -812,8 +790,8 @@ _jit_classify(jit_state_t *_jit, jit_code_t code) switch (code) { case jit_code_data: case jit_code_save: case jit_code_load: - case jit_code_label: case jit_code_note: case jit_code_prolog: - case jit_code_epilog: + case jit_code_name: case jit_code_label: case jit_code_note: + case jit_code_prolog: case jit_code_epilog: mask = 0; break; case jit_code_arg: case jit_code_arg_f: case jit_code_arg_d: @@ -1165,18 +1143,6 @@ _jit_optimize(jit_state_t *_jit) } } -void -_jit_annotate(jit_state_t *_jit) -{ - jit_node_t *node; - - for (node = _jit->note.head; node; node = node->link) { - if (node->v.p) - jit_set_note(node->v.n->u.p, node->w.w, - (jit_uint8_t *)node->u.p - _jit->code.ptr); - } -} - void _jit_reglive(jit_state_t *_jit, jit_node_t *node) {