vm: replace remaining stack_frame-based logic
							parent
							
								
									d74f194b07
								
							
						
					
					
						commit
						604ceb957c
					
				
							
								
								
									
										112
									
								
								vm/callstack.cpp
								
								
								
								
							
							
						
						
									
										112
									
								
								vm/callstack.cpp
								
								
								
								
							| 
						 | 
				
			
			@ -3,14 +3,6 @@
 | 
			
		|||
namespace factor
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
void factor_vm::check_frame(stack_frame *frame)
 | 
			
		||||
{
 | 
			
		||||
#ifdef FACTOR_DEBUG
 | 
			
		||||
	check_code_pointer((cell)frame->entry_point);
 | 
			
		||||
	FACTOR_ASSERT(frame->size != 0);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
callstack *factor_vm::allot_callstack(cell size)
 | 
			
		||||
{
 | 
			
		||||
	callstack *stack = allot<callstack>(callstack_object_size(size));
 | 
			
		||||
| 
						 | 
				
			
			@ -26,22 +18,23 @@ This means that if 'callstack' is called in tail position, we
 | 
			
		|||
will have popped a necessary frame... however this word is only
 | 
			
		||||
called by continuation implementation, and user code shouldn't
 | 
			
		||||
be calling it at all, so we leave it as it is for now. */
 | 
			
		||||
stack_frame *factor_vm::second_from_top_stack_frame(context *ctx)
 | 
			
		||||
void *factor_vm::second_from_top_stack_frame(context *ctx)
 | 
			
		||||
{
 | 
			
		||||
	stack_frame *frame = ctx->bottom_frame();
 | 
			
		||||
	while(frame >= ctx->callstack_top
 | 
			
		||||
		&& frame_successor(frame) >= ctx->callstack_top
 | 
			
		||||
		&& frame_successor(frame_successor(frame)) >= ctx->callstack_top)
 | 
			
		||||
	void *frame_top = ctx->callstack_top;
 | 
			
		||||
	for (unsigned i = 0; i < 2; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		frame = frame_successor(frame);
 | 
			
		||||
		void *pred = frame_predecessor(frame_top);
 | 
			
		||||
		if (pred >= ctx->callstack_bottom)
 | 
			
		||||
			return frame_top;
 | 
			
		||||
		frame_top = pred;
 | 
			
		||||
	}
 | 
			
		||||
	return frame + 1;
 | 
			
		||||
	return frame_top;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cell factor_vm::capture_callstack(context *ctx)
 | 
			
		||||
{
 | 
			
		||||
	stack_frame *top = second_from_top_stack_frame(ctx);
 | 
			
		||||
	stack_frame *bottom = ctx->callstack_bottom;
 | 
			
		||||
	void *top = second_from_top_stack_frame(ctx);
 | 
			
		||||
	void *bottom = ctx->callstack_bottom;
 | 
			
		||||
 | 
			
		||||
	fixnum size = std::max((fixnum)0,(fixnum)bottom - (fixnum)top);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -61,49 +54,13 @@ void factor_vm::primitive_callstack_for()
 | 
			
		|||
	ctx->push(capture_callstack(other_ctx));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
code_block *factor_vm::frame_code(stack_frame *frame)
 | 
			
		||||
void *factor_vm::frame_predecessor(void *frame_top)
 | 
			
		||||
{
 | 
			
		||||
	check_frame(frame);
 | 
			
		||||
	return (code_block *)frame->entry_point - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
code_block_type factor_vm::frame_type(stack_frame *frame)
 | 
			
		||||
{
 | 
			
		||||
	return frame_code(frame)->type();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cell factor_vm::frame_executing(stack_frame *frame)
 | 
			
		||||
{
 | 
			
		||||
	return frame_code(frame)->owner;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cell factor_vm::frame_executing_quot(stack_frame *frame)
 | 
			
		||||
{
 | 
			
		||||
	return frame_code(frame)->owner_quot();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
stack_frame *factor_vm::frame_successor(stack_frame *frame)
 | 
			
		||||
{
 | 
			
		||||
	check_frame(frame);
 | 
			
		||||
	return (stack_frame *)((cell)frame - frame->size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cell factor_vm::frame_offset(stack_frame *frame)
 | 
			
		||||
{
 | 
			
		||||
	char *return_address = (char *)FRAME_RETURN_ADDRESS(frame,this);
 | 
			
		||||
	FACTOR_ASSERT(return_address != 0);
 | 
			
		||||
	return frame_code(frame)->offset(return_address);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::set_frame_offset(stack_frame *frame, cell offset)
 | 
			
		||||
{
 | 
			
		||||
	char *entry_point = (char *)frame_code(frame)->entry_point();
 | 
			
		||||
	FRAME_RETURN_ADDRESS(frame,this) = entry_point + offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cell factor_vm::frame_scan(stack_frame *frame)
 | 
			
		||||
{
 | 
			
		||||
	return frame_code(frame)->scan(this, FRAME_RETURN_ADDRESS(frame,this));
 | 
			
		||||
	void *addr = frame_return_address((void*)frame_top);
 | 
			
		||||
	FACTOR_ASSERT(addr != 0);
 | 
			
		||||
	code_block *owner = code->code_block_for_address((cell)addr);
 | 
			
		||||
	cell frame_size = owner->stack_frame_size_for_address((cell)addr);
 | 
			
		||||
	return (void*)((char*)frame_top + frame_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct stack_frame_accumulator {
 | 
			
		||||
| 
						 | 
				
			
			@ -145,14 +102,18 @@ void factor_vm::primitive_callstack_to_array()
 | 
			
		|||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
stack_frame *factor_vm::innermost_stack_frame(stack_frame *bottom, stack_frame *top)
 | 
			
		||||
void *factor_vm::innermost_stack_frame(void *bottom, void *top)
 | 
			
		||||
{
 | 
			
		||||
	stack_frame *frame = bottom - 1;
 | 
			
		||||
 | 
			
		||||
	while(frame >= top && frame_successor(frame) >= top)
 | 
			
		||||
		frame = frame_successor(frame);
 | 
			
		||||
 | 
			
		||||
	return frame;
 | 
			
		||||
	/* if (top < bottom)
 | 
			
		||||
	{
 | 
			
		||||
		void *pred = frame_predecessor(top);
 | 
			
		||||
		if (pred < bottom)
 | 
			
		||||
			return pred;
 | 
			
		||||
		else
 | 
			
		||||
			return top;
 | 
			
		||||
	}
 | 
			
		||||
	else */
 | 
			
		||||
		return top;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Some primitives implementing a limited form of callstack mutation.
 | 
			
		||||
| 
						 | 
				
			
			@ -160,15 +121,17 @@ Used by the single stepper. */
 | 
			
		|||
void factor_vm::primitive_innermost_stack_frame_executing()
 | 
			
		||||
{
 | 
			
		||||
	callstack *stack = untag_check<callstack>(ctx->pop());
 | 
			
		||||
	stack_frame *frame = innermost_stack_frame(stack->bottom(), stack->top());
 | 
			
		||||
	ctx->push(frame_executing_quot(frame));
 | 
			
		||||
	void *frame = innermost_stack_frame(stack->bottom(), stack->top());
 | 
			
		||||
	void *addr = frame_return_address(frame);
 | 
			
		||||
	ctx->push(code->code_block_for_address((cell)addr)->owner_quot());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::primitive_innermost_stack_frame_scan()
 | 
			
		||||
{
 | 
			
		||||
	callstack *stack = untag_check<callstack>(ctx->pop());
 | 
			
		||||
	stack_frame *frame = innermost_stack_frame(stack->bottom(), stack->top());
 | 
			
		||||
	ctx->push(frame_scan(frame));
 | 
			
		||||
	void *frame = innermost_stack_frame(stack->bottom(), stack->top());
 | 
			
		||||
	void *addr = frame_return_address(frame);
 | 
			
		||||
	ctx->push(code->code_block_for_address((cell)addr)->scan(this,addr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::primitive_set_innermost_stack_frame_quot()
 | 
			
		||||
| 
						 | 
				
			
			@ -181,10 +144,11 @@ void factor_vm::primitive_set_innermost_stack_frame_quot()
 | 
			
		|||
 | 
			
		||||
	jit_compile_quot(quot.value(),true);
 | 
			
		||||
 | 
			
		||||
	stack_frame *inner = innermost_stack_frame(stack->bottom(), stack->top());
 | 
			
		||||
	cell offset = frame_offset(inner);
 | 
			
		||||
	inner->entry_point = quot->entry_point;
 | 
			
		||||
	set_frame_offset(inner,offset);
 | 
			
		||||
	void *inner = innermost_stack_frame(stack->bottom(), stack->top());
 | 
			
		||||
	void *addr = frame_return_address(inner);
 | 
			
		||||
	code_block *block = code->code_block_for_address((cell)addr);
 | 
			
		||||
	cell offset = block->offset(addr);
 | 
			
		||||
	set_frame_return_address(inner, (char*)quot->entry_point + offset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::primitive_callstack_bounds()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,16 +27,6 @@ inline void factor_vm::iterate_callstack_object(callstack *stack_,
 | 
			
		|||
		code_block *owner = code->code_block_for_address((cell)fixed_addr);
 | 
			
		||||
		cell frame_size = owner->stack_frame_size_for_address((cell)fixed_addr);
 | 
			
		||||
 | 
			
		||||
#ifdef FACTOR_DEBUG
 | 
			
		||||
		// check our derived owner and frame size against the ones stored in the frame
 | 
			
		||||
		// by the function prolog
 | 
			
		||||
		stack_frame *frame = (stack_frame*)((char*)frame_top + frame_size) - 1;
 | 
			
		||||
		void *fixed_entry_point =
 | 
			
		||||
			(void*)fixup.translate_code((code_block*)frame->entry_point);
 | 
			
		||||
		FACTOR_ASSERT(owner->entry_point() == fixed_entry_point);
 | 
			
		||||
		FACTOR_ASSERT(frame_size == frame->size);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		iterator(frame_top, frame_size, owner, fixed_addr);
 | 
			
		||||
		frame_offset += frame_size;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -72,16 +62,6 @@ inline void factor_vm::iterate_callstack(context *ctx, Iterator &iterator, Fixup
 | 
			
		|||
 | 
			
		||||
		cell frame_size = fixed_owner->stack_frame_size_for_address((cell)fixed_addr);
 | 
			
		||||
 | 
			
		||||
#ifdef FACTOR_DEBUG
 | 
			
		||||
		// check our derived owner and frame size against the ones stored in the frame
 | 
			
		||||
		// by the function prolog
 | 
			
		||||
		stack_frame *frame = (stack_frame*)(frame_top + frame_size) - 1;
 | 
			
		||||
		void *fixed_entry_point = Fixup::translated_code_block_map
 | 
			
		||||
			? (void*)fixup.translate_code((code_block*)frame->entry_point)
 | 
			
		||||
			: frame->entry_point;
 | 
			
		||||
		FACTOR_ASSERT(owner->entry_point() == fixed_entry_point);
 | 
			
		||||
		FACTOR_ASSERT(frame_size == frame->size);
 | 
			
		||||
#endif
 | 
			
		||||
		void *fixed_addr_for_iter = Fixup::translated_code_block_map
 | 
			
		||||
			? fixed_addr
 | 
			
		||||
			: addr;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,9 +49,6 @@ struct call_frame_code_block_visitor {
 | 
			
		|||
			: fixup.fixup_code(owner);
 | 
			
		||||
		void *fixed_addr = compiled->address_for_offset(owner->offset(addr));
 | 
			
		||||
		set_frame_return_address(frame_top, fixed_addr);
 | 
			
		||||
		// XXX remove this when prolog data is removed
 | 
			
		||||
		stack_frame *frame = (stack_frame*)((char*)frame_top + frame_size) - 1;
 | 
			
		||||
		frame->entry_point = compiled->entry_point();
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -508,14 +508,13 @@ struct find_symbol_at_address_visitor {
 | 
			
		|||
image load. It finds the symbol and library, and throws an error. */
 | 
			
		||||
void factor_vm::undefined_symbol()
 | 
			
		||||
{
 | 
			
		||||
	stack_frame *frame = innermost_stack_frame(ctx->callstack_bottom,
 | 
			
		||||
		ctx->callstack_top);
 | 
			
		||||
	code_block *compiled = frame_code(frame);
 | 
			
		||||
	cell return_address = (cell)FRAME_RETURN_ADDRESS(frame, this);
 | 
			
		||||
	find_symbol_at_address_visitor visitor(this, return_address);
 | 
			
		||||
	void *frame = innermost_stack_frame(ctx->callstack_bottom, ctx->callstack_top);
 | 
			
		||||
	void *return_address = frame_return_address(frame);
 | 
			
		||||
	code_block *compiled = code->code_block_for_address((cell)return_address);
 | 
			
		||||
	find_symbol_at_address_visitor visitor(this, (cell)return_address);
 | 
			
		||||
	compiled->each_instruction_operand(visitor);
 | 
			
		||||
	if (!to_boolean(visitor.symbol))
 | 
			
		||||
		critical_error("Can't find RT_DLSYM at return address", return_address);
 | 
			
		||||
		critical_error("Can't find RT_DLSYM at return address", (cell)return_address);
 | 
			
		||||
	else
 | 
			
		||||
		general_error(ERROR_UNDEFINED_SYMBOL,visitor.symbol,visitor.library);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,8 +20,8 @@ struct context {
 | 
			
		|||
	// First 4 fields accessed directly by compiler. See basis/vm/vm.factor
 | 
			
		||||
 | 
			
		||||
	/* Factor callstack pointers */
 | 
			
		||||
	stack_frame *callstack_top;
 | 
			
		||||
	stack_frame *callstack_bottom;
 | 
			
		||||
	void *callstack_top;
 | 
			
		||||
	void *callstack_bottom;
 | 
			
		||||
 | 
			
		||||
	/* current datastack top pointer */
 | 
			
		||||
	cell datastack;
 | 
			
		||||
| 
						 | 
				
			
			@ -73,11 +73,6 @@ struct context {
 | 
			
		|||
		datastack += sizeof(cell);
 | 
			
		||||
		replace(tagged);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stack_frame *bottom_frame()
 | 
			
		||||
	{
 | 
			
		||||
		return callstack_bottom - 1;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
VM_C_API context *new_context(factor_vm *parent);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ namespace factor
 | 
			
		|||
#define FACTOR_CPU_STRING "ppc.32"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CALLSTACK_BOTTOM(ctx) (stack_frame *)(ctx->callstack_seg->end - 32)
 | 
			
		||||
#define CALLSTACK_BOTTOM(ctx) (void *)(ctx->callstack_seg->end - 32)
 | 
			
		||||
 | 
			
		||||
/* In the instruction sequence:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,18 +13,16 @@ void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell handler)
 | 
			
		|||
		the signal handler to do its thing, and launch the handler without going
 | 
			
		||||
		through the resumable subprimitive. */
 | 
			
		||||
		signal_resumable = false;
 | 
			
		||||
		stack_frame *frame = ctx->bottom_frame();
 | 
			
		||||
		void *frame_top = (void*)ctx->callstack_top;
 | 
			
		||||
 | 
			
		||||
		while((cell)frame >= *sp
 | 
			
		||||
			&& frame >= ctx->callstack_top
 | 
			
		||||
			&& (cell)frame >= ctx->callstack_seg->start + stack_reserved)
 | 
			
		||||
		while(frame_top < ctx->callstack_bottom
 | 
			
		||||
			&& (cell)frame_top < ctx->callstack_seg->start + stack_reserved)
 | 
			
		||||
		{
 | 
			
		||||
			frame = frame_successor(frame);
 | 
			
		||||
			frame_top = frame_predecessor(frame_top);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cell newsp = (cell)(frame+1);
 | 
			
		||||
		*sp = newsp;
 | 
			
		||||
		ctx->callstack_top = (stack_frame*)newsp;
 | 
			
		||||
		*sp = (cell)frame_top;
 | 
			
		||||
		ctx->callstack_top = frame_top;
 | 
			
		||||
		*pc = handler;
 | 
			
		||||
	} else {
 | 
			
		||||
		signal_resumable = true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,6 @@
 | 
			
		|||
namespace factor
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#define FRAME_RETURN_ADDRESS(frame,vm) *(void **)(vm->frame_successor(frame) + 1)
 | 
			
		||||
 | 
			
		||||
inline static void* frame_return_address(void *frame_top)
 | 
			
		||||
{
 | 
			
		||||
	return *(void**)frame_top;
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +11,7 @@ inline static void set_frame_return_address(void *frame_top, void *return_addres
 | 
			
		|||
	*(void**)frame_top = return_address;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define CALLSTACK_BOTTOM(ctx) (stack_frame *)(ctx->callstack_seg->end - sizeof(cell) * 5)
 | 
			
		||||
#define CALLSTACK_BOTTOM(ctx) (void *)(ctx->callstack_seg->end - sizeof(cell) * 5)
 | 
			
		||||
 | 
			
		||||
inline static void flush_icache(cell start, cell len) {}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ template<typename Func> Func factor_vm::get_entry_point(cell n)
 | 
			
		|||
	return (Func)entry_point_word->entry_point;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::unwind_native_frames(cell quot, stack_frame *to)
 | 
			
		||||
void factor_vm::unwind_native_frames(cell quot, void *to)
 | 
			
		||||
{
 | 
			
		||||
	tagged<word> entry_point_word(special_objects[UNWIND_NATIVE_FRAMES_WORD]);
 | 
			
		||||
	void *func = entry_point_word->entry_point;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@ namespace factor
 | 
			
		|||
{
 | 
			
		||||
 | 
			
		||||
typedef void (* c_to_factor_func_type)(cell quot);
 | 
			
		||||
typedef void (* unwind_native_frames_func_type)(cell quot, stack_frame *to);
 | 
			
		||||
typedef void (* unwind_native_frames_func_type)(cell quot, void *to);
 | 
			
		||||
typedef cell (* get_fpu_state_func_type)();
 | 
			
		||||
typedef void (* set_fpu_state_func_type)(cell state);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -349,30 +349,18 @@ struct dll : public object {
 | 
			
		|||
	void *handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct stack_frame {
 | 
			
		||||
	/* Updated by procedure prologue with procedure start address */
 | 
			
		||||
	void *entry_point;
 | 
			
		||||
	/* Frame size in bytes */
 | 
			
		||||
	cell size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct callstack : public object {
 | 
			
		||||
	static const cell type_number = CALLSTACK_TYPE;
 | 
			
		||||
	/* tagged */
 | 
			
		||||
	cell length;
 | 
			
		||||
	
 | 
			
		||||
	stack_frame *frame_at(cell offset) const
 | 
			
		||||
	{
 | 
			
		||||
		return (stack_frame *)((char *)(this + 1) + offset);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void *frame_top_at(cell offset) const
 | 
			
		||||
	{
 | 
			
		||||
		return (void *)((char *)(this + 1) + offset);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stack_frame *top() const { return (stack_frame *)(this + 1); }
 | 
			
		||||
	stack_frame *bottom() const { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
 | 
			
		||||
	void *top() const { return (void *)(this + 1); }
 | 
			
		||||
	void *bottom() const { return (void *)((cell)(this + 1) + untag_fixnum(length)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct tuple : public object {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,31 +49,32 @@ void factor_vm::record_sample(bool prolog_p)
 | 
			
		|||
			counts, special_objects[OBJ_CURRENT_THREAD]));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct record_callstack_sample_iterator {
 | 
			
		||||
	std::vector<cell> *sample_callstacks;
 | 
			
		||||
	bool skip_p;
 | 
			
		||||
 | 
			
		||||
	record_callstack_sample_iterator(std::vector<cell> *sample_callstacks, bool prolog_p)
 | 
			
		||||
		: sample_callstacks(sample_callstacks), skip_p(prolog_p) {}
 | 
			
		||||
 | 
			
		||||
	void operator()(void *frame_top, cell frame_size, code_block *owner, void *addr)
 | 
			
		||||
	{
 | 
			
		||||
		if (skip_p)
 | 
			
		||||
			skip_p = false;
 | 
			
		||||
		else
 | 
			
		||||
			sample_callstacks->push_back(owner->owner);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void factor_vm::record_callstack_sample(cell *begin, cell *end, bool prolog_p)
 | 
			
		||||
{
 | 
			
		||||
	*begin = sample_callstacks.size();
 | 
			
		||||
	stack_frame *frame = ctx->bottom_frame();
 | 
			
		||||
	if (prolog_p)
 | 
			
		||||
	{
 | 
			
		||||
		FACTOR_ASSERT(frame >= ctx->callstack_top);
 | 
			
		||||
		stack_frame *next_frame = frame_successor(frame);
 | 
			
		||||
		while (next_frame >= ctx->callstack_top)
 | 
			
		||||
		{
 | 
			
		||||
			sample_callstacks.push_back(frame_code(frame)->owner);
 | 
			
		||||
			frame = next_frame;
 | 
			
		||||
			next_frame = frame_successor(next_frame);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		while (frame >= ctx->callstack_top)
 | 
			
		||||
		{
 | 
			
		||||
			sample_callstacks.push_back(frame_code(frame)->owner);
 | 
			
		||||
			frame = frame_successor(frame);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	record_callstack_sample_iterator recorder(&sample_callstacks, prolog_p);
 | 
			
		||||
	iterate_callstack(ctx, recorder);
 | 
			
		||||
 | 
			
		||||
	*end = sample_callstacks.size();
 | 
			
		||||
 | 
			
		||||
	std::reverse(sample_callstacks.begin() + *begin, sample_callstacks.end());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::set_sampling_profiler(fixnum rate)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								vm/vm.hpp
								
								
								
								
							
							
						
						
									
										16
									
								
								vm/vm.hpp
								
								
								
								
							| 
						 | 
				
			
			@ -627,22 +627,14 @@ struct factor_vm
 | 
			
		|||
	template<typename Iterator>
 | 
			
		||||
	void iterate_callstack_object(callstack *stack_, Iterator &iterator);
 | 
			
		||||
 | 
			
		||||
	void check_frame(stack_frame *frame);
 | 
			
		||||
	callstack *allot_callstack(cell size);
 | 
			
		||||
	stack_frame *second_from_top_stack_frame(context *ctx);
 | 
			
		||||
	void *second_from_top_stack_frame(context *ctx);
 | 
			
		||||
	cell capture_callstack(context *ctx);
 | 
			
		||||
	void primitive_callstack();
 | 
			
		||||
	void primitive_callstack_for();
 | 
			
		||||
	code_block *frame_code(stack_frame *frame);
 | 
			
		||||
	code_block_type frame_type(stack_frame *frame);
 | 
			
		||||
	cell frame_executing(stack_frame *frame);
 | 
			
		||||
	cell frame_executing_quot(stack_frame *frame);
 | 
			
		||||
	stack_frame *frame_successor(stack_frame *frame);
 | 
			
		||||
	cell frame_scan(stack_frame *frame);
 | 
			
		||||
	cell frame_offset(stack_frame *frame);
 | 
			
		||||
	void set_frame_offset(stack_frame *frame, cell offset);
 | 
			
		||||
	void *frame_predecessor(void *frame);
 | 
			
		||||
	void primitive_callstack_to_array();
 | 
			
		||||
	stack_frame *innermost_stack_frame(stack_frame *bottom, stack_frame *top);
 | 
			
		||||
	void *innermost_stack_frame(void *bottom, void *top);
 | 
			
		||||
	void primitive_innermost_stack_frame_executing();
 | 
			
		||||
	void primitive_innermost_stack_frame_scan();
 | 
			
		||||
	void primitive_set_innermost_stack_frame_quot();
 | 
			
		||||
| 
						 | 
				
			
			@ -714,7 +706,7 @@ struct factor_vm
 | 
			
		|||
	// entry points
 | 
			
		||||
	void c_to_factor(cell quot);
 | 
			
		||||
	template<typename Func> Func get_entry_point(cell n);
 | 
			
		||||
	void unwind_native_frames(cell quot, stack_frame *to);
 | 
			
		||||
	void unwind_native_frames(cell quot, void *to);
 | 
			
		||||
	cell get_fpu_state();
 | 
			
		||||
	void set_fpu_state(cell state);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue