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
parent
199d6c3082
commit
e6dade3f94
|
@ -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();
|
||||
|
|
56
vm/debug.cpp
56
vm/debug.cpp
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue