aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js55
-rw-r--r--src/compiler.js2
-rw-r--r--src/dlmalloc.c5
-rw-r--r--src/library.js20
-rw-r--r--src/parseTools.js1
-rw-r--r--src/runtime.js3
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) {