Skip to content

Commit c6080b0

Browse files
committed
Remove unnecessary computed gotos
The computed goto is a GCC extension that isn't implemented by clang when targeting wasm. Recent versions of emscripten failed to optimize it. In fact, the emulator didn't need it and it can be replaced with a simple boolean when waiting with timeout. Signed-off-by: Paul Guyot <[email protected]>
1 parent f6d5d16 commit c6080b0

File tree

2 files changed

+19
-44
lines changed

2 files changed

+19
-44
lines changed

src/libAtomVM/context.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ struct Context
139139
unsigned int has_max_heap_size : 1;
140140

141141
bool trap_exit : 1;
142+
#ifndef AVM_NO_EMU
143+
bool waiting_with_timeout : 1;
144+
#endif
142145
#ifdef ENABLE_ADVANCED_TRACE
143146
unsigned int trace_calls : 1;
144147
unsigned int trace_call_args : 1;

src/libAtomVM/opcodesswitch.h

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,7 @@ static void destroy_extended_registers(Context *ctx, unsigned int live)
11001100
#define PROCESS_SIGNAL_MESSAGES() \
11011101
{ \
11021102
MailboxMessage *signal_message = mailbox_process_outer_list(&ctx->mailbox); \
1103-
void *next_label = NULL; \
1103+
bool handle_error = false; \
11041104
bool reprocess_outer = false; \
11051105
while (signal_message) { \
11061106
switch (signal_message->type) { \
@@ -1113,7 +1113,7 @@ static void destroy_extended_registers(Context *ctx, unsigned int live)
11131113
case GCSignal: { \
11141114
if (UNLIKELY(memory_ensure_free_opt(ctx, 0, MEMORY_FORCE_SHRINK) != MEMORY_GC_OK)) { \
11151115
SET_ERROR(OUT_OF_MEMORY_ATOM); \
1116-
next_label = &&handle_error; \
1116+
handle_error = true; \
11171117
} \
11181118
break; \
11191119
} \
@@ -1128,15 +1128,15 @@ static void destroy_extended_registers(Context *ctx, unsigned int live)
11281128
= CONTAINER_OF(signal_message, struct TermSignal, base); \
11291129
if (UNLIKELY(!context_process_signal_trap_answer(ctx, trap_answer))) { \
11301130
SET_ERROR(OUT_OF_MEMORY_ATOM); \
1131-
next_label = &&handle_error; \
1131+
handle_error = true; \
11321132
} \
11331133
break; \
11341134
} \
11351135
case TrapExceptionSignal: { \
11361136
struct ImmediateSignal *trap_exception \
11371137
= CONTAINER_OF(signal_message, struct ImmediateSignal, base); \
11381138
SET_ERROR(trap_exception->immediate); \
1139-
next_label = &&handle_error; \
1139+
handle_error = true; \
11401140
break; \
11411141
} \
11421142
case FlushMonitorSignal: \
@@ -1152,7 +1152,7 @@ static void destroy_extended_registers(Context *ctx, unsigned int live)
11521152
= CONTAINER_OF(signal_message, struct TermSignal, base); \
11531153
if (UNLIKELY(!context_process_signal_set_group_leader(ctx, group_leader))) { \
11541154
SET_ERROR(OUT_OF_MEMORY_ATOM); \
1155-
next_label = &&handle_error; \
1155+
handle_error = true; \
11561156
} \
11571157
break; \
11581158
} \
@@ -1231,8 +1231,8 @@ static void destroy_extended_registers(Context *ctx, unsigned int live)
12311231
if (context_get_flags(ctx, Killed)) { \
12321232
goto terminate_context; \
12331233
} \
1234-
if (next_label) { \
1235-
goto *next_label; \
1234+
if (handle_error) { \
1235+
goto handle_error; \
12361236
} \
12371237
if (context_get_flags(ctx, Trap)) { \
12381238
SCHEDULE_WAIT_ANY(mod); \
@@ -1920,26 +1920,16 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
19201920
}
19211921
#endif
19221922

1923-
#pragma GCC diagnostic push
1924-
#pragma GCC diagnostic ignored "-Wpedantic"
1925-
// Handle traps.
1926-
if (ctx->restore_trap_handler) {
1927-
#if AVM_NO_JIT
1928-
goto *ctx->restore_trap_handler;
1929-
#elif AVM_NO_EMU
1930-
native_pc = ctx->restore_trap_handler;
1931-
#else
1932-
if (mod->native_code == NULL) {
1933-
goto *ctx->restore_trap_handler;
1934-
} else {
1935-
native_pc = ctx->restore_trap_handler;
1936-
}
1937-
#endif
1923+
// Handle waiting timeout
1924+
#ifndef AVM_NO_EMU
1925+
if (ctx->waiting_with_timeout) {
1926+
goto wait_timeout_trap_handler;
19381927
} else {
1928+
#endif
19391929
// Handle signals
19401930
PROCESS_SIGNAL_MESSAGES();
1931+
#ifndef AVM_NO_EMU
19411932
}
1942-
#pragma GCC diagnostic pop
19431933
#endif
19441934

19451935
#ifdef IMPL_CODE_LOADER
@@ -2728,10 +2718,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
27282718
if (context_get_flags(ctx, WaitingTimeout | WaitingTimeoutExpired)) {
27292719
scheduler_cancel_timeout(ctx);
27302720
}
2731-
#pragma GCC diagnostic push
2732-
#pragma GCC diagnostic ignored "-Wpedantic"
27332721
PROCESS_SIGNAL_MESSAGES();
2734-
#pragma GCC diagnostic pop
27352722
mailbox_remove_message(&ctx->mailbox, &ctx->heap);
27362723
// Cannot GC now as remove_message is GC neutral
27372724
#endif
@@ -2759,10 +2746,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
27592746

27602747
#ifdef IMPL_EXECUTE_LOOP
27612748
term ret;
2762-
#pragma GCC diagnostic push
2763-
#pragma GCC diagnostic ignored "-Wpedantic"
27642749
PROCESS_SIGNAL_MESSAGES();
2765-
#pragma GCC diagnostic pop
27662750
if (mailbox_peek(ctx, &ret)) {
27672751
TRACE_RECEIVE(ctx, ret);
27682752

@@ -2782,10 +2766,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
27822766
USED_BY_TRACE(label);
27832767

27842768
#ifdef IMPL_EXECUTE_LOOP
2785-
#pragma GCC diagnostic push
2786-
#pragma GCC diagnostic ignored "-Wpedantic"
27872769
PROCESS_SIGNAL_MESSAGES();
2788-
#pragma GCC diagnostic pop
27892770
mailbox_next(&ctx->mailbox);
27902771
pc = mod->labels[label];
27912772
#endif
@@ -2830,10 +2811,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
28302811
}
28312812
TRACE("wait_timeout/2, label: %i, timeout: %li\n", label, (long int) t);
28322813

2833-
#pragma GCC diagnostic push
2834-
#pragma GCC diagnostic ignored "-Wpedantic"
28352814
PROCESS_SIGNAL_MESSAGES();
2836-
#pragma GCC diagnostic pop
28372815
int needs_to_wait = 0;
28382816
if (context_get_flags(ctx, WaitingTimeout | WaitingTimeoutExpired) == 0) {
28392817
if (timeout != INFINITY_ATOM) {
@@ -2847,10 +2825,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
28472825
}
28482826

28492827
if (needs_to_wait) {
2850-
#pragma GCC diagnostic push
2851-
#pragma GCC diagnostic ignored "-Wpedantic"
2852-
ctx->restore_trap_handler = &&wait_timeout_trap_handler;
2853-
#pragma GCC diagnostic pop
2828+
ctx->waiting_with_timeout = true;
28542829
SCHEDULE_WAIT(mod, saved_pc);
28552830
} else {
28562831
JUMP_TO_ADDRESS(mod->labels[label]);
@@ -2877,20 +2852,17 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
28772852
int timeout;
28782853
DECODE_COMPACT_TERM(timeout, pc)
28792854
TRACE("wait_timeout_trap_handler, label: %i\n", label);
2880-
#pragma GCC diagnostic push
2881-
#pragma GCC diagnostic ignored "-Wpedantic"
28822855
PROCESS_SIGNAL_MESSAGES();
2883-
#pragma GCC diagnostic pop
28842856
if (context_get_flags(ctx, WaitingTimeoutExpired)) {
2885-
ctx->restore_trap_handler = NULL;
2857+
ctx->waiting_with_timeout = false;
28862858
} else {
28872859
if (UNLIKELY(!mailbox_has_next(&ctx->mailbox))) {
28882860
// No message is here.
28892861
// We were signaled for another reason.
28902862
ctx = scheduler_wait(ctx);
28912863
goto schedule_in;
28922864
} else {
2893-
ctx->restore_trap_handler = NULL;
2865+
ctx->waiting_with_timeout = false;
28942866
JUMP_TO_ADDRESS(mod->labels[label]);
28952867
}
28962868
}

0 commit comments

Comments
 (0)