Skip to content

Commit ea193b4

Browse files
authored
wasm2c: harmonize bulk mem ops re: i32/i64 (#2506) + parametrize memchecks per-memory (#2507)
The PR updates the bulk memory operations (memory.fill, memory.copy, table.fill, etc.) to support 64-bit addresses and counts. Previously these functions only took u32's, even with memory64 enabled. (#2506) This PR also allows "software-bounds-checked" memories and "guard-page-checked" memories to coexist in the same module. It creates two versions of every memory operation: an unrestricted version (that works with any memory) and a _default32 version (for memories with default page size and i32 indexing). (#2507) #2506 and #2507 have been squashed together to avoid a performance regression. This is a stepping stone to supporting custom-page-sizes (which will need to be software-bounds-checked) (#2508).
1 parent 4e7d7ef commit ea193b4

17 files changed

+1142
-631
lines changed

src/c-writer.cc

+18-1
Original file line numberDiff line numberDiff line change
@@ -1369,7 +1369,24 @@ static std::string GetMemoryTypeString(const Memory& memory) {
13691369
}
13701370

13711371
static std::string GetMemoryAPIString(const Memory& memory, std::string api) {
1372-
return memory.page_limits.is_shared ? (api + "_shared") : api;
1372+
std::string suffix;
1373+
if (memory.page_limits.is_shared) {
1374+
suffix += "_shared";
1375+
}
1376+
1377+
// Memory load and store routines can be optimized for default-page-size,
1378+
// 32-bit memories (by using hardware to bounds-check memory access).
1379+
// Append "_default32" to these function names to choose the (possibly) fast
1380+
// path.
1381+
//
1382+
// We don't need to do this for runtime routines; those can check the
1383+
// wasm_rt_memory_t structure.
1384+
if (api.substr(0, 8) != "wasm_rt_" &&
1385+
memory.page_size == WABT_DEFAULT_PAGE_SIZE &&
1386+
memory.page_limits.is_64 == false) {
1387+
suffix += "_default32";
1388+
}
1389+
return api + suffix;
13731390
}
13741391

13751392
void CWriter::WriteInitExpr(const ExprList& expr_list) {

src/prebuilt/wasm2c_atomicops_source_declarations.cc

+73-63
Large diffs are not rendered by default.

src/prebuilt/wasm2c_simd_source_declarations.cc

+26-20
Original file line numberDiff line numberDiff line change
@@ -15,56 +15,62 @@ R"w2c_template(#endif
1515
R"w2c_template(// TODO: equivalent constraint for ARM and other architectures
1616
)w2c_template"
1717
R"w2c_template(
18-
#define DEFINE_SIMD_LOAD_FUNC(name, func, t) \
18+
#define DEFINE_SIMD_LOAD_FUNC(name, func, t) \
1919
)w2c_template"
20-
R"w2c_template( static inline v128 name(wasm_rt_memory_t* mem, u64 addr) { \
20+
R"w2c_template( static inline v128 name##_unchecked(wasm_rt_memory_t* mem, u64 addr) { \
2121
)w2c_template"
22-
R"w2c_template( MEMCHECK(mem, addr, t); \
22+
R"w2c_template( v128 result = func(MEM_ADDR(mem, addr, sizeof(t))); \
2323
)w2c_template"
24-
R"w2c_template( v128 result = func(MEM_ADDR(mem, addr, sizeof(t))); \
24+
R"w2c_template( SIMD_FORCE_READ(result); \
2525
)w2c_template"
26-
R"w2c_template( SIMD_FORCE_READ(result); \
26+
R"w2c_template( return result; \
2727
)w2c_template"
28-
R"w2c_template( return result; \
28+
R"w2c_template( } \
2929
)w2c_template"
30-
R"w2c_template( }
30+
R"w2c_template( DEF_MEM_CHECKS0(name, _, t, return, v128);
3131
)w2c_template"
3232
R"w2c_template(
3333
#define DEFINE_SIMD_LOAD_LANE(name, func, t, lane) \
3434
)w2c_template"
35-
R"w2c_template( static inline v128 name(wasm_rt_memory_t* mem, u64 addr, v128 vec) { \
35+
R"w2c_template( static inline v128 name##_unchecked(wasm_rt_memory_t* mem, u64 addr, \
3636
)w2c_template"
37-
R"w2c_template( MEMCHECK(mem, addr, t); \
37+
R"w2c_template( v128 vec) { \
3838
)w2c_template"
3939
R"w2c_template( v128 result = func(MEM_ADDR(mem, addr, sizeof(t)), vec, lane); \
4040
)w2c_template"
4141
R"w2c_template( SIMD_FORCE_READ(result); \
4242
)w2c_template"
4343
R"w2c_template( return result; \
4444
)w2c_template"
45-
R"w2c_template( }
45+
R"w2c_template( } \
46+
)w2c_template"
47+
R"w2c_template( DEF_MEM_CHECKS1(name, _, t, return, v128, v128);
4648
)w2c_template"
4749
R"w2c_template(
48-
#define DEFINE_SIMD_STORE(name, t) \
50+
#define DEFINE_SIMD_STORE(name, t) \
51+
)w2c_template"
52+
R"w2c_template( static inline void name##_unchecked(wasm_rt_memory_t* mem, u64 addr, \
4953
)w2c_template"
50-
R"w2c_template( static inline void name(wasm_rt_memory_t* mem, u64 addr, v128 value) { \
54+
R"w2c_template( v128 value) { \
5155
)w2c_template"
52-
R"w2c_template( MEMCHECK(mem, addr, t); \
56+
R"w2c_template( simde_wasm_v128_store(MEM_ADDR(mem, addr, sizeof(t)), value); \
5357
)w2c_template"
54-
R"w2c_template( simde_wasm_v128_store(MEM_ADDR(mem, addr, sizeof(t)), value); \
58+
R"w2c_template( } \
5559
)w2c_template"
56-
R"w2c_template( }
60+
R"w2c_template( DEF_MEM_CHECKS1(name, _, t, , void, v128);
5761
)w2c_template"
5862
R"w2c_template(
59-
#define DEFINE_SIMD_STORE_LANE(name, func, t, lane) \
63+
#define DEFINE_SIMD_STORE_LANE(name, func, t, lane) \
64+
)w2c_template"
65+
R"w2c_template( static inline void name##_unchecked(wasm_rt_memory_t* mem, u64 addr, \
6066
)w2c_template"
61-
R"w2c_template( static inline void name(wasm_rt_memory_t* mem, u64 addr, v128 value) { \
67+
R"w2c_template( v128 value) { \
6268
)w2c_template"
63-
R"w2c_template( MEMCHECK(mem, addr, t); \
69+
R"w2c_template( func(MEM_ADDR(mem, addr, sizeof(t)), value, lane); \
6470
)w2c_template"
65-
R"w2c_template( func(MEM_ADDR(mem, addr, sizeof(t)), value, lane); \
71+
R"w2c_template( } \
6672
)w2c_template"
67-
R"w2c_template( }
73+
R"w2c_template( DEF_MEM_CHECKS1(name, _, t, , void, v128);
6874
)w2c_template"
6975
R"w2c_template(
7076
// clang-format off

0 commit comments

Comments
 (0)