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