2 * Copyright (C) 2013-2023 Free Software Foundation, Inc.
4 * This file is part of GNU lightning.
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
17 * Paulo Cesar Pereira de Andrade
20 #include <lightning.h>
21 #include <lightning/jit_private.h>
26 #define new_note(u, v) _new_note(_jit, u, v)
27 static jit_note_t *_new_note(jit_state_t *, jit_uint8_t*, char*);
28 static void new_line(jit_int32_t,jit_note_t*,char*,jit_int32_t,jit_int32_t);
29 #define note_search_index(u) _note_search_index(_jit, u)
30 static jit_int32_t _note_search_index(jit_state_t*, jit_uint8_t*);
31 static jit_int32_t line_insert_index(jit_note_t*,jit_int32_t);
32 static jit_int32_t line_search_index(jit_note_t*,jit_int32_t);
33 static jit_int32_t offset_insert_index(jit_line_t*,jit_int32_t);
34 static jit_int32_t offset_search_index(jit_line_t*,jit_int32_t);
50 _jit_name(jit_state_t *_jit, const char *name)
54 node = jit_new_node(jit_code_name);
56 node->v.n = jit_data(name, strlen(name) + 1, 1);
59 if (_jitc->note.head == NULL)
60 _jitc->note.head = _jitc->note.tail = node;
62 _jitc->note.tail->link = node;
63 _jitc->note.tail = node;
66 _jitc->note.size += sizeof(jit_note_t);
67 /* remember previous note is invalid due to name change */
68 _jitc->note.note = NULL;
69 return (_jitc->note.name = node);
73 _jit_note(jit_state_t *_jit, const char *name, int line)
77 node = jit_new_node(jit_code_note);
79 node->v.n = jit_data(name, strlen(name) + 1, 1);
83 if (_jitc->note.head == NULL)
84 _jitc->note.head = _jitc->note.tail = node;
86 _jitc->note.tail->link = node;
87 _jitc->note.tail = node;
89 if (_jitc->note.note == NULL ||
90 (name == NULL && _jitc->note.note != NULL) ||
91 (name != NULL && _jitc->note.note == NULL) ||
92 (name != NULL && _jitc->note.note != NULL &&
93 strcmp(name, (char *)_jitc->data.ptr + _jitc->note.note->v.n->u.w)))
94 _jitc->note.size += sizeof(jit_line_t);
95 _jitc->note.size += sizeof(jit_int32_t) * 2;
96 return (_jitc->note.note = node);
100 _jit_annotate(jit_state_t *_jit)
106 jit_word_t note_offset;
107 jit_word_t line_offset;
109 /* initialize pointers in mmaped data area */
110 _jit->note.ptr = (jit_note_t *)_jitc->note.base;
111 _jit->note.length = 0;
114 for (node = _jitc->note.head; node; node = node->link) {
115 if (node->code == jit_code_name)
116 note = new_note(node->u.p, node->v.p ? node->v.n->u.p : NULL);
117 else if (node->v.p) {
119 note = new_note(node->u.p, NULL);
120 jit_set_note(note, node->v.n->u.p, node->w.w,
121 (jit_uint8_t *)node->u.p - note->code);
126 note->size = _jit->pc.uc - note->code;
128 /* annotations may be very complex with conditions to extend
129 * or ignore redundant notes, as well as add entries to earlier
130 * notes, so, relocate the information to the data buffer,
131 * with likely over allocated reserved space */
133 /* relocate jit_line_t objects */
134 for (note_offset = 0; note_offset < _jit->note.length; note_offset++) {
135 note = _jit->note.ptr + note_offset;
136 if ((length = sizeof(jit_line_t) * note->length) == 0)
138 assert(_jitc->note.base + length <= _jit->data.ptr + _jit->data.length);
139 jit_memcpy(_jitc->note.base, note->lines, length);
140 jit_free((jit_pointer_t *)¬e->lines);
141 note->lines = (jit_line_t *)_jitc->note.base;
142 _jitc->note.base += length;
145 /* relocate offset and line number information */
146 for (note_offset = 0; note_offset < _jit->note.length; note_offset++) {
147 note = _jit->note.ptr + note_offset;
148 for (line_offset = 0; line_offset < note->length; line_offset++) {
149 line = note->lines + line_offset;
150 length = sizeof(jit_int32_t) * line->length;
151 assert(_jitc->note.base + length <=
152 _jit->data.ptr + _jit->data.length);
153 jit_memcpy(_jitc->note.base, line->linenos, length);
154 jit_free((jit_pointer_t *)&line->linenos);
155 line->linenos = (jit_int32_t *)_jitc->note.base;
156 _jitc->note.base += length;
157 assert(_jitc->note.base + length <=
158 _jit->data.ptr + _jit->data.length);
159 jit_memcpy(_jitc->note.base, line->offsets, length);
160 jit_free((jit_pointer_t *)&line->offsets);
161 line->offsets = (jit_int32_t *)_jitc->note.base;
162 _jitc->note.base += length;
168 _jit_set_note(jit_state_t *_jit, jit_note_t *note,
169 char *file, int lineno, jit_int32_t offset)
174 index = line_insert_index(note, offset);
175 if (note->length && index == note->length &&
176 note->lines[index - 1].file == file)
178 if (index >= note->length || note->lines[index].file != file)
179 new_line(index, note, file, lineno, offset);
181 line = note->lines + index;
182 index = offset_insert_index(line, offset);
183 if (index < line->length && line->offsets[index] == offset) {
184 /* common case if no code was generated for several source lines */
185 if (line->linenos[index] < lineno)
186 line->linenos[index] = lineno;
188 else if (index < line->length && line->linenos[index] == lineno) {
189 /* common case of extending entry */
190 if (line->offsets[index] > offset)
191 line->offsets[index] = offset;
194 /* line or offset changed */
195 if ((line->length & 15) == 0) {
196 jit_realloc((jit_pointer_t *)&line->linenos,
197 line->length * sizeof(jit_int32_t),
198 (line->length + 17) * sizeof(jit_int32_t));
199 jit_realloc((jit_pointer_t *)&line->offsets,
200 line->length * sizeof(jit_int32_t),
201 (line->length + 17) * sizeof(jit_int32_t));
203 if (index < note->length) {
204 jit_memmove(line->linenos + index + 1, line->linenos + index,
205 sizeof(jit_int32_t) * (line->length - index));
206 jit_memmove(line->offsets + index + 1, line->offsets + index,
207 sizeof(jit_int32_t) * (line->length - index));
209 line->linenos[index] = lineno;
210 line->offsets[index] = offset;
217 _jit_get_note(jit_state_t *_jit, jit_pointer_t code,
218 char **name, char **file, jit_int32_t *lineno)
225 if ((index = note_search_index((jit_uint8_t *)code)) >= _jit->note.length)
227 note = _jit->note.ptr + index;
228 if ((jit_uint8_t *)code < note->code ||
229 (jit_uint8_t *)code >= note->code + note->size)
231 offset = (jit_uint8_t *)code - note->code;
232 if ((index = line_search_index(note, offset)) >= note->length)
234 if (index == 0 && offset < note->lines[0].offsets[0])
236 line = note->lines + index;
237 if ((index = offset_search_index(line, offset)) >= line->length)
245 *lineno = line->linenos[index];
251 _new_note(jit_state_t *_jit, jit_uint8_t *code, char *name)
256 if (_jit->note.length) {
257 prev = _jit->note.ptr + _jit->note.length - 1;
258 assert(code >= prev->code);
259 prev->size = code - prev->code;
261 note = (jit_note_t *)_jitc->note.base;
262 _jitc->note.base += sizeof(jit_note_t);
271 new_line(jit_int32_t index, jit_note_t *note,
272 char *file, jit_int32_t lineno, jit_int32_t offset)
276 if (note->lines == NULL)
277 jit_alloc((jit_pointer_t *)¬e->lines, 16 * sizeof(jit_line_t));
278 else if ((note->length & 15) == 15)
279 jit_realloc((jit_pointer_t *)¬e->lines,
280 note->length * sizeof(jit_line_t),
281 (note->length + 17) * sizeof(jit_line_t));
283 if (index < note->length)
284 jit_memmove(note->lines + index + 1, note->lines + index,
285 sizeof(jit_line_t) * (note->length - index));
286 line = note->lines + index;
291 jit_alloc((jit_pointer_t *)&line->linenos, 16 * sizeof(jit_int32_t));
292 line->linenos[0] = lineno;
293 jit_alloc((jit_pointer_t *)&line->offsets, 16 * sizeof(jit_int32_t));
294 line->offsets[0] = offset;
298 _note_search_index(jit_state_t *_jit, jit_uint8_t *code)
306 top = _jit->note.length;
307 notes = _jit->note.ptr;
308 for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
309 if (code < notes[index].code)
311 else if (code >= notes[index].code &&
312 code - notes[index].code < notes[index].size)
322 line_insert_index(jit_note_t *note, jit_int32_t offset)
331 if ((lines = note->lines) == NULL)
333 for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
334 if (offset < *lines[index].offsets)
340 return ((bot + top) >> 1);
344 line_search_index(jit_note_t *note, jit_int32_t offset)
353 if ((lines = note->lines) == NULL)
355 for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
356 if (offset < *lines[index].offsets)
358 /* offset should be already verified to be in range */
359 else if (index == note->length - 1 ||
360 (offset >= *lines[index].offsets &&
361 offset < *lines[index + 1].offsets))
371 offset_insert_index(jit_line_t *line, jit_int32_t offset)
376 jit_int32_t *offsets;
380 offsets = line->offsets;
381 for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
382 if (offset < offsets[index])
388 return ((bot + top) >> 1);
392 offset_search_index(jit_line_t *line, jit_int32_t offset)
397 jit_int32_t *offsets;
401 offsets = line->offsets;
402 for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) {
403 if (offset < offsets[index])
405 /* offset should be already verified to be in range */
406 else if (index == line->length - 1 ||
407 (offset >= offsets[index] && offset < offsets[index + 1]))