From 3adf299b7707bb51a1c2d04ceff0a0462f32c2f5 Mon Sep 17 00:00:00 2001 From: tingyuan Date: Wed, 20 Mar 2013 16:51:51 +0800 Subject: [PATCH 1/9] Put preloaded files on HEAP instead of another ArrayBuffers. --- tools/file_packager.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/file_packager.py b/tools/file_packager.py index 73ff4919bc83b..d2827db6813b6 100644 --- a/tools/file_packager.py +++ b/tools/file_packager.py @@ -321,9 +321,12 @@ def was_seen(name): if file_['mode'] == 'preload': use_data += ''' curr = DataRequest.prototype.requests['%s']; - curr.response = byteArray.subarray(%d,%d); + var data = byteArray.subarray(%d, %d); + ptr = _valloc(%d); + HEAPU8.set(data, ptr); + curr.response = HEAPU8.subarray(ptr, ptr + %d); curr.onload(); - ''' % (file_['name'], file_['data_start'], file_['data_end']) + ''' % (file_['name'], file_['data_start'], file_['data_end'], file_['data_end'] - file_['data_start'], file_['data_end'] - file_['data_start']) use_data += " Module['removeRunDependency']('datafile_%s');\n" % data_target if Compression.on: From 1ce0f6c6b288eff8313e022b8ac62051e2ccc9f4 Mon Sep 17 00:00:00 2001 From: tingyuan Date: Wed, 20 Mar 2013 16:53:42 +0800 Subject: [PATCH 2/9] Add checks to existences of Module['setStatus']. --- tools/file_packager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/file_packager.py b/tools/file_packager.py index d2827db6813b6..ece1896de39e5 100644 --- a/tools/file_packager.py +++ b/tools/file_packager.py @@ -368,9 +368,9 @@ def was_seen(name): num++; } total = Math.ceil(total * Module.expectedDataFileDownloads/num); - Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')'); + if (Module['setStatus']) Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')'); } else if (!Module.dataFileDownloads) { - Module['setStatus']('Downloading data...'); + if (Module['setStatus']) Module['setStatus']('Downloading data...'); } } dataFile.open('GET', '%s', true); From 14c821b31d819315415a6a8b72e872a5a28e5d2d Mon Sep 17 00:00:00 2001 From: tingyuan Date: Wed, 20 Mar 2013 17:15:08 +0800 Subject: [PATCH 3/9] Specialize Array/TypedArray in allocate() to avoid unnecessary array constructions. --- src/preamble.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/preamble.js b/src/preamble.js index 7538b19c35a0a..db4f02eb85385 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -462,7 +462,11 @@ function allocate(slab, types, allocator, ptr) { #if USE_TYPED_ARRAYS == 2 if (singleType === 'i8') { - HEAPU8.set(new Uint8Array(slab), ret); + if (slab.subarray || slab.slice) { + HEAPU8.set(slab, ret); + } else { + HEAPU8.set(new Uint8Array(slab), ret); + } return ret; } #endif From 1a11016600234ec016327a492c7760c55ccbd808 Mon Sep 17 00:00:00 2001 From: tingyuan Date: Wed, 20 Mar 2013 17:18:00 +0800 Subject: [PATCH 4/9] 1. mmap(): Make use of files that is backed by HEAP. 2. mmap(): Use valloc() directly. 3. mmap(): Try to avoid Array.slice() when possible. --- src/library.js | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/library.js b/src/library.js index 3d00a4d5dbd6e..8f33cfc36772b 100644 --- a/src/library.js +++ b/src/library.js @@ -3601,30 +3601,42 @@ LibraryManager.library = { * this implementation simply uses malloc underneath the call to * mmap. */ + var MAP_PRIVATE = 2; + var allocated = false; + if (!_mmap.mappings) _mmap.mappings = {}; + if (stream == -1) { - var ptr = _malloc(num); + var ptr = _valloc(num); + if (!ptr) return -1; + _memset(ptr, 0, num); + allocated = true; } else { var info = FS.streams[stream]; if (!info) return -1; var contents = info.object.contents; - contents = Array.prototype.slice.call(contents, offset, offset+num); - ptr = allocate(contents, 'i8', ALLOC_NORMAL); - } - // align to page size - var ret = ptr; - if (ptr % PAGE_SIZE != 0) { - var old = ptr; - ptr = _malloc(num + PAGE_SIZE); - ret = alignMemoryPage(ptr); - _memcpy(ret, old, num); - _free(old); - } - if (stream == -1) { - _memset(ret, 0, num); + // Only make a new copy when the file is not in HEAP or MAP_PRIVATE is specified. + if (contents.buffer === HEAPU8.buffer && flags & MAP_PRIVATE == 0) { + ptr = contents.byteOffset; + allocated = false; + } else { + // Try to avoid unnecessary slices. + if (offset > 0 || offset + num < contents.length) { + if (contents.subarray) { + contents = contents.subarray(offset, offset+num); + } else { + contents = Array.prototype.slice.call(contents, offset, offset+num); + } + } + ptr = _valloc(num); + if (!ptr) return -1; + HEAPU8.set(contents, ptr); + allocated = true; + } } - _mmap.mappings[ret] = { malloc: ptr, num: num }; - return ret; + + _mmap.mappings[ptr] = { malloc: ptr, num: num, allocated: allocated }; + return ptr; }, __01mmap64_: 'mmap', @@ -3635,7 +3647,8 @@ LibraryManager.library = { if (!info) return 0; if (num == info.num) { _mmap.mappings[start] = null; - _free(info.malloc); + if (info.allocated) + _free(info.malloc); } return 0; }, From af958277ecb03b22cf51854619aa10e0a8e61ca5 Mon Sep 17 00:00:00 2001 From: tingyuan Date: Mon, 15 Apr 2013 14:14:45 +0800 Subject: [PATCH 5/9] Assert that MAP_SHARED is only specified with files backed by HEAP. --- src/library.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/library.js b/src/library.js index 8f33cfc36772b..b0ffbce5c0a8e 100644 --- a/src/library.js +++ b/src/library.js @@ -3615,8 +3615,10 @@ LibraryManager.library = { var info = FS.streams[stream]; if (!info) return -1; var contents = info.object.contents; - // Only make a new copy when the file is not in HEAP or MAP_PRIVATE is specified. - if (contents.buffer === HEAPU8.buffer && flags & MAP_PRIVATE == 0) { + // Only make a new copy when MAP_PRIVATE is specified. + if (flags & MAP_PRIVATE == 0) { + // We can't emulate MAP_SHARED when the file is not backed by HEAP. + assert(contents.buffer === HEAPU8.buffer); ptr = contents.byteOffset; allocated = false; } else { From e5151333eef3487f7e71bc1eb09c6e12fb0dc75a Mon Sep 17 00:00:00 2001 From: tingyuan Date: Mon, 15 Apr 2013 14:16:44 +0800 Subject: [PATCH 6/9] mmap(): Align to malloc's default alignment instead of pages. --- src/library.js | 4 ++-- tools/file_packager.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/library.js b/src/library.js index b0ffbce5c0a8e..d3c8360423b19 100644 --- a/src/library.js +++ b/src/library.js @@ -3607,7 +3607,7 @@ LibraryManager.library = { if (!_mmap.mappings) _mmap.mappings = {}; if (stream == -1) { - var ptr = _valloc(num); + var ptr = _malloc(num); if (!ptr) return -1; _memset(ptr, 0, num); allocated = true; @@ -3630,7 +3630,7 @@ LibraryManager.library = { contents = Array.prototype.slice.call(contents, offset, offset+num); } } - ptr = _valloc(num); + ptr = _malloc(num); if (!ptr) return -1; HEAPU8.set(contents, ptr); allocated = true; diff --git a/tools/file_packager.py b/tools/file_packager.py index ece1896de39e5..2bba84be9c638 100644 --- a/tools/file_packager.py +++ b/tools/file_packager.py @@ -322,7 +322,7 @@ def was_seen(name): use_data += ''' curr = DataRequest.prototype.requests['%s']; var data = byteArray.subarray(%d, %d); - ptr = _valloc(%d); + ptr = _malloc(%d); HEAPU8.set(data, ptr); curr.response = HEAPU8.subarray(ptr, ptr + %d); curr.onload(); From a3919f52ab0fc227b2adc80f1d309d0d4bb3f3ff Mon Sep 17 00:00:00 2001 From: tingyuan Date: Tue, 16 Apr 2013 15:10:54 +0800 Subject: [PATCH 7/9] Unleash the 4k alignment of mmap() in the test_mmap(). --- tests/runner.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/runner.py b/tests/runner.py index 99c536e3ecfaa..16fdc5a7bc0ad 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -6991,7 +6991,9 @@ def test_mmap(self): for (int i = 0; i < 10; i++) { int* map = (int*)mmap(0, 5000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); + /* TODO: Should we align to 4k? assert(((int)map) % 4096 == 0); // aligned + */ assert(munmap(map, 5000) == 0); } From fa4449af0fbd038d7d4c10a6586d5dae47c8c99d Mon Sep 17 00:00:00 2001 From: tingyuan Date: Wed, 17 Apr 2013 10:47:18 +0800 Subject: [PATCH 8/9] Make a temporary variable local. --- tools/file_packager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/file_packager.py b/tools/file_packager.py index 2bba84be9c638..21027999706c1 100644 --- a/tools/file_packager.py +++ b/tools/file_packager.py @@ -322,7 +322,7 @@ def was_seen(name): use_data += ''' curr = DataRequest.prototype.requests['%s']; var data = byteArray.subarray(%d, %d); - ptr = _malloc(%d); + var ptr = _malloc(%d); HEAPU8.set(data, ptr); curr.response = HEAPU8.subarray(ptr, ptr + %d); curr.onload(); From b4216219e92e2ed7272fff60267072e57a7899ab Mon Sep 17 00:00:00 2001 From: tingyuan Date: Mon, 22 Apr 2013 12:25:49 +0800 Subject: [PATCH 9/9] Conform to coding conventions. --- src/library.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/library.js b/src/library.js index d3c8360423b19..3a2b6d82401fd 100644 --- a/src/library.js +++ b/src/library.js @@ -3649,8 +3649,9 @@ LibraryManager.library = { if (!info) return 0; if (num == info.num) { _mmap.mappings[start] = null; - if (info.allocated) + if (info.allocated) { _free(info.malloc); + } } return 0; },