Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 3 additions & 51 deletions system/lib/compiler-rt/stack_limits.S
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
#endif

.globaltype __stack_pointer, PTR
.globl __stack_pointer

.section .globals,"",@

# TODO(sbc): It would be nice if these we initialized directly
# using PTR.const rather than using the `emscripten_stack_init`
.globaltype __stack_end, PTR
__stack_end:
.globl __stack_end
.globaltype __stack_base, PTR
.globl __stack_base
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love that these are now globals symbols...I wish we could find a way to avoid the need for divergence here between wasm workers and pthreads, but for now this seems reasonable.

__stack_base:

.section .text,"",@
Expand Down Expand Up @@ -82,57 +85,6 @@ emscripten_stack_get_free:
PTR.sub
end_function

#ifdef __EMSCRIPTEN_WASM_WORKERS__
# TODO: Relocate the following to its own file wasm_worker.S, but need to figure out how to reference
# __stack_base and __stack_end globals from a separate file as externs in order for that to work.
.globl _emscripten_wasm_worker_initialize
_emscripten_wasm_worker_initialize:
.functype _emscripten_wasm_worker_initialize (PTR /*stackLowestAddress*/, i32 /*stackSize*/) -> ()

// __stack_end = stackLowestAddress + (__builtin_wasm_tls_size() + 15) & -16;
local.get 0
.globaltype __tls_size, PTR, immutable
global.get __tls_size
PTR.add
PTR.const 0xf
PTR.add
PTR.const -0x10
PTR.and
global.set __stack_end

// __stack_base = stackLowestAddress + stackSize;
local.get 0
local.get 1
#ifdef __wasm64__
i64.extend_i32_u
#endif
PTR.add
global.set __stack_base

// TODO: We'd like to do this here to avoid JS side calls to __set_stack_limits.
// (or even better, we'd like to avoid duplicate versions of the stack variables)
// See https://github.com/emscripten-core/emscripten/issues/16496
// global.get __stack_base
// global.get __stack_end
// .functype __set_stack_limits (PTR, PTR) -> ()
// call __set_stack_limits

// __wasm_init_tls(stackLowestAddress);
local.get 0
.functype __wasm_init_tls (PTR) -> ()
call __wasm_init_tls

// N.b. The function __wasm_init_tls above does not need
// __stack_pointer initialized, and it destroys the value it was set to.
// So we must initialize __stack_pointer only *after* completing __wasm_init_tls:

// __stack_pointer = __stack_base;
global.get __stack_base
global.set __stack_pointer

end_function
#endif

# Add emscripten_stack_init to static ctors
.section .init_array.1,"",@
.p2align ALIGN
Expand Down
3 changes: 1 addition & 2 deletions system/lib/dlmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@
/* XXX Emscripten Tracing API. This defines away the code if tracing is disabled. */
#include <emscripten/trace.h>

#ifdef __EMSCRIPTEN_WASM_WORKERS__
#ifdef __EMSCRIPTEN_SHARED_MEMORY__
#define USE_LOCKS 1
#endif

/* Make malloc() and free() threadsafe by securing the memory allocations with pthread mutexes. */
#if __EMSCRIPTEN_PTHREADS__
#define USE_LOCKS 1
#define USE_SPIN_LOCKS 0 // Ensure we use pthread_mutex_t.
#endif

Expand Down
64 changes: 64 additions & 0 deletions system/lib/wasm_worker/wasm_worker_initialize.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.extern __stack_pointer
.extern __stack_base
.extern __stack_end

#ifdef __wasm64__
#define PTR i64
#define ALIGN 3
#define PTRSTORE .int64
#else
#define PTR i32
#define ALIGN 2
#define PTRSTORE .int32
#endif

.globaltype __stack_pointer, PTR
.globaltype __stack_end, PTR
.globaltype __stack_base, PTR

.globl _emscripten_wasm_worker_initialize
_emscripten_wasm_worker_initialize:
.functype _emscripten_wasm_worker_initialize (PTR /*stackLowestAddress*/, i32 /*stackSize*/) -> ()

// __stack_end = stackLowestAddress + (__builtin_wasm_tls_size() + 15) & -16;
local.get 0
.globaltype __tls_size, PTR, immutable
global.get __tls_size
PTR.add
PTR.const 0xf
PTR.add
PTR.const -0x10
PTR.and
global.set __stack_end

// __stack_base = stackLowestAddress + stackSize;
local.get 0
local.get 1
#ifdef __wasm64__
i64.extend_i32_u
#endif
PTR.add
global.set __stack_base

// TODO: We'd like to do this here to avoid JS side calls to __set_stack_limits.
// (or even better, we'd like to avoid duplicate versions of the stack variables)
// See https://github.com/emscripten-core/emscripten/issues/16496
// global.get __stack_base
// global.get __stack_end
// .functype __set_stack_limits (PTR, PTR) -> ()
// call __set_stack_limits

// __wasm_init_tls(stackLowestAddress);
local.get 0
.functype __wasm_init_tls (PTR) -> ()
call __wasm_init_tls

// N.b. The function __wasm_init_tls above does not need
// __stack_pointer initialized, and it destroys the value it was set to.
// So we must initialize __stack_pointer only *after* completing __wasm_init_tls:

// __stack_pointer = __stack_base;
global.get __stack_base
global.set __stack_pointer

end_function
2 changes: 2 additions & 0 deletions test/core/test_dlfcn_self.exports
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ __progname_full
__sig_actions
__sig_pending
__signgam
__stack_base
__stack_chk_guard
__stack_end
__threwValue
__timezone
__tzname
Expand Down
2 changes: 1 addition & 1 deletion test/core/test_em_asm_unicode.out
Original file line number Diff line number Diff line change
@@ -1 +1 @@
hello world…
hello world…
2 changes: 1 addition & 1 deletion test/core/test_longjmp.out
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
first
result: 1 1
second
result: 2 -1
result: 2 -1
2 changes: 1 addition & 1 deletion tools/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -1413,7 +1413,7 @@ def phase_linker_setup(options, state, newargs):
'removeRunDependency',
]

if settings.SHARED_MEMORY or settings.RELOCATABLE or settings.ASYNCIFY_LAZY_LOAD_CODE:
if settings.PTHREADS or settings.WASM_WORKERS or settings.RELOCATABLE or settings.ASYNCIFY_LAZY_LOAD_CODE:
settings.IMPORTED_MEMORY = 1

set_initial_memory()
Expand Down
21 changes: 18 additions & 3 deletions tools/system_libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,12 +742,17 @@ def vary_on(cls):

@classmethod
def get_default_variation(cls, **kwargs):
return super().get_default_variation(is_mt=settings.PTHREADS, is_ww=settings.WASM_WORKERS and not settings.PTHREADS, **kwargs)
return super().get_default_variation(
is_mt=settings.PTHREADS,
is_ww=settings.SHARED_MEMORY and not settings.PTHREADS,
**kwargs
)

@classmethod
def variations(cls):
combos = super(MTLibrary, cls).variations()
# To save on # of variations, pthreads and Wasm workers when used together, just use pthreads variation.

# These are mutually exclusive, only one flag will be set at any give time.
return [combo for combo in combos if not combo['is_mt'] or not combo['is_ww']]


Expand Down Expand Up @@ -1452,9 +1457,19 @@ def get_default_variation(cls, **kwargs):
return super().get_default_variation(stub=not settings.WASM_WORKERS, **kwargs)

def get_files(self):
files = []
if self.is_stub:
files = [
'library_wasm_worker_stub.c'
]
else:
files = [
'library_wasm_worker.c',
'wasm_worker_initialize.S',
]
return files_in_path(
path='system/lib/wasm_worker',
filenames=['library_wasm_worker_stub.c' if self.is_stub else 'library_wasm_worker.c'])
filenames=files)

def can_use(self):
# see src/library_wasm_worker.js
Expand Down
Loading