vm: factor out sample counting code

db4
Joe Groff 2011-10-31 18:27:51 -07:00
parent baebb317e4
commit 27ac4c60f4
5 changed files with 73 additions and 64 deletions

View File

@ -174,14 +174,14 @@ void factor_vm::enqueue_safepoint_sample(cell samples, cell pc, bool foreign_thr
{ {
if (FACTOR_MEMORY_BARRIER(), sampling_profiler_p) if (FACTOR_MEMORY_BARRIER(), sampling_profiler_p)
{ {
FACTOR_ATOMIC_ADD(&safepoint_sample_count, samples); FACTOR_ATOMIC_ADD(&safepoint_sample_counts.sample_count, samples);
if (foreign_thread_p) if (foreign_thread_p)
FACTOR_ATOMIC_ADD(&safepoint_foreign_thread_sample_count, samples); FACTOR_ATOMIC_ADD(&safepoint_sample_counts.foreign_thread_sample_count, samples);
else { else {
if (FACTOR_MEMORY_BARRIER(), current_gc) if (FACTOR_MEMORY_BARRIER(), current_gc)
FACTOR_ATOMIC_ADD(&safepoint_gc_sample_count, samples); FACTOR_ATOMIC_ADD(&safepoint_sample_counts.gc_sample_count, samples);
if (pc != 0 && !code->seg->in_segment_p(pc)) if (pc != 0 && !code->seg->in_segment_p(pc))
FACTOR_ATOMIC_ADD(&safepoint_foreign_sample_count, samples); FACTOR_ATOMIC_ADD(&safepoint_sample_counts.foreign_sample_count, samples);
} }
code->guard_safepoint(); code->guard_safepoint();
} }

View File

@ -3,17 +3,35 @@
namespace factor namespace factor
{ {
profiling_sample_count profiling_sample_count::record_counts() volatile
{
FACTOR_MEMORY_BARRIER();
profiling_sample_count returned(
sample_count,
gc_sample_count,
foreign_sample_count,
foreign_thread_sample_count);
FACTOR_ATOMIC_SUB(&sample_count, returned.sample_count);
FACTOR_ATOMIC_SUB(&gc_sample_count, returned.gc_sample_count);
FACTOR_ATOMIC_SUB(&foreign_sample_count, returned.foreign_sample_count);
FACTOR_ATOMIC_SUB(&foreign_thread_sample_count, returned.foreign_thread_sample_count);
return returned;
}
void profiling_sample_count::clear() volatile
{
sample_count = 0;
gc_sample_count = 0;
foreign_sample_count = 0;
foreign_thread_sample_count = 0;
FACTOR_MEMORY_BARRIER();
}
profiling_sample::profiling_sample(factor_vm *vm, profiling_sample::profiling_sample(factor_vm *vm,
fixnum sample_count, profiling_sample_count const &counts,
fixnum gc_sample_count,
fixnum foreign_sample_count,
fixnum foreign_thread_sample_count,
context *ctx) context *ctx)
: :
sample_count(sample_count), counts(counts),
gc_sample_count(gc_sample_count),
foreign_sample_count(foreign_sample_count),
foreign_thread_sample_count(foreign_thread_sample_count),
ctx(ctx) ctx(ctx)
{ {
vm->record_callstack_sample(&callstack_begin, &callstack_end); vm->record_callstack_sample(&callstack_begin, &callstack_end);
@ -21,37 +39,9 @@ profiling_sample::profiling_sample(factor_vm *vm,
void factor_vm::record_sample() void factor_vm::record_sample()
{ {
fixnum recorded_sample_count; profiling_sample_count counts = safepoint_sample_counts.record_counts();
fixnum recorded_gc_sample_count; if (!counts.empty())
fixnum recorded_foreign_sample_count; samples.push_back(profiling_sample(this, counts, ctx));
fixnum recorded_foreign_thread_sample_count;
FACTOR_MEMORY_BARRIER();
recorded_sample_count = safepoint_sample_count;
recorded_gc_sample_count = safepoint_gc_sample_count;
recorded_foreign_sample_count = safepoint_foreign_sample_count;
recorded_foreign_thread_sample_count = safepoint_foreign_thread_sample_count;
if (recorded_sample_count
+ recorded_gc_sample_count
+ recorded_foreign_sample_count
+ recorded_foreign_thread_sample_count
== 0)
return;
/* Another sample signal could be raised while we record these counts */
FACTOR_ATOMIC_SUB(&safepoint_sample_count, recorded_sample_count);
FACTOR_ATOMIC_SUB(&safepoint_gc_sample_count, recorded_gc_sample_count);
FACTOR_ATOMIC_SUB(&safepoint_foreign_sample_count, recorded_foreign_sample_count);
FACTOR_ATOMIC_SUB(&safepoint_foreign_thread_sample_count, recorded_foreign_thread_sample_count);
samples.push_back(profiling_sample(
this,
recorded_sample_count,
recorded_gc_sample_count,
recorded_foreign_sample_count,
recorded_foreign_thread_sample_count,
ctx
));
} }
void factor_vm::record_callstack_sample(cell *begin, cell *end) void factor_vm::record_callstack_sample(cell *begin, cell *end)
@ -90,10 +80,7 @@ void factor_vm::clear_samples()
void factor_vm::start_sampling_profiler() void factor_vm::start_sampling_profiler()
{ {
safepoint_sample_count = 0; safepoint_sample_counts.clear();
safepoint_gc_sample_count = 0;
safepoint_foreign_sample_count = 0;
safepoint_foreign_thread_sample_count = 0;
clear_samples(); clear_samples();
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); sample_callstacks.reserve(100*FACTOR_PROFILE_SAMPLES_PER_SECOND);
@ -127,10 +114,10 @@ void factor_vm::primitive_get_samples()
{ {
data_root<array> sample(allot_array(6, false_object),this); data_root<array> sample(allot_array(6, false_object),this);
set_array_nth(sample.untagged(),0,from_unsigned_cell(from_iter->sample_count)); set_array_nth(sample.untagged(),0,from_unsigned_cell(from_iter->counts.sample_count));
set_array_nth(sample.untagged(),1,from_unsigned_cell(from_iter->gc_sample_count)); set_array_nth(sample.untagged(),1,from_unsigned_cell(from_iter->counts.gc_sample_count));
set_array_nth(sample.untagged(),2,from_unsigned_cell(from_iter->foreign_sample_count)); set_array_nth(sample.untagged(),2,from_unsigned_cell(from_iter->counts.foreign_sample_count));
set_array_nth(sample.untagged(),3,from_unsigned_cell(from_iter->foreign_thread_sample_count)); set_array_nth(sample.untagged(),3,from_unsigned_cell(from_iter->counts.foreign_thread_sample_count));
set_array_nth(sample.untagged(),4,allot_alien((void*)from_iter->ctx)); set_array_nth(sample.untagged(),4,allot_alien((void*)from_iter->ctx));
cell callstack_size = from_iter->callstack_end - from_iter->callstack_begin; cell callstack_size = from_iter->callstack_end - from_iter->callstack_begin;

View File

@ -3,7 +3,7 @@ namespace factor
#define FACTOR_PROFILE_SAMPLES_PER_SECOND 1000 #define FACTOR_PROFILE_SAMPLES_PER_SECOND 1000
struct profiling_sample struct profiling_sample_count
{ {
// Number of samples taken before the safepoint that recorded the sample // Number of samples taken before the safepoint that recorded the sample
fixnum sample_count; fixnum sample_count;
@ -13,6 +13,38 @@ struct profiling_sample
fixnum foreign_sample_count; fixnum foreign_sample_count;
// Number of samples taken during code execution in non-Factor threads // Number of samples taken during code execution in non-Factor threads
fixnum foreign_thread_sample_count; fixnum foreign_thread_sample_count;
profiling_sample_count() :
sample_count(0),
gc_sample_count(0),
foreign_sample_count(0),
foreign_thread_sample_count(0) {}
profiling_sample_count(fixnum sample_count,
fixnum gc_sample_count,
fixnum foreign_sample_count,
fixnum foreign_thread_sample_count) :
sample_count(sample_count),
gc_sample_count(gc_sample_count),
foreign_sample_count(foreign_sample_count),
foreign_thread_sample_count(foreign_thread_sample_count) {}
bool empty() const
{
return sample_count
+ gc_sample_count
+ foreign_sample_count
+ foreign_thread_sample_count == 0;
}
profiling_sample_count record_counts() volatile;
void clear() volatile;
};
struct profiling_sample
{
// Sample counts
profiling_sample_count counts;
// Active context during sample // Active context during sample
context *ctx; context *ctx;
/* The callstack at safepoint time. Indexes to the beginning and ending /* The callstack at safepoint time. Indexes to the beginning and ending
@ -20,10 +52,7 @@ struct profiling_sample
cell callstack_begin, callstack_end; cell callstack_begin, callstack_end;
profiling_sample(factor_vm *vm, profiling_sample(factor_vm *vm,
fixnum sample_count, profiling_sample_count const &counts,
fixnum gc_sample_count,
fixnum foreign_sample_count,
fixnum foreign_thread_sample_count,
context *ctx); context *ctx);
}; };

View File

@ -10,10 +10,6 @@ factor_vm::factor_vm() :
counting_profiler_p(false), counting_profiler_p(false),
sampling_profiler_p(false), sampling_profiler_p(false),
safepoint_fep(false), safepoint_fep(false),
safepoint_sample_count(0),
safepoint_gc_sample_count(0),
safepoint_foreign_sample_count(0),
safepoint_foreign_thread_sample_count(0),
gc_off(false), gc_off(false),
current_gc(NULL), current_gc(NULL),
gc_events(NULL), gc_events(NULL),

View File

@ -75,10 +75,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; std::vector<code_block*> sample_callstacks;
volatile fixnum safepoint_sample_count; volatile profiling_sample_count safepoint_sample_counts;
volatile fixnum safepoint_gc_sample_count;
volatile fixnum safepoint_foreign_sample_count;
volatile fixnum safepoint_foreign_thread_sample_count;
/* GC is off during heap walking */ /* GC is off during heap walking */
bool gc_off; bool gc_off;