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;
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)
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();
}
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);
};
}
/* 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;
/* 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);