Skip to content

Commit 0882510

Browse files
authored
Remove DYNAMICTOP_PTR (#12057)
DYNAMICTOP_PTR has been a pointer to where DYNAMICTOP is stored, which represented the top of "dynamic" memory (not static, and not stack; or in other words, dynamic == managed by sbrk/malloc). We represented it on the JS side so that we could allocate from JS directly, in particular during startup. However, that has caused a bunch of complexity that is not really worth it, and it's also work done after link that we'd like to remove (WebAssembly/binaryen#3043). This PR moves us to a place where malloc-like allocation is disallowed from JS during startup. Instead, JS should call sbrk or malloc normally (which can only be done after startup). This change removes the final static allocation from JS, which means that we no longer adjust memory layout after link, and therefore this PR removes the special updating of the stack pointer and sbrk location that we used to do. (This just removes the --pass-arg stuff for those in emcc.py, to show that this works and passes tests - there is a bunch more code that can be removed but is deferred to keep this as small as possible.) Dynamic linking, however is an exception: we need to allocate room for dynamic libraries during startup (the main module needs them before it starts to run). To support that, this PR still keeps around getMemory() (which does a dynamic allocation during startup) and dynamicAlloc in a simplified form. That form just updates __heap_base as we allocate, and then when the main program starts, __heap_base is a normal extern global that it receives, and it initializes sbrk using that (after that point, dynamic allocations are disallowed and asserted against). This change should not be user-visible, except for removing the allocate() JS function's ALLOC_DYNAMIC option (since we no longer allow that type of allocation). This can only land when it removes the last static allocation from JS. This has a small code size benefit, basically it removes things like these: 340,341d339 < var DYNAMIC_BASE = 5263904, DYNAMICTOP_PTR = 20992; < 361,362d358 < HEAP32[DYNAMICTOP_PTR >> 2] = DYNAMIC_BASE; < The benefit to pthreads builds is larger as it removes a bunch of special code for DYNAMICTOP_PTR that we had there. Note that I'm not totally happy with the sbrk implementation, but we can improve it once malloc is not linked in by default (see comment).
1 parent b10fe2f commit 0882510

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+148
-158
lines changed

ChangeLog.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ See docs/process.md for how version tagging works.
1717

1818
Current Trunk
1919
-------------
20+
- Remove `ALLOC_DYNAMIC` and deprecate `dynamicAlloc`. (#12057, which also
21+
removes the internal `DYNAMICTOP_PTR` API.)
2022

2123
2.0.2: 09/02/2020
2224
-----------------
@@ -26,13 +28,13 @@ Current Trunk
2628
in chrome), and it made things more complex. The behavior has been changed
2729
to be simpler and just leave the browser's error code as it is.
2830
- Enable `--no-heap-copy` file packager option by default, and remove the old
29-
defualt behavior entirely. That is the behavior we should have had from the
30-
beginning as it is more memory-efficient.
31+
default behavior entirely. That is the behavior we should have had from the
32+
beginning as it is more memory-efficient. (#12027)
3133
- `--no-entry` is now required in `STANDALONE_WASM` mode when building a reactor
3234
(application without a main function). Previously exporting a list of
3335
functions that didn't include `_main` would imply this. Now the list of
3436
`EXPORTED_FUNCTIONS` is not relevant in the deciding the type of application
35-
to build.
37+
to build. (#12020)
3638
- Allow polymorphic types to be used without RTTI when using embind. (#10914)
3739
- Do not remove `__original_main` using `--inline-main`. We used to do this
3840
so that it didn't show up in stack traces (which could be confusing because
@@ -43,7 +45,7 @@ Current Trunk
4345
to add `__original_main` to there (since you are doing manual fine-tuning of
4446
the list of functions, which depends on the wasm's internals). Note that this
4547
should not matter in `-O2+` anyhow as normal inlining generally removes
46-
`__original_main`.
48+
`__original_main`. (#11995)
4749

4850
2.0.1: 08/21/2020
4951
-----------------

emcc.py

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,14 @@ def check(input_file):
12641264
if shared.Settings.RELOCATABLE:
12651265
shared.Settings.ALLOW_TABLE_GROWTH = 1
12661266

1267+
# various settings require sbrk() access
1268+
if shared.Settings.DETERMINISTIC or \
1269+
shared.Settings.EMSCRIPTEN_TRACING or \
1270+
shared.Settings.MALLOC == 'emmalloc' or \
1271+
shared.Settings.SAFE_HEAP or \
1272+
shared.Settings.MEMORYPROFILER:
1273+
shared.Settings.EXPORTED_FUNCTIONS += ['_sbrk']
1274+
12671275
if shared.Settings.ASYNCIFY:
12681276
# See: https://github.com/emscripten-core/emscripten/issues/12065
12691277
# See: https://github.com/emscripten-core/emscripten/issues/12066
@@ -1466,8 +1474,9 @@ def check(input_file):
14661474
shared.Settings.GLOBAL_BASE = 1024
14671475

14681476
if shared.Settings.SAFE_HEAP:
1469-
# SAFE_HEAP check includes calling emscripten_get_sbrk_ptr().
1470-
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['emscripten_get_sbrk_ptr', '$unSign']
1477+
# SAFE_HEAP check includes calling emscripten_get_sbrk_ptr() from wasm
1478+
shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_get_sbrk_ptr']
1479+
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$unSign']
14711480

14721481
if not shared.Settings.DECLARE_ASM_MODULE_EXPORTS:
14731482
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$exportAsmFunctions']
@@ -1520,7 +1529,6 @@ def check(input_file):
15201529
]
15211530

15221531
shared.Settings.EXPORTED_RUNTIME_METHODS += [
1523-
'getMemory',
15241532
'addRunDependency',
15251533
'removeRunDependency',
15261534
]
@@ -2595,20 +2603,6 @@ def do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
25952603
intermediate_debug_info = bool(debug_info or options.emit_symbol_map or shared.Settings.ASYNCIFY_ONLY or shared.Settings.ASYNCIFY_REMOVE or shared.Settings.ASYNCIFY_ADD)
25962604

25972605
if options.binaryen_passes:
2598-
if '--post-emscripten' in options.binaryen_passes and not shared.Settings.SIDE_MODULE:
2599-
if not shared.Settings.RELOCATABLE:
2600-
# With the wasm backend stack point value is baked in at link time. However, emscripten's
2601-
# JS compiler can allocate more static data which then shifts the stack pointer.
2602-
# See `makeStaticAlloc` in the JS compiler.
2603-
options.binaryen_passes += ['--pass-arg=stack-pointer@%d' % shared.Settings.STACK_BASE]
2604-
# the value of the sbrk pointer has been computed by the JS compiler, and we can apply it in the wasm
2605-
# (we can't add this value when we placed post-emscripten in the proper position in the list of
2606-
# passes because that was before the value was computed)
2607-
# note that we don't pass this for a side module, as the value can't be applied - it must be
2608-
# imported
2609-
options.binaryen_passes += ['--pass-arg=emscripten-sbrk-ptr@%d' % shared.Settings.DYNAMICTOP_PTR]
2610-
if shared.Settings.STANDALONE_WASM:
2611-
options.binaryen_passes += ['--pass-arg=emscripten-sbrk-val@%d' % shared.Settings.DYNAMIC_BASE]
26122606
# note that wasm-ld can strip DWARF info for us too (--strip-debug), but it
26132607
# also strips the Names section. so to emit just the Names section we don't
26142608
# tell wasm-ld to strip anything, and we do it here.

emscripten.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ def align_memory(addr):
120120

121121

122122
def align_static_bump(metadata):
123+
# TODO: remove static bump entirely
123124
metadata['staticBump'] = align_memory(metadata['staticBump'])
124125
return metadata['staticBump']
125126

@@ -191,7 +192,6 @@ def apply_forwarded_data(forwarded_data):
191192
forwarded_json = json.loads(forwarded_data)
192193
# Be aware of JS static allocations
193194
shared.Settings.STATIC_BUMP = forwarded_json['STATIC_BUMP']
194-
shared.Settings.DYNAMICTOP_PTR = forwarded_json['DYNAMICTOP_PTR']
195195
# Be aware of JS static code hooks
196196
StaticCodeHooks.atinits = str(forwarded_json['ATINITS'])
197197
StaticCodeHooks.atmains = str(forwarded_json['ATMAINS'])

site/source/docs/api_reference/preamble.js.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ The :ref:`emscripten-memory-model` uses a typed array buffer (``ArrayBuffer``) t
404404
.. COMMENT (not rendered) : The following methods are explicitly not part of the public API and not documented. Note that in some case referred to by function name, other cases by Module assignment.
405405
406406
function allocate(slab, types, allocator, ptr) — Internal and use is discouraged. Documentation can remain in source code but not here.
407-
associated constants ALLOC_NORMAL, ALLOC_STACK, ALLOC_DYNAMIC, ALLOC_NONE
407+
associated constants ALLOC_NORMAL, ALLOC_STACK, ALLOC_NONE
408408
409409
function addOnPreRun
410410
function addOnInit
@@ -413,7 +413,6 @@ The :ref:`emscripten-memory-model` uses a typed array buffer (``ArrayBuffer``) t
413413
function addOnPostRun
414414
Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
415415
Module['ALLOC_STACK'] = ALLOC_STACK;
416-
Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
417416
Module['ALLOC_NONE'] = ALLOC_NONE;
418417
Module['HEAP'] = HEAP;
419418
Module['IHEAP'] = IHEAP;

src/deterministic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Module['thisProgram'] = 'thisProgram'; // for consistency between different buil
2121

2222
function hashMemory(id) {
2323
var ret = 0;
24-
var len = HEAP32[DYNAMICTOP_PTR>>2];
24+
var len = _sbrk();
2525
for (var i = 0; i < len; i++) {
2626
ret = (ret*17 + HEAPU8[i])|0;
2727
}

src/library.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -444,12 +444,6 @@ LibraryManager.library = {
444444
return HEAPU8.length;
445445
},
446446

447-
emscripten_get_sbrk_ptr__asm: true,
448-
emscripten_get_sbrk_ptr__sig: 'i',
449-
emscripten_get_sbrk_ptr: function() {
450-
return {{{ DYNAMICTOP_PTR }}};
451-
},
452-
453447
#if ABORTING_MALLOC
454448
$abortOnCannotGrowMemory: function(requestedSize) {
455449
#if ASSERTIONS

src/library_emmalloc.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
*/
66

77
mergeInto(LibraryManager.library, {
8-
emmalloc_unclaimed_heap_memory__deps: ['emscripten_get_sbrk_ptr'],
98
emmalloc_unclaimed_heap_memory: function() {
10-
var dynamicTop = HEAPU32[_emscripten_get_sbrk_ptr()>>2];
9+
var dynamicTop = _sbrk();
1110
#if ALLOW_MEMORY_GROWTH
1211
#if WASM
1312
#if MAXIMUM_MEMORY != -1

src/library_pthread.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,8 @@ var LibraryPThread = {
415415
'asmJsUrlOrBlob': Module["asmJsUrlOrBlob"],
416416
#endif
417417
#if !MINIMAL_RUNTIME
418-
'DYNAMIC_BASE': DYNAMIC_BASE,
418+
'DYNAMIC_BASE': DYNAMIC_BASE
419419
#endif
420-
'DYNAMICTOP_PTR': DYNAMICTOP_PTR
421420
});
422421
},
423422

src/library_trace.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ var LibraryTracing = {
269269
#if !MINIMAL_RUNTIME
270270
'dynamic_base': DYNAMIC_BASE,
271271
#endif
272-
'dynamic_top': HEAP32[DYNAMICTOP_PTR>>2],
272+
'dynamic_top': _sbrk(),
273273
'total_memory': HEAP8.length
274274
};
275275
var now = EmscriptenTrace.now();

src/memoryprofiler.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,11 @@ var emscriptenMemoryProfiler = {
486486
html += '<br />STACK memory area used now (should be zero): ' + self.formatBytes(STACKTOP - STACK_BASE) + '.' + colorBar('#FFFF00') + ' STACK watermark highest seen usage (approximate lower-bound!): ' + self.formatBytes(Math.abs(self.stackTopWatermark - STACK_BASE));
487487

488488
var DYNAMIC_BASE = {{{ getQuoted('DYNAMIC_BASE') }}};
489-
var DYNAMICTOP = HEAP32[DYNAMICTOP_PTR>>2];
489+
// During startup sbrk may not be defined yet. Ideally we should probably
490+
// refactor memoryprofiler so that it only gets here after compiled code is
491+
// ready to be called. For now, if the runtime is not yet initialized,
492+
// assume the brk is right after the stack.
493+
var DYNAMICTOP = runtimeInitialized ? _sbrk() : STACK_BASE;
490494
html += "<br />DYNAMIC memory area size: " + self.formatBytes(DYNAMICTOP - DYNAMIC_BASE);
491495
html += ". DYNAMIC_BASE: " + toHex(DYNAMIC_BASE, width);
492496
html += ". DYNAMICTOP: " + toHex(DYNAMICTOP, width) + ".";

0 commit comments

Comments
 (0)