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