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
							parent
							
								
									2f6f69eb5b
								
							
						
					
					
						commit
						b5c6658ae5
					
				| 
						 | 
				
			
			@ -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 \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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(¤t_gc_p))
 | 
			
		||||
      atomic::fetch_add(&sample_counts.gc_sample_count, samples);
 | 
			
		||||
    if (atomic::load(&parent->current_jit_count) > 0)
 | 
			
		||||
    if (atomic::load(¤t_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);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								vm/vm.hpp
								
								
								
								
							
							
						
						
									
										10
									
								
								vm/vm.hpp
								
								
								
								
							| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue