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
Joe Groff 2011-10-29 14:41:48 -07:00
parent b341b0ce13
commit be5c7476d7
3 changed files with 36 additions and 14 deletions

View File

@ -3,6 +3,18 @@
namespace factor 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() void factor_vm::record_sample()
{ {
cell recorded_sample_count; cell recorded_sample_count;
@ -18,13 +30,26 @@ void factor_vm::record_sample()
FACTOR_ATOMIC_SUB(&safepoint_gc_sample_count, recorded_gc_sample_count); FACTOR_ATOMIC_SUB(&safepoint_gc_sample_count, recorded_gc_sample_count);
samples.push_back(profiling_sample( samples.push_back(profiling_sample(
this,
recorded_sample_count, recorded_sample_count,
recorded_gc_sample_count, recorded_gc_sample_count,
ctx, ctx
capture_callstack(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) void factor_vm::set_sampling_profiler(bool sampling_p)
{ {
if (sampling_p == sampling_profiler_p) if (sampling_p == sampling_profiler_p)
@ -42,6 +67,7 @@ void factor_vm::start_sampling_profiler()
safepoint_gc_sample_count = 0; safepoint_gc_sample_count = 0;
samples.clear(); samples.clear();
samples.reserve(10*FACTOR_PROFILE_SAMPLES_PER_SECOND); samples.reserve(10*FACTOR_PROFILE_SAMPLES_PER_SECOND);
sample_callstacks.reserve(100*FACTOR_PROFILE_SAMPLES_PER_SECOND);
sampling_profiler_p = true; sampling_profiler_p = true;
start_sampling_profiler_timer(); start_sampling_profiler_timer();
} }

View File

@ -11,20 +11,14 @@ struct profiling_sample
cell gc_sample_count; cell gc_sample_count;
// Active context during sample // Active context during sample
context *ctx; context *ctx;
// The callstack at safepoint time /* The callstack at safepoint time. Indexes to the beginning and ending
cell callstack; 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, cell gc_sample_count,
context *ctx, context *ctx);
cell callstack)
:
sample_count(sample_count),
gc_sample_count(gc_sample_count),
ctx(ctx),
callstack(callstack)
{
}
}; };
} }

View File

@ -74,6 +74,7 @@ struct factor_vm
/* State kept by the sampling profiler */ /* State kept by the sampling profiler */
std::vector<profiling_sample> samples; std::vector<profiling_sample> samples;
std::vector<code_block*> sample_callstacks;
volatile cell safepoint_sample_count; volatile cell safepoint_sample_count;
volatile cell safepoint_gc_sample_count; volatile cell safepoint_gc_sample_count;
@ -191,6 +192,7 @@ struct factor_vm
/* Sampling profiler */ /* Sampling profiler */
void record_sample(); void record_sample();
void record_callstack_sample(cell *begin, cell *end);
void start_sampling_profiler(); void start_sampling_profiler();
void end_sampling_profiler(); void end_sampling_profiler();
void set_sampling_profiler(bool sampling); void set_sampling_profiler(bool sampling);