aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-12-16 17:46:05 -0800
committerAlon Zakai <alonzakai@gmail.com>2011-12-16 17:46:05 -0800
commitef3d0541e91af4b7279bd8e30b112b1a3a108f9e (patch)
tree0a47cfd57be19b093e06f92e7f15186f9dbad9c5
parent086526150c8dc53800a63af9571c62410a161cc6 (diff)
fix bug with accessing memory beyond TOTAL_MEMORY through sbrk
-rw-r--r--src/library.js13
-rw-r--r--src/preamble.js10
-rw-r--r--src/runtime.js9
-rw-r--r--tests/runner.py7
4 files changed, 20 insertions, 19 deletions
diff --git a/src/library.js b/src/library.js
index 2a4a5e7d..ba9ef0f8 100644
--- a/src/library.js
+++ b/src/library.js
@@ -2111,15 +2111,12 @@ LibraryManager.library = {
// TODO: We could in theory slice off the top of the HEAP when
// sbrk gets a negative increment in |bytes|...
var self = _sbrk;
- if (!self.STATICTOP) {
- STATICTOP = alignMemoryPage(STATICTOP);
- self.STATICTOP = STATICTOP;
- self.DATASIZE = 0;
- } else {
- assert(self.STATICTOP == STATICTOP, "No one should touch the heap!");
+ if (!self.called) {
+ STATICTOP = alignMemoryPage(STATICTOP); // make sure we start out aligned
+ self.called = true;
}
- var ret = STATICTOP + self.DATASIZE;
- self.DATASIZE += alignMemoryPage(bytes);
+ var ret = STATICTOP;
+ if (bytes != 0) Runtime.staticAlloc(bytes);
return ret; // Previous break location.
},
open64: 'open',
diff --git a/src/preamble.js b/src/preamble.js
index cd9138d4..8a0f6eb6 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -23,6 +23,10 @@ var ACCEPTABLE_SAFE_HEAP_ERRORS = 0;
function SAFE_HEAP_ACCESS(dest, type, store, ignore) {
//if (dest === A_NUMBER) print ([dest, type, store] + ' ' + new Error().stack); // Something like this may be useful, in debugging
+
+ assert(dest < STATICTOP);
+ assert(STATICTOP <= TOTAL_MEMORY);
+
#if USE_TYPED_ARRAYS == 2
return; // It is legitimate to violate the load-store assumption in this case
#endif
@@ -533,12 +537,11 @@ var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32;
var STACK_ROOT, STACKTOP, STACK_MAX;
var STATICTOP;
#if USE_TYPED_ARRAYS
-var LAST_STATICTOP;
function enlargeMemory() {
- // LAST_STATICTOP is the previous top, TOTAL_MEMORY is the current size of the actual array, and STATICTOP is the new top.
+ // TOTAL_MEMORY is the current size of the actual array, and STATICTOP is the new top.
#if ASSERTIONS
printErr('Warning: Enlarging memory arrays, this is not fast! ' + [STATICTOP, TOTAL_MEMORY]);
- assert(STATICTOP >= TOTAL_MEMORY && LAST_STATICTOP < TOTAL_MEMORY);
+ assert(STATICTOP >= TOTAL_MEMORY);
assert(TOTAL_MEMORY > 4); // So the loop below will not be infinite
#endif
while (TOTAL_MEMORY <= STATICTOP) { // Simple heuristic. Override enlargeMemory() if your program has something more optimal for it
@@ -610,6 +613,7 @@ var FAST_MEMORY = Module['FAST_MEMORY'] || {{{ FAST_MEMORY }}};
var base = intArrayFromString('(null)'); // So printing %s of NULL gives '(null)'
// Also this ensures we leave 0 as an invalid address, 'NULL'
+STATICTOP = base.length;
for (var i = 0; i < base.length; i++) {
{{{ makeSetValue(0, 'i', 'base[i]', 'i8') }}}
}
diff --git a/src/runtime.js b/src/runtime.js
index 0b36f967..e1a6db39 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -10,7 +10,7 @@ var RuntimeGenerator = {
alloc: function(size, type, init) {
var ret = type + 'TOP';
if (ASSERTIONS) {
- ret += '; assert(' + size + ' > 0, "Trying to allocate 0")';
+ ret += '; assert(' + size + ' != 0, "Trying to allocate 0")';
}
if (init) {
ret += '; _memset(' + type + 'TOP, 0, ' + size + ')';
@@ -54,11 +54,10 @@ var RuntimeGenerator = {
return ret += 'STACKTOP = __stackBase__';
},
- // An allocation that cannot be free'd
+ // An allocation that cannot normally be free'd (except through sbrk, which once
+ // called, takes control of STATICTOP)
staticAlloc: function(size) {
- var ret = '';
- if (USE_TYPED_ARRAYS) ret += 'LAST_STATICTOP = STATICTOP;'
- ret += RuntimeGenerator.alloc(size, 'STATIC', INIT_HEAP);
+ var ret = RuntimeGenerator.alloc(size, 'STATIC', INIT_HEAP);
if (USE_TYPED_ARRAYS) ret += '; if (STATICTOP >= TOTAL_MEMORY) enlargeMemory();'
return ret;
},
diff --git a/tests/runner.py b/tests/runner.py
index 9224cb4b..5eb88062 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -3564,9 +3564,9 @@ at function.:blag
# emcc should build in dlmalloc automatically, and do all the sign correction etc. for it
try_delete(os.path.join(self.get_dir(), 'src.cpp.o.js'))
- # XXX find out why we fail without TOTAL_MEMORY here. that should not happen!
- output = Popen([EMCC, '-g', '-s', 'TOTAL_MEMORY=104857600', path_from_root('tests', 'dlmalloc_test.c'),
+ output = Popen([EMCC, path_from_root('tests', 'dlmalloc_test.c'),
'-o', os.path.join(self.get_dir(), 'src.cpp.o.js')], stdout=PIPE, stderr=PIPE).communicate()
+ #print output
self.do_run('x', '*1,0*', ['200', '1'], no_build=True)
self.do_run('x', '*400,0*', ['400', '400'], no_build=True)
@@ -5062,7 +5062,8 @@ Options that are modified or new in %s include:
# TODO: when ready, switch tools/shared building to use emcc over emmaken
# TODO: when this is done, more test runner to test these (i.e., test all -Ox thoroughly)
# TODO: emscripten tutorial with emcc
- # TODO: deprecate llvm optimizations etc. in emscripten.py.
+ # TODO: deprecate llvm optimizations, dlmalloc, etc. in emscripten.py.
+ # TODO: hide output from compiling dlmalloc internally
# Finally, do some web browser tests
def run_browser(html_file, message):