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) {