parent
81911b9f87
commit
6c0ecf631a
|
@ -115,10 +115,10 @@ void factor_vm::verify_memory_protection_error(cell addr)
|
||||||
fatal_error("Memory protection fault during gc", addr);
|
fatal_error("Memory protection fault during gc", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::memory_protection_error(cell addr)
|
void factor_vm::memory_protection_error(cell pc, cell addr)
|
||||||
{
|
{
|
||||||
if(code->safepoint_p(addr))
|
if(code->safepoint_p(addr))
|
||||||
safepoint.handle_safepoint(this);
|
safepoint.handle_safepoint(this, pc);
|
||||||
else if(ctx->datastack_seg->underflow_p(addr))
|
else if(ctx->datastack_seg->underflow_p(addr))
|
||||||
general_error(ERROR_DATASTACK_UNDERFLOW,false_object,false_object);
|
general_error(ERROR_DATASTACK_UNDERFLOW,false_object,false_object);
|
||||||
else if(ctx->datastack_seg->overflow_p(addr))
|
else if(ctx->datastack_seg->overflow_p(addr))
|
||||||
|
@ -158,7 +158,7 @@ void factor_vm::primitive_unimplemented()
|
||||||
|
|
||||||
void factor_vm::memory_signal_handler_impl()
|
void factor_vm::memory_signal_handler_impl()
|
||||||
{
|
{
|
||||||
memory_protection_error(signal_fault_addr);
|
memory_protection_error(signal_fault_pc, signal_fault_addr);
|
||||||
if (!signal_resumable)
|
if (!signal_resumable)
|
||||||
{
|
{
|
||||||
/* In theory we should only get here if the callstack overflowed during a
|
/* In theory we should only get here if the callstack overflowed during a
|
||||||
|
|
|
@ -40,6 +40,7 @@ void factor_vm::call_fault_handler(
|
||||||
if(exception == EXC_BAD_ACCESS)
|
if(exception == EXC_BAD_ACCESS)
|
||||||
{
|
{
|
||||||
signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state);
|
signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state);
|
||||||
|
signal_fault_pc = (cell)MACH_PROGRAM_COUNTER(thread_state);
|
||||||
verify_memory_protection_error(signal_fault_addr);
|
verify_memory_protection_error(signal_fault_addr);
|
||||||
handler = (cell)factor::memory_signal_handler_impl;
|
handler = (cell)factor::memory_signal_handler_impl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,6 +167,7 @@ void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
||||||
factor_vm *vm = current_vm();
|
factor_vm *vm = current_vm();
|
||||||
vm->verify_memory_protection_error((cell)siginfo->si_addr);
|
vm->verify_memory_protection_error((cell)siginfo->si_addr);
|
||||||
vm->signal_fault_addr = (cell)siginfo->si_addr;
|
vm->signal_fault_addr = (cell)siginfo->si_addr;
|
||||||
|
vm->signal_fault_pc = (cell)UAP_PROGRAM_COUNTER(uap);
|
||||||
vm->dispatch_signal(uap,factor::memory_signal_handler_impl);
|
vm->dispatch_signal(uap,factor::memory_signal_handler_impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ void safepoint_state::enqueue_samples(factor_vm *parent, cell samples, cell pc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void safepoint_state::handle_safepoint(factor_vm *parent) volatile
|
void safepoint_state::handle_safepoint(factor_vm *parent, cell pc) volatile
|
||||||
{
|
{
|
||||||
parent->code->unguard_safepoint();
|
parent->code->unguard_safepoint();
|
||||||
parent->faulting_p = false;
|
parent->faulting_p = false;
|
||||||
|
@ -49,7 +49,13 @@ void safepoint_state::handle_safepoint(factor_vm *parent) volatile
|
||||||
atomic::store(&fep_p, false);
|
atomic::store(&fep_p, false);
|
||||||
}
|
}
|
||||||
else if (atomic::load(&parent->sampling_profiler_p))
|
else if (atomic::load(&parent->sampling_profiler_p))
|
||||||
parent->record_sample();
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct safepoint_state
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_safepoint(factor_vm *parent) volatile;
|
void handle_safepoint(factor_vm *parent, cell pc) volatile;
|
||||||
|
|
||||||
void enqueue_safepoint(factor_vm *parent) volatile;
|
void enqueue_safepoint(factor_vm *parent) volatile;
|
||||||
void enqueue_samples(factor_vm *parent, cell samples, cell pc, bool foreign_thread_p) volatile;
|
void enqueue_samples(factor_vm *parent, cell samples, cell pc, bool foreign_thread_p) volatile;
|
||||||
|
|
|
@ -31,32 +31,47 @@ void profiling_sample_count::clear() volatile
|
||||||
}
|
}
|
||||||
|
|
||||||
profiling_sample::profiling_sample(factor_vm *vm,
|
profiling_sample::profiling_sample(factor_vm *vm,
|
||||||
|
bool prolog_p,
|
||||||
profiling_sample_count const &counts,
|
profiling_sample_count const &counts,
|
||||||
cell thread)
|
cell thread)
|
||||||
:
|
:
|
||||||
counts(counts),
|
counts(counts),
|
||||||
thread(thread)
|
thread(thread)
|
||||||
{
|
{
|
||||||
vm->record_callstack_sample(&callstack_begin, &callstack_end);
|
vm->record_callstack_sample(&callstack_begin, &callstack_end, prolog_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::record_sample()
|
void factor_vm::record_sample(bool prolog_p)
|
||||||
{
|
{
|
||||||
profiling_sample_count counts = safepoint.sample_counts.record_counts();
|
profiling_sample_count counts = safepoint.sample_counts.record_counts();
|
||||||
if (!counts.empty())
|
if (!counts.empty())
|
||||||
samples.push_back(profiling_sample(this,
|
samples.push_back(profiling_sample(this, prolog_p,
|
||||||
counts, special_objects[OBJ_CURRENT_THREAD]));
|
counts, special_objects[OBJ_CURRENT_THREAD]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::record_callstack_sample(cell *begin, cell *end)
|
void factor_vm::record_callstack_sample(cell *begin, cell *end, bool prolog_p)
|
||||||
{
|
{
|
||||||
*begin = sample_callstacks.size();
|
*begin = sample_callstacks.size();
|
||||||
stack_frame *frame = ctx->bottom_frame();
|
stack_frame *frame = ctx->bottom_frame();
|
||||||
|
if (prolog_p)
|
||||||
while (frame >= ctx->callstack_top) {
|
{
|
||||||
|
assert(frame >= ctx->callstack_top);
|
||||||
|
stack_frame *next_frame = frame_successor(frame);
|
||||||
|
while (next_frame >= ctx->callstack_top)
|
||||||
|
{
|
||||||
|
sample_callstacks.push_back(frame_code(frame)->owner);
|
||||||
|
frame = next_frame;
|
||||||
|
next_frame = frame_successor(next_frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (frame >= ctx->callstack_top)
|
||||||
|
{
|
||||||
sample_callstacks.push_back(frame_code(frame)->owner);
|
sample_callstacks.push_back(frame_code(frame)->owner);
|
||||||
frame = frame_successor(frame);
|
frame = frame_successor(frame);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*end = sample_callstacks.size();
|
*end = sample_callstacks.size();
|
||||||
}
|
}
|
||||||
|
@ -98,7 +113,7 @@ void factor_vm::end_sampling_profiler()
|
||||||
{
|
{
|
||||||
atomic::store(&sampling_profiler_p, false);
|
atomic::store(&sampling_profiler_p, false);
|
||||||
end_sampling_profiler_timer();
|
end_sampling_profiler_timer();
|
||||||
record_sample();
|
record_sample(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_sampling_profiler()
|
void factor_vm::primitive_sampling_profiler()
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct profiling_sample
|
||||||
cell callstack_begin, callstack_end;
|
cell callstack_begin, callstack_end;
|
||||||
|
|
||||||
profiling_sample(factor_vm *vm,
|
profiling_sample(factor_vm *vm,
|
||||||
|
bool prolog_p,
|
||||||
profiling_sample_count const &counts,
|
profiling_sample_count const &counts,
|
||||||
cell thread);
|
cell thread);
|
||||||
};
|
};
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct factor_vm
|
||||||
bool signal_resumable;
|
bool signal_resumable;
|
||||||
cell signal_number;
|
cell signal_number;
|
||||||
cell signal_fault_addr;
|
cell signal_fault_addr;
|
||||||
|
cell signal_fault_pc;
|
||||||
unsigned int signal_fpu_status;
|
unsigned int signal_fpu_status;
|
||||||
|
|
||||||
/* Pipe used to notify Factor multiplexer of signals */
|
/* Pipe used to notify Factor multiplexer of signals */
|
||||||
|
@ -204,8 +205,8 @@ struct factor_vm
|
||||||
|
|
||||||
// sampling_profiler
|
// sampling_profiler
|
||||||
void clear_samples();
|
void clear_samples();
|
||||||
void record_sample();
|
void record_sample(bool prolog_p);
|
||||||
void record_callstack_sample(cell *begin, cell *end);
|
void record_callstack_sample(cell *begin, cell *end, bool prolog_p);
|
||||||
void start_sampling_profiler(fixnum rate);
|
void start_sampling_profiler(fixnum rate);
|
||||||
void end_sampling_profiler();
|
void end_sampling_profiler();
|
||||||
void set_sampling_profiler(fixnum rate);
|
void set_sampling_profiler(fixnum rate);
|
||||||
|
@ -218,7 +219,7 @@ struct factor_vm
|
||||||
void type_error(cell type, cell tagged);
|
void type_error(cell type, cell tagged);
|
||||||
void not_implemented_error();
|
void not_implemented_error();
|
||||||
void verify_memory_protection_error(cell addr);
|
void verify_memory_protection_error(cell addr);
|
||||||
void memory_protection_error(cell addr);
|
void memory_protection_error(cell pc, cell addr);
|
||||||
void signal_error(cell signal);
|
void signal_error(cell signal);
|
||||||
void divide_by_zero_error();
|
void divide_by_zero_error();
|
||||||
void fp_trap_error(unsigned int fpu_status);
|
void fp_trap_error(unsigned int fpu_status);
|
||||||
|
|
Loading…
Reference in New Issue