1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-06 07:30:28 +02:00

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).
This commit is contained in:
pcpa 2013-01-18 18:05:57 -02:00
parent c5421a8c76
commit 9e86ef12cf
31 changed files with 339 additions and 203 deletions

View file

@ -1,3 +1,19 @@
2013-01-18 Paulo Andrade <pcpa@gnu.org>
* 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 <pcpa@gnu.org>
* check/add.tst, check/allocai.tst, check/bp.tst, check/divi.tst,

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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) /**/

View file

@ -819,9 +819,6 @@ ok:
.c "ok\n"
.code
jmpi main
main:
prolog
alu(__LINE__, add)

View file

@ -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

View file

@ -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

View file

@ -76,9 +76,6 @@ L##x##C:
LDST0(R2, F0)
.code
jmpi main
main:
prolog
/* Simple test to simplify validating encodings before

View file

@ -83,9 +83,6 @@ Lu##x##C:
LDST0(V2, R2)
.code
jmpi main
main:
prolog
/* Simple test to simplify validating encodings before

View file

@ -95,9 +95,6 @@ L##x##C:
LDST0(V2, R2, F0)
.code
jmpi main
main:
prolog
/* Simple test to simplify validating encodings before

View file

@ -93,9 +93,6 @@ Lu##x##C:
LDST0(R2, R1)
.code
jmpi main
main:
prolog
/* Simple test to simplify validating encodings before

View file

@ -83,9 +83,6 @@ L##x##C:
LDST0(V2, R2, F0)
.code
jmpi main
main:
prolog
/* Simple test to simplify validating encodings before

View file

@ -105,9 +105,6 @@ Lu##x##C##1:
LDST0(R0, R2, V2)
.code
jmpi main
main:
prolog
/* Simple test to simplify validating encodings before

View file

@ -120,9 +120,6 @@ L##x##C:
LDST0(R0, R1, R2, F5)
.code
jmpi main
main:
prolog
/* Simple test to simplify validating encodings before

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -20,9 +20,6 @@ buff:
.size 256
.code
jmpi main
main:
prolog
/*

View file

@ -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*);

View file

@ -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*);

View file

@ -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:

View file

@ -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;
}

View file

@ -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:

View file

@ -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

View file

@ -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:

View file

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

View file

@ -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:

View file

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