diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 55 | ||||
-rw-r--r-- | src/compiler.js | 2 | ||||
-rw-r--r-- | src/dlmalloc.c | 5 | ||||
-rw-r--r-- | src/library.js | 20 | ||||
-rw-r--r-- | src/parseTools.js | 1 | ||||
-rw-r--r-- | src/runtime.js | 3 |
6 files changed, 61 insertions, 25 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index 4aac53a8..6fd7ef66 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -788,26 +788,49 @@ function analyzer(data, sidePass) { delete item.allocatedSize; } func.initialStack = index; - // We need to note if stack allocations other than initial allocs can happen here - // (for example, via alloca). If so, we need to rewind the stack when we leave. func.otherStackAllocations = false; - var finishedInitial = false; - for (var i = 0; i < lines.length; i++) { - var item = lines[i].value; - if (!item || item.intertype != 'alloca') { - finishedInitial = true; - continue; + while (func.initialStack == 0) { // one-time loop with possible abort in the middle + // If there is no obvious need for stack management, perhaps we don't need it + // (we try to optimize that way with SKIP_STACK_IN_SMALL). However, + // we need to note if stack allocations other than initial allocs can happen here + // If so, we need to rewind the stack when we leave. + + // By-value params are causes of additional allocas (although we could in theory make them normal allocas too) + func.params.forEach(function(param) { + if (param.byVal) { + func.otherStackAllocations = true; + } + }); + if (func.otherStackAllocations) break; + + // Allocas + var finishedInitial = false; + for (var i = 0; i < lines.length; i++) { + var item = lines[i].value; + if (!item || item.intertype != 'alloca') { + finishedInitial = true; + continue; + } + if (item.intertype == 'alloca' && finishedInitial) { + func.otherStackAllocations = true; + break; + } } - if (item.intertype == 'alloca' && finishedInitial) { - func.otherStackAllocations = true; + if (func.otherStackAllocations) break; + + // Varargs + for (var i = 0; i < lines.length; i++) { + var item = lines[i]; + if (item.value) item = item.value; + if (item.intertype == 'call' && isVarArgsFunctionType(item.type)) { + func.otherStackAllocations = true; + break; + } } + if (func.otherStackAllocations) break; + + break; } - // by-value params are also causes of additional allocas (although we could in theory make them normal allocas too) - func.params.forEach(function(param) { - if (param.byVal) { - func.otherStackAllocations = true; - } - }); }); this.forwardItem(data, 'Relooper'); } diff --git a/src/compiler.js b/src/compiler.js index 655fd9a6..bf9d9c54 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -8,7 +8,7 @@ try { } catch(e) {} -// The environment setup code appears here, in shell.js, and in tests/hello_world.js because it can't be shared. Keep them in sync! +// The environment setup code appears here, in shell.js, in js_optimizer.js and in tests/hello_world.js because it can't be shared. Keep them in sync! // *** Environment setup code *** var arguments_ = []; diff --git a/src/dlmalloc.c b/src/dlmalloc.c index aa37dc0d..6185b1c7 100644 --- a/src/dlmalloc.c +++ b/src/dlmalloc.c @@ -588,7 +588,10 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP #define INSECURE 0 #endif /* INSECURE */ #ifndef HAVE_MMAP -#define HAVE_MMAP 1 +/* XXX Emscripten + * mmap uses malloc, so malloc can't use mmap + */ +#define HAVE_MMAP 0 #endif /* HAVE_MMAP */ #ifndef MMAP_CLEARS #define MMAP_CLEARS 1 diff --git a/src/library.js b/src/library.js index 426f7035..3ede01af 100644 --- a/src/library.js +++ b/src/library.js @@ -3177,10 +3177,13 @@ LibraryManager.library = { mmap__deps: ['$FS'], mmap: function(start, num, prot, flags, stream, offset) { - // FIXME: Leaky and non-share - //if (stream == -1) { // XXX We should handle -1 here, but this code leads to an infinite loop - // return allocate(num, 'i8', ALLOC_NORMAL); - //} + /* FIXME: Since mmap is normally implemented at the kernel level, + * this implementation simply uses malloc underneath the call to + * mmap. + */ + if (stream == -1) { + return allocate(num, 'i8', ALLOC_NORMAL); + } var info = FS.streams[stream]; if (!info) return -1; return allocate(info.object.contents.slice(offset, offset+num), @@ -3189,7 +3192,6 @@ LibraryManager.library = { __01mmap64_: 'mmap', munmap: function(start, num) { - // FIXME: Not really correct at all. _free(start); }, @@ -3200,7 +3202,13 @@ LibraryManager.library = { // ========================================================================== malloc: function(bytes) { - return Runtime.staticAlloc(bytes || 1); // accept 0 as an input because libc implementations tend to + /* Over-allocate to make sure it is byte-aligned by 8. + * This will leak memory, but this is only the dummy + * implementation (replaced by dlmalloc normally) so + * not an issue. + */ + ptr = Runtime.staticAlloc(bytes + 8); + return (ptr+8) & 0xFFFFFFF8; }, _Znwj: 'malloc', _Znaj: 'malloc', diff --git a/src/parseTools.js b/src/parseTools.js index 22c2f440..18ce807e 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -779,6 +779,7 @@ function generateStructTypes(type) { var start = index; for (var i = 0; i < typeData.fields.length; i++) { var type = typeData.fields[i]; + if (!SAFE_HEAP && isPointerType(type)) type = '*'; // do not include unneeded type names without safe heap if (Runtime.isNumberType(type) || isPointerType(type)) { if (I64_MODE == 1 && type == 'i64') { ret[index++] = 'i64'; diff --git a/src/runtime.js b/src/runtime.js index 2b81258d..6439d0ed 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -34,7 +34,8 @@ var RuntimeGenerator = { stackEnter: function(initial, force) { if (initial === 0 && SKIP_STACK_IN_SMALL && !force) return ''; - var ret = 'var __stackBase__ = STACKTOP; STACKTOP += ' + initial; + var ret = 'var __stackBase__ = STACKTOP'; + if (initial > 0) ret += '; STACKTOP += ' + initial; if (USE_TYPED_ARRAYS == 2) { assert(initial % QUANTUM_SIZE == 0); if (ASSERTIONS) { |