VM: removing the safepoint_state class

The code reads better if the safepoint_state methods and
attributes (sample_counts and safepoint_fep_p) are moved to the vm
class.
char-rename
Björn Lindqvist 2016-08-15 15:13:30 +02:00
parent 2f6f69eb5b
commit b5c6658ae5
11 changed files with 41 additions and 61 deletions

View File

@ -104,7 +104,6 @@ ifdef CONFIG
vm/image.hpp \
vm/callbacks.hpp \
vm/dispatch.hpp \
vm/safepoints.hpp \
vm/vm.hpp \
vm/allot.hpp \
vm/tagged.hpp \

View File

@ -124,7 +124,7 @@ void factor_vm::primitive_unimplemented() { not_implemented_error(); }
void memory_signal_handler_impl() {
factor_vm* vm = current_vm();
if (vm->code->safepoint_p(vm->signal_fault_addr)) {
vm->safepoint.handle_safepoint(vm, vm->signal_fault_pc);
vm->handle_safepoint(vm->signal_fault_pc);
}
else {
vm_error_type type = vm->ctx->address_to_error(vm->signal_fault_addr);

View File

@ -122,7 +122,6 @@ namespace factor { struct factor_vm; }
#include "image.hpp"
#include "callbacks.hpp"
#include "dispatch.hpp"
#include "safepoints.hpp"
#include "vm.hpp"
#include "allot.hpp"
#include "data_roots.hpp"

View File

@ -170,7 +170,7 @@ void fep_signal_handler(int signal, siginfo_t* siginfo, void* uap) {
factor_vm* vm = current_vm_p();
if (vm) {
vm->safepoint.enqueue_fep(vm);
vm->enqueue_fep();
enqueue_signal(vm, signal);
} else
fatal_error("Foreign thread received signal", signal);
@ -184,8 +184,7 @@ void sample_signal_handler(int signal, siginfo_t* siginfo, void* uap) {
vm = thread_vms.begin()->second;
}
if (atomic::load(&vm->sampling_profiler_p))
vm->safepoint.enqueue_samples(vm, 1, (cell)UAP_PROGRAM_COUNTER(uap),
foreign_thread);
vm->enqueue_samples(1, (cell)UAP_PROGRAM_COUNTER(uap), foreign_thread);
else if (!foreign_thread)
enqueue_signal(vm, signal);
}

View File

@ -275,7 +275,7 @@ static BOOL WINAPI ctrl_handler(DWORD dwCtrlType) {
actually support native threads. */
FACTOR_ASSERT(thread_vms.size() == 1);
factor_vm* vm = thread_vms.begin()->second;
vm->safepoint.enqueue_fep(vm);
vm->enqueue_fep();
/* Before leaving the ctrl_handler, try and wake up the main
thread. */
@ -344,7 +344,7 @@ void factor_vm::sampler_thread_loop() {
continue;
cell pc = get_thread_pc(thread);
safepoint.enqueue_samples(this, samples, pc, false);
enqueue_samples(samples, pc, false);
}
}

View File

@ -2,51 +2,50 @@
namespace factor {
void safepoint_state::enqueue_fep(factor_vm* parent) volatile {
if (parent->fep_p)
void factor_vm::enqueue_fep() {
if (fep_p)
fatal_error("Low-level debugger interrupted", 0);
atomic::store(&fep_p, true);
parent->code->set_safepoint_guard(true);
atomic::store(&safepoint_fep_p, true);
code->set_safepoint_guard(true);
}
void safepoint_state::enqueue_samples(factor_vm* parent,
cell samples,
cell pc,
bool foreign_thread_p) volatile {
void factor_vm::enqueue_samples(cell samples,
cell pc,
bool foreign_thread_p) {
if (!atomic::load(&parent->sampling_profiler_p))
if (!atomic::load(&sampling_profiler_p))
return;
atomic::fetch_add(&sample_counts.sample_count, samples);
if (foreign_thread_p)
atomic::fetch_add(&sample_counts.foreign_thread_sample_count, samples);
else {
if (atomic::load(&parent->current_gc_p))
if (atomic::load(&current_gc_p))
atomic::fetch_add(&sample_counts.gc_sample_count, samples);
if (atomic::load(&parent->current_jit_count) > 0)
if (atomic::load(&current_jit_count) > 0)
atomic::fetch_add(&sample_counts.jit_sample_count, samples);
if (!parent->code->seg->in_segment_p(pc))
if (!code->seg->in_segment_p(pc))
atomic::fetch_add(&sample_counts.foreign_sample_count, samples);
}
parent->code->set_safepoint_guard(true);
code->set_safepoint_guard(true);
}
void safepoint_state::handle_safepoint(factor_vm* parent, cell pc) volatile {
parent->code->set_safepoint_guard(false);
parent->faulting_p = false;
void factor_vm::handle_safepoint(cell pc) {
code->set_safepoint_guard(false);
faulting_p = false;
if (atomic::load(&fep_p)) {
if (atomic::load(&parent->sampling_profiler_p))
parent->end_sampling_profiler();
if (atomic::load(&safepoint_fep_p)) {
if (atomic::load(&sampling_profiler_p))
end_sampling_profiler();
std::cout << "Interrupted\n";
parent->factorbug();
atomic::store(&fep_p, false);
} else if (atomic::load(&parent->sampling_profiler_p)) {
FACTOR_ASSERT(parent->code->seg->in_segment_p(pc));
code_block* block = parent->code->code_block_for_address(pc);
factorbug();
atomic::store(&safepoint_fep_p, false);
} else if (atomic::load(&sampling_profiler_p)) {
FACTOR_ASSERT(code->seg->in_segment_p(pc));
code_block* block = code->code_block_for_address(pc);
bool prolog_p = block->entry_point() == pc;
parent->record_sample(prolog_p);
record_sample(prolog_p);
}
}

View File

@ -1,16 +0,0 @@
namespace factor {
struct safepoint_state {
cell fep_p;
profiling_sample_count sample_counts;
safepoint_state() : fep_p(false), sample_counts() {}
void handle_safepoint(factor_vm* parent, cell pc) volatile;
void enqueue_samples(factor_vm* parent, cell samples, cell pc,
bool foreign_thread_p) volatile;
void enqueue_fep(factor_vm* parent) volatile;
};
}

View File

@ -32,7 +32,7 @@ profiling_sample::profiling_sample(profiling_sample_count const& counts, cell th
callstack_end(callstack_end) { }
void factor_vm::record_sample(bool prolog_p) {
profiling_sample_count counts = safepoint.sample_counts.record_counts();
profiling_sample_count counts = sample_counts.record_counts();
if (counts.empty()) {
return;
}
@ -66,7 +66,7 @@ void factor_vm::set_sampling_profiler(fixnum rate) {
void factor_vm::start_sampling_profiler(fixnum rate) {
samples_per_second = rate;
safepoint.sample_counts.clear();
sample_counts.clear();
/* Release the memory consumed by collecting samples. */
samples.clear();
samples.shrink_to_fit();

View File

@ -12,13 +12,6 @@ struct profiling_sample_count {
/* Number of samples taken during code execution in non-Factor threads */
fixnum foreign_thread_sample_count;
profiling_sample_count()
: sample_count(0),
gc_sample_count(0),
jit_sample_count(0),
foreign_sample_count(0),
foreign_thread_sample_count(0) {}
profiling_sample_count(fixnum sample_count, fixnum gc_sample_count,
fixnum jit_sample_count, fixnum foreign_sample_count,
fixnum foreign_thread_sample_count)

View File

@ -12,6 +12,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),
gc_off(false),
data(NULL), code(NULL), callbacks(NULL),
current_gc(NULL),
@ -24,7 +25,7 @@ factor_vm::factor_vm(THREADHANDLE thread)
full_output(false),
last_nano_count(0),
signal_callstack_seg(NULL),
safepoint() {
safepoint_fep_p(false) {
primitive_reset_dispatch_stats();
}

View File

@ -87,6 +87,7 @@ struct factor_vm {
/* State kept by the sampling profiler */
std::vector<profiling_sample> samples;
std::vector<cell> sample_callstacks;
volatile profiling_sample_count sample_counts;
/* GC is off during heap walking */
bool gc_off;
@ -145,8 +146,8 @@ struct factor_vm {
/* Are we already handling a fault? Used to catch double memory faults */
static bool fatal_erroring_p;
/* Safepoint state */
volatile safepoint_state safepoint;
/* Two fep_p variants, one might be redundant. */
volatile cell safepoint_fep_p;
/* contexts */
context* new_context();
@ -679,6 +680,11 @@ struct factor_vm {
cell get_fpu_state();
void set_fpu_state(cell state);
/* safepoints */
void handle_safepoint(cell pc);
void enqueue_samples(cell samples, cell pc, bool foreign_thread_p);
void enqueue_fep();
/* factor */
void prepare_boot_image();
void init_factor(vm_parameters* p);