SAFE_SPLIT_MEMORY, parallel to SAFE_HEAP

This commit is contained in:
Alon Zakai 2015-09-19 13:52:32 -07:00
Родитель d0fcdbd9d9
Коммит c4ef20e254
4 изменённых файлов: 63 добавлений и 3 удалений

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