SAFE_SPLIT_MEMORY, parallel to SAFE_HEAP
This commit is contained in:
Родитель
d0fcdbd9d9
Коммит
c4ef20e254
4
emcc
4
emcc
|
@ -955,7 +955,9 @@ try:
|
||||||
if shared.Settings.ASM_JS == 1:
|
if shared.Settings.ASM_JS == 1:
|
||||||
logging.warning('not all asm.js optimizations are possible with SPLIT_MEMORY, disabling those')
|
logging.warning('not all asm.js optimizations are possible with SPLIT_MEMORY, disabling those')
|
||||||
shared.Settings.ASM_JS = 2
|
shared.Settings.ASM_JS = 2
|
||||||
assert not shared.Settings.SAFE_HEAP, 'TODO: safe heap with SPLIT_MEMORY'
|
if shared.Settings.SAFE_HEAP:
|
||||||
|
shared.Settings.SAFE_HEAP = 0
|
||||||
|
shared.Settings.SAFE_SPLIT_MEMORY = 1 # we use our own infrastructure
|
||||||
assert not shared.Settings.RELOCATABLE, 'no SPLIT_MEMORY with RELOCATABLE'
|
assert not shared.Settings.RELOCATABLE, 'no SPLIT_MEMORY with RELOCATABLE'
|
||||||
assert not shared.Settings.USE_PTHREADS, 'no SPLIT_MEMORY with pthreads'
|
assert not shared.Settings.USE_PTHREADS, 'no SPLIT_MEMORY with pthreads'
|
||||||
if not js_opts:
|
if not js_opts:
|
||||||
|
|
|
@ -869,7 +869,7 @@ function _emscripten_replace_memory(newBuffer) {
|
||||||
buffer = newBuffer;
|
buffer = newBuffer;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
'''] + ['' if not settings['SPLIT_MEMORY'] else '''
|
'''] + ['' if not settings['SPLIT_MEMORY'] or settings['SAFE_SPLIT_MEMORY'] else '''
|
||||||
function get8(ptr) {
|
function get8(ptr) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
return HEAP8s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 0] | 0;
|
return HEAP8s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 0] | 0;
|
||||||
|
|
|
@ -1367,77 +1367,132 @@ function freeSplitChunk(i) {
|
||||||
HEAPF64 = fake(HEAPF64s);
|
HEAPF64 = fake(HEAPF64s);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// TODO: add SAFE_HEAP here
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
function checkPtr(ptr, shifts) {
|
||||||
|
if (ptr <= 0) abort('segmentation fault storing to address ' + ptr);
|
||||||
|
if (ptr !== ((ptr >> shifts) << shifts)) abort('alignment error storing to address ' + ptr + ', which was expected to be aligned to a shift of ' + shifts);
|
||||||
|
if ((ptr >> SPLIT_MEMORY_BITS) !== (ptr + Math.pow(2, shifts) - 1 >> SPLIT_MEMORY_BITS)) abort('segmentation fault, write spans split chunks ' + [ptr, shifts]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
function get8(ptr) {
|
function get8(ptr) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 0);
|
||||||
|
#endif
|
||||||
return HEAP8s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 0] | 0;
|
return HEAP8s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 0] | 0;
|
||||||
}
|
}
|
||||||
function get16(ptr) {
|
function get16(ptr) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 1);
|
||||||
|
#endif
|
||||||
return HEAP16s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 1] | 0;
|
return HEAP16s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 1] | 0;
|
||||||
}
|
}
|
||||||
function get32(ptr) {
|
function get32(ptr) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 2);
|
||||||
|
#endif
|
||||||
return HEAP32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2] | 0;
|
return HEAP32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2] | 0;
|
||||||
}
|
}
|
||||||
function getU8(ptr) {
|
function getU8(ptr) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 0);
|
||||||
|
#endif
|
||||||
return HEAPU8s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 0] | 0;
|
return HEAPU8s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 0] | 0;
|
||||||
}
|
}
|
||||||
function getU16(ptr) {
|
function getU16(ptr) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 1);
|
||||||
|
#endif
|
||||||
return HEAPU16s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 1] | 0;
|
return HEAPU16s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 1] | 0;
|
||||||
}
|
}
|
||||||
function getU32(ptr) {
|
function getU32(ptr) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 2);
|
||||||
|
#endif
|
||||||
return HEAPU32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2] | 0;
|
return HEAPU32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2] | 0;
|
||||||
}
|
}
|
||||||
function getF32(ptr) {
|
function getF32(ptr) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 2);
|
||||||
|
#endif
|
||||||
return +HEAPF32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2];
|
return +HEAPF32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2];
|
||||||
}
|
}
|
||||||
function getF64(ptr) {
|
function getF64(ptr) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 3);
|
||||||
|
#endif
|
||||||
return +HEAPF64s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 3];
|
return +HEAPF64s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 3];
|
||||||
}
|
}
|
||||||
function set8(ptr, value) {
|
function set8(ptr, value) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
value = value | 0;
|
value = value | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 0);
|
||||||
|
#endif
|
||||||
HEAP8s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 0] = value;
|
HEAP8s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 0] = value;
|
||||||
}
|
}
|
||||||
function set16(ptr, value) {
|
function set16(ptr, value) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
value = value | 0;
|
value = value | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 1);
|
||||||
|
#endif
|
||||||
HEAP16s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 1] = value;
|
HEAP16s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 1] = value;
|
||||||
}
|
}
|
||||||
function set32(ptr, value) {
|
function set32(ptr, value) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
value = value | 0;
|
value = value | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 2);
|
||||||
|
#endif
|
||||||
HEAP32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2] = value;
|
HEAP32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2] = value;
|
||||||
}
|
}
|
||||||
function setU8(ptr, value) {
|
function setU8(ptr, value) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
value = value | 0;
|
value = value | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 0);
|
||||||
|
#endif
|
||||||
HEAPU8s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 0] = value;
|
HEAPU8s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 0] = value;
|
||||||
}
|
}
|
||||||
function setU16(ptr, value) {
|
function setU16(ptr, value) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
value = value | 0;
|
value = value | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 1);
|
||||||
|
#endif
|
||||||
HEAPU16s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 1] = value;
|
HEAPU16s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 1] = value;
|
||||||
}
|
}
|
||||||
function setU32(ptr, value) {
|
function setU32(ptr, value) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
value = value | 0;
|
value = value | 0;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 2);
|
||||||
|
#endif
|
||||||
HEAPU32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2] = value;
|
HEAPU32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2] = value;
|
||||||
}
|
}
|
||||||
function setF32(ptr, value) {
|
function setF32(ptr, value) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
value = +value;
|
value = +value;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 2);
|
||||||
|
#endif
|
||||||
HEAPF32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2] = value;
|
HEAPF32s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 2] = value;
|
||||||
}
|
}
|
||||||
function setF64(ptr, value) {
|
function setF64(ptr, value) {
|
||||||
ptr = ptr | 0;
|
ptr = ptr | 0;
|
||||||
value = +value;
|
value = +value;
|
||||||
|
#if SAFE_SPLIT_MEMORY
|
||||||
|
checkPtr(ptr, 3);
|
||||||
|
#endif
|
||||||
HEAPF64s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 3] = value;
|
HEAPF64s[ptr >> SPLIT_MEMORY_BITS][(ptr & SPLIT_MEMORY_MASK) >> 3] = value;
|
||||||
}
|
}
|
||||||
#endif // SPLIT_MEMORY
|
#endif // SPLIT_MEMORY
|
||||||
|
@ -1445,8 +1500,10 @@ function setF64(ptr, value) {
|
||||||
#endif // USE_PTHREADS
|
#endif // USE_PTHREADS
|
||||||
|
|
||||||
// Endianness check (note: assumes compiler arch was little-endian)
|
// Endianness check (note: assumes compiler arch was little-endian)
|
||||||
|
#if SAFE_SPLIT_MEMORY == 0
|
||||||
HEAP32[0] = 255;
|
HEAP32[0] = 255;
|
||||||
assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
|
assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
|
||||||
|
#endif
|
||||||
|
|
||||||
Module['HEAP'] = HEAP;
|
Module['HEAP'] = HEAP;
|
||||||
Module['buffer'] = buffer;
|
Module['buffer'] = buffer;
|
||||||
|
|
|
@ -568,6 +568,7 @@ var SPLIT_MEMORY = 0; // If > 0, we split memory into chunks, of the size given
|
||||||
// better since it can free chunks in the middle.
|
// better since it can free chunks in the middle.
|
||||||
// TODO: more docs
|
// TODO: more docs
|
||||||
// TODO: add malloc-split to embuilder
|
// TODO: add malloc-split to embuilder
|
||||||
|
var SAFE_SPLIT_MEMORY = 0; // Similar to SAFE_HEAP, but for SPLIT_MEMORY.
|
||||||
|
|
||||||
var RUNNING_JS_OPTS = 0; // whether js opts will be run, after the main compiler
|
var RUNNING_JS_OPTS = 0; // whether js opts will be run, after the main compiler
|
||||||
var BOOTSTRAPPING_STRUCT_INFO = 0; // whether we are in the generate struct_info bootstrap phase
|
var BOOTSTRAPPING_STRUCT_INFO = 0; // whether we are in the generate struct_info bootstrap phase
|
||||||
|
|
Загрузка…
Ссылка в новой задаче