#include "master.hpp" namespace factor { void safepoint_state::enqueue_safepoint(factor_vm *parent) volatile { parent->code->guard_safepoint(); } void safepoint_state::enqueue_fep(factor_vm *parent) volatile { if (parent->fep_p) fatal_error("Low-level debugger interrupted", 0); atomic::store(&fep_p, true); enqueue_safepoint(parent); } void safepoint_state::enqueue_samples(factor_vm *parent, cell samples, cell pc, bool foreign_thread_p) volatile { if (atomic::load(&parent->sampling_profiler_p)) { 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)) atomic::fetch_add(&sample_counts.gc_sample_count, samples); if (atomic::load(&parent->current_jit_count) > 0) atomic::fetch_add(&sample_counts.jit_sample_count, samples); if (!parent->code->seg->in_segment_p(pc)) atomic::fetch_add(&sample_counts.foreign_sample_count, samples); } enqueue_safepoint(parent); } } void safepoint_state::handle_safepoint(factor_vm *parent, cell pc) volatile { parent->code->unguard_safepoint(); parent->faulting_p = false; if (atomic::load(&fep_p)) { if (atomic::load(&parent->sampling_profiler_p)) parent->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); bool prolog_p = (cell)block->entry_point() == pc; parent->record_sample(prolog_p); } } }