vm: don't allocate callstack samples on data heap
Invoking a GC during a safepoint has some complications, so stuff the callstack samples in a vector instead.db4
							parent
							
								
									b341b0ce13
								
							
						
					
					
						commit
						be5c7476d7
					
				| 
						 | 
				
			
			@ -3,6 +3,18 @@
 | 
			
		|||
namespace factor
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
profiling_sample::profiling_sample(factor_vm *vm,
 | 
			
		||||
	cell sample_count,
 | 
			
		||||
	cell gc_sample_count,
 | 
			
		||||
	context *ctx)
 | 
			
		||||
	:
 | 
			
		||||
	sample_count(sample_count),
 | 
			
		||||
	gc_sample_count(gc_sample_count),
 | 
			
		||||
	ctx(ctx)
 | 
			
		||||
{
 | 
			
		||||
	vm->record_callstack_sample(&callstack_begin, &callstack_end);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::record_sample()
 | 
			
		||||
{
 | 
			
		||||
	cell recorded_sample_count;
 | 
			
		||||
| 
						 | 
				
			
			@ -18,13 +30,26 @@ void factor_vm::record_sample()
 | 
			
		|||
	FACTOR_ATOMIC_SUB(&safepoint_gc_sample_count, recorded_gc_sample_count);
 | 
			
		||||
 | 
			
		||||
	samples.push_back(profiling_sample(
 | 
			
		||||
		this,
 | 
			
		||||
		recorded_sample_count,
 | 
			
		||||
		recorded_gc_sample_count,
 | 
			
		||||
		ctx,
 | 
			
		||||
		capture_callstack(ctx)
 | 
			
		||||
		ctx
 | 
			
		||||
	));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::record_callstack_sample(cell *begin, cell *end)
 | 
			
		||||
{
 | 
			
		||||
	*begin = sample_callstacks.size();
 | 
			
		||||
	stack_frame *frame = ctx->callstack_bottom - 1;
 | 
			
		||||
 | 
			
		||||
	while (frame >= ctx->callstack_top) {
 | 
			
		||||
		sample_callstacks.push_back((code_block*)frame->entry_point - 1);
 | 
			
		||||
		frame = frame_successor(frame);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*end = sample_callstacks.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::set_sampling_profiler(bool sampling_p)
 | 
			
		||||
{
 | 
			
		||||
	if (sampling_p == sampling_profiler_p)
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +67,7 @@ void factor_vm::start_sampling_profiler()
 | 
			
		|||
	safepoint_gc_sample_count = 0;
 | 
			
		||||
	samples.clear();
 | 
			
		||||
	samples.reserve(10*FACTOR_PROFILE_SAMPLES_PER_SECOND);
 | 
			
		||||
	sample_callstacks.reserve(100*FACTOR_PROFILE_SAMPLES_PER_SECOND);
 | 
			
		||||
	sampling_profiler_p = true;
 | 
			
		||||
	start_sampling_profiler_timer();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,20 +11,14 @@ struct profiling_sample
 | 
			
		|||
	cell gc_sample_count;
 | 
			
		||||
	// Active context during sample
 | 
			
		||||
	context *ctx;
 | 
			
		||||
	// The callstack at safepoint time
 | 
			
		||||
	cell callstack;
 | 
			
		||||
	/* The callstack at safepoint time. Indexes to the beginning and ending
 | 
			
		||||
	code_block entries in the vm sample_callstacks array. */
 | 
			
		||||
	cell callstack_begin, callstack_end;
 | 
			
		||||
 | 
			
		||||
	profiling_sample(cell sample_count,
 | 
			
		||||
	profiling_sample(factor_vm *vm,
 | 
			
		||||
		cell sample_count,
 | 
			
		||||
		cell gc_sample_count,
 | 
			
		||||
		context *ctx,
 | 
			
		||||
		cell callstack)
 | 
			
		||||
		:
 | 
			
		||||
		sample_count(sample_count),
 | 
			
		||||
		gc_sample_count(gc_sample_count),
 | 
			
		||||
		ctx(ctx),
 | 
			
		||||
		callstack(callstack)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
		context *ctx);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,6 +74,7 @@ struct factor_vm
 | 
			
		|||
 | 
			
		||||
	/* State kept by the sampling profiler */
 | 
			
		||||
	std::vector<profiling_sample> samples;
 | 
			
		||||
	std::vector<code_block*> sample_callstacks;
 | 
			
		||||
	volatile cell safepoint_sample_count;
 | 
			
		||||
	volatile cell safepoint_gc_sample_count;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -191,6 +192,7 @@ struct factor_vm
 | 
			
		|||
 | 
			
		||||
	/* Sampling profiler */
 | 
			
		||||
	void record_sample();
 | 
			
		||||
	void record_callstack_sample(cell *begin, cell *end);
 | 
			
		||||
	void start_sampling_profiler();
 | 
			
		||||
	void end_sampling_profiler();
 | 
			
		||||
	void set_sampling_profiler(bool sampling);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue