Skip to content

Commit 65f16e8

Browse files
committed
Forward port changes from v0.6 release branch
Merge "Fix ESP32 SPI driver about passing a term to a function expecting a non-term" (#1658) and "Reduce memory footprint of line refs" (#1654) from release-0.6.
2 parents aa68f29 + 29943ee commit 65f16e8

File tree

4 files changed

+89
-45
lines changed

4 files changed

+89
-45
lines changed

src/libAtomVM/module.c

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ static void module_add_label(Module *mod, int index, const uint8_t *ptr);
5858
static enum ModuleLoadResult module_build_imported_functions_table(Module *this_module, uint8_t *table_data, GlobalContext *glb);
5959
static void module_parse_line_table(Module *mod, const uint8_t *data, size_t len);
6060

61+
struct LineRefOffset
62+
{
63+
struct ListHead head;
64+
unsigned int offset;
65+
};
66+
6167
#define IMPL_CODE_LOADER 1
6268
#include "opcodesswitch.h"
6369
#undef TRACE
@@ -285,7 +291,6 @@ Module *module_new_from_iff_binary(GlobalContext *global, const void *iff_binary
285291
}
286292

287293
module_parse_line_table(mod, beam_file + offsets[LINT] + 8, sizes[LINT]);
288-
list_init(&mod->line_ref_offsets);
289294

290295
if (offsets[LITT]) {
291296
if (!module_are_literals_compressed(beam_file + offsets[LITT])) {
@@ -320,7 +325,40 @@ Module *module_new_from_iff_binary(GlobalContext *global, const void *iff_binary
320325
mod->free_literals_data = 0;
321326
}
322327

323-
mod->end_instruction_ii = read_core_chunk(mod);
328+
struct ListHead line_refs;
329+
list_init(&line_refs);
330+
mod->end_instruction_ii = read_core_chunk(mod, &line_refs);
331+
332+
// Create the list of offsets if the module has line informations.
333+
if (mod->line_refs_table != NULL) {
334+
// Compute the size of the list
335+
size_t num_offsets = 0;
336+
struct ListHead *item = line_refs.next;
337+
while (item != &line_refs) {
338+
num_offsets++;
339+
item = item->next;
340+
}
341+
mod->line_refs_offsets = malloc(num_offsets * sizeof(unsigned int));
342+
if (IS_NULL_PTR(mod->line_refs_offsets)) {
343+
fprintf(stderr, "Warning: Unable to allocate space for line refs offset, module has %zu offsets. Line information in stacktraces may be missing\n", num_offsets);
344+
} else {
345+
size_t index = 0;
346+
item = line_refs.next;
347+
while (item != &line_refs) {
348+
struct LineRefOffset *offset = CONTAINER_OF(item, struct LineRefOffset, head);
349+
mod->line_refs_offsets[index] = offset->offset;
350+
index++;
351+
item = item->next;
352+
}
353+
mod->line_refs_offsets_count = num_offsets;
354+
}
355+
}
356+
// Empty the list
357+
while (!list_is_empty(&line_refs)) {
358+
struct ListHead *item = line_refs.next;
359+
list_remove(item);
360+
free(item);
361+
}
324362

325363
return mod;
326364
}
@@ -331,6 +369,7 @@ COLD_FUNC void module_destroy(Module *module)
331369
free(module->imported_funcs);
332370
free(module->literals_table);
333371
free(module->local_atoms_to_global_table);
372+
free(module->line_refs_offsets);
334373
if (module->free_literals_data) {
335374
free(module->literals_data);
336375
}
@@ -718,19 +757,28 @@ static void module_parse_line_table(Module *mod, const uint8_t *data, size_t len
718757
}
719758
}
720759

721-
void module_insert_line_ref_offset(Module *mod, int line_ref, int offset)
760+
void module_insert_line_ref_offset(Module *mod, struct ListHead *line_refs, uint32_t line_ref, int offset)
722761
{
723762
if (IS_NULL_PTR(mod->line_refs_table) || line_ref == 0) {
724763
return;
725764
}
726765
struct LineRefOffset *ref_offset = malloc(sizeof(struct LineRefOffset));
727766
if (IS_NULL_PTR(ref_offset)) {
728-
fprintf(stderr, "Warning: Unable to allocate space for line ref offset. Line information in stacktraces may be missing\n");
767+
size_t num_refs = 0;
768+
// Empty the list
769+
while (!list_is_empty(line_refs)) {
770+
struct ListHead *item = line_refs->next;
771+
list_remove(item);
772+
free(item);
773+
num_refs++;
774+
}
775+
fprintf(stderr, "Warning: Unable to allocate space for an additional line ref offset (we had %zu). Line information in stacktraces may be missing\n", num_refs);
776+
// Give up having line numbers for this module.
777+
mod->line_refs_table = NULL;
729778
return;
730779
}
731-
ref_offset->line_ref = line_ref;
732780
ref_offset->offset = offset;
733-
list_append(&mod->line_ref_offsets, &ref_offset->head);
781+
list_append(line_refs, &ref_offset->head);
734782
}
735783

736784
static bool module_find_line_ref(Module *mod, uint16_t line_ref, uint32_t *line, size_t *filename_len, const uint8_t **filename)
@@ -744,30 +792,30 @@ static bool module_find_line_ref(Module *mod, uint16_t line_ref, uint32_t *line,
744792

745793
bool module_find_line(Module *mod, unsigned int offset, uint32_t *line, size_t *filename_len, const uint8_t **filename)
746794
{
747-
int i = 0;
748-
struct LineRefOffset *head = GET_LIST_ENTRY(&mod->line_ref_offsets, struct LineRefOffset, head);
749-
struct ListHead *item;
750-
LIST_FOR_EACH (item, &mod->line_ref_offsets) {
751-
struct LineRefOffset *ref_offset = GET_LIST_ENTRY(item, struct LineRefOffset, head);
752-
753-
if (offset == ref_offset->offset) {
754-
return module_find_line_ref(mod, ref_offset->line_ref, line, filename_len, filename);
755-
} else if (i == 0 && offset < ref_offset->offset) {
795+
size_t i;
796+
unsigned int ref_offset;
797+
uint32_t line_ref;
798+
const uint8_t *ref_pc;
799+
if (IS_NULL_PTR(mod->line_refs_offsets)) {
800+
return false;
801+
}
802+
for (i = 0; i < mod->line_refs_offsets_count; i++) {
803+
ref_offset = mod->line_refs_offsets[i];
804+
if (offset == ref_offset) {
805+
ref_pc = &mod->code->code[ref_offset];
806+
DECODE_LITERAL(line_ref, ref_pc);
807+
return module_find_line_ref(mod, line_ref, line, filename_len, filename);
808+
} else if (i == 0 && offset < ref_offset) {
756809
return false;
757-
} else {
758-
759-
struct LineRefOffset *prev_ref_offset = GET_LIST_ENTRY(ref_offset->head.prev, struct LineRefOffset, head);
760-
if (prev_ref_offset->offset <= offset && offset < ref_offset->offset) {
761-
return module_find_line_ref(mod, prev_ref_offset->line_ref, line, filename_len, filename);
762-
}
763-
764-
struct LineRefOffset *next_ref_offset = GET_LIST_ENTRY(ref_offset->head.next, struct LineRefOffset, head);
765-
if (next_ref_offset == head && ref_offset->offset <= offset) {
766-
return module_find_line_ref(mod, ref_offset->line_ref, line, filename_len, filename);
767-
}
810+
} else if (offset < ref_offset) {
811+
ref_offset = mod->line_refs_offsets[i - 1];
812+
ref_pc = &mod->code->code[ref_offset];
813+
DECODE_LITERAL(line_ref, ref_pc);
814+
return module_find_line_ref(mod, line_ref, line, filename_len, filename);
768815
}
769-
770-
++i;
771816
}
772-
return false;
817+
ref_offset = mod->line_refs_offsets[i - 1];
818+
ref_pc = &mod->code->code[ref_offset];
819+
DECODE_LITERAL(line_ref, ref_pc);
820+
return module_find_line_ref(mod, line_ref, line, filename_len, filename);
773821
}

src/libAtomVM/module.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,6 @@ struct ModuleFilename
8888
size_t len;
8989
};
9090

91-
struct LineRefOffset
92-
{
93-
struct ListHead head;
94-
unsigned int offset;
95-
uint16_t line_ref;
96-
};
97-
9891
struct Module
9992
{
10093
#ifdef ENABLE_ADVANCED_TRACE
@@ -113,7 +106,8 @@ struct Module
113106
size_t locations_count;
114107
const uint8_t *locations_table;
115108

116-
struct ListHead line_ref_offsets;
109+
unsigned int *line_refs_offsets;
110+
size_t line_refs_offsets_count;
117111

118112
const struct ExportedFunction **imported_funcs;
119113

@@ -391,10 +385,11 @@ bool module_get_function_from_label(Module *this_module, int label, AtomString *
391385
* is a no-op.
392386
*
393387
* @param mod the module
388+
* @param line_refs the list of line references to append to
394389
* @param line_ref the line reference (index)
395390
* @param offset the instruction offset at which the line instruction occurred.
396391
*/
397-
void module_insert_line_ref_offset(Module *mod, int line_ref, int offset);
392+
void module_insert_line_ref_offset(Module *mod, struct ListHead *line_refs, uint32_t line_ref, int offset);
398393

399394
/*
400395
* @brief Find the latest line reference (index) before or at which the instruction offset

src/libAtomVM/opcodesswitch.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,9 +1819,9 @@ static bool maybe_call_native(Context *ctx, AtomString module_name, AtomString f
18191819
#endif
18201820

18211821
#ifdef IMPL_CODE_LOADER
1822-
int read_core_chunk0(Module *mod);
1822+
int read_core_chunk0(Module *mod, struct ListHead *line_refs);
18231823

1824-
int read_core_chunk(Module *mod)
1824+
int read_core_chunk(Module *mod, struct ListHead *line_refs)
18251825
#else
18261826
#ifdef IMPL_EXECUTE_LOOP
18271827
int context_execute_loop(Context *ctx, Module *mod, const char *function_name, int arity)
@@ -1858,7 +1858,7 @@ static bool maybe_call_native(Context *ctx, AtomString module_name, AtomString f
18581858
#endif
18591859

18601860
#ifdef IMPL_CODE_LOADER
1861-
return read_core_chunk0(mod);
1861+
return read_core_chunk0(mod, line_refs);
18621862
#endif
18631863
#ifdef IMPL_EXECUTE_LOOP
18641864
// This process is the first scheduler process
@@ -1870,7 +1870,7 @@ static bool maybe_call_native(Context *ctx, AtomString module_name, AtomString f
18701870
}
18711871

18721872
#ifdef IMPL_CODE_LOADER
1873-
int read_core_chunk0(Module *mod)
1873+
int read_core_chunk0(Module *mod, struct ListHead *line_refs)
18741874
#else
18751875
#ifdef IMPL_EXECUTE_LOOP
18761876
HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
@@ -5765,15 +5765,16 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
57655765

57665766
case OP_LINE: {
57675767
#ifdef IMPL_CODE_LOADER
5768-
const uint8_t *saved_pc = pc -1;
5768+
unsigned int offset = pc - code;
57695769
#endif
57705770
uint32_t line_number;
5771+
// This decode increments pc and ensures we can decode it
57715772
DECODE_LITERAL(line_number, pc);
57725773

57735774
TRACE("line/1: %i\n", line_number);
57745775

57755776
#ifdef IMPL_CODE_LOADER
5776-
module_insert_line_ref_offset(mod, line_number, saved_pc - code);
5777+
module_insert_line_ref_offset(mod, line_refs, line_number, offset);
57775778
#endif
57785779
break;
57795780
}

src/platforms/esp32/components/avm_builtins/spi_driver.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ static NativeHandlerResult spidriver_consume_mailbox(Context *ctx)
658658
ret = OUT_OF_MEMORY_ATOM;
659659
}
660660
term unkn_a = globalcontext_make_atom(ctx->global, ATOM_STR("\xF", "unknown_command"));
661-
ret = create_pair(ctx, ERROR_ATOM, esp_err_to_term(ctx->global, unkn_a));
661+
ret = create_pair(ctx, ERROR_ATOM, unkn_a);
662662
}
663663

664664
term ret_msg;

0 commit comments

Comments
 (0)