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))
return;
atomic::fetch_add(&sample_counts.sample_count, samples);
atomic::fetch_add(&current_sample.sample_count, samples);
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 {
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)
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))
atomic::fetch_add(&sample_counts.foreign_sample_count, samples);
atomic::fetch_add(&current_sample.foreign_sample_count, samples);
}
code->set_safepoint_guard(true);
}
// Allocates memory (record_sample)
void factor_vm::handle_safepoint(cell pc) {
code->set_safepoint_guard(false);
faulting_p = false;

View File

@ -36,11 +36,11 @@ void factor_vm::growarr_add(array *growarr_, cell elt_) {
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();
profiling_sample_count returned(sample_count, gc_sample_count,
jit_sample_count, foreign_sample_count,
foreign_thread_sample_count);
profiling_sample returned(sample_count, gc_sample_count,
jit_sample_count, foreign_sample_count,
foreign_thread_sample_count);
atomic::fetch_subtract(&sample_count, returned.sample_count);
atomic::fetch_subtract(&gc_sample_count, returned.gc_sample_count);
atomic::fetch_subtract(&jit_sample_count, returned.jit_sample_count);
@ -50,7 +50,7 @@ profiling_sample_count profiling_sample_count::record_counts() volatile {
return returned;
}
void profiling_sample_count::clear() volatile {
void profiling_sample::clear_counts() volatile {
sample_count = 0;
gc_sample_count = 0;
jit_sample_count = 0;
@ -59,16 +59,10 @@ void profiling_sample_count::clear() volatile {
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)
void factor_vm::record_sample(bool prolog_p) {
profiling_sample_count counts = sample_counts.record_counts();
if (counts.empty()) {
profiling_sample result = current_sample.record_counts();
if (result.empty()) {
return;
}
// 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());
// Add the sample.
cell thread = special_objects[OBJ_CURRENT_THREAD];
samples.push_back(profiling_sample(counts, thread, begin, end));
result.thread = special_objects[OBJ_CURRENT_THREAD];
result.callstack_begin = begin;
result.callstack_end = end;
samples.push_back(result);
}
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) {
special_objects[OBJ_SAMPLE_CALLSTACKS] = tag<array>(allot_growarr());
samples_per_second = rate;
sample_counts.clear();
current_sample.clear_counts();
// Release the memory consumed by collecting samples.
samples.clear();
samples.shrink_to_fit();
@ -141,15 +137,15 @@ void factor_vm::primitive_get_samples() {
data_root<array> sample(allot_array(7, false_object), this);
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,
tag_fixnum(from_iter->counts.gc_sample_count));
tag_fixnum(from_iter->gc_sample_count));
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,
tag_fixnum(from_iter->counts.foreign_sample_count));
tag_fixnum(from_iter->foreign_sample_count));
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);

View File

@ -1,6 +1,12 @@
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
fixnum sample_count;
// 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
fixnum foreign_thread_sample_count;
profiling_sample_count(fixnum sample_count, fixnum gc_sample_count,
fixnum jit_sample_count, fixnum foreign_sample_count,
fixnum foreign_thread_sample_count)
: sample_count(sample_count),
profiling_sample(fixnum sample_count, fixnum gc_sample_count,
fixnum jit_sample_count, fixnum foreign_sample_count,
fixnum foreign_thread_sample_count)
: thread(0),
callstack_begin(0),
callstack_end(0),
sample_count(sample_count),
gc_sample_count(gc_sample_count),
jit_sample_count(jit_sample_count),
foreign_sample_count(foreign_sample_count),
foreign_thread_sample_count(foreign_thread_sample_count) {}
profiling_sample record_counts() volatile;
void clear_counts() volatile;
bool empty() const {
return sample_count + gc_sample_count + jit_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 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),
signal_pipe_input(0),
signal_pipe_output(0),
sample_counts(0, 0, 0, 0, 0),
current_sample(0, 0, 0, 0, 0),
gc_off(false),
data(NULL), code(NULL), callbacks(NULL),
current_gc(NULL),

View File

@ -86,7 +86,7 @@ struct factor_vm {
// State kept by the sampling profiler
std::vector<profiling_sample> samples;
volatile profiling_sample_count sample_counts;
volatile profiling_sample current_sample;
// GC is off during heap walking
bool gc_off;