VM: new function set_memory_locked(true/false)
it wraps the mprotect/VirtualProtect platform differences and makes it so you can unify some windows/unix code path forksdb4
parent
a2e8af2581
commit
56ddb59b00
|
@ -212,7 +212,7 @@ cell factor_vm::lookup_external_address(relocation_type rel_type,
|
|||
case RT_INLINE_CACHE_MISS:
|
||||
return (cell)&factor::inline_cache_miss;
|
||||
case RT_SAFEPOINT:
|
||||
return (cell)code->safepoint_page;
|
||||
return code->safepoint_page;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ code_heap::code_heap(cell size) {
|
|||
allocator = new free_list_allocator<code_block>(seg->end - start, start);
|
||||
|
||||
/* See os-windows-x86.64.cpp for seh_area usage */
|
||||
safepoint_page = (void*)seg->start;
|
||||
safepoint_page = seg->start;
|
||||
seh_area = (char*)seg->start + getpagesize();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ struct code_heap {
|
|||
segment* seg;
|
||||
|
||||
/* Memory area reserved for safepoint guard page */
|
||||
void* safepoint_page;
|
||||
cell safepoint_page;
|
||||
|
||||
/* Memory area reserved for SEH. Only used on Windows */
|
||||
char* seh_area;
|
||||
|
@ -51,7 +51,7 @@ struct code_heap {
|
|||
|
||||
bool safepoint_p(cell addr) {
|
||||
cell page_mask = ~(getpagesize() - 1);
|
||||
return (addr & page_mask) == (cell)safepoint_page;
|
||||
return (addr & page_mask) == safepoint_page;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -13,4 +13,6 @@ void unlock_console();
|
|||
void ignore_ctrl_c();
|
||||
void handle_ctrl_c();
|
||||
|
||||
bool set_memory_locked(cell base, cell size, bool locked);
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
namespace factor {
|
||||
|
||||
bool set_memory_locked(cell base, cell size, bool locked) {
|
||||
int prot = locked ? PROT_NONE : PROT_READ | PROT_WRITE;
|
||||
int status = mprotect((char*)base, size, prot);
|
||||
return status != -1;
|
||||
}
|
||||
|
||||
THREADHANDLE start_thread(void* (*start_routine)(void*), void* args) {
|
||||
pthread_attr_t attr;
|
||||
pthread_t thread;
|
||||
|
@ -98,19 +104,17 @@ segment::segment(cell size_, bool executable_p) {
|
|||
}
|
||||
|
||||
void segment::set_border_locked(bool locked) {
|
||||
int prot = locked ? PROT_NONE : PROT_READ | PROT_WRITE;
|
||||
int pagesize = getpagesize();
|
||||
|
||||
cell lo = start - pagesize;
|
||||
if (mprotect((char*)lo, pagesize, prot) == -1) {
|
||||
if (!set_memory_locked(lo, pagesize, locked)) {
|
||||
check_ENOMEM("mprotect low");
|
||||
fatal_error("Cannot (un)protect low guard page", lo);
|
||||
}
|
||||
|
||||
cell hi = end;
|
||||
if (mprotect((char*)hi, pagesize, prot) == -1) {
|
||||
if (!set_memory_locked(hi, pagesize, locked)) {
|
||||
check_ENOMEM("mprotect high");
|
||||
fatal_error("Cannot protect high guard page", lo);
|
||||
fatal_error("Cannot (un)protect high guard page", hi);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,13 +126,13 @@ segment::~segment() {
|
|||
}
|
||||
|
||||
void code_heap::guard_safepoint() {
|
||||
if (mprotect(safepoint_page, getpagesize(), PROT_NONE) == -1)
|
||||
fatal_error("Cannot protect safepoint guard page", (cell)safepoint_page);
|
||||
if (!set_memory_locked(safepoint_page, getpagesize(), true))
|
||||
fatal_error("Cannot protect safepoint guard page", safepoint_page);
|
||||
}
|
||||
|
||||
void code_heap::unguard_safepoint() {
|
||||
if (mprotect(safepoint_page, getpagesize(), PROT_WRITE) == -1)
|
||||
fatal_error("Cannot unprotect safepoint guard page", (cell)safepoint_page);
|
||||
if (!set_memory_locked(safepoint_page, getpagesize(), false))
|
||||
fatal_error("Cannot unprotect safepoint guard page", safepoint_page);
|
||||
}
|
||||
|
||||
void factor_vm::dispatch_signal(void* uap, void(handler)()) {
|
||||
|
|
|
@ -4,6 +4,13 @@ namespace factor {
|
|||
|
||||
HMODULE hFactorDll;
|
||||
|
||||
bool set_memory_locked(cell base, cell size, bool locked) {
|
||||
int prot = locked ? PAGE_NOACCESS : PAGE_READWRITE;
|
||||
DWORD ignore;
|
||||
int status = VirtualProtect((char*)base, size, prot, &ignore);
|
||||
return status != 0;
|
||||
}
|
||||
|
||||
void factor_vm::init_ffi() {
|
||||
hFactorDll = GetModuleHandle(NULL);
|
||||
if (!hFactorDll)
|
||||
|
@ -101,18 +108,15 @@ segment::segment(cell size_, bool executable_p) {
|
|||
}
|
||||
|
||||
void segment::set_border_locked(bool locked) {
|
||||
int prot = locked ? PAGE_NOACCESS : PAGE_READWRITE;
|
||||
int pagesize = getpagesize();
|
||||
DWORD ignore;
|
||||
|
||||
cell lo = start - pagesize;
|
||||
if (!VirtualProtect((char*)lo, pagesize, prot, &ignore)) {
|
||||
if (!set_memory_locked(lo, pagesize, locked)) {
|
||||
fatal_error("Cannot (un)protect low guard page", lo);
|
||||
}
|
||||
|
||||
cell hi = end;
|
||||
if (!VirtualProtect((char*)hi, pagesize, prot, &ignore)) {
|
||||
fatal_error("Cannot (un)protect high guard page", lo);
|
||||
if (!set_memory_locked(hi, pagesize, locked)) {
|
||||
fatal_error("Cannot (un)protect high guard page", hi);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,15 +138,13 @@ long getpagesize() {
|
|||
}
|
||||
|
||||
void code_heap::guard_safepoint() {
|
||||
DWORD ignore;
|
||||
if (!VirtualProtect(safepoint_page, getpagesize(), PAGE_NOACCESS, &ignore))
|
||||
fatal_error("Cannot protect safepoint guard page", (cell)safepoint_page);
|
||||
if (!set_memory_locked(safepoint_page, getpagesize(), true))
|
||||
fatal_error("Cannot protect safepoint guard page", safepoint_page);
|
||||
}
|
||||
|
||||
void code_heap::unguard_safepoint() {
|
||||
DWORD ignore;
|
||||
if (!VirtualProtect(safepoint_page, getpagesize(), PAGE_READWRITE, &ignore))
|
||||
fatal_error("Cannot unprotect safepoint guard page", (cell)safepoint_page);
|
||||
if (!set_memory_locked(safepoint_page, getpagesize(), false))
|
||||
fatal_error("Cannot unprotect safepoint guard page", safepoint_page);
|
||||
}
|
||||
|
||||
void factor_vm::move_file(const vm_char* path1, const vm_char* path2) {
|
||||
|
|
Loading…
Reference in New Issue