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
|
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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue