diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 7dc3eb650e5..c80fdc1b5de 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -1331,7 +1331,6 @@ task array_list1(type: RunKonanTest) { } task hash_map0(type: RunKonanTest) { - expectedFail = (project.testTarget == 'wasm32') // The test fails on wasm32 (remainder by zero) goldValue = "OK\n" source = "runtime/collections/hash_map0.kt" } diff --git a/runtime/src/launcher/js/launcher.js b/runtime/src/launcher/js/launcher.js index 2043700ca77..01d0775dba9 100644 --- a/runtime/src/launcher/js/launcher.js +++ b/runtime/src/launcher/js/launcher.js @@ -84,6 +84,13 @@ var konan_dependencies = { Konan_heap_lower: function() { return konanStackTop; }, + Konan_heap_grow: function(pages) { + // The buffer is allocated anew on calls to grow(), + // so renew the heap array. + var oldLength = memory.grow(pages); + heap = new Uint8Array(konan_dependencies.env.memory.buffer); + return oldLength; + }, Konan_abort: function(pointer) { throw new Error("Konan_abort(" + utf8decode(toString(pointer)) + ")"); }, @@ -110,7 +117,7 @@ var konan_dependencies = { // Approximate it with write() to stdout for now. write(utf8decode(toString(str))); // TODO: write() d8 specific. }, - memory: new WebAssembly.Memory({ initial: 256 }) + memory: new WebAssembly.Memory({ initial: 256, maximum: 16384 }) } }; @@ -124,7 +131,6 @@ module.env.tablebase = 0; instance = new WebAssembly.Instance(module, konan_dependencies); memory = konan_dependencies.env.memory heap = new Uint8Array(konan_dependencies.env.memory.buffer); -heap32 = new Uint32Array(konan_dependencies.env.memory.buffer); konanStackTop = stackTop(); try { diff --git a/runtime/src/main/cpp/Porting.cpp b/runtime/src/main/cpp/Porting.cpp index 5e97be1df06..6017013205b 100644 --- a/runtime/src/main/cpp/Porting.cpp +++ b/runtime/src/main/cpp/Porting.cpp @@ -171,11 +171,14 @@ uint64_t getTimeMicros() { // This one is an interface to query module.env.memory.buffer.byteLength extern "C" unsigned long Konan_heap_upper(); extern "C" unsigned long Konan_heap_lower(); +extern "C" unsigned long Konan_heap_grow(unsigned long); #define MFAIL ((void*) ~(size_t)0) -#define WASM_PAGESIZE 65536U +#define WASM_PAGESIZE_EXPONENT 16 +#define WASM_PAGESIZE (1u << WASM_PAGESIZE_EXPONENT) #define WASM_PAGEMASK ((WASM_PAGESIZE-(size_t)1)) #define PAGE_ALIGN(value) ((value + WASM_PAGEMASK) & ~(WASM_PAGEMASK)) +#define IN_PAGES(value) (value >> WASM_PAGESIZE_EXPONENT) void* moreCore(int size) { static int initialized = 0; @@ -184,7 +187,6 @@ void* moreCore(int size) { if (!initialized) { sbrk_top = (void*)PAGE_ALIGN(Konan_heap_lower()); - upperHeapLimit = (void*)Konan_heap_upper(); initialized = 1; } @@ -197,12 +199,12 @@ void* moreCore(int size) { size = PAGE_ALIGN(size); void* old_sbrk_top = sbrk_top; + long excess = (char*)sbrk_top + size - (char*)Konan_heap_upper(); + if (excess > 0) { + Konan_heap_grow(IN_PAGES(PAGE_ALIGN(excess))); + } sbrk_top = (char*)sbrk_top + size; - if (((char*)sbrk_top - (char*)upperHeapLimit) >= 0) { - // TODO: Consider using grow() and .maximum Memory settings. - abort(); - } return old_sbrk_top; }