Change C++ exception usage back into a longjmp() due to GCC bugs

db4
Slava Pestov 2009-10-05 03:27:28 -05:00
parent 14840edc4b
commit 6c047127ee
9 changed files with 122 additions and 126 deletions

View File

@ -60,6 +60,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
vm/strings.o \ vm/strings.o \
vm/tuples.o \ vm/tuples.o \
vm/utilities.o \ vm/utilities.o \
vm/vm.o \
vm/words.o \ vm/words.o \
vm/write_barrier.o vm/write_barrier.o

View File

@ -12,18 +12,16 @@ gc_state::gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_ge
data(data_), data(data_),
growing_data_heap(growing_data_heap_), growing_data_heap(growing_data_heap_),
collecting_gen(collecting_gen_), collecting_gen(collecting_gen_),
collecting_aging_again(false),
start_time(current_micros()) { } start_time(current_micros()) { }
gc_state::~gc_state() { } gc_state::~gc_state() { }
/* If a generation fills up, throw this error. It is caught in garbage_collection() */
struct generation_full_condition { };
/* Given a pointer to oldspace, copy it to newspace */ /* Given a pointer to oldspace, copy it to newspace */
object *factor_vm::copy_untagged_object_impl(object *pointer, cell size) object *factor_vm::copy_untagged_object_impl(object *pointer, cell size)
{ {
if(current_gc->newspace->here + size >= current_gc->newspace->end) if(current_gc->newspace->here + size >= current_gc->newspace->end)
throw generation_full_condition(); longjmp(current_gc->gc_unwind,1);
object *newpointer = allot_zone(current_gc->newspace,size); object *newpointer = allot_zone(current_gc->newspace,size);
@ -502,7 +500,6 @@ void factor_vm::begin_gc(cell requested_bytes)
void factor_vm::end_gc() void factor_vm::end_gc()
{ {
gc_stats *s = &stats[current_gc->collecting_gen]; gc_stats *s = &stats[current_gc->collecting_gen];
cell gc_elapsed = (current_micros() - current_gc->start_time); cell gc_elapsed = (current_micros() - current_gc->start_time);
@ -545,10 +542,34 @@ void factor_vm::garbage_collection(cell collecting_gen_, bool growing_data_heap_
/* Keep trying to GC higher and higher generations until we don't run out /* Keep trying to GC higher and higher generations until we don't run out
of space */ of space */
for(;;) if(setjmp(current_gc->gc_unwind))
{ {
try /* We come back here if a generation is full */
/* We have no older generations we can try collecting, so we
resort to growing the data heap */
if(current_gc->collecting_tenured_p())
{ {
current_gc->growing_data_heap = true;
/* see the comment in unmark_marked() */
code->unmark_marked();
}
/* we try collecting aging space twice before going on to
collect tenured */
else if(data->have_aging_p()
&& current_gc->collecting_gen == data->aging()
&& !current_gc->collecting_aging_again)
{
current_gc->collecting_aging_again = true;
}
/* Collect the next oldest generation */
else
{
current_gc->collecting_gen++;
}
}
begin_gc(requested_bytes); begin_gc(requested_bytes);
/* Initialize chase pointer */ /* Initialize chase pointer */
@ -585,37 +606,6 @@ void factor_vm::garbage_collection(cell collecting_gen_, bool growing_data_heap_
update_dirty_code_blocks(); update_dirty_code_blocks();
/* GC completed without any generations filling up; finish up */ /* GC completed without any generations filling up; finish up */
break;
}
catch(const generation_full_condition &c)
{
/* We come back here if a generation is full */
/* We have no older generations we can try collecting, so we
resort to growing the data heap */
if(current_gc->collecting_tenured_p())
{
current_gc->growing_data_heap = true;
/* see the comment in unmark_marked() */
code->unmark_marked();
}
/* we try collecting aging space twice before going on to
collect tenured */
else if(data->have_aging_p()
&& current_gc->collecting_gen == data->aging()
&& !current_gc->collecting_aging_again)
{
current_gc->collecting_aging_again = true;
}
/* Collect the next oldest generation */
else
{
current_gc->collecting_gen++;
}
}
}
end_gc(); end_gc();
delete current_gc; delete current_gc;

View File

@ -34,6 +34,8 @@ struct gc_state {
/* GC start time, for benchmarking */ /* GC start time, for benchmarking */
u64 start_time; u64 start_time;
jmp_buf gc_unwind;
explicit gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_gen_); explicit gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_gen_);
~gc_state(); ~gc_state();

2
vm/generic_arrays.hpp Normal file → Executable file
View File

@ -4,7 +4,7 @@ namespace factor
template<typename Array> cell array_capacity(Array *array) template<typename Array> cell array_capacity(Array *array)
{ {
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
assert(array->h.hi_tag() == T::type_number); assert(array->h.hi_tag() == Array::type_number);
#endif #endif
return array->capacity >> TAG_BITS; return array->capacity >> TAG_BITS;
} }

View File

@ -46,7 +46,8 @@ LONG factor_vm::exception_handler(PEXCEPTION_POINTERS pe)
else else
signal_callstack_top = NULL; signal_callstack_top = NULL;
switch (e->ExceptionCode) { switch (e->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION: case EXCEPTION_ACCESS_VIOLATION:
signal_fault_addr = e->ExceptionInformation[1]; signal_fault_addr = e->ExceptionInformation[1];
c->EIP = (cell)factor::memory_signal_handler_impl; c->EIP = (cell)factor::memory_signal_handler_impl;

View File

@ -330,6 +330,7 @@ void factor_vm::compile_all_words()
} }
printf("done\n");
/* Update XTs in code heap */ /* Update XTs in code heap */
word_updater updater(this); word_updater updater(this);
iterate_code_heap(updater); iterate_code_heap(updater);

0
vm/tuples.cpp Normal file → Executable file
View File

11
vm/vm.cpp Executable file
View File

@ -0,0 +1,11 @@
#include "master.hpp"
namespace factor
{
factor_vm::factor_vm()
{
memset(this,0,sizeof(factor_vm));
}
}

12
vm/vm.hpp Normal file → Executable file
View File

@ -535,7 +535,6 @@ struct factor_vm
//code_heap //code_heap
heap *code; heap *code;
unordered_map<heap_block *, char *> forwarding; unordered_map<heap_block *, char *> forwarding;
typedef void (factor_vm::*code_heap_iterator)(code_block *compiled);
void init_code_heap(cell size); void init_code_heap(cell size);
bool in_code_heap_p(cell ptr); bool in_code_heap_p(cell ptr);
@ -743,16 +742,7 @@ struct factor_vm
void call_fault_handler(exception_type_t exception, exception_data_type_t code, MACH_EXC_STATE_TYPE *exc_state, MACH_THREAD_STATE_TYPE *thread_state, MACH_FLOAT_STATE_TYPE *float_state); void call_fault_handler(exception_type_t exception, exception_data_type_t code, MACH_EXC_STATE_TYPE *exc_state, MACH_THREAD_STATE_TYPE *thread_state, MACH_FLOAT_STATE_TYPE *float_state);
#endif #endif
factor_vm() factor_vm();
: profiling_p(false),
secure_gc(false),
gc_off(false),
fep_disabled(false),
full_output(false),
max_pic_size(0)
{
memset(this,0,sizeof(this)); // just to make sure
}
}; };