VM: merging the profiling_sample and profiling_sample_count classes

This refactoring makes the code a bit simpler.
modern-harvey2
Björn Lindqvist 2017-06-25 01:15:40 +02:00
parent e66b1a594a
commit abbf8f8f1f
5 changed files with 41 additions and 49 deletions

View File

@ -15,21 +15,22 @@ void factor_vm::enqueue_samples(cell samples,
if (!atomic::load(&sampling_profiler_p)) if (!atomic::load(&sampling_profiler_p))
return; return;
atomic::fetch_add(&sample_counts.sample_count, samples); atomic::fetch_add(&current_sample.sample_count, samples);
if (foreign_thread_p) if (foreign_thread_p)
atomic::fetch_add(&sample_counts.foreign_thread_sample_count, samples); atomic::fetch_add(&current_sample.foreign_thread_sample_count, samples);
else { else {
if (atomic::load(&current_gc_p)) if (atomic::load(&current_gc_p))
atomic::fetch_add(&sample_counts.gc_sample_count, samples); atomic::fetch_add(&current_sample.gc_sample_count, samples);
if (atomic::load(&current_jit_count) > 0) if (atomic::load(&current_jit_count) > 0)
atomic::fetch_add(&sample_counts.jit_sample_count, samples); atomic::fetch_add(&current_sample.jit_sample_count, samples);
if (!code->seg->in_segment_p(pc)) if (!code->seg->in_segment_p(pc))
atomic::fetch_add(&sample_counts.foreign_sample_count, samples); atomic::fetch_add(&current_sample.foreign_sample_count, samples);
} }
code->set_safepoint_guard(true); code->set_safepoint_guard(true);
} }
// Allocates memory (record_sample)
void factor_vm::handle_safepoint(cell pc) { void factor_vm::handle_safepoint(cell pc) {
code->set_safepoint_guard(false); code->set_safepoint_guard(false);
faulting_p = false; faulting_p = false;

View File

@ -36,9 +36,9 @@ void factor_vm::growarr_add(array *growarr_, cell elt_) {
set_array_nth(growarr.untagged(), 0, tag_fixnum(count + 1)); set_array_nth(growarr.untagged(), 0, tag_fixnum(count + 1));
} }
profiling_sample_count profiling_sample_count::record_counts() volatile { profiling_sample profiling_sample::record_counts() volatile {
atomic::fence(); atomic::fence();
profiling_sample_count returned(sample_count, gc_sample_count, profiling_sample returned(sample_count, gc_sample_count,
jit_sample_count, foreign_sample_count, jit_sample_count, foreign_sample_count,
foreign_thread_sample_count); foreign_thread_sample_count);
atomic::fetch_subtract(&sample_count, returned.sample_count); atomic::fetch_subtract(&sample_count, returned.sample_count);
@ -50,7 +50,7 @@ profiling_sample_count profiling_sample_count::record_counts() volatile {
return returned; return returned;
} }
void profiling_sample_count::clear() volatile { void profiling_sample::clear_counts() volatile {
sample_count = 0; sample_count = 0;
gc_sample_count = 0; gc_sample_count = 0;
jit_sample_count = 0; jit_sample_count = 0;
@ -59,16 +59,10 @@ void profiling_sample_count::clear() volatile {
atomic::fence(); atomic::fence();
} }
profiling_sample::profiling_sample(profiling_sample_count const& counts, cell thread,
cell callstack_begin, cell callstack_end)
: counts(counts), thread(thread),
callstack_begin(callstack_begin),
callstack_end(callstack_end) { }
// Allocates memory (sample_callstacks2->add) // Allocates memory (sample_callstacks2->add)
void factor_vm::record_sample(bool prolog_p) { void factor_vm::record_sample(bool prolog_p) {
profiling_sample_count counts = sample_counts.record_counts(); profiling_sample result = current_sample.record_counts();
if (counts.empty()) { if (result.empty()) {
return; return;
} }
// Appends the callstack, which is just a sequence of quotation or // Appends the callstack, which is just a sequence of quotation or
@ -89,8 +83,10 @@ void factor_vm::record_sample(bool prolog_p) {
cell end = growarr_capacity(callstacks.untagged()); cell end = growarr_capacity(callstacks.untagged());
// Add the sample. // Add the sample.
cell thread = special_objects[OBJ_CURRENT_THREAD]; result.thread = special_objects[OBJ_CURRENT_THREAD];
samples.push_back(profiling_sample(counts, thread, begin, end)); result.callstack_begin = begin;
result.callstack_end = end;
samples.push_back(result);
} }
void factor_vm::set_sampling_profiler(fixnum rate) { void factor_vm::set_sampling_profiler(fixnum rate) {
@ -104,7 +100,7 @@ void factor_vm::set_sampling_profiler(fixnum rate) {
void factor_vm::start_sampling_profiler(fixnum rate) { void factor_vm::start_sampling_profiler(fixnum rate) {
special_objects[OBJ_SAMPLE_CALLSTACKS] = tag<array>(allot_growarr()); special_objects[OBJ_SAMPLE_CALLSTACKS] = tag<array>(allot_growarr());
samples_per_second = rate; samples_per_second = rate;
sample_counts.clear(); current_sample.clear_counts();
// Release the memory consumed by collecting samples. // Release the memory consumed by collecting samples.
samples.clear(); samples.clear();
samples.shrink_to_fit(); samples.shrink_to_fit();
@ -141,15 +137,15 @@ void factor_vm::primitive_get_samples() {
data_root<array> sample(allot_array(7, false_object), this); data_root<array> sample(allot_array(7, false_object), this);
set_array_nth(sample.untagged(), 0, set_array_nth(sample.untagged(), 0,
tag_fixnum(from_iter->counts.sample_count)); tag_fixnum(from_iter->sample_count));
set_array_nth(sample.untagged(), 1, set_array_nth(sample.untagged(), 1,
tag_fixnum(from_iter->counts.gc_sample_count)); tag_fixnum(from_iter->gc_sample_count));
set_array_nth(sample.untagged(), 2, set_array_nth(sample.untagged(), 2,
tag_fixnum(from_iter->counts.jit_sample_count)); tag_fixnum(from_iter->jit_sample_count));
set_array_nth(sample.untagged(), 3, set_array_nth(sample.untagged(), 3,
tag_fixnum(from_iter->counts.foreign_sample_count)); tag_fixnum(from_iter->foreign_sample_count));
set_array_nth(sample.untagged(), 4, set_array_nth(sample.untagged(), 4,
tag_fixnum(from_iter->counts.foreign_thread_sample_count)); tag_fixnum(from_iter->foreign_thread_sample_count));
set_array_nth(sample.untagged(), 5, from_iter->thread); set_array_nth(sample.untagged(), 5, from_iter->thread);

View File

@ -1,6 +1,12 @@
namespace factor { namespace factor {
struct profiling_sample_count { struct profiling_sample {
// Active thread during sample
cell thread;
// The callstack at safepoint time. Indexes to the beginning and ending
// word entries in the vm sample_callstacks array.
cell callstack_begin, callstack_end;
// 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;
// Number of samples taken during GC // Number of samples taken during GC
@ -12,36 +18,25 @@ struct profiling_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(fixnum sample_count, fixnum gc_sample_count, profiling_sample(fixnum sample_count, fixnum gc_sample_count,
fixnum jit_sample_count, fixnum foreign_sample_count, fixnum jit_sample_count, fixnum foreign_sample_count,
fixnum foreign_thread_sample_count) fixnum foreign_thread_sample_count)
: sample_count(sample_count), : thread(0),
callstack_begin(0),
callstack_end(0),
sample_count(sample_count),
gc_sample_count(gc_sample_count), gc_sample_count(gc_sample_count),
jit_sample_count(jit_sample_count), jit_sample_count(jit_sample_count),
foreign_sample_count(foreign_sample_count), foreign_sample_count(foreign_sample_count),
foreign_thread_sample_count(foreign_thread_sample_count) {} foreign_thread_sample_count(foreign_thread_sample_count) {}
profiling_sample record_counts() volatile;
void clear_counts() volatile;
bool empty() const { bool empty() const {
return sample_count + gc_sample_count + jit_sample_count + return sample_count + gc_sample_count + jit_sample_count +
foreign_sample_count + foreign_thread_sample_count == foreign_sample_count + foreign_thread_sample_count ==
0; 0;
} }
profiling_sample_count record_counts() volatile;
void clear() volatile;
};
struct profiling_sample {
// Sample counts
profiling_sample_count counts;
// Active thread during sample
cell thread;
// 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(profiling_sample_count const& counts, cell thread,
cell callstack_begin, cell callstack_end);
}; };
} }

View File

@ -16,7 +16,7 @@ factor_vm::factor_vm(THREADHANDLE thread)
sampling_profiler_p(false), sampling_profiler_p(false),
signal_pipe_input(0), signal_pipe_input(0),
signal_pipe_output(0), signal_pipe_output(0),
sample_counts(0, 0, 0, 0, 0), current_sample(0, 0, 0, 0, 0),
gc_off(false), gc_off(false),
data(NULL), code(NULL), callbacks(NULL), data(NULL), code(NULL), callbacks(NULL),
current_gc(NULL), current_gc(NULL),

View File

@ -86,7 +86,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;
volatile profiling_sample_count sample_counts; volatile profiling_sample current_sample;
// GC is off during heap walking // GC is off during heap walking
bool gc_off; bool gc_off;