Change C++ exception usage back into a longjmp() due to GCC bugs
							parent
							
								
									14840edc4b
								
							
						
					
					
						commit
						6c047127ee
					
				
							
								
								
									
										1
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										1
									
								
								Makefile
								
								
								
								
							| 
						 | 
				
			
			@ -60,6 +60,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
 | 
			
		|||
	vm/strings.o \
 | 
			
		||||
	vm/tuples.o \
 | 
			
		||||
	vm/utilities.o \
 | 
			
		||||
        vm/vm.o \
 | 
			
		||||
	vm/words.o \
 | 
			
		||||
	vm/write_barrier.o
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,18 +12,16 @@ gc_state::gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_ge
 | 
			
		|||
	data(data_),
 | 
			
		||||
	growing_data_heap(growing_data_heap_),
 | 
			
		||||
	collecting_gen(collecting_gen_),
 | 
			
		||||
        collecting_aging_again(false),
 | 
			
		||||
	start_time(current_micros()) { }
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
object *factor_vm::copy_untagged_object_impl(object *pointer, cell size)
 | 
			
		||||
{
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -502,7 +500,6 @@ void factor_vm::begin_gc(cell requested_bytes)
 | 
			
		|||
 | 
			
		||||
void factor_vm::end_gc()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	gc_stats *s = &stats[current_gc->collecting_gen];
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
        /* Initialize chase pointer */
 | 
			
		||||
| 
						 | 
				
			
			@ -585,37 +606,6 @@ void factor_vm::garbage_collection(cell collecting_gen_, bool growing_data_heap_
 | 
			
		|||
                update_dirty_code_blocks();
 | 
			
		||||
 | 
			
		||||
        /* 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();
 | 
			
		||||
 | 
			
		||||
	delete current_gc;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,8 @@ struct gc_state {
 | 
			
		|||
	/* GC start time, for benchmarking */
 | 
			
		||||
	u64 start_time;
 | 
			
		||||
 | 
			
		||||
        jmp_buf gc_unwind;
 | 
			
		||||
 | 
			
		||||
	explicit gc_state(data_heap *data_, bool growing_data_heap_, cell collecting_gen_);
 | 
			
		||||
	~gc_state();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ namespace factor
 | 
			
		|||
template<typename Array> cell array_capacity(Array *array)
 | 
			
		||||
{
 | 
			
		||||
#ifdef FACTOR_DEBUG
 | 
			
		||||
	assert(array->h.hi_tag() == T::type_number);
 | 
			
		||||
	assert(array->h.hi_tag() == Array::type_number);
 | 
			
		||||
#endif
 | 
			
		||||
	return array->capacity >> TAG_BITS;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,8 @@ LONG factor_vm::exception_handler(PEXCEPTION_POINTERS pe)
 | 
			
		|||
	else
 | 
			
		||||
		signal_callstack_top = NULL;
 | 
			
		||||
 | 
			
		||||
    switch (e->ExceptionCode) {
 | 
			
		||||
        switch (e->ExceptionCode)
 | 
			
		||||
        {
 | 
			
		||||
        case EXCEPTION_ACCESS_VIOLATION:
 | 
			
		||||
		signal_fault_addr = e->ExceptionInformation[1];
 | 
			
		||||
		c->EIP = (cell)factor::memory_signal_handler_impl;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -330,6 +330,7 @@ void factor_vm::compile_all_words()
 | 
			
		|||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
        printf("done\n");
 | 
			
		||||
	/* Update XTs in code heap */
 | 
			
		||||
	word_updater updater(this);
 | 
			
		||||
	iterate_code_heap(updater);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
#include "master.hpp"
 | 
			
		||||
 | 
			
		||||
namespace factor
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
factor_vm::factor_vm()
 | 
			
		||||
{
 | 
			
		||||
        memset(this,0,sizeof(factor_vm));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -535,7 +535,6 @@ struct factor_vm
 | 
			
		|||
	//code_heap
 | 
			
		||||
	heap *code;
 | 
			
		||||
	unordered_map<heap_block *, char *> forwarding;
 | 
			
		||||
	typedef void (factor_vm::*code_heap_iterator)(code_block *compiled);
 | 
			
		||||
 | 
			
		||||
	void init_code_heap(cell size);
 | 
			
		||||
	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);
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	}
 | 
			
		||||
	factor_vm();
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue