guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 173/437: Add filename and line number annotation abstrac


From: Andy Wingo
Subject: [Guile-commits] 173/437: Add filename and line number annotation abstraction.
Date: Mon, 2 Jul 2018 05:14:11 -0400 (EDT)

wingo pushed a commit to branch lightning
in repository guile.

commit a34410eee2170f7e05f33920edae4d8ccac1f8ad
Author: pcpa <address@hidden>
Date:   Fri Jan 11 15:29:35 2013 -0200

    Add filename and line number annotation abstraction.
    
        * lib/jit_note.c: New file implementing a simple string+integer
        annotation, that should be used to map filename and line number
        to offsets in the generated jit.
    
        * include/lightning.h, lib/lightning.c: Update for the new
        note code.
          Add an extra mandatory argument to init_jit, that is used
        as argument to bfd_openr.
          Change from generic void* to char* the argument to jit_note
        and add an extra integer argument, to map to filename and
        line number.
    
        * check/ccall.c, check/lightning.c, include/lightning/jit_private.h,
        lib/jit_arm.c, lib/jit_disasm.c, lib/jit_mips.c, lib/jit_ppc.c,
        lib/jit_print.c, lib/jit_x86.c: lib/Makefile.am: Update for the
        new annotation code.
    
        * configure.ac, check/Makefile.am: Update to work with latest
        automake.
---
 .gitignore                      |   2 +
 ChangeLog                       |  22 ++++
 check/Makefile.am               |  59 +++++++++-
 check/ccall.c                   |  10 +-
 check/lightning.c               |  26 +++--
 configure.ac                    |   7 +-
 include/lightning.h             |   7 +-
 include/lightning/jit_private.h |  24 ++++
 lib/Makefile.am                 |   1 +
 lib/jit_arm.c                   |   1 +
 lib/jit_disasm.c                |  57 ++++++++--
 lib/jit_mips.c                  |   1 +
 lib/jit_note.c                  | 236 ++++++++++++++++++++++++++++++++++++++++
 lib/jit_ppc.c                   |   1 +
 lib/jit_print.c                 |  10 +-
 lib/jit_x86.c                   |   1 +
 lib/lightning.c                 |  45 +++++++-
 17 files changed, 464 insertions(+), 46 deletions(-)

diff --git a/.gitignore b/.gitignore
index 326fac8..a89a8e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,9 +14,11 @@ config.sub
 configure
 install-sh
 libtool
+lightning-*.tar.*
 ltmain.sh
 missing
 stamp-h1
+test-driver
 check/.deps
 lib/.deps
 m4/libtool.m4
diff --git a/ChangeLog b/ChangeLog
index 97d8b26..e738193 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2013-01-11 Paulo Andrade <address@hidden>
+
+       * lib/jit_note.c: New file implementing a simple string+integer
+       annotation, that should be used to map filename and line number
+       to offsets in the generated jit.
+
+       * include/lightning.h, lib/lightning.c: Update for the new
+       note code.
+         Add an extra mandatory argument to init_jit, that is used
+       as argument to bfd_openr.
+         Change from generic void* to char* the argument to jit_note
+       and add an extra integer argument, to map to filename and
+       line number.
+
+       * check/ccall.c, check/lightning.c, include/lightning/jit_private.h,
+       lib/jit_arm.c, lib/jit_disasm.c, lib/jit_mips.c, lib/jit_ppc.c,
+       lib/jit_print.c, lib/jit_x86.c: lib/Makefile.am: Update for the
+       new annotation code.
+
+       * configure.ac, check/Makefile.am: Update to work with latest
+       automake.
+
 2013-01-09 Paulo Andrade <address@hidden>
 
        * include/lightning.h, lib/jit_arm.c, jit_mips-fpu.c,
diff --git a/check/Makefile.am b/check/Makefile.am
index 8324c36..ce78c49 100644
--- a/check/Makefile.am
+++ b/check/Makefile.am
@@ -96,21 +96,72 @@ $(base_TESTS):      check.sh
 TESTS = $(base_TESTS)
 
 if test_x86_x87
-x87_TESTS = $(addsuffix .x87, $(base_TESTS))
+#x87_TESTS = $(addsuffix .x87, $(base_TESTS))
+x87_TESTS =                                    \
+       3to2.x87 add.x87 allocai.x87            \
+       bp.x87 divi.x87 fib.x87 rpn.x87         \
+       ldstr.x87 ldsti.x87                     \
+       ldstxr.x87 ldstxi.x87                   \
+       ldstr-c.x87 ldstxr-c.x87 ldstxi-c.x87   \
+       cvt.x87 branch.x87                      \
+       alu_add.x87 alux_add.x87                \
+       alu_sub.x87 alux_sub.x87                \
+       alu_mul.x87 alu_div.x87 alu_rem.x87     \
+       alu_and.x87 alu_or.x87 alu_xor.x87      \
+       alu_lsh.x87 alu_rsh.x87                 \
+       alu_com.x87 alu_neg.x87                 \
+       fop_abs.x87 fop_sqrt.x87                \
+       varargs.x87 stack.x87                   \
+       clobber.x87 carry.x87 call.x87          \
+       float.x87
 $(x87_TESTS):  check.x87.sh
        $(LN_S) $(srcdir)/check.x87.sh $@
 TESTS += $(x87_TESTS)
 endif
 
 if test_arm_arm
-arm_TESTS = $(addsuffix .arm, $(base_TESTS))
+#arm_TESTS = $(addsuffix .arm, $(base_TESTS))
+arm_TESTS =                                    \
+       3to2.arm add.arm allocai.arm            \
+       bp.arm divi.arm fib.arm rpn.arm         \
+       ldstr.arm ldsti.arm                     \
+       ldstxr.arm ldstxi.arm                   \
+       ldstr-c.arm ldstxr-c.arm ldstxi-c.arm   \
+       cvt.arm branch.arm                      \
+       alu_add.arm alux_add.arm                \
+       alu_sub.arm alux_sub.arm                \
+       alu_mul.arm alu_div.arm alu_rem.arm     \
+       alu_and.arm alu_or.arm alu_xor.arm      \
+       alu_lsh.arm alu_rsh.arm                 \
+       alu_com.arm alu_neg.arm                 \
+       fop_abs.arm fop_sqrt.arm                \
+       varargs.arm stack.arm                   \
+       clobber.arm carry.arm call.arm          \
+       float.arm
 $(arm_TESTS):  check.arm.sh
        $(LN_S) $(srcdir)/check.arm.sh $@
 TESTS += $(arm_TESTS)
 endif
 
 if test_arm_swf
-swf_TESTS = $(addsuffix .swf, $(base_TESTS))
+#swf_TESTS = $(addsuffix .swf, $(base_TESTS))
+swf_TESTS =                                    \
+       3to2.swf add.swf allocai.swf            \
+       bp.swf divi.swf fib.swf rpn.swf         \
+       ldstr.swf ldsti.swf                     \
+       ldstxr.swf ldstxi.swf                   \
+       ldstr-c.swf ldstxr-c.swf ldstxi-c.swf   \
+       cvt.swf branch.swf                      \
+       alu_add.swf alux_add.swf                \
+       alu_sub.swf alux_sub.swf                \
+       alu_mul.swf alu_div.swf alu_rem.swf     \
+       alu_and.swf alu_or.swf alu_xor.swf      \
+       alu_lsh.swf alu_rsh.swf                 \
+       alu_com.swf alu_neg.swf                 \
+       fop_abs.swf fop_sqrt.swf                \
+       varargs.swf stack.swf                   \
+       clobber.swf carry.swf call.swf          \
+       float.swf
 $(swf_TESTS):  check.swf.sh
        $(LN_S) $(srcdir)/check.swf.sh $@
 TESTS += $(swf_TESTS)
@@ -119,7 +170,7 @@ endif
 TESTS += ccall
 CLEANFILES = $(TESTS)
 
-TESTS_ENVIRONMENT=$(srcdir)/run-test
+#TESTS_ENVIRONMENT=$(srcdir)/run-test;
 
 debug:         $(check_PROGRAMS)
        $(LIBTOOL) --mode=execute gdb $(check_PROGRAMS)
diff --git a/check/ccall.c b/check/ccall.c
index 1ff6b2a..201bc2e 100644
--- a/check/ccall.c
+++ b/check/ccall.c
@@ -600,7 +600,7 @@ main(int argc, char *argv[])
     jit_node_t          *a10,*a11,*a12,*a13,*a14,*a15;
     jit_node_t          *jmp;
 
-    init_jit();
+    init_jit(argv[0]);
     _jit = jit_new_state();
 
     jmpi_main = jit_jmpi();
@@ -701,9 +701,10 @@ main(int argc, char *argv[])
 #else
 #  define jit_extr_l(u, v)                     /**/
 #endif
-       
+
+#define strfy(n)                               #n      
 #define defi(T, N)                                                     \
-    n##T##N = jit_note(NULL);                                          \
+    n##T##N = jit_note(strfy(n##T##N), 0);                             \
     jit_prolog();                                                      \
     arg##N();                                                          \
     get##N(,T,JIT_R)                                                   \
@@ -711,7 +712,7 @@ main(int argc, char *argv[])
     jit_retr(JIT_R0);                                                  \
     jit_epilog();
 #define deff(T, N)                                                     \
-    n##T##N = jit_note(NULL);                                          \
+    n##T##N = jit_note(strfy(n##T##N), 0);                             \
     jit_prolog();                                                      \
     arg##N(T);                                                         \
     get##N(T,T,JIT_F);                                                 \
@@ -751,6 +752,7 @@ main(int argc, char *argv[])
 #undef def
 
     jit_patch(jmpi_main);
+    jit_note("main", 0);
     jit_prolog();
 
 #define  push0(T)      /**/
diff --git a/check/lightning.c b/check/lightning.c
index 4c05ba7..90bdd7c 100644
--- a/check/lightning.c
+++ b/check/lightning.c
@@ -207,6 +207,7 @@ struct label {
     char               *name;
     void               *value;
     label_kind_t        kind;
+    int                         line;
 };
 
 typedef enum {
@@ -501,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);
+static label_t *new_label(label_kind_t kind, char *name, void *value, int 
line);
 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);
@@ -1808,7 +1809,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());
+                         parser.string, jit_forward(), 0);
 
     return (label);
 }
@@ -2263,7 +2264,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);
+       label = new_label(label_kind_dynamic, parser.string, value, 0);
     }
     parser.type = type_p;
     parser.value.p = label->value;
@@ -3476,7 +3477,9 @@ parse(void)
                    if ((label = get_label_by_name(parser.string))) {
                        if (label->kind == label_kind_code_forward) {
                            label->kind = label_kind_code;
-                           label->value = jit_label();
+                           label->line = parser.line;
+                           jit_link(label->value);
+                           jit_note(parser.string, parser.line);
                        }
                        else
                            error("label %s: redefined", parser.string);
@@ -3492,7 +3495,8 @@ parse(void)
                        }
                        else
                            error("label not in .code or .data");
-                       label = new_label(kind, parser.string, value);
+                       label = new_label(kind, parser.string, value,
+                                         parser.line);
                    }
                    break;
                }
@@ -3588,7 +3592,7 @@ xcalloc(size_t nmemb, size_t size)
 }
 
 static label_t *
-new_label(label_kind_t kind, char *name, void *value)
+new_label(label_kind_t kind, char *name, void *value, int line)
 {
     label_t    *label;
 
@@ -3596,8 +3600,11 @@ new_label(label_kind_t kind, char *name, void *value)
     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);
 }
 
@@ -3787,9 +3794,10 @@ main(int argc, char *argv[])
     int                         opt_short;
     char                cmdline[8192];
 
-    init_jit();
-
     progname = argv[0];
+
+    init_jit(progname);
+
     for (;;) {
        if ((opt_short = getopt_long_only(argc, argv, short_options,
                                          long_options, &opt_index)) < 0)
@@ -3934,8 +3942,6 @@ main(int argc, char *argv[])
     parser.line = 1;
     parser.string = (char *)xmalloc(parser.length = 4096);
 
-    labels = new_hash();
-
 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
     /* double precision                0x200
      * round nearest                   0x000
diff --git a/configure.ac b/configure.ac
index 98f0edd..9d5e433 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,7 +19,7 @@ AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([dist-bzip2])
 AC_CONFIG_MACRO_DIR(m4)
 
-AM_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADER(config.h)
 
 AC_PROG_CC
 AC_PROG_INSTALL
@@ -53,10 +53,7 @@ if test "x$DISASSEMBLER" != "xno"; then
 fi
 AM_CONDITIONAL(with_disassembler, [test "x$DISASSEMBLER" != "xno"])
 if test "x$DISASSEMBLER" != "xno"; then
-    case "$target_os" in
-       *linux*) LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDISASSEMBLER=1"  ;;
-       *)                                                              ;;
-    esac
+    LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDISASSEMBLER=1"
 fi
 
 cpu=
diff --git a/include/lightning.h b/include/lightning.h
index 821177e..41c83fa 100644
--- a/include/lightning.h
+++ b/include/lightning.h
@@ -102,7 +102,7 @@ typedef enum {
 #define jit_data(u,v)          _jit_data(_jit,u,v)
     jit_code_data,
     jit_code_save,             jit_code_load,
-#define jit_note(u)            jit_new_node_ww(jit_code_note,0,(jit_word_t)u)
+#define jit_note(u, v)         _jit_note(_jit, u, v)
 #define jit_label()            _jit_label(_jit)
 #define jit_forward()          _jit_forward(_jit)
 #define jit_link(u)            _jit_link(_jit,u)
@@ -732,7 +732,7 @@ typedef enum {
 /*
  * Prototypes
  */
-extern void init_jit(void);
+extern void init_jit(char*);
 extern void finish_jit(void);
 
 extern jit_state_t *jit_new_state(void);
@@ -740,8 +740,7 @@ extern jit_state_t *jit_new_state(void);
 #define jit_address(node)      _jit_address(_jit, node)
 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);
-extern jit_node_t *_jit_note(jit_state_t*, jit_pointer_t);
-
+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*);
 extern void _jit_link(jit_state_t*, jit_node_t*);
diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h
index ca6f970..5efeee8 100644
--- a/include/lightning/jit_private.h
+++ b/include/lightning/jit_private.h
@@ -125,6 +125,7 @@ jit_regset_scan1(jit_regset_t, jit_int32_t);
  * Types
  */
 typedef union jit_data         jit_data_t;
+typedef struct jit_note                jit_note_t;
 typedef struct jit_block       jit_block_t;
 typedef struct jit_value       jit_value_t;
 typedef struct jit_function    jit_function_t;
@@ -152,6 +153,13 @@ union jit_data {
     jit_node_t         *n;
 };
 
+struct jit_note {
+    char               *name;
+    jit_int32_t                *linenos;
+    jit_int32_t                *offsets;
+    jit_word_t          length;
+};
+
 struct jit_node {
     jit_node_t         *next;
     jit_code_t          code;
@@ -269,6 +277,12 @@ struct jit_state {
        jit_word_t        length;
     } pool;
     jit_node_t          *list;
+    struct {
+       jit_note_t      *ptr;
+       jit_node_t      *head;          /* first note node */
+       jit_node_t      *tail;          /* linked list insertion */
+       jit_word_t       length;
+    } note;
 #if __arm__
 #  if DISASSEMBLER
     struct {
@@ -378,9 +392,19 @@ _emit_stxi_d(jit_state_t*, jit_word_t, jit_int32_t, 
jit_int32_t);
 extern void jit_init_debug(void);
 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_annotate()         _jit_annotate(_jit)
+extern void _jit_annotate(jit_state_t*);
+
 /*
  * Externs
  */
 extern jit_register_t   _rvs[];
+extern const char      *jit_progname;
 
 #endif /* _jit_private_h */
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 2b28377..02d5897 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -18,6 +18,7 @@ liblightning_LTLIBRARIES = liblightning.la
 liblightningdir = $(libdir)
 liblightning_la_SOURCES =      \
        jit_disasm.c            \
+       jit_note.c              \
        jit_print.c             \
        lightning.c
 
diff --git a/lib/jit_arm.c b/lib/jit_arm.c
index d331683..7b467b1 100644
--- a/lib/jit_arm.c
+++ b/lib/jit_arm.c
@@ -1543,6 +1543,7 @@ _jit_emit(jit_state_t *_jit)
 
     __clear_cache(_jit->code.ptr, _jit->pc.uc);
     _jit->done = 1;
+    jit_annotate();
 
     return (_jit->code.ptr);
 }
diff --git a/lib/jit_disasm.c b/lib/jit_disasm.c
index c0a5079..602d96b 100644
--- a/lib/jit_disasm.c
+++ b/lib/jit_disasm.c
@@ -17,7 +17,9 @@
 
 #include <lightning.h>
 #include <lightning/jit_private.h>
-#include <dis-asm.h>
+#if DISASSEMBLER
+#  include <dis-asm.h>
+#endif
 
 /*
  * Prototypes
@@ -45,6 +47,7 @@ static asymbol                        **disasm_symbols;
 static asymbol                  *disasm_synthetic;
 static long                      disasm_num_symbols;
 static long                      disasm_num_synthetic;
+static jit_state_t              *disasm_jit;
 #define disasm_stream            stdout
 #endif
 
@@ -57,9 +60,7 @@ jit_init_debug(void)
 #if DISASSEMBLER
     bfd_init();
 
-    /* FIXME */
-    disasm_bfd = bfd_openr("/proc/self/exe", NULL);
-
+    disasm_bfd = bfd_openr(jit_progname, NULL);
     assert(disasm_bfd);
     bfd_check_format(disasm_bfd, bfd_object);
     bfd_check_format(disasm_bfd, bfd_archive);
@@ -193,12 +194,27 @@ disasm_compare_symbols(const void *ap, const void *bp)
 static void
 disasm_print_address(bfd_vma addr, struct disassemble_info *info)
 {
+    char               *name;
+    int                         line;
     char                buffer[address_buffer_length];
 
     sprintf(buffer, address_buffer_format, (long long)addr);
     (*info->fprintf_func)(info->stream, "0x%s", buffer);
 
-    if (disasm_num_symbols) {
+#  define _jit                         disasm_jit
+#  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);
+       }
+    }
+#  undef jit_pointer_p
+#  undef _jit
+    else if (disasm_num_symbols) {
        long             low;
        long             high;
        long             offset;
@@ -241,15 +257,17 @@ disasm_print_address(bfd_vma addr, struct 
disassemble_info *info)
 static void
 _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length)
 {
-    int                        bytes;
+    int                         bytes;
+    char               *name, *old_name;
+    int                         line,  old_line;
 #if __arm__
-    jit_int32_t                offset;
-    jit_bool_t         data_info;
-    jit_int32_t                data_offset;
+    jit_int32_t                 offset;
+    jit_bool_t          data_info;
+    jit_int32_t                 data_offset;
 #endif
-    bfd_vma            pc = (jit_uword_t)code;
-    bfd_vma            end = (jit_uword_t)code + length;
-    char               buffer[address_buffer_length];
+    bfd_vma             pc = (jit_uword_t)code;
+    bfd_vma             end = (jit_uword_t)code + length;
+    char                buffer[address_buffer_length];
 
 #if __arm__
     data_info = 1;
@@ -258,6 +276,9 @@ _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_line = 0;
+    disasm_jit = _jit;
     while (pc < end) {
 #if __arm__
     again:
@@ -289,6 +310,18 @@ _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);
+           old_name = name;
+           old_line = line;
+       }
+
        bytes = sprintf(buffer, address_buffer_format, (long long)pc);
        (*disasm_info.fprintf_func)(disasm_stream, "%*c0x%s\t",
                                    16 - bytes, ' ', buffer);
diff --git a/lib/jit_mips.c b/lib/jit_mips.c
index cbf4ebd..94c4ff3 100644
--- a/lib/jit_mips.c
+++ b/lib/jit_mips.c
@@ -1250,6 +1250,7 @@ _jit_emit(jit_state_t *_jit)
     _flush_cache((char *)_jit->code.ptr, _jit->pc.uc - _jit->code.ptr, ICACHE);
 #endif
     _jit->done = 1;
+    jit_annotate();
 
     return (_jit->code.ptr);
 }
diff --git a/lib/jit_note.c b/lib/jit_note.c
new file mode 100644
index 0000000..648ecac
--- /dev/null
+++ b/lib/jit_note.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013  Free Software Foundation, Inc.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Authors:
+ *     Paulo Cesar Pereira de Andrade
+ */
+
+#include <lightning.h>
+#include <lightning/jit_private.h>
+
+/*
+ * 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 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);
+
+/*
+ * Implementation
+ */
+void
+jit_init_note(void)
+{
+}
+
+void
+jit_finish_note(void)
+{
+}
+
+void
+_jit_set_note(jit_state_t *_jit,
+             char *name, int lineno, jit_int32_t offset)
+{
+    jit_note_t         *note;
+    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);
+    else {
+       note = _jit->note.ptr + index;
+       index = offset_insert_index(note, offset);
+       if (note->offsets[index] == offset) {
+           /* common case if no code was generated for several source lines */
+           if (note->linenos[index] < lineno)
+               note->linenos[index] = lineno;
+       }
+       else if (note->linenos[index] == lineno) {
+           /* common case of extending entry */
+           if (note->offsets[index] > offset)
+               note->offsets[index] = offset;
+       }
+       else {
+           /* line or offset changed */
+           if ((note->length & 15) == 0) {
+               note->linenos = realloc(note->linenos, (note->length + 17) *
+                                       sizeof(jit_int32_t));
+               note->offsets = realloc(note->offsets, (note->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));
+           }
+           note->linenos[index] = lineno;
+           note->offsets[index] = offset;
+           ++note->length;
+       }
+    }
+}
+
+jit_bool_t
+_jit_get_note(jit_state_t *_jit, jit_uint8_t *code,
+             char **name, jit_int32_t *lineno)
+{
+    jit_note_t         *note;
+    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])
+       return (0);
+    note = _jit->note.ptr + index;
+    if ((index = offset_search_index(note, offset)) >= note->length)
+       return (0);
+
+    if (name)
+       *name = note->name;
+    if (lineno)
+       *lineno = note->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)
+{
+    jit_note_t         *note;
+
+    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;
+    }
+
+    return ((bot + top) >> 1);
+}
+
+static jit_int32_t
+_note_search_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;
+       /* 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))
+           break;
+       else
+           bot = index + 1;
+    }
+
+    return (index);
+}
+
+static jit_int32_t
+offset_insert_index(jit_note_t *note, jit_int32_t offset)
+{
+    jit_int32_t                 bot;
+    jit_int32_t                 top;
+    jit_int32_t                 index;
+    jit_int32_t                *offsets;
+
+    bot = 0;
+    top = note->length;
+    offsets = note->offsets;
+    for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
+       if (offset < offsets[index])
+           top = index;
+       else
+           bot = index + 1;
+    }
+
+    return ((bot + top) >> 1);
+}
+
+static jit_int32_t
+offset_search_index(jit_note_t *note, jit_int32_t offset)
+{
+    jit_int32_t                 bot;
+    jit_int32_t                 top;
+    jit_int32_t                 index;
+    jit_int32_t                *offsets;
+
+    bot = 0;
+    top = note->length;
+    offsets = note->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 ||
+                (offset >= offsets[index] && offset < offsets[index + 1]))
+           break;
+       else
+           bot = index + 1;
+    }
+
+    return (index);
+}
diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c
index c4a507e..44b01e5 100644
--- a/lib/jit_ppc.c
+++ b/lib/jit_ppc.c
@@ -1213,6 +1213,7 @@ _jit_emit(jit_state_t *_jit)
 
     __clear_cache(_jit->code.ptr, _jit->pc.uc);
     _jit->done = 1;
+    jit_annotate();
 
     return (_jit->code.ptr);
 }
diff --git a/lib/jit_print.c b/lib/jit_print.c
index 0b3d3bc..8d54045 100644
--- a/lib/jit_print.c
+++ b/lib/jit_print.c
@@ -375,13 +375,15 @@ _jit_print(jit_state_t *_jit)
            else
                print_flt(node->w.d);
            continue;
-
            case jit_code_note:
-               /* FIXME should be name:line information */
                print_chr(' ');
-               print_ptr(node->v.p);
+               if (node->v.p)
+                   print_str(node->v.n->u.p);
+               if (node->v.p && node->w.w)
+                   print_chr(':');
+               if (node->w.w)
+                   print_dec(node->w.w);
                break;
-
            case jit_code_data:
            case jit_code_label:
            case jit_code_prolog:       case jit_code_epilog:
diff --git a/lib/jit_x86.c b/lib/jit_x86.c
index fe7aa98..99063d9 100644
--- a/lib/jit_x86.c
+++ b/lib/jit_x86.c
@@ -1630,6 +1630,7 @@ _jit_emit(jit_state_t *_jit)
        patch_at(node, _jit->patches.ptr[offset].inst, word);
     }
     _jit->done = 1;
+    jit_annotate();
 
     return (_jit->code.ptr);
 }
diff --git a/lib/lightning.c b/lib/lightning.c
index f61aed3..62cfea4 100644
--- a/lib/lightning.c
+++ b/lib/lightning.c
@@ -127,11 +127,17 @@ _patch_register(jit_state_t *jit, jit_node_t *node, 
jit_node_t *link,
                jit_int32_t regno, jit_int32_t patch);
 
 /*
+ * Initialization
+ */
+const char     *jit_progname;
+
+/*
  * Implementation
  */
 void
-init_jit(void)
+init_jit(char *progname)
 {
+    jit_progname = progname;
     jit_get_cpu();
     jit_init_debug();
 }
@@ -406,6 +412,29 @@ _jit_data(jit_state_t *_jit, jit_pointer_t data, 
jit_word_t length)
     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));
+    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)
 {
@@ -1113,7 +1142,6 @@ _jit_optimize(jit_state_t *_jit)
        }
     }
 
-#if JIT_HASH_CONSTS
     /* create read only data buffer */
     if ((_jit->data.length = (_jit->data.offset + 4095) & -4096)) {
        jit_uint8_t     *ptr;
@@ -1132,7 +1160,18 @@ _jit_optimize(jit_state_t *_jit)
            }
        }
     }
-#endif
+}
+
+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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]