Skip to content

Commit 8b5e393

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 8b5e393

File tree

3 files changed

+25
-47
lines changed

3 files changed

+25
-47
lines changed

src/libAtomVM/context.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ Context *context_new(GlobalContext *glb)
9696
#else
9797
ctx->saved_function_ptr = NULL;
9898
#endif
99-
ctx->restore_trap_handler = NULL;
99+
#ifndef AVM_NO_EMU
100+
ctx->waiting_with_timeout = false;
101+
#endif
100102

101103
ctx->leader = 0;
102104

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: 19 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ extern "C" {
6666
#define SET_ERROR(error_type_atom) \
6767
x_regs[0] = ERROR_ATOM; \
6868
x_regs[1] = error_type_atom; \
69-
x_regs[2] = stacktrace_create_raw(ctx, mod, native_pc - mod->native_code, ERROR_ATOM);
69+
x_regs[2] = stacktrace_create_raw(ctx, mod, (const uint8_t *) native_pc - (const uint8_t *) mod->native_code, ERROR_ATOM);
7070
#else
7171
#define SET_ERROR(error_type_atom) \
7272
x_regs[0] = ERROR_ATOM; \
7373
x_regs[1] = error_type_atom; \
7474
if (mod->native_code) { \
75-
x_regs[2] = stacktrace_create_raw(ctx, mod, native_pc - mod->native_code, ERROR_ATOM); \
75+
x_regs[2] = stacktrace_create_raw(ctx, mod, (const uint8_t *) native_pc - (const uint8_t *) mod->native_code, ERROR_ATOM); \
7676
} else { \
7777
x_regs[2] = stacktrace_create_raw(ctx, mod, pc - code, ERROR_ATOM); \
7878
}
@@ -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,17 @@ 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
1933+
#endif
19431934
#endif
19441935

19451936
#ifdef IMPL_CODE_LOADER
@@ -2728,10 +2719,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
27282719
if (context_get_flags(ctx, WaitingTimeout | WaitingTimeoutExpired)) {
27292720
scheduler_cancel_timeout(ctx);
27302721
}
2731-
#pragma GCC diagnostic push
2732-
#pragma GCC diagnostic ignored "-Wpedantic"
27332722
PROCESS_SIGNAL_MESSAGES();
2734-
#pragma GCC diagnostic pop
27352723
mailbox_remove_message(&ctx->mailbox, &ctx->heap);
27362724
// Cannot GC now as remove_message is GC neutral
27372725
#endif
@@ -2759,10 +2747,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
27592747

27602748
#ifdef IMPL_EXECUTE_LOOP
27612749
term ret;
2762-
#pragma GCC diagnostic push
2763-
#pragma GCC diagnostic ignored "-Wpedantic"
27642750
PROCESS_SIGNAL_MESSAGES();
2765-
#pragma GCC diagnostic pop
27662751
if (mailbox_peek(ctx, &ret)) {
27672752
TRACE_RECEIVE(ctx, ret);
27682753

@@ -2782,10 +2767,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
27822767
USED_BY_TRACE(label);
27832768

27842769
#ifdef IMPL_EXECUTE_LOOP
2785-
#pragma GCC diagnostic push
2786-
#pragma GCC diagnostic ignored "-Wpedantic"
27872770
PROCESS_SIGNAL_MESSAGES();
2788-
#pragma GCC diagnostic pop
27892771
mailbox_next(&ctx->mailbox);
27902772
pc = mod->labels[label];
27912773
#endif
@@ -2830,10 +2812,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
28302812
}
28312813
TRACE("wait_timeout/2, label: %i, timeout: %li\n", label, (long int) t);
28322814

2833-
#pragma GCC diagnostic push
2834-
#pragma GCC diagnostic ignored "-Wpedantic"
28352815
PROCESS_SIGNAL_MESSAGES();
2836-
#pragma GCC diagnostic pop
28372816
int needs_to_wait = 0;
28382817
if (context_get_flags(ctx, WaitingTimeout | WaitingTimeoutExpired) == 0) {
28392818
if (timeout != INFINITY_ATOM) {
@@ -2847,10 +2826,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
28472826
}
28482827

28492828
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
2829+
ctx->waiting_with_timeout = true;
28542830
SCHEDULE_WAIT(mod, saved_pc);
28552831
} else {
28562832
JUMP_TO_ADDRESS(mod->labels[label]);
@@ -2877,20 +2853,17 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
28772853
int timeout;
28782854
DECODE_COMPACT_TERM(timeout, pc)
28792855
TRACE("wait_timeout_trap_handler, label: %i\n", label);
2880-
#pragma GCC diagnostic push
2881-
#pragma GCC diagnostic ignored "-Wpedantic"
28822856
PROCESS_SIGNAL_MESSAGES();
2883-
#pragma GCC diagnostic pop
28842857
if (context_get_flags(ctx, WaitingTimeoutExpired)) {
2885-
ctx->restore_trap_handler = NULL;
2858+
ctx->waiting_with_timeout = false;
28862859
} else {
28872860
if (UNLIKELY(!mailbox_has_next(&ctx->mailbox))) {
28882861
// No message is here.
28892862
// We were signaled for another reason.
28902863
ctx = scheduler_wait(ctx);
28912864
goto schedule_in;
28922865
} else {
2893-
ctx->restore_trap_handler = NULL;
2866+
ctx->waiting_with_timeout = false;
28942867
JUMP_TO_ADDRESS(mod->labels[label]);
28952868
}
28962869
}

0 commit comments

Comments
 (0)