diff --git a/vm/sampling_profiler.cpp b/vm/sampling_profiler.cpp index 08e6427654..b7311d78f7 100644 --- a/vm/sampling_profiler.cpp +++ b/vm/sampling_profiler.cpp @@ -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(); } diff --git a/vm/sampling_profiler.hpp b/vm/sampling_profiler.hpp index 540d6b6913..86c3d3cc84 100644 --- a/vm/sampling_profiler.hpp +++ b/vm/sampling_profiler.hpp @@ -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); }; } diff --git a/vm/vm.hpp b/vm/vm.hpp index 2c2772e990..a29716b877 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -74,6 +74,7 @@ struct factor_vm /* State kept by the sampling profiler */ std::vector samples; + std::vector 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);