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 forks
db4
Björn Lindqvist 2015-08-24 08:47:36 +02:00 committed by John Benediktsson
parent a2e8af2581
commit 56ddb59b00
6 changed files with 33 additions and 25 deletions

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;
}
};

View File

@ -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);
}

View File

@ -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)()) {

View File

@ -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) {