Skip to content

Always use bulkmemory memcpy and memset when available #20144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 28, 2023
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
8 changes: 4 additions & 4 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,8 @@ addToLibrary({
$ENV: {},

// In -Oz builds, we replace memcpy() altogether with a non-unrolled wasm
// variant, so we should never emit emscripten_memcpy_big() in the build.
// In STANDALONE_WASM we avoid the emscripten_memcpy_big dependency so keep
// variant, so we should never emit emscripten_memcpy_js() in the build.
// In STANDALONE_WASM we avoid the emscripten_memcpy_js dependency so keep
// the wasm file standalone.
// In BULK_MEMORY mode we include native versions of these functions based
// on memory.fill and memory.copy.
Expand All @@ -407,11 +407,11 @@ addToLibrary({
// AppleWebKit/605.1.15 Safari/604.1 Version/13.0.4 iPhone OS 13_3 on iPhone 6s with iOS 13.3
// AppleWebKit/605.1.15 Version/13.0.3 Intel Mac OS X 10_15_1 on Safari 13.0.3 (15608.3.10.1.4) on macOS Catalina 10.15.1
// Hence the support status of .copyWithin() for Safari version range [10.0.0, 10.1.0] is unknown.
emscripten_memcpy_big: `= Uint8Array.prototype.copyWithin
emscripten_memcpy_js: `= Uint8Array.prototype.copyWithin
? (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num)
: (dest, src, num) => HEAPU8.set(HEAPU8.subarray(src, src+num), dest)`,
#else
emscripten_memcpy_big: (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num),
emscripten_memcpy_js: (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num),
#endif

#endif
Expand Down
2 changes: 1 addition & 1 deletion src/library_sigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ sigs = {
emscripten_math_sqrt__sig: 'dd',
emscripten_math_tan__sig: 'dd',
emscripten_math_tanh__sig: 'dd',
emscripten_memcpy_big__sig: 'vppp',
emscripten_memcpy_js__sig: 'vppp',
emscripten_navigator_hardware_concurrency__sig: 'i',
emscripten_notify_memory_growth__sig: 'vp',
emscripten_num_logical_cores__sig: 'i',
Expand Down
10 changes: 7 additions & 3 deletions system/lib/libc/emscripten_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ extern "C" {

// An external JS implementation that is efficient for very large copies, using
// HEAPU8.set()
void emscripten_memcpy_big(void* __restrict__ dest,
void emscripten_memcpy_js(void* __restrict__ dest,
const void* __restrict__ src,
size_t n) EM_IMPORT(emscripten_memcpy_big);
void emscripten_memset_big(void* ptr, char value, size_t n);
size_t n) EM_IMPORT(emscripten_memcpy_js);

void* emscripten_memcpy_bulkmem(void* __restrict__ dest,
const void* __restrict__ src,
size_t n);
void* emscripten_memset_bulkmem(void* ptr, char value, size_t n);

void emscripten_notify_memory_growth(size_t memory_index);

Expand Down
10 changes: 8 additions & 2 deletions system/lib/libc/emscripten_memcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ static void *__memcpy(void *dest, const void *src, size_t n) {
return dest;
}

#elif defined(__wasm_bulk_memory__)

static void *__memcpy(void *restrict dest, const void *restrict src, size_t n) {
return emscripten_memcpy_bulkmem(dest, src, n);
}

#else

static void *__memcpy(void *restrict dest, const void *restrict src, size_t n) {
Expand All @@ -29,9 +35,9 @@ static void *__memcpy(void *restrict dest, const void *restrict src, size_t n) {
unsigned char *block_aligned_d_end;
unsigned char *d_end;

#if !defined(EMSCRIPTEN_STANDALONE_WASM) || defined(__wasm_bulk_memory__)
#if !defined(EMSCRIPTEN_STANDALONE_WASM)
if (n >= 512) {
emscripten_memcpy_big(dest, src, n);
emscripten_memcpy_js(dest, src, n);
return dest;
}
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
#define PTR i32
#endif

.globl emscripten_memcpy_big
emscripten_memcpy_big:
.functype emscripten_memcpy_big (PTR, PTR, PTR) -> ()
.globl emscripten_memcpy_bulkmem
emscripten_memcpy_bulkmem:
.functype emscripten_memcpy_bulkmem (PTR, PTR, PTR) -> (PTR)
local.get 0
local.get 1
local.get 2
memory.copy 0, 0
local.get 0
end_function
10 changes: 1 addition & 9 deletions system/lib/libc/emscripten_memset.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,8 @@ void *__memset(void *str, int c, size_t n) {

#elif defined(__wasm_bulk_memory__)

#define memset __musl_memset
#include "musl/src/string/memset.c"
#undef memset

void *__memset(void *str, int c, size_t n) {
if (n >= 512) {
emscripten_memset_big(str, c, n);
return str;
}
return __musl_memset(str, c, n);
return emscripten_memset_bulkmem(str, c, n);
}

#else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
#define PTR i32
#endif

.globl emscripten_memset_big
emscripten_memset_big:
.functype emscripten_memset_big (PTR, i32, PTR) -> ()
.globl emscripten_memset_bulkmem
emscripten_memset_bulkmem:
.functype emscripten_memset_bulkmem (PTR, i32, PTR) -> (PTR)
local.get 0
local.get 1
local.get 2
memory.fill 0
local.get 0
end_function
5 changes: 0 additions & 5 deletions system/lib/standalone/standalone.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,6 @@ weak int getentropy(void* buffer, size_t length) {

// Emscripten additions

// Should never be called in standalone mode
weak void emscripten_memcpy_big(void *restrict dest, const void *restrict src, size_t n) {
__builtin_unreachable();
}

size_t emscripten_get_heap_max() {
// In standalone mode we don't have any wasm instructions to access the max
// memory size so the best we can do (without calling an import) is return
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_ctors1.imports
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
env.__cxa_throw
env.abort
env.emscripten_memcpy_big
env.emscripten_memcpy_js
env.emscripten_resize_heap
env.strftime_l
wasi_snapshot_preview1.environ_get
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_ctors1.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
25060
25059
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_ctors1.sent
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__cxa_throw
abort
emscripten_memcpy_big
emscripten_memcpy_js
emscripten_resize_heap
environ_get
environ_sizes_get
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_ctors1.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
123498
123497
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_ctors2.imports
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
env.__cxa_throw
env.abort
env.emscripten_memcpy_big
env.emscripten_memcpy_js
env.emscripten_resize_heap
env.strftime_l
wasi_snapshot_preview1.fd_close
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_ctors2.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
25028
25027
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_ctors2.sent
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__cxa_throw
abort
emscripten_memcpy_big
emscripten_memcpy_js
emscripten_resize_heap
environ_get
environ_sizes_get
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_ctors2.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
123403
123402
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_except.imports
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ env.__cxa_throw
env.__cxa_uncaught_exceptions
env.__resumeException
env.abort
env.emscripten_memcpy_big
env.emscripten_memcpy_js
env.emscripten_resize_heap
env.invoke_diii
env.invoke_fiii
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_except.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
29193
29192
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_except.sent
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ __cxa_throw
__cxa_uncaught_exceptions
__resumeException
abort
emscripten_memcpy_big
emscripten_memcpy_js
emscripten_resize_heap
environ_get
environ_sizes_get
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_except.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
166328
166327
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_except_wasm.imports
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
env.abort
env.emscripten_memcpy_big
env.emscripten_memcpy_js
env.emscripten_resize_heap
env.strftime_l
wasi_snapshot_preview1.environ_get
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_except_wasm.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24834
24833
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_except_wasm.sent
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
abort
emscripten_memcpy_big
emscripten_memcpy_js
emscripten_resize_heap
environ_get
environ_sizes_get
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_except_wasm.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
137117
137116
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_mangle.imports
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ env.__cxa_throw
env.__cxa_uncaught_exceptions
env.__resumeException
env.abort
env.emscripten_memcpy_big
env.emscripten_memcpy_js
env.emscripten_resize_heap
env.invoke_diii
env.invoke_fiii
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_mangle.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
29192
29191
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_mangle.sent
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ __cxa_throw
__cxa_uncaught_exceptions
__resumeException
abort
emscripten_memcpy_big
emscripten_memcpy_js
emscripten_resize_heap
environ_get
environ_sizes_get
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_mangle.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
221419
221418
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_noexcept.imports
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
env.__cxa_throw
env.abort
env.emscripten_memcpy_big
env.emscripten_memcpy_js
env.emscripten_resize_heap
env.strftime_l
wasi_snapshot_preview1.environ_get
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_noexcept.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
25060
25059
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_noexcept.sent
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__cxa_throw
abort
emscripten_memcpy_big
emscripten_memcpy_js
emscripten_resize_heap
environ_get
environ_sizes_get
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_noexcept.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
126300
126299
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_wasmfs.imports
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ env._wasmfs_stdin_get_char
env.abort
env.emscripten_date_now
env.emscripten_err
env.emscripten_memcpy_big
env.emscripten_memcpy_js
env.emscripten_out
env.emscripten_resize_heap
env.getentropy
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_wasmfs.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12469
12468
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_wasmfs.sent
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ _wasmfs_stdin_get_char
abort
emscripten_date_now
emscripten_err
emscripten_memcpy_big
emscripten_memcpy_js
emscripten_out
emscripten_resize_heap
environ_get
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_wasmfs.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
163625
163624
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O0.imports
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
env.emscripten_memcpy_big
env.emscripten_memcpy_js
wasi_snapshot_preview1.fd_write
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O0.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
23682
23681
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O0.sent
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
emscripten_memcpy_big
emscripten_memcpy_js
fd_write
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O0.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12156
12155
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O1.imports
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
env.emscripten_memcpy_big
env.emscripten_memcpy_js
wasi_snapshot_preview1.fd_write
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O1.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8094
8093
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O1.sent
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
emscripten_memcpy_big
emscripten_memcpy_js
fd_write
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O1.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2413
2412
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O2.imports
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
env.emscripten_memcpy_big
env.emscripten_memcpy_js
wasi_snapshot_preview1.fd_write
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O2.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5753
5752
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O2.sent
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
emscripten_memcpy_big
emscripten_memcpy_js
fd_write
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_O2.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2054
2053
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_dylink.imports
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ env.__indirect_function_table
env.__memory_base
env.__stack_pointer
env.__table_base
env.emscripten_memcpy_big
env.emscripten_memcpy_js
env.emscripten_resize_heap
env.memory
wasi_snapshot_preview1.fd_write
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_dylink.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
14820
14819
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_dylink.sent
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ __indirect_function_table
__memory_base
__stack_pointer
__table_base
emscripten_memcpy_big
emscripten_memcpy_js
emscripten_resize_heap
fd_write
memory
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_hello_dylink.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9377
9376
2 changes: 1 addition & 1 deletion test/other/test_unoptimized_code_size.js.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
58712
58709
2 changes: 1 addition & 1 deletion test/other/test_unoptimized_code_size.wasm.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12153
12152
2 changes: 1 addition & 1 deletion test/other/test_unoptimized_code_size_no_asserts.js.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
32008
32005
2 changes: 1 addition & 1 deletion test/other/test_unoptimized_code_size_no_asserts.wasm.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
11600
11599
2 changes: 1 addition & 1 deletion test/other/test_unoptimized_code_size_strict.js.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
57399
57396
2 changes: 1 addition & 1 deletion test/other/test_unoptimized_code_size_strict.wasm.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12153
12152
8 changes: 4 additions & 4 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -13486,11 +13486,11 @@ def run(args, expect_bulk_mem):
funcs = self.parse_wasm('test_memops_bulk_memory.wasm')[2]
js = read_file('test_memops_bulk_memory.js')
if expect_bulk_mem:
self.assertNotContained('_emscripten_memcpy_big', js)
self.assertIn('$emscripten_memcpy_big', funcs)
self.assertNotContained('_emscripten_memcpy_js', js)
self.assertIn('$emscripten_memcpy_bulkmem', funcs)
else:
self.assertContained('_emscripten_memcpy_big', js)
self.assertNotIn('$emscripten_memcpy_big', funcs)
self.assertContained('_emscripten_memcpy_js', js)
self.assertNotIn('$emscripten_memcpy_bulkmem', funcs)

# By default we expect to find _emscripten_memcpy_big in the generaed JS and not in the
# native code.
Expand Down
Loading