diff --git a/vm/code_block.cpp b/vm/code_block.cpp index bd7a93bf6d..507dd3bd61 100755 --- a/vm/code_block.cpp +++ b/vm/code_block.cpp @@ -93,9 +93,9 @@ void factor_vm::undefined_symbol() general_error(ERROR_UNDEFINED_SYMBOL,F,F,NULL); } -void undefined_symbol(factor_vm *myvm) +void undefined_symbol() { - return myvm->undefined_symbol(); + return SIGNAL_VM_PTR()->undefined_symbol(); } /* Look up an external library symbol referenced by a compiled code block */ diff --git a/vm/contexts.cpp b/vm/contexts.cpp index 6e51ed8ba9..d2d9db2b51 100644 --- a/vm/contexts.cpp +++ b/vm/contexts.cpp @@ -43,9 +43,9 @@ context *factor_vm::alloc_context() } else { - new_context = (context *)safe_malloc(sizeof(context)); - new_context->datastack_region = alloc_segment(ds_size); - new_context->retainstack_region = alloc_segment(rs_size); + new_context = new context; + new_context->datastack_region = new segment(this,ds_size); + new_context->retainstack_region = new segment(this,rs_size); } return new_context; diff --git a/vm/data_gc.cpp b/vm/data_gc.cpp index 011cc1f5f3..07f457b447 100755 --- a/vm/data_gc.cpp +++ b/vm/data_gc.cpp @@ -455,7 +455,7 @@ void factor_vm::end_gc(cell gc_elapsed) if(growing_data_heap) { - dealloc_data_heap(old_data_heap); + delete old_data_heap; old_data_heap = NULL; growing_data_heap = false; } diff --git a/vm/data_heap.cpp b/vm/data_heap.cpp index 5eaa715e6c..ecc891b369 100755 --- a/vm/data_heap.cpp +++ b/vm/data_heap.cpp @@ -3,14 +3,6 @@ namespace factor { -cell factor_vm::init_zone(zone *z, cell size, cell start) -{ - z->size = size; - z->start = z->here = start; - z->end = start + size; - return z->end; -} - void factor_vm::init_card_decks() { cell start = align(data->seg->start,deck_size); @@ -19,89 +11,86 @@ void factor_vm::init_card_decks() decks_offset = (cell)data->decks - (start >> deck_bits); } -data_heap *factor_vm::alloc_data_heap(cell gens, cell young_size,cell aging_size,cell tenured_size) +data_heap::data_heap(factor_vm *myvm, cell gen_count_, cell young_size_, cell aging_size_, cell tenured_size_) { - young_size = align(young_size,deck_size); - aging_size = align(aging_size,deck_size); - tenured_size = align(tenured_size,deck_size); + young_size_ = align(young_size_,deck_size); + aging_size_ = align(aging_size_,deck_size); + tenured_size_ = align(tenured_size_,deck_size); - data_heap *data = (data_heap *)safe_malloc(sizeof(data_heap)); - data->young_size = young_size; - data->aging_size = aging_size; - data->tenured_size = tenured_size; - data->gen_count = gens; + young_size = young_size_; + aging_size = aging_size_; + tenured_size = tenured_size_; + gen_count = gen_count_; cell total_size; - if(data->gen_count == 2) + if(gen_count == 2) total_size = young_size + 2 * tenured_size; - else if(data->gen_count == 3) + else if(gen_count == 3) total_size = young_size + 2 * aging_size + 2 * tenured_size; else { - fatal_error("Invalid number of generations",data->gen_count); - return NULL; /* can't happen */ + total_size = 0; + fatal_error("Invalid number of generations",gen_count); } total_size += deck_size; - data->seg = alloc_segment(total_size); + seg = new segment(myvm,total_size); - data->generations = (zone *)safe_malloc(sizeof(zone) * data->gen_count); - data->semispaces = (zone *)safe_malloc(sizeof(zone) * data->gen_count); + generations = new zone[gen_count]; + semispaces = new zone[gen_count]; cell cards_size = total_size >> card_bits; - data->allot_markers = (cell *)safe_malloc(cards_size); - data->allot_markers_end = data->allot_markers + cards_size; + allot_markers = new char[cards_size]; + allot_markers_end = allot_markers + cards_size; - data->cards = (cell *)safe_malloc(cards_size); - data->cards_end = data->cards + cards_size; + cards = new char[cards_size]; + cards_end = cards + cards_size; cell decks_size = total_size >> deck_bits; - data->decks = (cell *)safe_malloc(decks_size); - data->decks_end = data->decks + decks_size; + decks = new char[decks_size]; + decks_end = decks + decks_size; - cell alloter = align(data->seg->start,deck_size); + cell alloter = align(seg->start,deck_size); - alloter = init_zone(&data->generations[data->tenured()],tenured_size,alloter); - alloter = init_zone(&data->semispaces[data->tenured()],tenured_size,alloter); + alloter = generations[tenured()].init_zone(tenured_size,alloter); + alloter = semispaces[tenured()].init_zone(tenured_size,alloter); - if(data->gen_count == 3) + if(gen_count == 3) { - alloter = init_zone(&data->generations[data->aging()],aging_size,alloter); - alloter = init_zone(&data->semispaces[data->aging()],aging_size,alloter); + alloter = generations[aging()].init_zone(aging_size,alloter); + alloter = semispaces[aging()].init_zone(aging_size,alloter); } - if(data->gen_count >= 2) + if(gen_count >= 2) { - alloter = init_zone(&data->generations[data->nursery()],young_size,alloter); - alloter = init_zone(&data->semispaces[data->nursery()],0,alloter); + alloter = generations[nursery()].init_zone(young_size,alloter); + alloter = semispaces[nursery()].init_zone(0,alloter); } - if(data->seg->end - alloter > deck_size) - critical_error("Bug in alloc_data_heap",alloter); - - return data; + if(seg->end - alloter > deck_size) + myvm->critical_error("Bug in alloc_data_heap",alloter); } data_heap *factor_vm::grow_data_heap(data_heap *data, cell requested_bytes) { cell new_tenured_size = (data->tenured_size * 2) + requested_bytes; - return alloc_data_heap(data->gen_count, + return new data_heap(this, + data->gen_count, data->young_size, data->aging_size, new_tenured_size); } -void factor_vm::dealloc_data_heap(data_heap *data) +data_heap::~data_heap() { - dealloc_segment(data->seg); - free(data->generations); - free(data->semispaces); - free(data->allot_markers); - free(data->cards); - free(data->decks); - free(data); + delete seg; + delete[] generations; + delete[] semispaces; + delete[] allot_markers; + delete[] cards; + delete[] decks; } void factor_vm::clear_cards(cell from, cell to) @@ -162,7 +151,7 @@ void factor_vm::set_data_heap(data_heap *data_) void factor_vm::init_data_heap(cell gens,cell young_size,cell aging_size,cell tenured_size,bool secure_gc_) { - set_data_heap(alloc_data_heap(gens,young_size,aging_size,tenured_size)); + set_data_heap(new data_heap(this,gens,young_size,aging_size,tenured_size)); secure_gc = secure_gc_; init_data_gc(); } diff --git a/vm/data_heap.hpp b/vm/data_heap.hpp index 81a3405d42..8b8ca59185 100755 --- a/vm/data_heap.hpp +++ b/vm/data_heap.hpp @@ -9,6 +9,14 @@ struct zone { cell here; cell size; cell end; + + cell init_zone(cell size_, cell start_) + { + size = size_; + start = here = start_; + end = start_ + size_; + return end; + } }; struct data_heap { @@ -23,14 +31,14 @@ struct data_heap { zone *generations; zone *semispaces; - cell *allot_markers; - cell *allot_markers_end; + char *allot_markers; + char *allot_markers_end; - cell *cards; - cell *cards_end; + char *cards; + char *cards_end; - cell *decks; - cell *decks_end; + char *decks; + char *decks_end; /* the 0th generation is where new objects are allocated. */ cell nursery() { return 0; } @@ -42,6 +50,9 @@ struct data_heap { cell tenured() { return gen_count - 1; } bool have_aging_p() { return gen_count > 2; } + + data_heap(factor_vm *myvm, cell gen_count, cell young_size, cell aging_size, cell tenured_size); + ~data_heap(); }; static const cell max_gen_count = 3; @@ -51,11 +62,6 @@ inline static bool in_zone(zone *z, object *pointer) return (cell)pointer >= z->start && (cell)pointer < z->end; } -/* set up guard pages to check for under/overflow. -size must be a multiple of the page size */ -segment *alloc_segment(cell size); // defined in OS-*.cpp files PD -void dealloc_segment(segment *block); - PRIMITIVE(data_room); PRIMITIVE(size); diff --git a/vm/heap.cpp b/vm/heap.cpp index 0905d7c190..c8262cb7f5 100644 --- a/vm/heap.cpp +++ b/vm/heap.cpp @@ -14,7 +14,7 @@ void heap::clear_free_list() heap::heap(factor_vm *myvm_, cell size) { myvm = myvm_; - seg = myvm->alloc_segment(myvm->align_page(size)); + seg = new segment(myvm,align_page(size)); if(!seg) fatal_error("Out of memory in new_heap",size); clear_free_list(); } diff --git a/vm/inlineimpls.hpp b/vm/inlineimpls.hpp index db6ef8abf4..7074f0d33a 100644 --- a/vm/inlineimpls.hpp +++ b/vm/inlineimpls.hpp @@ -4,13 +4,6 @@ namespace factor // I've had to copy inline implementations here to make dependencies work. Am hoping to move this code back into include files // once the rest of the reentrant changes are done. -PD -// segments.hpp - -inline cell factor_vm::align_page(cell a) -{ - return align(a,getpagesize()); -} - // write_barrier.hpp inline card *factor_vm::addr_to_card(cell a) diff --git a/vm/os-genunix.cpp b/vm/os-genunix.cpp index 7f2429e46a..015a76f842 100644 --- a/vm/os-genunix.cpp +++ b/vm/os-genunix.cpp @@ -18,6 +18,7 @@ void early_init() { } #define SUFFIX ".image" #define SUFFIX_LEN 6 +/* You must delete[] the result yourself. */ const char *default_image_path() { const char *path = vm_executable_path(); @@ -31,7 +32,7 @@ const char *default_image_path() const char *iter = path; while(*iter) { len++; iter++; } - char *new_path = (char *)safe_malloc(PATH_MAX + SUFFIX_LEN + 1); + char *new_path = new char[PATH_MAX + SUFFIX_LEN + 1]; memcpy(new_path,path,len + 1); memcpy(new_path + len,SUFFIX,SUFFIX_LEN + 1); return new_path; diff --git a/vm/os-linux.cpp b/vm/os-linux.cpp index 66b197e7c9..2d26fba390 100644 --- a/vm/os-linux.cpp +++ b/vm/os-linux.cpp @@ -3,10 +3,10 @@ namespace factor { -/* Snarfed from SBCL linux-so.c. You must free() this yourself. */ +/* Snarfed from SBCL linux-so.c. You must delete[] the result yourself. */ const char *vm_executable_path() { - char *path = (char *)safe_malloc(PATH_MAX + 1); + char *path = new char[PATH_MAX + 1]; int size = readlink("/proc/self/exe", path, PATH_MAX); if (size < 0) diff --git a/vm/os-unix.cpp b/vm/os-unix.cpp index c829c3570c..d1af5cb565 100644 --- a/vm/os-unix.cpp +++ b/vm/os-unix.cpp @@ -83,8 +83,11 @@ inline void factor_vm::primitive_existsp() PRIMITIVE_FORWARD(existsp) -segment *factor_vm::alloc_segment(cell size) +segment::segment(factor_vm *myvm_, cell size_) { + myvm = myvm_; + size = size_; + int pagesize = getpagesize(); char *array = (char *)mmap(NULL,pagesize + size + pagesize, @@ -92,7 +95,7 @@ segment *factor_vm::alloc_segment(cell size) MAP_ANON | MAP_PRIVATE,-1,0); if(array == (char*)-1) - out_of_memory(); + myvm->out_of_memory(); if(mprotect(array,pagesize,PROT_NONE) == -1) fatal_error("Cannot protect low guard page",(cell)array); @@ -100,26 +103,16 @@ segment *factor_vm::alloc_segment(cell size) if(mprotect(array + pagesize + size,pagesize,PROT_NONE) == -1) fatal_error("Cannot protect high guard page",(cell)array); - segment *retval = (segment *)safe_malloc(sizeof(segment)); - - retval->start = (cell)(array + pagesize); - retval->size = size; - retval->end = retval->start + size; - - return retval; + start = (cell)(array + pagesize); + end = start + size; } -void dealloc_segment(segment *block) +segment::~segment() { int pagesize = getpagesize(); - - int retval = munmap((void*)(block->start - pagesize), - pagesize + block->size + pagesize); - + int retval = munmap((void*)(start - pagesize),pagesize + size + pagesize); if(retval) - fatal_error("dealloc_segment failed",0); - - free(block); + fatal_error("Segment deallocation failed",0); } stack_frame *factor_vm::uap_stack_pointer(void *uap) diff --git a/vm/os-windows.cpp b/vm/os-windows.cpp index 7d4b345da6..077bc48aa1 100644 --- a/vm/os-windows.cpp +++ b/vm/os-windows.cpp @@ -98,14 +98,17 @@ inline void factor_vm::primitive_existsp() PRIMITIVE_FORWARD(existsp) -segment *factor_vm::alloc_segment(cell size) +segment::segment(factor_vm *myvm_, cell size_) { + myvm = myvm_; + size = size_; + char *mem; DWORD ignore; if((mem = (char *)VirtualAlloc(NULL, getpagesize() * 2 + size, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == 0) - out_of_memory(); + myvm->out_of_memory(); if (!VirtualProtect(mem, getpagesize(), PAGE_NOACCESS, &ignore)) fatal_error("Cannot allocate low guard page", (cell)mem); @@ -114,22 +117,16 @@ segment *factor_vm::alloc_segment(cell size) getpagesize(), PAGE_NOACCESS, &ignore)) fatal_error("Cannot allocate high guard page", (cell)mem); - segment *block = (segment *)safe_malloc(sizeof(segment)); - - block->start = (cell)mem + getpagesize(); - block->size = size; - block->end = block->start + size; - - return block; + start = (cell)mem + getpagesize(); + end = start + size; } -void factor_vm::dealloc_segment(segment *block) +segment::~segment() { SYSTEM_INFO si; GetSystemInfo(&si); - if(!VirtualFree((void*)(block->start - si.dwPageSize), 0, MEM_RELEASE)) - fatal_error("dealloc_segment failed",0); - free(block); + if(!VirtualFree((void*)(start - si.dwPageSize), 0, MEM_RELEASE)) + myvm->fatal_error("Segment deallocation failed",0); } long factor_vm::getpagesize() diff --git a/vm/segments.hpp b/vm/segments.hpp index a715b4dabc..1884526ad2 100644 --- a/vm/segments.hpp +++ b/vm/segments.hpp @@ -1,10 +1,23 @@ namespace factor { +struct factor_vm; + +inline cell align_page(cell a) +{ + return align(a,getpagesize()); +} + +/* segments set up guard pages to check for under/overflow. +size must be a multiple of the page size */ struct segment { + factor_vm *myvm; cell start; cell size; cell end; + + segment(factor_vm *myvm, cell size); + ~segment(); }; } diff --git a/vm/vm.hpp b/vm/vm.hpp index 056393edb4..d75c3e0eaf 100644 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -5,9 +5,6 @@ namespace factor struct factor_vm : factor_vm_data { - // segments - inline cell align_page(cell a); - // contexts void reset_datastack(); void reset_retainstack(); @@ -127,11 +124,8 @@ struct factor_vm : factor_vm_data { bignum *digit_stream_to_bignum(unsigned int n_digits, unsigned int (*producer)(unsigned int, factor_vm *), unsigned int radix, int negative_p); //data_heap - cell init_zone(zone *z, cell size, cell start); void init_card_decks(); - data_heap *alloc_data_heap(cell gens, cell young_size,cell aging_size,cell tenured_size); data_heap *grow_data_heap(data_heap *data, cell requested_bytes); - void dealloc_data_heap(data_heap *data); void clear_cards(cell from, cell to); void clear_decks(cell from, cell to); void clear_allot_markers(cell from, cell to); @@ -560,14 +554,12 @@ struct factor_vm : factor_vm_data { void ffi_dlopen(dll *dll); void *ffi_dlsym(dll *dll, symbol_char *symbol); void ffi_dlclose(dll *dll); - segment *alloc_segment(cell size); void c_to_factor_toplevel(cell quot); // os-windows #if defined(WINDOWS) void sleep_micros(u64 usec); long getpagesize(); - void dealloc_segment(segment *block); const vm_char *vm_executable_path(); const vm_char *default_image_path(); void windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int length);