vm: move dispatch_signal_handler to cpu-x86.cpp
The new signal handler dispatch is logic is CISC-centric; defer fixing it until we find someone who caresdb4
							parent
							
								
									a6b80f3efa
								
							
						
					
					
						commit
						5d59faa7d1
					
				| 
						 | 
				
			
			@ -1 +1,2 @@
 | 
			
		|||
PLAF_DLL_OBJS += vm/cpu-x86.o
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +1,2 @@
 | 
			
		|||
PLAF_DLL_OBJS += vm/cpu-x86.o
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,75 +18,6 @@ callstack *factor_vm::allot_callstack(cell size)
 | 
			
		|||
	return stack;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell handler)
 | 
			
		||||
{
 | 
			
		||||
	if (!code->seg->in_segment_p(*pc) || *sp < ctx->callstack_seg->start + stack_reserved)
 | 
			
		||||
	{
 | 
			
		||||
		/* Fault came from foreign code, a callstack overflow, or we would probably
 | 
			
		||||
		overflow if we tried the resumable handler. We can't resume, so cut the
 | 
			
		||||
		callstack down to the shallowest Factor stack frame that leaves room for
 | 
			
		||||
		the signal handler to do its thing and launch the handler without going
 | 
			
		||||
		through the resumable subprimitive. */
 | 
			
		||||
		signal_resumable = false;
 | 
			
		||||
		stack_frame *frame = ctx->callstack_bottom - 1;
 | 
			
		||||
 | 
			
		||||
		while((cell)frame >= *sp
 | 
			
		||||
			&& frame >= ctx->callstack_top
 | 
			
		||||
			&& (cell)frame >= ctx->callstack_seg->start + stack_reserved)
 | 
			
		||||
		{
 | 
			
		||||
			frame = frame_successor(frame);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// XXX FRAME_RETURN_ADDRESS
 | 
			
		||||
		cell newsp = (cell)(frame+1);
 | 
			
		||||
		*sp = newsp;
 | 
			
		||||
		ctx->callstack_top = (stack_frame*)newsp;
 | 
			
		||||
		*pc = handler;
 | 
			
		||||
	} else {
 | 
			
		||||
		signal_resumable = true;
 | 
			
		||||
		// Fault came from Factor, and we've got a good callstack. Route the signal
 | 
			
		||||
		// handler through the resumable signal handler subprimitive.
 | 
			
		||||
		cell offset = *sp % 16;
 | 
			
		||||
 | 
			
		||||
		signal_handler_addr = handler;
 | 
			
		||||
		tagged<word> handler_word = tagged<word>(special_objects[SIGNAL_HANDLER_WORD]);
 | 
			
		||||
 | 
			
		||||
		/* XXX horribly x86-centric */
 | 
			
		||||
		/* True stack frames are always 16-byte aligned. Leaf procedures
 | 
			
		||||
		that don't create a stack frame will be out of alignment by sizeof(cell)
 | 
			
		||||
		bytes. */
 | 
			
		||||
		/* On architectures with a link register we would have to check for leafness
 | 
			
		||||
		by matching the PC to a word. We should also use FRAME_RETURN_ADDRESS instead
 | 
			
		||||
		of assuming the stack pointer is the right place to put the resume address. */
 | 
			
		||||
		if (offset == 0)
 | 
			
		||||
		{
 | 
			
		||||
			cell newsp = *sp - sizeof(cell);
 | 
			
		||||
			*sp = newsp;
 | 
			
		||||
			*(cell*)newsp = *pc;
 | 
			
		||||
		}
 | 
			
		||||
		else if (offset == 16 - sizeof(cell))
 | 
			
		||||
		{
 | 
			
		||||
			// Make a fake frame for the leaf procedure
 | 
			
		||||
			code_block *leaf_block = code->code_block_for_address(*pc);
 | 
			
		||||
			assert(leaf_block != NULL);
 | 
			
		||||
 | 
			
		||||
			// XXX get platform-appropriate stack frame size
 | 
			
		||||
			cell newsp = *sp - 32;
 | 
			
		||||
			*(cell*)(newsp + 32 -   sizeof(cell)) = 32;
 | 
			
		||||
			*(cell*)(newsp + 32 - 2*sizeof(cell)) = (cell)leaf_block->entry_point();
 | 
			
		||||
			*(cell*) newsp                        = *pc;
 | 
			
		||||
			*sp = newsp;
 | 
			
		||||
			handler_word = tagged<word>(special_objects[LEAF_SIGNAL_HANDLER_WORD]);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			fatal_error("Invalid stack frame during signal handler", *sp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		*pc = (cell)handler_word->code->entry_point();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* We ignore the two topmost frames, the 'callstack' primitive
 | 
			
		||||
frame itself, and the frame calling the 'callstack' primitive,
 | 
			
		||||
so that set-callstack doesn't get stuck in an infinite loop.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
#include "master.hpp"
 | 
			
		||||
 | 
			
		||||
namespace factor
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell handler)
 | 
			
		||||
{
 | 
			
		||||
	if (!code->seg->in_segment_p(*pc) || *sp < ctx->callstack_seg->start + stack_reserved)
 | 
			
		||||
	{
 | 
			
		||||
		/* Fault came from foreign code, a callstack overflow, or we would probably
 | 
			
		||||
		overflow if we tried the resumable handler. We can't resume, so cut the
 | 
			
		||||
		callstack down to the shallowest Factor stack frame that leaves room for
 | 
			
		||||
		the signal handler to do its thing and launch the handler without going
 | 
			
		||||
		through the resumable subprimitive. */
 | 
			
		||||
		signal_resumable = false;
 | 
			
		||||
		stack_frame *frame = ctx->callstack_bottom - 1;
 | 
			
		||||
 | 
			
		||||
		while((cell)frame >= *sp
 | 
			
		||||
			&& frame >= ctx->callstack_top
 | 
			
		||||
			&& (cell)frame >= ctx->callstack_seg->start + stack_reserved)
 | 
			
		||||
		{
 | 
			
		||||
			frame = frame_successor(frame);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cell newsp = (cell)(frame+1);
 | 
			
		||||
		*sp = newsp;
 | 
			
		||||
		ctx->callstack_top = (stack_frame*)newsp;
 | 
			
		||||
		*pc = handler;
 | 
			
		||||
	} else {
 | 
			
		||||
		signal_resumable = true;
 | 
			
		||||
		// Fault came from Factor, and we've got a good callstack. Route the signal
 | 
			
		||||
		// handler through the resumable signal handler subprimitive.
 | 
			
		||||
		cell offset = *sp % 16;
 | 
			
		||||
 | 
			
		||||
		signal_handler_addr = handler;
 | 
			
		||||
		tagged<word> handler_word = tagged<word>(special_objects[SIGNAL_HANDLER_WORD]);
 | 
			
		||||
 | 
			
		||||
		/* True stack frames are always 16-byte aligned. Leaf procedures
 | 
			
		||||
		that don't create a stack frame will be out of alignment by sizeof(cell)
 | 
			
		||||
		bytes. */
 | 
			
		||||
		/* On architectures with a link register we would have to check for leafness
 | 
			
		||||
		by matching the PC to a word. We should also use FRAME_RETURN_ADDRESS instead
 | 
			
		||||
		of assuming the stack pointer is the right place to put the resume address. */
 | 
			
		||||
		if (offset == 0)
 | 
			
		||||
		{
 | 
			
		||||
			cell newsp = *sp - sizeof(cell);
 | 
			
		||||
			*sp = newsp;
 | 
			
		||||
			*(cell*)newsp = *pc;
 | 
			
		||||
		}
 | 
			
		||||
		else if (offset == 16 - sizeof(cell))
 | 
			
		||||
		{
 | 
			
		||||
			// Make a fake frame for the leaf procedure
 | 
			
		||||
			code_block *leaf_block = code->code_block_for_address(*pc);
 | 
			
		||||
			assert(leaf_block != NULL);
 | 
			
		||||
 | 
			
		||||
			cell newsp = *sp - 32;
 | 
			
		||||
			*(cell*)(newsp + 32 -   sizeof(cell)) = 32;
 | 
			
		||||
			*(cell*)(newsp + 32 - 2*sizeof(cell)) = (cell)leaf_block->entry_point();
 | 
			
		||||
			*(cell*) newsp                        = *pc;
 | 
			
		||||
			*sp = newsp;
 | 
			
		||||
			handler_word = tagged<word>(special_objects[LEAF_SIGNAL_HANDLER_WORD]);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			fatal_error("Invalid stack frame during signal handler", *sp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		*pc = (cell)handler_word->code->entry_point();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -63,9 +63,9 @@ void factor_vm::call_fault_handler(
 | 
			
		|||
	assert(handler != 0);
 | 
			
		||||
 | 
			
		||||
	dispatch_signal_handler(
 | 
			
		||||
		&MACH_STACK_POINTER(thread_state),
 | 
			
		||||
		&MACH_PROGRAM_COUNTER(thread_state),
 | 
			
		||||
		handler
 | 
			
		||||
		(cell*)&MACH_STACK_POINTER(thread_state),
 | 
			
		||||
		(cell*)&MACH_PROGRAM_COUNTER(thread_state),
 | 
			
		||||
		(cell)handler
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,8 +18,7 @@ void register_vm_with_thread(factor_vm *vm)
 | 
			
		|||
 | 
			
		||||
factor_vm *current_vm_p()
 | 
			
		||||
{
 | 
			
		||||
	factor_vm *vm = (factor_vm*)pthread_getspecific(current_vm_tls_key);
 | 
			
		||||
	return vm;
 | 
			
		||||
	return (factor_vm*)pthread_getspecific(current_vm_tls_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,9 +139,9 @@ void code_heap::unguard_safepoint()
 | 
			
		|||
void factor_vm::dispatch_signal(void *uap, void (handler)())
 | 
			
		||||
{
 | 
			
		||||
	dispatch_signal_handler(
 | 
			
		||||
		&UAP_STACK_POINTER(uap),
 | 
			
		||||
		&UAP_PROGRAM_COUNTER(uap),
 | 
			
		||||
		FUNCTION_CODE_POINTER(handler)
 | 
			
		||||
		(cell*)&UAP_STACK_POINTER(uap),
 | 
			
		||||
		(cell*)&UAP_PROGRAM_COUNTER(uap),
 | 
			
		||||
		(cell)FUNCTION_CODE_POINTER(handler)
 | 
			
		||||
	);
 | 
			
		||||
	UAP_SET_TOC_POINTER(uap, (cell)FUNCTION_TOC_POINTER(handler));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								vm/vm.hpp
								
								
								
								
							
							
						
						
									
										13
									
								
								vm/vm.hpp
								
								
								
								
							| 
						 | 
				
			
			@ -616,18 +616,9 @@ struct factor_vm
 | 
			
		|||
	void primitive_set_innermost_stack_frame_quot();
 | 
			
		||||
	void primitive_callstack_bounds();
 | 
			
		||||
	template<typename Iterator> void iterate_callstack(context *ctx, Iterator &iterator);
 | 
			
		||||
	void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);
 | 
			
		||||
	void dispatch_signal_handler_from_leaf(cell *sp, cell *pc, cell newpc);
 | 
			
		||||
 | 
			
		||||
	template<typename CellA, typename CellB, typename CellC>
 | 
			
		||||
	void dispatch_signal_handler(CellA *sp, CellB *pc, CellC newpc)
 | 
			
		||||
	{
 | 
			
		||||
		dispatch_signal_handler(
 | 
			
		||||
			reinterpret_cast<cell*>(sp),
 | 
			
		||||
			reinterpret_cast<cell*>(pc),
 | 
			
		||||
			(cell)newpc
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
	// cpu-*
 | 
			
		||||
	void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);
 | 
			
		||||
 | 
			
		||||
	// alien
 | 
			
		||||
	char *pinned_alien_offset(cell obj);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue