Lower the stack usage of a few functions

In vm/compaction.cpp I rescoped some variables to lower the stack usage
from 592 to 560 bytes. I wasn't very successful with this. The stack
usage is larger than it looks because methods on the structures used
take an implicit this pointer and a reference to the data (so the data
has to live out it's full scope and can't be put in a register).

In vm/debug.cpp I made a large (1024 bytes) stack allocated buffer
simply dynamically allocated.

In vm/os-unix.cpp I rescoped signal handling structures to not coincide
with each other and reduced a very large (1024 bytes) amount of stack
usage to less than 500 bytes.
db4
Steven Stewart-Gallus 2014-06-19 13:12:25 -07:00 committed by John Benediktsson
parent 199d6c3082
commit e6dade3f94
3 changed files with 98 additions and 80 deletions

View File

@ -191,31 +191,38 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p) {
const object* data_finger = tenured->first_block();
const code_block* code_finger = code->allocator->first_block();
compaction_fixup fixup(data_forwarding_map, code_forwarding_map, &data_finger,
&code_finger);
slot_visitor<compaction_fixup> data_forwarder(this, fixup);
code_block_visitor<compaction_fixup> code_forwarder(this, fixup);
{
compaction_fixup fixup(data_forwarding_map, code_forwarding_map, &data_finger,
&code_finger);
code_forwarder.visit_code_roots();
slot_visitor<compaction_fixup> data_forwarder(this, fixup);
code_block_visitor<compaction_fixup> code_forwarder(this, fixup);
/* Object start offsets get recomputed by the object_compaction_updater */
data->tenured->starts.clear_object_start_offsets();
code_forwarder.visit_code_roots();
/* Slide everything in tenured space up, and update data and code heap
pointers inside objects. */
object_compaction_updater object_updater(this, fixup);
tenured->compact(object_updater, fixup, &data_finger);
/* Object start offsets get recomputed by the object_compaction_updater */
data->tenured->starts.clear_object_start_offsets();
/* Slide everything in the code heap up, and update data and code heap
pointers inside code blocks. */
code_block_compaction_updater<compaction_fixup> code_block_updater(
this, fixup, data_forwarder, code_forwarder);
code->allocator->compact(code_block_updater, fixup, &code_finger);
/* Slide everything in tenured space up, and update data and code heap
pointers inside objects. */
{
object_compaction_updater object_updater(this, fixup);
tenured->compact(object_updater, fixup, &data_finger);
}
data_forwarder.visit_roots();
if (trace_contexts_p) {
data_forwarder.visit_contexts();
code_forwarder.visit_context_code_blocks();
/* Slide everything in the code heap up, and update data and code heap
pointers inside code blocks. */
{
code_block_compaction_updater<compaction_fixup> code_block_updater(
this, fixup, data_forwarder, code_forwarder);
code->allocator->compact(code_block_updater, fixup, &code_finger);
}
data_forwarder.visit_roots();
if (trace_contexts_p) {
data_forwarder.visit_contexts();
code_forwarder.visit_context_code_blocks();
}
}
update_code_roots_for_compaction();

View File

@ -475,7 +475,7 @@ void factor_vm::factorbug() {
bool seen_command = false;
for (;;) {
char cmd[1024];
std::string cmd;
std::cout << "> " << std::flush;
@ -498,9 +498,9 @@ void factor_vm::factorbug() {
seen_command = true;
if (strcmp(cmd, "q") == 0)
if (cmd == "q")
exit(1);
if (strcmp(cmd, "d") == 0) {
if (cmd == "d") {
cell addr = read_cell_hex();
if (std::cin.peek() == ' ')
std::cin.ignore();
@ -509,67 +509,67 @@ void factor_vm::factorbug() {
break;
cell count = read_cell_hex();
dump_memory(addr, addr + count);
} else if (strcmp(cmd, "u") == 0) {
} else if (cmd == "u") {
cell addr = read_cell_hex();
cell count = object_size(addr);
dump_memory(addr, addr + count);
} else if (strcmp(cmd, ".") == 0) {
} else if (cmd == ".") {
cell addr = read_cell_hex();
print_obj(addr);
std::cout << std::endl;
} else if (strcmp(cmd, "trim") == 0)
} else if (cmd == "trim")
full_output = !full_output;
else if (strcmp(cmd, "ds") == 0)
else if (cmd == "ds")
dump_memory(ctx->datastack_seg->start, ctx->datastack);
else if (strcmp(cmd, "dr") == 0)
else if (cmd == "dr")
dump_memory(ctx->retainstack_seg->start, ctx->retainstack);
else if (strcmp(cmd, ".s") == 0)
else if (cmd == ".s")
print_datastack();
else if (strcmp(cmd, ".r") == 0)
else if (cmd == ".r")
print_retainstack();
else if (strcmp(cmd, ".c") == 0)
else if (cmd == ".c")
print_callstack();
else if (strcmp(cmd, "e") == 0) {
else if (cmd == "e") {
for (cell i = 0; i < special_object_count; i++)
dump_cell((cell)&special_objects[i]);
} else if (strcmp(cmd, "g") == 0)
} else if (cmd == "g")
dump_generations();
else if (strcmp(cmd, "c") == 0) {
else if (cmd == "c") {
exit_fep(this);
return;
} else if (strcmp(cmd, "t") == 0) {
} else if (cmd == "t") {
exit_fep(this);
general_error(ERROR_INTERRUPT, false_object, false_object);
FACTOR_ASSERT(false);
} else if (strcmp(cmd, "data") == 0)
} else if (cmd == "data")
dump_objects(TYPE_COUNT);
else if (strcmp(cmd, "edges") == 0)
else if (cmd == "edges")
dump_edges();
else if (strcmp(cmd, "refs") == 0) {
else if (cmd == "refs") {
cell addr = read_cell_hex();
std::cout << "Data heap references:" << std::endl;
find_data_references(addr);
std::cout << std::endl;
} else if (strcmp(cmd, "words") == 0)
} else if (cmd == "words")
dump_objects(WORD_TYPE);
else if (strcmp(cmd, "tuples") == 0)
else if (cmd == "tuples")
dump_objects(TUPLE_TYPE);
else if (strcmp(cmd, "push") == 0) {
else if (cmd == "push") {
cell addr = read_cell_hex();
ctx->push(addr);
} else if (strcmp(cmd, "code") == 0)
} else if (cmd == "code")
dump_code_heap();
else if (strcmp(cmd, "compact-gc") == 0)
else if (cmd == "compact-gc")
primitive_compact_gc();
else if (strcmp(cmd, "gc") == 0)
else if (cmd == "gc")
primitive_full_gc();
else if (strcmp(cmd, "compact-gc") == 0)
else if (cmd == "compact-gc")
primitive_compact_gc();
else if (strcmp(cmd, "help") == 0)
else if (cmd == "help")
factorbug_usage(true);
else if (strcmp(cmd, "abort") == 0)
else if (cmd == "abort")
abort();
else if (strcmp(cmd, "breakpoint") == 0)
else if (cmd == "breakpoint")
breakpoint();
else
std::cout << "unknown command" << std::endl;

View File

@ -273,50 +273,61 @@ void factor_vm::unix_init_signals() {
if (sigaltstack(&signal_callstack, (stack_t*)NULL) < 0)
fatal_error("sigaltstack() failed", 0);
struct sigaction memory_sigaction;
struct sigaction synchronous_sigaction;
struct sigaction enqueue_sigaction;
struct sigaction sample_sigaction;
struct sigaction fpe_sigaction;
struct sigaction ignore_sigaction;
{
struct sigaction memory_sigaction;
init_sigaction_with_handler(&memory_sigaction, memory_signal_handler);
sigaction_safe(SIGBUS, &memory_sigaction, NULL);
sigaction_safe(SIGSEGV, &memory_sigaction, NULL);
sigaction_safe(SIGTRAP, &memory_sigaction, NULL);
}
init_sigaction_with_handler(&memory_sigaction, memory_signal_handler);
sigaction_safe(SIGBUS, &memory_sigaction, NULL);
sigaction_safe(SIGSEGV, &memory_sigaction, NULL);
sigaction_safe(SIGTRAP, &memory_sigaction, NULL);
{
struct sigaction fpe_sigaction;
init_sigaction_with_handler(&fpe_sigaction, fpe_signal_handler);
sigaction_safe(SIGFPE, &fpe_sigaction, NULL);
}
init_sigaction_with_handler(&fpe_sigaction, fpe_signal_handler);
sigaction_safe(SIGFPE, &fpe_sigaction, NULL);
{
struct sigaction synchronous_sigaction;
init_sigaction_with_handler(&synchronous_sigaction,
synchronous_signal_handler);
sigaction_safe(SIGILL, &synchronous_sigaction, NULL);
sigaction_safe(SIGABRT, &synchronous_sigaction, NULL);
}
init_sigaction_with_handler(&synchronous_sigaction,
synchronous_signal_handler);
sigaction_safe(SIGILL, &synchronous_sigaction, NULL);
sigaction_safe(SIGABRT, &synchronous_sigaction, NULL);
init_sigaction_with_handler(&enqueue_sigaction, enqueue_signal_handler);
sigaction_safe(SIGWINCH, &enqueue_sigaction, NULL);
sigaction_safe(SIGUSR1, &enqueue_sigaction, NULL);
sigaction_safe(SIGCONT, &enqueue_sigaction, NULL);
sigaction_safe(SIGURG, &enqueue_sigaction, NULL);
sigaction_safe(SIGIO, &enqueue_sigaction, NULL);
sigaction_safe(SIGPROF, &enqueue_sigaction, NULL);
sigaction_safe(SIGVTALRM, &enqueue_sigaction, NULL);
{
struct sigaction enqueue_sigaction;
init_sigaction_with_handler(&enqueue_sigaction, enqueue_signal_handler);
sigaction_safe(SIGWINCH, &enqueue_sigaction, NULL);
sigaction_safe(SIGUSR1, &enqueue_sigaction, NULL);
sigaction_safe(SIGCONT, &enqueue_sigaction, NULL);
sigaction_safe(SIGURG, &enqueue_sigaction, NULL);
sigaction_safe(SIGIO, &enqueue_sigaction, NULL);
sigaction_safe(SIGPROF, &enqueue_sigaction, NULL);
sigaction_safe(SIGVTALRM, &enqueue_sigaction, NULL);
#ifdef SIGINFO
sigaction_safe(SIGINFO, &enqueue_sigaction, NULL);
sigaction_safe(SIGINFO, &enqueue_sigaction, NULL);
#endif
}
handle_ctrl_c();
init_sigaction_with_handler(&sample_sigaction, sample_signal_handler);
sigaction_safe(SIGALRM, &sample_sigaction, NULL);
{
struct sigaction sample_sigaction;
init_sigaction_with_handler(&sample_sigaction, sample_signal_handler);
sigaction_safe(SIGALRM, &sample_sigaction, NULL);
}
/* We don't use SA_IGN here because then the ignore action is inherited
by subprocesses, which we don't want. There is a unit test in
io.launcher.unix for this. */
init_sigaction_with_handler(&ignore_sigaction, ignore_signal_handler);
sigaction_safe(SIGPIPE, &ignore_sigaction, NULL);
/* We send SIGUSR2 to the stdin_loop thread to interrupt it on FEP */
sigaction_safe(SIGUSR2, &ignore_sigaction, NULL);
{
struct sigaction ignore_sigaction;
init_sigaction_with_handler(&ignore_sigaction, ignore_signal_handler);
sigaction_safe(SIGPIPE, &ignore_sigaction, NULL);
/* We send SIGUSR2 to the stdin_loop thread to interrupt it on FEP */
sigaction_safe(SIGUSR2, &ignore_sigaction, NULL);
}
}
/* On Unix, shared fds such as stdin cannot be set to non-blocking mode