mmap for poison heap
This commit is contained in:
@@ -377,7 +377,7 @@ int cell_init(int argc, char **argv)
|
||||
free(boot_data);
|
||||
return 1;
|
||||
}
|
||||
JSContext *ctx = JS_NewContextWithHeapSize(g_runtime, 16 * 1024 * 1024);
|
||||
JSContext *ctx = JS_NewContextWithHeapSize(g_runtime, 1024 * 1024);
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
free(boot_data); JS_FreeRuntime(g_runtime);
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
*/
|
||||
// #define DUMP_BYTECODE (1)
|
||||
/* dump GC summary: old/new heap, recovery %, heap growth */
|
||||
// #define DUMP_GC
|
||||
#define DUMP_GC
|
||||
/* dump detailed GC: roots, scanning, object traversal (implies DUMP_GC) */
|
||||
// #define DUMP_GC_DETAIL
|
||||
#ifdef DUMP_GC_DETAIL
|
||||
@@ -115,6 +115,14 @@
|
||||
#define gc_poison_region(addr, size) ((void)0)
|
||||
#define gc_unpoison_region(addr, size) ((void)0)
|
||||
#endif
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static inline size_t poison_page_align(size_t size) {
|
||||
size_t ps = (size_t)sysconf(_SC_PAGESIZE);
|
||||
return (size + ps - 1) & ~(ps - 1);
|
||||
}
|
||||
#endif /* POISON_HEAP */
|
||||
|
||||
#ifdef HAVE_ASAN
|
||||
|
||||
@@ -935,7 +935,10 @@ void buddy_destroy (BuddyAllocator *b) {
|
||||
static void *heap_block_alloc(JSRuntime *rt, size_t size) {
|
||||
#ifdef POISON_HEAP
|
||||
(void)rt;
|
||||
return malloc(size);
|
||||
size = poison_page_align(size);
|
||||
void *p = mmap(NULL, size, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
return (p == MAP_FAILED) ? NULL : p;
|
||||
#else
|
||||
return buddy_alloc(&rt->buddy, size);
|
||||
#endif
|
||||
@@ -944,8 +947,9 @@ static void *heap_block_alloc(JSRuntime *rt, size_t size) {
|
||||
static void heap_block_free(JSRuntime *rt, void *ptr, size_t size) {
|
||||
#ifdef POISON_HEAP
|
||||
(void)rt;
|
||||
(void)size;
|
||||
/* Don't free - leave it poisoned to catch stale accesses */
|
||||
/* mmap'd memory is intentionally never munmap'd so virtual addresses
|
||||
are never reused (preventing stale pointer aliasing). Pages stay
|
||||
resident because chase() reads forwarding pointers from old blocks. */
|
||||
gc_poison_region(ptr, size);
|
||||
#else
|
||||
buddy_free(&rt->buddy, ptr, size);
|
||||
@@ -1174,10 +1178,16 @@ int ctx_gc (JSContext *ctx, int allow_grow, size_t alloc_size) {
|
||||
while (new_size < need && new_size < (1ULL << BUDDY_MAX_ORDER))
|
||||
new_size *= 2;
|
||||
}
|
||||
#ifdef POISON_HEAP
|
||||
new_size = poison_page_align(new_size);
|
||||
#endif
|
||||
uint8_t *new_block = heap_block_alloc (rt, new_size);
|
||||
if (!new_block) {
|
||||
/* Try with same size */
|
||||
new_size = ctx->current_block_size;
|
||||
#ifdef POISON_HEAP
|
||||
new_size = poison_page_align(new_size);
|
||||
#endif
|
||||
new_block = heap_block_alloc (rt, new_size);
|
||||
if (!new_block) return -1;
|
||||
}
|
||||
@@ -1432,6 +1442,9 @@ JSContext *JS_NewContextRawWithHeapSize (JSRuntime *rt, size_t heap_size) {
|
||||
}
|
||||
|
||||
/* Allocate initial heap block for bump allocation */
|
||||
#ifdef POISON_HEAP
|
||||
heap_size = poison_page_align(heap_size);
|
||||
#endif
|
||||
ctx->current_block_size = heap_size;
|
||||
ctx->next_block_size = ctx->current_block_size;
|
||||
ctx->heap_base = heap_block_alloc (rt, ctx->current_block_size);
|
||||
|
||||
Reference in New Issue
Block a user