mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-21 19:20:21 +02:00
Store all annotation information in the read only data buffer.
* include/lightning/jit_private.h, lib/jit_note.c, lib/lightning.c: Store all annotation information in the mmap'ed area reserved for read only data. This adds code to not allocate memory for jit_note_t objects, and to relocate jit_line_t objects and its contents after calculating annotation information. The jit_line_t objects are relocated because it is not possible to always calculate before hand data layout because note information may be extended or redundant entries removed, as well as allowed to be added in non sequential order. A bug was also corrected in _jit_set_note, that was causing it to allocate new jit_line_t objects when not needed. It was still working correctly, but allocating way more memory than required.
This commit is contained in:
parent
60c1c545fc
commit
6039794ec3
4 changed files with 117 additions and 36 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
2013-02-11 Paulo Andrade <pcpa@gnu.org>
|
||||||
|
|
||||||
|
* include/lightning/jit_private.h, lib/jit_note.c, lib/lightning.c:
|
||||||
|
Store all annotation information in the mmap'ed area reserved for
|
||||||
|
read only data. This adds code to not allocate memory for jit_note_t
|
||||||
|
objects, and to relocate jit_line_t objects and its contents after
|
||||||
|
calculating annotation information. The jit_line_t objects are
|
||||||
|
relocated because it is not possible to always calculate before
|
||||||
|
hand data layout because note information may be extended or
|
||||||
|
redundant entries removed, as well as allowed to be added in
|
||||||
|
non sequential order.
|
||||||
|
A bug was also corrected in _jit_set_note, that was causing it
|
||||||
|
to allocate new jit_line_t objects when not needed. It was still
|
||||||
|
working correctly, but allocating way more memory than required.
|
||||||
|
|
||||||
2013-02-05 Paulo Andrade <pcpa@gnu.org>
|
2013-02-05 Paulo Andrade <pcpa@gnu.org>
|
||||||
|
|
||||||
*include/lightning.h, lib/lightning.c: Add the new jit_live code
|
*include/lightning.h, lib/lightning.c: Add the new jit_live code
|
||||||
|
|
|
@ -319,10 +319,16 @@ struct jit_state {
|
||||||
} pool;
|
} pool;
|
||||||
jit_node_t *list;
|
jit_node_t *list;
|
||||||
struct {
|
struct {
|
||||||
jit_note_t *ptr;
|
jit_note_t *ptr;
|
||||||
jit_node_t *head; /* first note node */
|
jit_node_t *head; /* first note node */
|
||||||
jit_node_t *tail; /* linked list insertion */
|
jit_node_t *tail; /* linked list insertion */
|
||||||
jit_word_t length;
|
jit_word_t length;
|
||||||
|
|
||||||
|
/* fields to store temporary state information */
|
||||||
|
jit_word_t size;
|
||||||
|
jit_node_t *name;
|
||||||
|
jit_node_t *note;
|
||||||
|
jit_uint8_t *base;
|
||||||
} note;
|
} note;
|
||||||
#if __arm__
|
#if __arm__
|
||||||
# if DISASSEMBLER
|
# if DISASSEMBLER
|
||||||
|
|
|
@ -60,8 +60,11 @@ _jit_name(jit_state_t *_jit, char *name)
|
||||||
_jit->note.tail->link = node;
|
_jit->note.tail->link = node;
|
||||||
_jit->note.tail = node;
|
_jit->note.tail = node;
|
||||||
}
|
}
|
||||||
|
++_jit->note.length;
|
||||||
return (node);
|
_jit->note.size += sizeof(jit_note_t);
|
||||||
|
/* remember previous note is invalid due to name change */
|
||||||
|
_jit->note.note = NULL;
|
||||||
|
return (_jit->note.name = node);
|
||||||
}
|
}
|
||||||
|
|
||||||
jit_node_t *
|
jit_node_t *
|
||||||
|
@ -81,8 +84,14 @@ _jit_note(jit_state_t *_jit, char *name, int line)
|
||||||
_jit->note.tail->link = node;
|
_jit->note.tail->link = node;
|
||||||
_jit->note.tail = node;
|
_jit->note.tail = node;
|
||||||
}
|
}
|
||||||
|
if (_jit->note.note == NULL ||
|
||||||
return (node);
|
(name == NULL && _jit->note.note != NULL) ||
|
||||||
|
(name != NULL && _jit->note.note == NULL) ||
|
||||||
|
(name != NULL && _jit->note.note != NULL &&
|
||||||
|
strcmp(name, (char *)_jit->data.ptr + _jit->note.note->v.n->u.w)))
|
||||||
|
_jit->note.size += sizeof(jit_line_t);
|
||||||
|
_jit->note.size += sizeof(jit_int32_t) * 2;
|
||||||
|
return (_jit->note.note = node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -90,6 +99,14 @@ _jit_annotate(jit_state_t *_jit)
|
||||||
{
|
{
|
||||||
jit_node_t *node;
|
jit_node_t *node;
|
||||||
jit_note_t *note;
|
jit_note_t *note;
|
||||||
|
jit_line_t *line;
|
||||||
|
jit_word_t length;
|
||||||
|
jit_word_t note_offset;
|
||||||
|
jit_word_t line_offset;
|
||||||
|
|
||||||
|
/* initialize pointers in mmaped data area */
|
||||||
|
_jit->note.ptr = (jit_note_t *)_jit->note.base;
|
||||||
|
_jit->note.length = 0;
|
||||||
|
|
||||||
note = NULL;
|
note = NULL;
|
||||||
for (node = _jit->note.head; node; node = node->link) {
|
for (node = _jit->note.head; node; node = node->link) {
|
||||||
|
@ -105,6 +122,43 @@ _jit_annotate(jit_state_t *_jit)
|
||||||
/* last note */
|
/* last note */
|
||||||
if (note)
|
if (note)
|
||||||
note->size = _jit->pc.uc - note->code;
|
note->size = _jit->pc.uc - note->code;
|
||||||
|
|
||||||
|
/* annotations may be very complex with conditions to extend
|
||||||
|
* or ignore redudant notes, as well as add entries to earlier
|
||||||
|
* notes, so, relocate the information to the data buffer,
|
||||||
|
* with likely over allocated reserved space */
|
||||||
|
|
||||||
|
/* relocate jit_line_t objects */
|
||||||
|
for (note_offset = 0; note_offset < _jit->note.length; note_offset++) {
|
||||||
|
note = _jit->note.ptr + note_offset;
|
||||||
|
length = sizeof(jit_line_t) * note->length;
|
||||||
|
assert(_jit->note.base + length < _jit->data.ptr + _jit->data.length);
|
||||||
|
memcpy(_jit->note.base, note->lines, length);
|
||||||
|
free(note->lines);
|
||||||
|
note->lines = (jit_line_t *)_jit->note.base;
|
||||||
|
_jit->note.base += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* relocate offset and line number information */
|
||||||
|
for (note_offset = 0; note_offset < _jit->note.length; note_offset++) {
|
||||||
|
note = _jit->note.ptr + note_offset;
|
||||||
|
for (line_offset = 0; line_offset < note->length; line_offset++) {
|
||||||
|
line = note->lines + line_offset;
|
||||||
|
length = sizeof(jit_int32_t) * line->length;
|
||||||
|
assert(_jit->note.base + length <
|
||||||
|
_jit->data.ptr + _jit->data.length);
|
||||||
|
memcpy(_jit->note.base, line->linenos, length);
|
||||||
|
free(line->linenos);
|
||||||
|
line->linenos = (jit_int32_t *)_jit->note.base;
|
||||||
|
_jit->note.base += length;
|
||||||
|
assert(_jit->note.base + length <
|
||||||
|
_jit->data.ptr + _jit->data.length);
|
||||||
|
memcpy(_jit->note.base, line->offsets, length);
|
||||||
|
free(line->offsets);
|
||||||
|
line->offsets = (jit_int32_t *)_jit->note.base;
|
||||||
|
_jit->note.base += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -115,6 +169,9 @@ _jit_set_note(jit_state_t *_jit, jit_note_t *note,
|
||||||
jit_int32_t index;
|
jit_int32_t index;
|
||||||
|
|
||||||
index = line_insert_index(note, offset);
|
index = line_insert_index(note, offset);
|
||||||
|
if (note->length && index == note->length &&
|
||||||
|
note->lines[index - 1].file == file)
|
||||||
|
--index;
|
||||||
if (index >= note->length || note->lines[index].file != file)
|
if (index >= note->length || note->lines[index].file != file)
|
||||||
new_line(index, note, file, lineno, offset);
|
new_line(index, note, file, lineno, offset);
|
||||||
else {
|
else {
|
||||||
|
@ -190,26 +247,16 @@ _new_note(jit_state_t *_jit, jit_uint8_t *code, char *name)
|
||||||
jit_note_t *note;
|
jit_note_t *note;
|
||||||
jit_note_t *prev;
|
jit_note_t *prev;
|
||||||
|
|
||||||
if (_jit->note.ptr == NULL) {
|
if (_jit->note.length) {
|
||||||
prev = NULL;
|
|
||||||
_jit->note.ptr = malloc(sizeof(jit_note_t) * 8);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ((_jit->note.length & 7) == 7)
|
|
||||||
_jit->note.ptr = realloc(_jit->note.ptr, sizeof(jit_note_t) *
|
|
||||||
(_jit->note.length + 9));
|
|
||||||
prev = _jit->note.ptr + _jit->note.length - 1;
|
prev = _jit->note.ptr + _jit->note.length - 1;
|
||||||
}
|
|
||||||
if (prev) {
|
|
||||||
assert(code >= prev->code);
|
assert(code >= prev->code);
|
||||||
prev->size = code - prev->code;
|
prev->size = code - prev->code;
|
||||||
}
|
}
|
||||||
note = _jit->note.ptr + _jit->note.length;
|
note = (jit_note_t *)_jit->note.base;
|
||||||
|
_jit->note.base += sizeof(jit_note_t);
|
||||||
++_jit->note.length;
|
++_jit->note.length;
|
||||||
note->code = code;
|
note->code = code;
|
||||||
note->name = name;
|
note->name = name;
|
||||||
note->lines = NULL;
|
|
||||||
note->length = note->size = 0;
|
|
||||||
|
|
||||||
return (note);
|
return (note);
|
||||||
}
|
}
|
||||||
|
|
|
@ -531,6 +531,11 @@ jit_new_state(void)
|
||||||
sizeof(jit_data_info_t));
|
sizeof(jit_data_info_t));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* allocate at most one extra note in case jit_name() is
|
||||||
|
* never called, or called after adding at least one note */
|
||||||
|
_jit->note.length = 1;
|
||||||
|
_jit->note.size = sizeof(jit_note_t);
|
||||||
|
|
||||||
return (_jit);
|
return (_jit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1045,6 +1050,7 @@ _jit_patch_at(jit_state_t *_jit, jit_node_t *instr, jit_node_t *label)
|
||||||
void
|
void
|
||||||
_jit_optimize(jit_state_t *_jit)
|
_jit_optimize(jit_state_t *_jit)
|
||||||
{
|
{
|
||||||
|
jit_uint8_t *ptr;
|
||||||
jit_bool_t jump;
|
jit_bool_t jump;
|
||||||
jit_int32_t mask;
|
jit_int32_t mask;
|
||||||
jit_node_t *node;
|
jit_node_t *node;
|
||||||
|
@ -1151,22 +1157,29 @@ _jit_optimize(jit_state_t *_jit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create read only data buffer */
|
/* ensure it is aligned */
|
||||||
if ((_jit->data.length = (_jit->data.offset + 4095) & -4096)) {
|
_jit->data.offset = (_jit->data.offset + 7) & -8;
|
||||||
jit_uint8_t *ptr;
|
|
||||||
|
|
||||||
ptr = mmap(NULL, _jit->data.length,
|
/* create read only data buffer */
|
||||||
PROT_READ | PROT_WRITE,
|
_jit->data.length = (_jit->data.offset +
|
||||||
MAP_PRIVATE | MAP_ANON, -1, 0);
|
/* reserve space for annotations */
|
||||||
assert(ptr != MAP_FAILED);
|
_jit->note.size + 4095) & -4096;
|
||||||
memcpy(ptr, _jit->data.ptr, _jit->data.offset);
|
ptr = mmap(NULL, _jit->data.length,
|
||||||
free(_jit->data.ptr);
|
PROT_READ | PROT_WRITE,
|
||||||
_jit->data.ptr = ptr;
|
MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||||
for (offset = 0; offset < _jit->data.size; offset++) {
|
assert(ptr != MAP_FAILED);
|
||||||
for (node = _jit->data.table[offset]; node; node = node->next) {
|
memcpy(ptr, _jit->data.ptr, _jit->data.offset);
|
||||||
node->flag |= jit_flag_patch;
|
free(_jit->data.ptr);
|
||||||
node->u.w = (jit_word_t)(_jit->data.ptr + node->u.w);
|
_jit->data.ptr = ptr;
|
||||||
}
|
|
||||||
|
/* to be filled with note contents once offsets are known */
|
||||||
|
_jit->note.base = ptr + _jit->data.offset;
|
||||||
|
memset(_jit->note.base, 0, _jit->data.length - _jit->data.offset);
|
||||||
|
|
||||||
|
for (offset = 0; offset < _jit->data.size; offset++) {
|
||||||
|
for (node = _jit->data.table[offset]; node; node = node->next) {
|
||||||
|
node->flag |= jit_flag_patch;
|
||||||
|
node->u.w = (jit_word_t)(_jit->data.ptr + node->u.w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue