]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: don't allocate callstack samples on data heap
authorJoe Groff <arcata@gmail.com>
Sat, 29 Oct 2011 21:41:48 +0000 (14:41 -0700)
committerJoe Groff <arcata@gmail.com>
Wed, 2 Nov 2011 20:23:07 +0000 (13:23 -0700)
Invoking a GC during a safepoint has some complications, so stuff the callstack samples in a vector instead.

vm/sampling_profiler.cpp
vm/sampling_profiler.hpp
vm/vm.hpp

index 08e6427654e08fd3dcb8455c34ad57187a7b03cd..b7311d78f7568eef5ea2d933b0897e0327420347 100644 (file)
@@ -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();
 }
index 540d6b69132c51e2e198a47541206aa16fefa542..86c3d3cc849a7e7c9fb00cfdbf8f888d86363179 100644 (file)
@@ -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);
 };
 
 }
index 2c2772e9909b26a3cf044b08c275a2514b9885d7..a29716b8777040fc671e80a9701536c388795560 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -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);