diff --git a/vm/code_heap.hpp b/vm/code_heap.hpp index aed5a2bd13..fd125bae01 100755 --- a/vm/code_heap.hpp +++ b/vm/code_heap.hpp @@ -41,6 +41,8 @@ struct code_heap { void clear_mark_bits(); void free(code_block *compiled); void flush_icache(); + void guard_safepoint(); + void unguard_safepoint(); }; struct code_heap_room { diff --git a/vm/os-unix.cpp b/vm/os-unix.cpp index 91aca6e7be..7045a073bb 100755 --- a/vm/os-unix.cpp +++ b/vm/os-unix.cpp @@ -124,6 +124,18 @@ segment::~segment() fatal_error("Segment deallocation failed",0); } +void code_heap::guard_safepoint() +{ + if(mprotect(safepoint_page,getpagesize(),PROT_NONE) == -1) + fatal_error("Cannot protect safepoint guard page",(cell)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); +} + void factor_vm::dispatch_signal(void *uap, void (handler)()) { UAP_STACK_POINTER(uap) = (UAP_STACK_POINTER_TYPE)fix_callstack_top((stack_frame *)UAP_STACK_POINTER(uap)); diff --git a/vm/os-windows.cpp b/vm/os-windows.cpp index 795a80e5c7..3dc6da7863 100755 --- a/vm/os-windows.cpp +++ b/vm/os-windows.cpp @@ -148,6 +148,20 @@ long getpagesize() return g_pagesize; } +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); +} + +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); +} + void factor_vm::move_file(const vm_char *path1, const vm_char *path2) { if(MoveFileEx((path1),(path2),MOVEFILE_REPLACE_EXISTING) == false)