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