Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perform JS static allocations at compile time #7850

Merged
merged 32 commits into from
Jan 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0bdd47b
very wip
kripken Jan 9, 2019
e5bbc52
fix
kripken Jan 9, 2019
afc4c16
remove staticAlloc/ALLOC_STATIC
kripken Jan 9, 2019
ae0bbb5
fixes [ci skip]
kripken Jan 9, 2019
2e75cd8
more [ci skip]
kripken Jan 9, 2019
4a62b1f
do dynamic top emitting earlier in the js, so dynamicAlloc works ever…
kripken Jan 9, 2019
35282e2
new model [ci skip]
kripken Jan 10, 2019
30f2ff0
fix [ci skip]
kripken Jan 10, 2019
d6b4c00
test fix
kripken Jan 10, 2019
387034f
forward static bump from js to emscripten.py [ci skip]
kripken Jan 10, 2019
b07a654
fix static strings [ci skip]
kripken Jan 10, 2019
1c57b5d
fixes [ci skip]
kripken Jan 10, 2019
fdda39a
fixes [ci skip]
kripken Jan 10, 2019
de1ad42
Revert "fixes [ci skip]"
kripken Jan 10, 2019
8f7ce9c
Revert "Revert "fixes [ci skip]""
kripken Jan 10, 2019
ecedef6
fix [ci skip]
kripken Jan 10, 2019
0338565
test fix [ci skip]
kripken Jan 10, 2019
6d62a03
remove fixmes
kripken Jan 10, 2019
a470a71
proper allocation
kripken Jan 10, 2019
9d5c349
work [ci skip]
kripken Jan 10, 2019
a07858f
fix
kripken Jan 10, 2019
214f936
fix zlib compiler error
kripken Jan 10, 2019
afbac79
fix logger
kripken Jan 10, 2019
332849f
fix pthreads
kripken Jan 10, 2019
6d8a2c1
remove irrelevant test - without full stack overflow tests, anything …
kripken Jan 10, 2019
23ec68e
merge
kripken Jan 10, 2019
dccd4f1
cleanup
kripken Jan 10, 2019
c6e3ea3
cleanup
kripken Jan 10, 2019
c8aed5d
feedback
kripken Jan 11, 2019
080820d
Merge remote-tracking branch 'origin/incoming' into simplify-memory
kripken Jan 11, 2019
4b48ca9
assert that the stack and heap must be aligned
kripken Jan 11, 2019
9e44fd6
review feedback
kripken Jan 14, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1305,7 +1305,10 @@ def check(input_file):
shared.Settings.ASMJS_CODE_FILE = shared.JS.escape_for_js_string(os.path.basename(asm_target))

shared.Settings.ASM_JS = 2 # when targeting wasm, we use a wasm Memory, but that is not compatible with asm.js opts
shared.Settings.GLOBAL_BASE = 1024 # leave some room for mapping global vars
# for asm2wasm, a higher global base is useful for optimizing load/store offsets
# (and historically for mapping asm.js globals)
# TODO: for the wasm backend, we don't need this?
shared.Settings.GLOBAL_BASE = 1024
if shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS:
logger.warning('for wasm there is no need to set ELIMINATE_DUPLICATE_FUNCTIONS, the binaryen optimizer does it automatically')
shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS = 0
Expand Down
69 changes: 60 additions & 9 deletions emscripten.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,15 @@ def is_int(x):
return False


def align_memory(addr):
return (addr + 15) & -16
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find hex literals more readable for bitwise operations but YMMV



def align_static_bump(metadata):
metadata['staticBump'] = align_memory(metadata['staticBump'])
return metadata['staticBump']


def update_settings_glue(metadata):
if shared.Settings.CYBERDWARF:
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.append("cyberdwarf_Debugger")
Expand Down Expand Up @@ -581,6 +590,14 @@ def read_proxied_function_signatures(asmConsts):
if not shared.Settings.WASM_BACKEND:
shared.Settings.PROXIED_FUNCTION_SIGNATURES = read_proxied_function_signatures(metadata['asmConsts'])

shared.Settings.STATIC_BUMP = align_static_bump(metadata)


def apply_forwarded_data(forwarded_data):
forwarded_json = json.loads(forwarded_data)
# Be aware of JS static allocations
shared.Settings.STATIC_BUMP = forwarded_json['STATIC_BUMP']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

obviously STATIC_BUMP is preexisting, but it does seem odd to be setting global settings (which usually just come via command-line flags or a certain narrow set of ways to configure) based on this forwarded data.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually does this mean that STATIC_BUMP can now be demoted from a shared setting to something local to emscripten.py?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is slightly odd, yeah, we use shared.Settings as a global location for compiler state. We do mark them in settings.js with comments saying some are just for internal use, like this one. But perhaps they could be in shared.Internals or such?

Specifically here, this can't be a local var to the file since we do want to use it elsewhere (e.g. when we write the metadata we write this - although I didn't update all those places yet in this PR, to keep it small).



def compile_settings(compiler_engine, libraries, temp_files):
# Save settings to a file to work around v8 issue 1579
Expand All @@ -596,18 +613,53 @@ def compile_settings(compiler_engine, libraries, temp_files):
cwd=path_from_root('src'), env=env)
assert '//FORWARDED_DATA:' in out, 'Did not receive forwarded data in pre output - process failed?'
glue, forwarded_data = out.split('//FORWARDED_DATA:')

apply_forwarded_data(forwarded_data)

return glue, forwarded_data


def apply_memory(pre, metadata):
# Apply the statically-at-compile-time computed memory locations.
# Note: if RELOCATABLE, then only relative sizes can be computed, and we don't
# actually write out any absolute memory locations ({{{ STACK_BASE }}}
# does not exist, etc.)

# Memory layout:
# * first the static globals
global_start = shared.Settings.GLOBAL_BASE
static_bump = shared.Settings.STATIC_BUMP
# * then the stack (up on fastcomp, down on upstream)
stack_low = align_memory(global_start + static_bump)
stack_high = align_memory(stack_low + shared.Settings.TOTAL_STACK)
if shared.Settings.WASM_BACKEND:
stack_start = stack_high
stack_max = stack_low
else:
stack_start = stack_low
stack_max = stack_high
# * then dynamic memory begins
dynamic_start = align_memory(stack_high)

# Write it all out
pre = pre.replace('{{{ STATIC_BUMP }}}', str(static_bump))
pre = pre.replace('{{{ STACK_BASE }}}', str(stack_start))
pre = pre.replace('{{{ STACK_MAX }}}', str(stack_max))
pre = pre.replace('{{{ DYNAMIC_BASE }}}', str(dynamic_start))

logger.debug('global_start: %d stack_start: %d, stack_max: %d, dynamic_start: %d, static bump: %d', global_start, stack_start, stack_max, dynamic_start, static_bump)

return pre


def memory_and_global_initializers(pre, metadata, mem_init):
global_initializers = ', '.join('{ func: function() { %s() } }' % i for i in metadata['initializers'])

if shared.Settings.SIMD == 1:
pre = open(path_from_root(os.path.join('src', 'ecmascript_simd.js'))).read() + '\n\n' + pre

staticbump = metadata['staticBump']
while staticbump % 16 != 0:
staticbump += 1
staticbump = shared.Settings.STATIC_BUMP

pthread = ''
if shared.Settings.USE_PTHREADS:
pthread = 'if (!ENVIRONMENT_IS_PTHREAD)'
Expand All @@ -621,8 +673,8 @@ def memory_and_global_initializers(pre, metadata, mem_init):

if shared.Settings.SIDE_MODULE:
pre = pre.replace('GLOBAL_BASE', 'gb')
if shared.Settings.SIDE_MODULE or shared.Settings.WASM:
pre = pre.replace('{{{ STATIC_BUMP }}}', str(staticbump))

pre = apply_memory(pre, metadata)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the new logic still correct for sidemodules and/or !WASM? I don't see any mentions of those.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identical for wasm and !wasm.

In a side module we wouldn't have STACK_BASE etc., as the location is determined at runtime anyhow (by the dynamic loader). So maybe it's a little odd we compute those even though they are not written out. I'll add a comment.


return pre

Expand Down Expand Up @@ -1887,16 +1939,15 @@ def emscript_wasm_backend(infile, outfile, memfile, libraries, compiler_engine,

global_initializers = ', '.join('{ func: function() { %s() } }' % i for i in metadata['initializers'])

staticbump = metadata['staticBump']
while staticbump % 16 != 0:
staticbump += 1
staticbump = shared.Settings.STATIC_BUMP

pre = pre.replace('STATICTOP = STATIC_BASE + 0;', '''STATICTOP = STATIC_BASE + %d;
/* global initializers */ %s __ATINIT__.push(%s);
''' % (staticbump,
'if (!ENVIRONMENT_IS_PTHREAD)' if shared.Settings.USE_PTHREADS else '',
global_initializers))

pre = pre.replace('{{{ STATIC_BUMP }}}', str(staticbump))
pre = apply_memory(pre, metadata)

# merge forwarded data
shared.Settings.EXPORTED_FUNCTIONS = forwarded_json['EXPORTED_FUNCTIONS']
Expand Down
3 changes: 1 addition & 2 deletions site/source/docs/api_reference/preamble.js.rst
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ The :ref:`emscripten-memory-model` uses a typed array buffer (``ArrayBuffer``) t
.. 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.

function allocate(slab, types, allocator, ptr) — Internal and use is discouraged. Documentation can remain in source code but not here.
associated contants ALLOC_NORMAL, ALLOC_STACK, ALLOC_STATIC, ALLOC_DYNAMIC, ALLOC_NONE
associated contants ALLOC_NORMAL, ALLOC_STACK, ALLOC_DYNAMIC, ALLOC_NONE

function addOnPreRun
function addOnInit
Expand All @@ -414,7 +414,6 @@ The :ref:`emscripten-memory-model` uses a typed array buffer (``ArrayBuffer``) t
function addOnPostRun
Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
Module['ALLOC_STACK'] = ALLOC_STACK;
Module['ALLOC_STATIC'] = ALLOC_STATIC;
Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
Module['ALLOC_NONE'] = ALLOC_NONE;
Module['HEAP'] = HEAP;
Expand Down
2 changes: 1 addition & 1 deletion src/deterministic.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Module['thisProgram'] = 'thisProgram'; // for consistency between different buil

function hashMemory(id) {
var ret = 0;
var len = Math.max(HEAP32[DYNAMICTOP_PTR>>2], STATICTOP);
var len = HEAP32[DYNAMICTOP_PTR>>2];
for (var i = 0; i < len; i++) {
ret = (ret*17 + HEAPU8[i])|0;
}
Expand Down
19 changes: 3 additions & 16 deletions src/jsifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,6 @@ function JSify(data, functionsOnly) {
// Globals are done, here is the rest of static memory
if (!SIDE_MODULE) {
print('STATIC_BASE = GLOBAL_BASE;\n');
print('STATICTOP = STATIC_BASE + ' + Runtime.alignMemory(Variables.nextIndexedOffset) + ';\n');
} else {
print('gb = alignMemory(getMemory({{{ STATIC_BUMP }}} + ' + MAX_GLOBAL_ALIGN + '), ' + MAX_GLOBAL_ALIGN + ' || 1);\n');
// The static area consists of explicitly initialized data, followed by zero-initialized data.
Expand All @@ -440,8 +439,9 @@ function JSify(data, functionsOnly) {
// here, we just zero the whole thing, which is suboptimal, but should at least resolve bugs
// from uninitialized memory.
print('for (var i = gb; i < gb + {{{ STATIC_BUMP }}}; ++i) HEAP8[i] = 0;\n');
print('// STATICTOP = STATIC_BASE + ' + Runtime.alignMemory(Variables.nextIndexedOffset) + ';\n'); // comment as metadata only
}
// emit "metadata" in a comment. FIXME make this nicer
print('// STATICTOP = STATIC_BASE + ' + Runtime.alignMemory(Variables.nextIndexedOffset) + ';\n');
if (WASM) {
// export static base and bump, needed for linking in wasm binary's memory, dynamic linking, etc.
print('var STATIC_BUMP = {{{ STATIC_BUMP }}};');
Expand Down Expand Up @@ -487,7 +487,7 @@ function JSify(data, functionsOnly) {
if (!SIDE_MODULE) {
if (USE_PTHREADS) {
print('var tempDoublePtr;');
print('if (!ENVIRONMENT_IS_PTHREAD) tempDoublePtr = alignMemory(staticAlloc(12), 8);');
print('if (!ENVIRONMENT_IS_PTHREAD) tempDoublePtr = ' + makeStaticAlloc(12) + ';');
} else {
print('var tempDoublePtr = ' + makeStaticAlloc(8) + '');
}
Expand Down Expand Up @@ -542,19 +542,6 @@ function JSify(data, functionsOnly) {
for(i in proxiedFunctionInvokers) print(proxiedFunctionInvokers[i]+'\n');
print('if (!ENVIRONMENT_IS_PTHREAD) {\n // Only main thread initializes these, pthreads copy them over at thread worker init time (in worker.js)');
}
print('DYNAMICTOP_PTR = staticAlloc(4);\n');
print('STACK_BASE = STACKTOP = alignMemory(STATICTOP);\n');
if (STACK_START > 0) print('if (STACKTOP < ' + STACK_START + ') STACK_BASE = STACKTOP = alignMemory(' + STACK_START + ');\n');
print('STACK_MAX = STACK_BASE + TOTAL_STACK;\n');
print('DYNAMIC_BASE = alignMemory(STACK_MAX);\n');
if (WASM_BACKEND) {
// wasm backend stack goes down
print('STACKTOP = STACK_BASE + TOTAL_STACK;');
print('STACK_MAX = STACK_BASE;');
}
print('HEAP32[DYNAMICTOP_PTR>>2] = DYNAMIC_BASE;\n');
print('staticSealed = true; // seal the static portion of memory\n');
if (ASSERTIONS) print('assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");\n');
if (USE_PTHREADS) print('}\n');
}

Expand Down
30 changes: 16 additions & 14 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@
// object. For convenience, the short name appears here. Note that if you add a
// new function with an '_', it will not be found.

// Memory allocated during startup, in postsets, should only be ALLOC_STATIC
// Memory allocated during startup, in postsets, should only be static
// (using makeStaticAlloc)

LibraryManager.library = {
// keep this low in memory, because we flatten arrays with them in them
#if USE_PTHREADS
stdin: '; if (ENVIRONMENT_IS_PTHREAD) _stdin = PthreadWorkerInit._stdin; else PthreadWorkerInit._stdin = _stdin = staticAlloc(4)',
stdout: '; if (ENVIRONMENT_IS_PTHREAD) _stdout = PthreadWorkerInit._stdout; else PthreadWorkerInit._stdout = _stdout = staticAlloc(4)',
stderr: '; if (ENVIRONMENT_IS_PTHREAD) _stderr = PthreadWorkerInit._stderr; else PthreadWorkerInit._stderr = _stderr = staticAlloc(4)',
_impure_ptr: '; if (ENVIRONMENT_IS_PTHREAD) __impure_ptr = PthreadWorkerInit.__impure_ptr; else PthreadWorkerInit.__impure_ptr __impure_ptr = staticAlloc(4)',
__dso_handle: '; if (ENVIRONMENT_IS_PTHREAD) ___dso_handle = PthreadWorkerInit.___dso_handle; else PthreadWorkerInit.___dso_handle = ___dso_handle = staticAlloc(4)',
stdin: '; if (ENVIRONMENT_IS_PTHREAD) _stdin = PthreadWorkerInit._stdin; else PthreadWorkerInit._stdin = _stdin = {{{ makeStaticAlloc(4) }}}',
stdout: '; if (ENVIRONMENT_IS_PTHREAD) _stdout = PthreadWorkerInit._stdout; else PthreadWorkerInit._stdout = _stdout = {{{ makeStaticAlloc(4) }}}',
stderr: '; if (ENVIRONMENT_IS_PTHREAD) _stderr = PthreadWorkerInit._stderr; else PthreadWorkerInit._stderr = _stderr = {{{ makeStaticAlloc(4) }}}',
_impure_ptr: '; if (ENVIRONMENT_IS_PTHREAD) __impure_ptr = PthreadWorkerInit.__impure_ptr; else PthreadWorkerInit.__impure_ptr __impure_ptr = {{{ makeStaticAlloc(4) }}}',
__dso_handle: '; if (ENVIRONMENT_IS_PTHREAD) ___dso_handle = PthreadWorkerInit.___dso_handle; else PthreadWorkerInit.___dso_handle = ___dso_handle = {{{ makeStaticAlloc(4) }}}',
#else
stdin: '{{{ makeStaticAlloc(1) }}}',
stdout: '{{{ makeStaticAlloc(1) }}}',
Expand Down Expand Up @@ -1962,13 +1963,13 @@ LibraryManager.library = {

// Statically allocated time struct.
#if USE_PTHREADS
__tm_current: '; if (ENVIRONMENT_IS_PTHREAD) ___tm_current = PthreadWorkerInit.___tm_current; else PthreadWorkerInit.___tm_current = ___tm_current = allocate({{{ C_STRUCTS.tm.__size__ }}}, "i8", ALLOC_STATIC)',
__tm_timezone: '; if (ENVIRONMENT_IS_PTHREAD) ___tm_timezone = PthreadWorkerInit.___tm_timezone; else PthreadWorkerInit.___tm_timezone = ___tm_timezone = allocate(intArrayFromString("GMT"), "i8", ALLOC_STATIC)',
__tm_formatted: '; if (ENVIRONMENT_IS_PTHREAD) ___tm_formatted = PthreadWorkerInit.___tm_formatted; else PthreadWorkerInit.___tm_formatted = ___tm_formatted = allocate({{{ C_STRUCTS.tm.__size__ }}}, "i8", ALLOC_STATIC)',
__tm_current: '; if (ENVIRONMENT_IS_PTHREAD) ___tm_current = PthreadWorkerInit.___tm_current; else PthreadWorkerInit.___tm_current = ___tm_current = {{{ makeStaticAlloc(C_STRUCTS.tm.__size__) }}}',
__tm_timezone: '; if (ENVIRONMENT_IS_PTHREAD) ___tm_timezone = PthreadWorkerInit.___tm_timezone; else PthreadWorkerInit.___tm_timezone = ___tm_timezone = {{{ makeStaticString("GMT") }}}',
__tm_formatted: '; if (ENVIRONMENT_IS_PTHREAD) ___tm_formatted = PthreadWorkerInit.___tm_formatted; else PthreadWorkerInit.___tm_formatted = ___tm_formatted = {{{ makeStaticAlloc(C_STRUCTS.tm.__size__) }}}',
#else
__tm_current: '{{{ makeStaticAlloc(C_STRUCTS.tm.__size__) }}}',
// Statically allocated copy of the string "GMT" for gmtime() to point to
__tm_timezone: 'allocate(intArrayFromString("GMT"), "i8", ALLOC_STATIC)',
__tm_timezone: '{{{ makeStaticString("GMT") }}}',
// Statically allocated time strings.
__tm_formatted: '{{{ makeStaticAlloc(C_STRUCTS.tm.__size__) }}}',
#endif
Expand Down Expand Up @@ -3297,13 +3298,13 @@ LibraryManager.library = {
// ==========================================================================

#if USE_PTHREADS
in6addr_any: '; if (ENVIRONMENT_IS_PTHREAD) _in6addr_any = PthreadWorkerInit._in6addr_any; else PthreadWorkerInit._in6addr_any = _in6addr_any = allocate([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_STATIC)',
in6addr_loopback: '; if (ENVIRONMENT_IS_PTHREAD) _in6addr_loopback = PthreadWorkerInit._in6addr_loopback; else PthreadWorkerInit._in6addr_loopback = _in6addr_loopback = allocate([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], "i8", ALLOC_STATIC)',
in6addr_any: '; if (ENVIRONMENT_IS_PTHREAD) _in6addr_any = PthreadWorkerInit._in6addr_any; else PthreadWorkerInit._in6addr_any = _in6addr_any = {{{ makeStaticAlloc(16) }}}',
in6addr_loopback: '; if (ENVIRONMENT_IS_PTHREAD) _in6addr_loopback = PthreadWorkerInit._in6addr_loopback; else PthreadWorkerInit._in6addr_loopback = _in6addr_loopback = {{{ makeStaticAlloc(16) }}}',
#else
in6addr_any:
'allocate([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_STATIC)',
'{{{ makeStaticAlloc(16) }}}',
in6addr_loopback:
'allocate([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], "i8", ALLOC_STATIC)',
'{{{ makeStaticAlloc(16) }}}',
#endif

// ==========================================================================
Expand Down Expand Up @@ -4818,3 +4819,4 @@ function autoAddDeps(object, name) {
}
}
}

4 changes: 2 additions & 2 deletions src/library_fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
var LibraryFetch = {
#if USE_PTHREADS
$Fetch__postset: 'if (!ENVIRONMENT_IS_PTHREAD) Fetch.staticInit();',
fetch_work_queue: '; if (ENVIRONMENT_IS_PTHREAD) _fetch_work_queue = PthreadWorkerInit._fetch_work_queue; else PthreadWorkerInit._fetch_work_queue = _fetch_work_queue = staticAlloc(12)',
fetch_work_queue: '; if (ENVIRONMENT_IS_PTHREAD) _fetch_work_queue = PthreadWorkerInit._fetch_work_queue; else PthreadWorkerInit._fetch_work_queue = _fetch_work_queue = {{{ makeStaticAlloc(12) }}}',
#else
$Fetch__postset: 'Fetch.staticInit();',
fetch_work_queue: 'staticAlloc(12)',
fetch_work_queue: '{{{ makeStaticAlloc(12) }}}',
#endif
$Fetch: Fetch,
_emscripten_get_fetch_work_queue__deps: ['fetch_work_queue'],
Expand Down
11 changes: 5 additions & 6 deletions src/library_pthread.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var LibraryPThread = {
// mainThreadBlock: undefined,
initMainThreadBlock: function() {
if (ENVIRONMENT_IS_PTHREAD) return undefined;
PThread.mainThreadBlock = allocate({{{ C_STRUCTS.pthread.__size__ }}}, "i32*", ALLOC_STATIC);
PThread.mainThreadBlock = {{{ makeStaticAlloc(C_STRUCTS.pthread.__size__) }}};

for (var i = 0; i < {{{ C_STRUCTS.pthread.__size__ }}}/4; ++i) HEAPU32[PThread.mainThreadBlock/4+i] = 0;

Expand All @@ -34,7 +34,7 @@ var LibraryPThread = {
{{{ makeSetValue('headPtr', 0, 'headPtr', 'i32') }}};

// Allocate memory for thread-local storage.
var tlsMemory = allocate({{{ cDefine('PTHREAD_KEYS_MAX') }}} * 4, "i32*", ALLOC_STATIC);
var tlsMemory = {{{ makeStaticAlloc(cDefine('PTHREAD_KEYS_MAX') * 4) }}};
for (var i = 0; i < {{{ cDefine('PTHREAD_KEYS_MAX') }}}; ++i) HEAPU32[tlsMemory/4+i] = 0;
Atomics.store(HEAPU32, (PThread.mainThreadBlock + {{{ C_STRUCTS.pthread.tsd }}} ) >> 2, tlsMemory); // Init thread-local-storage memory array.
Atomics.store(HEAPU32, (PThread.mainThreadBlock + {{{ C_STRUCTS.pthread.tid }}} ) >> 2, PThread.mainThreadBlock); // Main thread ID.
Expand All @@ -54,7 +54,7 @@ var LibraryPThread = {

#if PTHREADS_PROFILING
createProfilerBlock: function(pthreadPtr) {
var profilerBlock = (pthreadPtr == PThread.mainThreadBlock) ? allocate({{{ C_STRUCTS.thread_profiler_block.__size__ }}}, "i32*", ALLOC_STATIC) : _malloc({{{ C_STRUCTS.thread_profiler_block.__size__ }}});
var profilerBlock = (pthreadPtr == PThread.mainThreadBlock) ? {{{ makeStaticAlloc(C_STRUCTS.thread_profiler_block.__size__) }}} : _malloc({{{ C_STRUCTS.thread_profiler_block.__size__ }}});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(it looks like the above three code blocks have historically overallocated 4x the number of bytes needed, but this change fixes that)

Atomics.store(HEAPU32, (pthreadPtr + {{{ C_STRUCTS.pthread.profilerBlock }}} ) >> 2, profilerBlock);

// Zero fill contents at startup.
Expand Down Expand Up @@ -400,7 +400,6 @@ var LibraryPThread = {
#endif
tempDoublePtr: tempDoublePtr,
TOTAL_MEMORY: TOTAL_MEMORY,
STATICTOP: STATICTOP,
DYNAMIC_BASE: DYNAMIC_BASE,
DYNAMICTOP_PTR: DYNAMICTOP_PTR,
PthreadWorkerInit: PthreadWorkerInit
Expand Down Expand Up @@ -529,7 +528,7 @@ var LibraryPThread = {
},

_num_logical_cores__deps: ['emscripten_force_num_logical_cores'],
_num_logical_cores: '; if (ENVIRONMENT_IS_PTHREAD) __num_logical_cores = PthreadWorkerInit.__num_logical_cores; else { PthreadWorkerInit.__num_logical_cores = __num_logical_cores = allocate(1, "i32*", ALLOC_STATIC); HEAPU32[__num_logical_cores>>2] = navigator["hardwareConcurrency"] || ' + {{{ PTHREAD_HINT_NUM_CORES }}} + '; }',
_num_logical_cores: '; if (ENVIRONMENT_IS_PTHREAD) __num_logical_cores = PthreadWorkerInit.__num_logical_cores; else { PthreadWorkerInit.__num_logical_cores = __num_logical_cores = {{{ makeStaticAlloc(4) }}}; HEAPU32[__num_logical_cores>>2] = navigator["hardwareConcurrency"] || ' + {{{ PTHREAD_HINT_NUM_CORES }}} + '; }',

emscripten_has_threading_support: function() {
return typeof SharedArrayBuffer !== 'undefined';
Expand Down Expand Up @@ -1031,7 +1030,7 @@ var LibraryPThread = {
},

// Stores the memory address that the main thread is waiting on, if any.
_main_thread_futex_wait_address: '; if (ENVIRONMENT_IS_PTHREAD) __main_thread_futex_wait_address = PthreadWorkerInit.__main_thread_futex_wait_address; else PthreadWorkerInit.__main_thread_futex_wait_address = __main_thread_futex_wait_address = allocate(1, "i32*", ALLOC_STATIC)',
_main_thread_futex_wait_address: '; if (ENVIRONMENT_IS_PTHREAD) __main_thread_futex_wait_address = PthreadWorkerInit.__main_thread_futex_wait_address; else PthreadWorkerInit.__main_thread_futex_wait_address = __main_thread_futex_wait_address = {{{ makeStaticAlloc(4) }}}',

// Returns 0 on success, or one of the values -ETIMEDOUT, -EWOULDBLOCK or -EINVAL on error.
emscripten_futex_wait__deps: ['_main_thread_futex_wait_address', 'emscripten_main_thread_process_queued_calls'],
Expand Down
1 change: 0 additions & 1 deletion src/library_trace.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ var LibraryTracing = {
if (EmscriptenTrace.postEnabled) {
var memory_layout = {
'static_base': STATIC_BASE,
'static_top': STATICTOP,
'stack_base': STACK_BASE,
'stack_top': STACKTOP,
'stack_max': STACK_MAX,
Expand Down
Loading