vm: use iostreams instead of printf for debug messages, clean up a few things
parent
af855b7fa9
commit
40351d40be
|
@ -286,7 +286,7 @@ struct literal_references_updater {
|
|||
if(parent->relocation_type_of(rel) == RT_IMMEDIATE)
|
||||
{
|
||||
cell offset = parent->relocation_offset_of(rel) + (cell)(compiled + 1);
|
||||
array *literals = parent->untag<array>(compiled->literals);
|
||||
array *literals = untag<array>(compiled->literals);
|
||||
fixnum absolute_value = array_nth(literals,index);
|
||||
parent->store_address_in_code_block(parent->relocation_class_of(rel),offset,absolute_value);
|
||||
}
|
||||
|
@ -457,10 +457,10 @@ code_block *factor_vm::allot_code_block(cell size, code_block_type type)
|
|||
cell used, total_free, max_free;
|
||||
code->allocator->usage(&used,&total_free,&max_free);
|
||||
|
||||
print_string("Code heap stats:\n");
|
||||
print_string("Used: "); print_cell(used); nl();
|
||||
print_string("Total free space: "); print_cell(total_free); nl();
|
||||
print_string("Largest free block: "); print_cell(max_free); nl();
|
||||
std::cout << "Code heap stats:\n";
|
||||
std::cout << "Used: " << used << "\n";
|
||||
std::cout << "Total free space: " << total_free << "\n";
|
||||
std::cout << "Largest free block: " << max_free << "\n";
|
||||
fatal_error("Out of memory in add-compiled-block",0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ template<typename TargetGeneration, typename Policy> struct collector {
|
|||
|
||||
if(immediate_p(pointer)) return;
|
||||
|
||||
object *untagged = parent->untag<object>(pointer);
|
||||
object *untagged = untag<object>(pointer);
|
||||
if(!policy.should_copy_p(untagged))
|
||||
{
|
||||
policy.visited_object(untagged);
|
||||
|
|
|
@ -120,7 +120,7 @@ cell factor_vm::object_size(cell tagged)
|
|||
}
|
||||
|
||||
/* Size of the object pointed to by an untagged pointer */
|
||||
cell object::size()
|
||||
cell object::size() const
|
||||
{
|
||||
if(free_p()) return ((free_heap_block *)this)->size();
|
||||
|
||||
|
|
206
vm/debug.cpp
206
vm/debug.cpp
|
@ -3,36 +3,31 @@
|
|||
namespace factor
|
||||
{
|
||||
|
||||
void factor_vm::print_chars(string* str)
|
||||
std::ostream &operator<<(std::ostream &out, const string *str)
|
||||
{
|
||||
cell i;
|
||||
for(i = 0; i < string_capacity(str); i++)
|
||||
putchar(string_nth(str,i));
|
||||
for(cell i = 0; i < string_capacity(str); i++)
|
||||
out << (char)str->nth(i);
|
||||
return out;
|
||||
}
|
||||
|
||||
void factor_vm::print_word(word* word, cell nesting)
|
||||
{
|
||||
if(tagged<object>(word->vocabulary).type_p(STRING_TYPE))
|
||||
{
|
||||
print_chars(untag<string>(word->vocabulary));
|
||||
print_string(":");
|
||||
}
|
||||
std::cout << untag<string>(word->vocabulary) << ":";
|
||||
|
||||
if(tagged<object>(word->name).type_p(STRING_TYPE))
|
||||
print_chars(untag<string>(word->name));
|
||||
std::cout << untag<string>(word->name);
|
||||
else
|
||||
{
|
||||
print_string("#<not a string: ");
|
||||
std::cout << "#<not a string: ";
|
||||
print_nested_obj(word->name,nesting);
|
||||
print_string(">");
|
||||
std::cout << ">";
|
||||
}
|
||||
}
|
||||
|
||||
void factor_vm::print_factor_string(string *str)
|
||||
{
|
||||
putchar('"');
|
||||
print_chars(str);
|
||||
putchar('"');
|
||||
std::cout << '"' << str << '"';
|
||||
}
|
||||
|
||||
void factor_vm::print_array(array* array, cell nesting)
|
||||
|
@ -51,12 +46,12 @@ void factor_vm::print_array(array* array, cell nesting)
|
|||
|
||||
for(i = 0; i < length; i++)
|
||||
{
|
||||
print_string(" ");
|
||||
std::cout << " ";
|
||||
print_nested_obj(array_nth(array,i),nesting);
|
||||
}
|
||||
|
||||
if(trimmed)
|
||||
print_string("...");
|
||||
std::cout << "...";
|
||||
}
|
||||
|
||||
void factor_vm::print_tuple(tuple *tuple, cell nesting)
|
||||
|
@ -64,12 +59,10 @@ void factor_vm::print_tuple(tuple *tuple, cell nesting)
|
|||
tuple_layout *layout = untag<tuple_layout>(tuple->layout);
|
||||
cell length = to_fixnum(layout->size);
|
||||
|
||||
print_string(" ");
|
||||
std::cout << " ";
|
||||
print_nested_obj(layout->klass,nesting);
|
||||
|
||||
cell i;
|
||||
bool trimmed;
|
||||
|
||||
if(length > 10 && !full_output)
|
||||
{
|
||||
trimmed = true;
|
||||
|
@ -78,21 +71,21 @@ void factor_vm::print_tuple(tuple *tuple, cell nesting)
|
|||
else
|
||||
trimmed = false;
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
for(cell i = 0; i < length; i++)
|
||||
{
|
||||
print_string(" ");
|
||||
std::cout << " ";
|
||||
print_nested_obj(tuple->data()[i],nesting);
|
||||
}
|
||||
|
||||
if(trimmed)
|
||||
print_string("...");
|
||||
std::cout << "...";
|
||||
}
|
||||
|
||||
void factor_vm::print_nested_obj(cell obj, fixnum nesting)
|
||||
{
|
||||
if(nesting <= 0 && !full_output)
|
||||
{
|
||||
print_string(" ... ");
|
||||
std::cout << " ... ";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -101,7 +94,7 @@ void factor_vm::print_nested_obj(cell obj, fixnum nesting)
|
|||
switch(tagged<object>(obj).type())
|
||||
{
|
||||
case FIXNUM_TYPE:
|
||||
print_fixnum(untag_fixnum(obj));
|
||||
std::cout << untag_fixnum(obj);
|
||||
break;
|
||||
case WORD_TYPE:
|
||||
print_word(untag<word>(obj),nesting - 1);
|
||||
|
@ -110,30 +103,27 @@ void factor_vm::print_nested_obj(cell obj, fixnum nesting)
|
|||
print_factor_string(untag<string>(obj));
|
||||
break;
|
||||
case F_TYPE:
|
||||
print_string("f");
|
||||
std::cout << "f";
|
||||
break;
|
||||
case TUPLE_TYPE:
|
||||
print_string("T{");
|
||||
std::cout << "T{";
|
||||
print_tuple(untag<tuple>(obj),nesting - 1);
|
||||
print_string(" }");
|
||||
std::cout << " }";
|
||||
break;
|
||||
case ARRAY_TYPE:
|
||||
print_string("{");
|
||||
std::cout << "{";
|
||||
print_array(untag<array>(obj),nesting - 1);
|
||||
print_string(" }");
|
||||
std::cout << " }";
|
||||
break;
|
||||
case QUOTATION_TYPE:
|
||||
print_string("[");
|
||||
std::cout << "[";
|
||||
quot = untag<quotation>(obj);
|
||||
print_array(untag<array>(quot->array),nesting - 1);
|
||||
print_string(" ]");
|
||||
std::cout << " ]";
|
||||
break;
|
||||
default:
|
||||
print_string("#<type ");
|
||||
print_cell(tagged<object>(obj).type());
|
||||
print_string(" @ ");
|
||||
print_cell_hex(obj);
|
||||
print_string(">");
|
||||
std::cout << "#<type " << tagged<object>(obj).type() << " @ ";
|
||||
std::cout << std::hex << obj << std::dec << ">";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -148,19 +138,19 @@ void factor_vm::print_objects(cell *start, cell *end)
|
|||
for(; start <= end; start++)
|
||||
{
|
||||
print_obj(*start);
|
||||
nl();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void factor_vm::print_datastack()
|
||||
{
|
||||
print_string("==== DATA STACK:\n");
|
||||
std::cout << "==== DATA STACK:\n";
|
||||
print_objects((cell *)ds_bot,(cell *)ds);
|
||||
}
|
||||
|
||||
void factor_vm::print_retainstack()
|
||||
{
|
||||
print_string("==== RETAIN STACK:\n");
|
||||
std::cout << "==== RETAIN STACK:\n";
|
||||
print_objects((cell *)rs_bot,(cell *)rs);
|
||||
}
|
||||
|
||||
|
@ -171,34 +161,48 @@ struct stack_frame_printer {
|
|||
void operator()(stack_frame *frame)
|
||||
{
|
||||
parent->print_obj(parent->frame_executing(frame));
|
||||
print_string("\n");
|
||||
std::cout << std::endl;
|
||||
parent->print_obj(parent->frame_scan(frame));
|
||||
print_string("\n");
|
||||
print_string("word/quot addr: ");
|
||||
print_cell_hex((cell)parent->frame_executing(frame));
|
||||
print_string("\n");
|
||||
print_string("word/quot xt: ");
|
||||
print_cell_hex((cell)frame->xt);
|
||||
print_string("\n");
|
||||
print_string("return address: ");
|
||||
print_cell_hex((cell)FRAME_RETURN_ADDRESS(frame,parent));
|
||||
print_string("\n");
|
||||
std::cout << std::endl;
|
||||
std::cout << "word/quot addr: ";
|
||||
std::cout << std::hex << (cell)parent->frame_executing(frame) << std::dec;
|
||||
std::cout << std::endl;
|
||||
std::cout << "word/quot xt: ";
|
||||
std::cout << std::hex << (cell)frame->xt << std::dec;
|
||||
std::cout << std::endl;
|
||||
std::cout << "return address: ";
|
||||
std::cout << std::hex << (cell)FRAME_RETURN_ADDRESS(frame,parent) << std::dec;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
void factor_vm::print_callstack()
|
||||
{
|
||||
print_string("==== CALL STACK:\n");
|
||||
std::cout << "==== CALL STACK:\n";
|
||||
stack_frame_printer printer(this);
|
||||
iterate_callstack(ctx,printer);
|
||||
}
|
||||
|
||||
struct padded_address {
|
||||
cell value;
|
||||
|
||||
explicit padded_address(cell value_) : value(value_) {}
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const padded_address &value)
|
||||
{
|
||||
char prev = out.fill('0');
|
||||
out.width(sizeof(cell) * 2);
|
||||
out << std::hex << value.value << std::dec;
|
||||
out.fill(prev);
|
||||
return out;
|
||||
}
|
||||
|
||||
void factor_vm::dump_cell(cell x)
|
||||
{
|
||||
print_cell_hex_pad(x); print_string(": ");
|
||||
std::cout << padded_address(x) << ": ";
|
||||
x = *(cell *)x;
|
||||
print_cell_hex_pad(x); print_string(" tag "); print_cell(TAG(x));
|
||||
nl();
|
||||
std::cout << padded_address(x) << " tag " << TAG(x) << std::endl;
|
||||
}
|
||||
|
||||
void factor_vm::dump_memory(cell from, cell to)
|
||||
|
@ -212,11 +216,11 @@ void factor_vm::dump_memory(cell from, cell to)
|
|||
template<typename Generation>
|
||||
void factor_vm::dump_generation(const char *name, Generation *gen)
|
||||
{
|
||||
print_string(name); print_string(": ");
|
||||
print_string("Start="); print_cell(gen->start);
|
||||
print_string(", size="); print_cell(gen->size);
|
||||
print_string(", end="); print_cell(gen->end);
|
||||
nl();
|
||||
std::cout << name << ": ";
|
||||
std::cout << "Start=" << gen->start;
|
||||
std::cout << ", size=" << gen->size;
|
||||
std::cout << ", end=" << gen->end;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void factor_vm::dump_generations()
|
||||
|
@ -225,11 +229,9 @@ void factor_vm::dump_generations()
|
|||
dump_generation("Aging",data->aging);
|
||||
dump_generation("Tenured",data->tenured);
|
||||
|
||||
print_string("Cards: base=");
|
||||
print_cell((cell)data->cards);
|
||||
print_string(", size=");
|
||||
print_cell((cell)(data->cards_end - data->cards));
|
||||
nl();
|
||||
std::cout << "Cards:";
|
||||
std::cout << "base=" << (cell)data->cards << ", ";
|
||||
std::cout << "size=" << (cell)(data->cards_end - data->cards) << std::endl;
|
||||
}
|
||||
|
||||
void factor_vm::dump_objects(cell type)
|
||||
|
@ -242,10 +244,9 @@ void factor_vm::dump_objects(cell type)
|
|||
{
|
||||
if(type == TYPE_COUNT || tagged<object>(obj).type_p(type))
|
||||
{
|
||||
print_cell_hex_pad(obj);
|
||||
print_string(" ");
|
||||
std::cout << padded_address(obj) << " ";
|
||||
print_nested_obj(obj,2);
|
||||
nl();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,10 +264,9 @@ struct data_references_finder {
|
|||
{
|
||||
if(look_for == *scan)
|
||||
{
|
||||
print_cell_hex_pad(obj);
|
||||
print_string(" ");
|
||||
std::cout << padded_address(obj) << " ";
|
||||
parent->print_nested_obj(obj,2);
|
||||
nl();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -311,9 +311,9 @@ struct code_block_printer {
|
|||
status = "allocated";
|
||||
}
|
||||
|
||||
print_cell_hex((cell)scan); print_string(" ");
|
||||
print_cell_hex(size); print_string(" ");
|
||||
print_string(status); print_string("\n");
|
||||
std::cout << std::hex << (cell)scan << std::dec << " ";
|
||||
std::cout << std::hex << size << std::dec << " ";
|
||||
std::cout << status << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -322,40 +322,40 @@ void factor_vm::dump_code_heap()
|
|||
{
|
||||
code_block_printer printer(this);
|
||||
code->allocator->iterate(printer);
|
||||
print_cell(printer.reloc_size); print_string(" bytes of relocation data\n");
|
||||
print_cell(printer.literal_size); print_string(" bytes of literal data\n");
|
||||
std::cout << printer.reloc_size << " bytes of relocation data\n";
|
||||
std::cout << printer.literal_size << " bytes of literal data\n";
|
||||
}
|
||||
|
||||
void factor_vm::factorbug()
|
||||
{
|
||||
if(fep_disabled)
|
||||
{
|
||||
print_string("Low level debugger disabled\n");
|
||||
std::cout << "Low level debugger disabled\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open_console(); */
|
||||
|
||||
print_string("Starting low level debugger...\n");
|
||||
print_string(" Basic commands:\n");
|
||||
print_string("q -- continue executing Factor - NOT SAFE\n");
|
||||
print_string("im -- save image to fep.image\n");
|
||||
print_string("x -- exit Factor\n");
|
||||
print_string(" Advanced commands:\n");
|
||||
print_string("d <addr> <count> -- dump memory\n");
|
||||
print_string("u <addr> -- dump object at tagged <addr>\n");
|
||||
print_string(". <addr> -- print object at tagged <addr>\n");
|
||||
print_string("t -- toggle output trimming\n");
|
||||
print_string("s r -- dump data, retain stacks\n");
|
||||
print_string(".s .r .c -- print data, retain, call stacks\n");
|
||||
print_string("e -- dump environment\n");
|
||||
print_string("g -- dump generations\n");
|
||||
print_string("data -- data heap dump\n");
|
||||
print_string("words -- words dump\n");
|
||||
print_string("tuples -- tuples dump\n");
|
||||
print_string("refs <addr> -- find data heap references to object\n");
|
||||
print_string("push <addr> -- push object on data stack - NOT SAFE\n");
|
||||
print_string("code -- code heap dump\n");
|
||||
std::cout << "Starting low level debugger...\n";
|
||||
std::cout << " Basic commands:\n";
|
||||
std::cout << "q -- continue executing Factor - NOT SAFE\n";
|
||||
std::cout << "im -- save image to fep.image\n";
|
||||
std::cout << "x -- exit Factor\n";
|
||||
std::cout << " Advanced commands:\n";
|
||||
std::cout << "d <addr> <count> -- dump memory\n";
|
||||
std::cout << "u <addr> -- dump object at tagged <addr>\n";
|
||||
std::cout << ". <addr> -- print object at tagged <addr>\n";
|
||||
std::cout << "t -- toggle output trimming\n";
|
||||
std::cout << "s r -- dump data, retain stacks\n";
|
||||
std::cout << ".s .r .c -- print data, retain, call stacks\n";
|
||||
std::cout << "e -- dump environment\n";
|
||||
std::cout << "g -- dump generations\n";
|
||||
std::cout << "data -- data heap dump\n";
|
||||
std::cout << "words -- words dump\n";
|
||||
std::cout << "tuples -- tuples dump\n";
|
||||
std::cout << "refs <addr> -- find data heap references to object\n";
|
||||
std::cout << "push <addr> -- push object on data stack - NOT SAFE\n";
|
||||
std::cout << "code -- code heap dump\n";
|
||||
|
||||
bool seen_command = false;
|
||||
|
||||
|
@ -363,7 +363,7 @@ void factor_vm::factorbug()
|
|||
{
|
||||
char cmd[1024];
|
||||
|
||||
print_string("READY\n");
|
||||
std::cout << "READY\n";
|
||||
fflush(stdout);
|
||||
|
||||
if(scanf("%1000s",cmd) <= 0)
|
||||
|
@ -403,7 +403,7 @@ void factor_vm::factorbug()
|
|||
{
|
||||
cell addr = read_cell_hex();
|
||||
print_obj(addr);
|
||||
print_string("\n");
|
||||
std::cout << std::endl;
|
||||
}
|
||||
else if(strcmp(cmd,"t") == 0)
|
||||
full_output = !full_output;
|
||||
|
@ -436,9 +436,9 @@ void factor_vm::factorbug()
|
|||
else if(strcmp(cmd,"refs") == 0)
|
||||
{
|
||||
cell addr = read_cell_hex();
|
||||
print_string("Data heap references:\n");
|
||||
std::cout << "Data heap references:\n";
|
||||
find_data_references(addr);
|
||||
nl();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
else if(strcmp(cmd,"words") == 0)
|
||||
dump_objects(WORD_TYPE);
|
||||
|
@ -452,14 +452,14 @@ void factor_vm::factorbug()
|
|||
else if(strcmp(cmd,"code") == 0)
|
||||
dump_code_heap();
|
||||
else
|
||||
print_string("unknown command\n");
|
||||
std::cout << "unknown command\n";
|
||||
}
|
||||
}
|
||||
|
||||
void factor_vm::primitive_die()
|
||||
{
|
||||
print_string("The die word was called by the library. Unless you called it yourself,\n");
|
||||
print_string("you have triggered a bug in Factor. Please report.\n");
|
||||
std::cout << "The die word was called by the library. Unless you called it yourself,\n";
|
||||
std::cout << "you have triggered a bug in Factor. Please report.\n";
|
||||
factorbug();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,22 +5,24 @@ namespace factor
|
|||
|
||||
void fatal_error(const char *msg, cell tagged)
|
||||
{
|
||||
print_string("fatal_error: "); print_string(msg);
|
||||
print_string(": "); print_cell_hex(tagged); nl();
|
||||
std::cout << "fatal_error: " << msg;
|
||||
std::cout << ": " << std::hex << tagged << std::dec;
|
||||
std::cout << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void critical_error(const char *msg, cell tagged)
|
||||
{
|
||||
print_string("You have triggered a bug in Factor. Please report.\n");
|
||||
print_string("critical_error: "); print_string(msg);
|
||||
print_string(": "); print_cell_hex(tagged); nl();
|
||||
std::cout << "You have triggered a bug in Factor. Please report.\n";
|
||||
std::cout << "critical_error: " << msg;
|
||||
std::cout << ": " << std::hex << tagged << std::dec;
|
||||
std::cout << std::endl;
|
||||
tls_vm()->factorbug();
|
||||
}
|
||||
|
||||
void out_of_memory()
|
||||
{
|
||||
print_string("Out of memory\n\n");
|
||||
std::cout << "Out of memory\n\n";
|
||||
tls_vm()->dump_generations();
|
||||
exit(1);
|
||||
}
|
||||
|
@ -59,10 +61,10 @@ void factor_vm::throw_error(cell error, stack_frame *callstack_top)
|
|||
crash. */
|
||||
else
|
||||
{
|
||||
print_string("You have triggered a bug in Factor. Please report.\n");
|
||||
print_string("early_error: ");
|
||||
std::cout << "You have triggered a bug in Factor. Please report.\n";
|
||||
std::cout << "early_error: ";
|
||||
print_obj(error);
|
||||
nl();
|
||||
std::cout << std::endl;
|
||||
factorbug();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ void factor_vm::default_parameters(vm_parameters *p)
|
|||
p->max_pic_size = 3;
|
||||
|
||||
p->fep = false;
|
||||
p->verbosegc = false;
|
||||
p->signals = true;
|
||||
|
||||
#ifdef WINDOWS
|
||||
|
@ -86,6 +87,7 @@ void factor_vm::init_parameters_from_args(vm_parameters *p, int argc, vm_char **
|
|||
else if(factor_arg(arg,STRING_LITERAL("-callbacks=%d"),&p->callback_size));
|
||||
else if(STRCMP(arg,STRING_LITERAL("-fep")) == 0) p->fep = true;
|
||||
else if(STRCMP(arg,STRING_LITERAL("-nosignals")) == 0) p->signals = false;
|
||||
else if(STRCMP(arg,STRING_LITERAL("-verbosegc")) == 0) p->verbosegc = true;
|
||||
else if(STRNCMP(arg,STRING_LITERAL("-i="),3) == 0) p->image_path = arg + 3;
|
||||
else if(STRCMP(arg,STRING_LITERAL("-console")) == 0) p->console = true;
|
||||
}
|
||||
|
@ -94,14 +96,13 @@ void factor_vm::init_parameters_from_args(vm_parameters *p, int argc, vm_char **
|
|||
/* Do some initialization that we do once only */
|
||||
void factor_vm::do_stage1_init()
|
||||
{
|
||||
print_string("*** Stage 2 early init... ");
|
||||
std::cout << "*** Stage 2 early init... ";
|
||||
fflush(stdout);
|
||||
|
||||
compile_all_words();
|
||||
userenv[STAGE2_ENV] = true_object;
|
||||
|
||||
print_string("done\n");
|
||||
fflush(stdout);
|
||||
std::cout << "done\n";
|
||||
}
|
||||
|
||||
void factor_vm::init_factor(vm_parameters *p)
|
||||
|
@ -141,6 +142,8 @@ void factor_vm::init_factor(vm_parameters *p)
|
|||
if(p->signals)
|
||||
init_signals();
|
||||
|
||||
verbosegc = p->verbosegc;
|
||||
|
||||
if(p->console)
|
||||
open_console();
|
||||
|
||||
|
|
11
vm/gc.cpp
11
vm/gc.cpp
|
@ -37,6 +37,9 @@ void factor_vm::gc(gc_op op,
|
|||
|
||||
current_gc = new gc_state(op);
|
||||
|
||||
if(verbosegc)
|
||||
std::cout << "GC requested, op=" << op << std::endl;
|
||||
|
||||
/* Keep trying to GC higher and higher generations until we don't run out
|
||||
of space */
|
||||
if(setjmp(current_gc->gc_unwind))
|
||||
|
@ -60,6 +63,9 @@ void factor_vm::gc(gc_op op,
|
|||
critical_error("Bad GC op\n",op);
|
||||
break;
|
||||
}
|
||||
|
||||
if(verbosegc)
|
||||
std::cout << "GC rewind, op=" << op << std::endl;
|
||||
}
|
||||
|
||||
switch(current_gc->op)
|
||||
|
@ -91,11 +97,14 @@ void factor_vm::gc(gc_op op,
|
|||
|
||||
delete current_gc;
|
||||
current_gc = NULL;
|
||||
|
||||
if(verbosegc)
|
||||
std::cout << "GC done, op=" << op << std::endl;
|
||||
}
|
||||
|
||||
void factor_vm::primitive_minor_gc()
|
||||
{
|
||||
gc(collect_nursery_op,
|
||||
gc(collect_full_op,
|
||||
0, /* requested size */
|
||||
true, /* trace contexts? */
|
||||
false /* compact code heap? */);
|
||||
|
|
26
vm/image.cpp
26
vm/image.cpp
|
@ -31,11 +31,8 @@ void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p)
|
|||
|
||||
if((cell)bytes_read != h->data_size)
|
||||
{
|
||||
print_string("truncated image: ");
|
||||
print_fixnum(bytes_read);
|
||||
print_string(" bytes read, ");
|
||||
print_cell(h->data_size);
|
||||
print_string(" bytes expected\n");
|
||||
std::cout << "truncated image: " << bytes_read << " bytes read, ";
|
||||
std::cout << h->data_size << " bytes expected\n";
|
||||
fatal_error("load_data_heap failed",0);
|
||||
}
|
||||
|
||||
|
@ -54,11 +51,8 @@ void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p)
|
|||
size_t bytes_read = fread(code->allocator->first_block(),1,h->code_size,file);
|
||||
if(bytes_read != h->code_size)
|
||||
{
|
||||
print_string("truncated image: ");
|
||||
print_fixnum(bytes_read);
|
||||
print_string(" bytes read, ");
|
||||
print_cell(h->code_size);
|
||||
print_string(" bytes expected\n");
|
||||
std::cout << "truncated image: " << bytes_read << " bytes read, ";
|
||||
std::cout << h->code_size << " bytes expected\n";
|
||||
fatal_error("load_code_heap failed",0);
|
||||
}
|
||||
}
|
||||
|
@ -243,8 +237,8 @@ void factor_vm::load_image(vm_parameters *p)
|
|||
FILE *file = OPEN_READ(p->image_path);
|
||||
if(file == NULL)
|
||||
{
|
||||
print_string("Cannot open image file: "); print_native_string(p->image_path); nl();
|
||||
print_string(strerror(errno)); nl();
|
||||
std::cout << "Cannot open image file: " << p->image_path << std::endl;
|
||||
std::cout << strerror(errno) << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -281,8 +275,8 @@ bool factor_vm::save_image(const vm_char *filename)
|
|||
file = OPEN_WRITE(filename);
|
||||
if(file == NULL)
|
||||
{
|
||||
print_string("Cannot open image file: "); print_native_string(filename); nl();
|
||||
print_string(strerror(errno)); nl();
|
||||
std::cout << "Cannot open image file: " << filename << std::endl;
|
||||
std::cout << strerror(errno) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -309,9 +303,7 @@ bool factor_vm::save_image(const vm_char *filename)
|
|||
if(fclose(file)) ok = false;
|
||||
|
||||
if(!ok)
|
||||
{
|
||||
print_string("save-image failed: "); print_string(strerror(errno)); nl();
|
||||
}
|
||||
std::cout << "save-image failed: " << strerror(errno) << std::endl;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ struct vm_parameters {
|
|||
cell young_size, aging_size, tenured_size;
|
||||
cell code_size;
|
||||
bool fep;
|
||||
bool verbosegc;
|
||||
bool console;
|
||||
bool signals;
|
||||
cell max_pic_size;
|
||||
|
|
|
@ -233,10 +233,10 @@ void *factor_vm::inline_cache_miss(cell return_address)
|
|||
set_call_target(return_address,xt);
|
||||
|
||||
#ifdef PIC_DEBUG
|
||||
printf("Updated %s call site 0x%lx with 0x%lx\n",
|
||||
tail_call_site_p(return_address) ? "tail" : "non-tail",
|
||||
return_address,
|
||||
(cell)xt);
|
||||
std::cout << "Updated "
|
||||
<< (tail_call_site_p(return_address) ? "tail" : "non-tail")
|
||||
<< " call site 0x" << std::hex << return_address << std::dec
|
||||
<< " with " << std::hex << (cell)xt << std::dec;
|
||||
#endif
|
||||
|
||||
return xt;
|
||||
|
|
|
@ -43,7 +43,7 @@ struct jit {
|
|||
void emit_subprimitive(cell word_) {
|
||||
gc_root<word> word(word_,parent);
|
||||
gc_root<array> code_pair(word->subprimitive,parent);
|
||||
literals.append(parent->untag<array>(array_nth(code_pair.untagged(),0)));
|
||||
literals.append(untag<array>(array_nth(code_pair.untagged(),0)));
|
||||
emit(array_nth(code_pair.untagged(),1));
|
||||
}
|
||||
|
||||
|
|
|
@ -112,25 +112,25 @@ struct header {
|
|||
|
||||
explicit header(cell value_) : value(value_ << TAG_BITS) {}
|
||||
|
||||
void check_header()
|
||||
void check_header() const
|
||||
{
|
||||
#ifdef FACTOR_DEBUG
|
||||
assert(TAG(value) == FIXNUM_TYPE && untag_fixnum(value) < TYPE_COUNT);
|
||||
#endif
|
||||
}
|
||||
|
||||
cell hi_tag()
|
||||
cell hi_tag() const
|
||||
{
|
||||
check_header();
|
||||
return value >> TAG_BITS;
|
||||
}
|
||||
|
||||
bool forwarding_pointer_p()
|
||||
bool forwarding_pointer_p() const
|
||||
{
|
||||
return TAG(value) == GC_COLLECTED;
|
||||
}
|
||||
|
||||
object *forwarding_pointer()
|
||||
object *forwarding_pointer() const
|
||||
{
|
||||
return (object *)UNTAG(value);
|
||||
}
|
||||
|
@ -147,13 +147,13 @@ struct object {
|
|||
NO_TYPE_CHECK;
|
||||
header h;
|
||||
|
||||
cell size();
|
||||
cell size() const;
|
||||
|
||||
cell *slots() { return (cell *)this; }
|
||||
cell *slots() const { return (cell *)this; }
|
||||
|
||||
/* Only valid for objects in tenured space; must fast to free_heap_block
|
||||
to do anything with it if its free */
|
||||
bool free_p()
|
||||
bool free_p() const
|
||||
{
|
||||
return h.value & 1 == 1;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ struct array : public object {
|
|||
/* tagged */
|
||||
cell capacity;
|
||||
|
||||
cell *data() { return (cell *)(this + 1); }
|
||||
cell *data() const { return (cell *)(this + 1); }
|
||||
};
|
||||
|
||||
/* These are really just arrays, but certain elements have special
|
||||
|
@ -187,7 +187,7 @@ struct bignum : public object {
|
|||
/* tagged */
|
||||
cell capacity;
|
||||
|
||||
cell *data() { return (cell *)(this + 1); }
|
||||
cell *data() const { return (cell *)(this + 1); }
|
||||
};
|
||||
|
||||
struct byte_array : public object {
|
||||
|
@ -201,7 +201,7 @@ struct byte_array : public object {
|
|||
cell padding1;
|
||||
#endif
|
||||
|
||||
template<typename Scalar> Scalar *data() { return (Scalar *)(this + 1); }
|
||||
template<typename Scalar> Scalar *data() const { return (Scalar *)(this + 1); }
|
||||
};
|
||||
|
||||
/* Assembly code makes assumptions about the layout of this struct */
|
||||
|
@ -214,7 +214,9 @@ struct string : public object {
|
|||
/* tagged */
|
||||
cell hashcode;
|
||||
|
||||
u8 *data() { return (u8 *)(this + 1); }
|
||||
u8 *data() const { return (u8 *)(this + 1); }
|
||||
|
||||
cell nth(cell i) const;
|
||||
};
|
||||
|
||||
/* The compiled code heap is structured into blocks. */
|
||||
|
@ -222,12 +224,12 @@ struct heap_block
|
|||
{
|
||||
cell header;
|
||||
|
||||
bool free_p()
|
||||
bool free_p() const
|
||||
{
|
||||
return header & 1 == 1;
|
||||
}
|
||||
|
||||
cell size()
|
||||
cell size() const
|
||||
{
|
||||
cell bytes = header >> 3;
|
||||
#ifdef FACTOR_DEBUG
|
||||
|
@ -258,12 +260,12 @@ struct code_block : public heap_block
|
|||
cell literals; /* tagged pointer to array or f */
|
||||
cell relocation; /* tagged pointer to byte-array or f */
|
||||
|
||||
void *xt()
|
||||
void *xt() const
|
||||
{
|
||||
return (void *)(this + 1);
|
||||
}
|
||||
|
||||
code_block_type type()
|
||||
code_block_type type() const
|
||||
{
|
||||
return (code_block_type)((header >> 1) & 0x3);
|
||||
}
|
||||
|
@ -273,12 +275,12 @@ struct code_block : public heap_block
|
|||
header = ((header & ~0x7) | (type << 1));
|
||||
}
|
||||
|
||||
bool pic_p()
|
||||
bool pic_p() const
|
||||
{
|
||||
return type() == code_block_pic;
|
||||
}
|
||||
|
||||
bool optimized_p()
|
||||
bool optimized_p() const
|
||||
{
|
||||
return type() == code_block_optimized;
|
||||
}
|
||||
|
@ -376,13 +378,13 @@ struct callstack : public object {
|
|||
/* tagged */
|
||||
cell length;
|
||||
|
||||
stack_frame *frame_at(cell offset)
|
||||
stack_frame *frame_at(cell offset) const
|
||||
{
|
||||
return (stack_frame *)((char *)(this + 1) + offset);
|
||||
}
|
||||
|
||||
stack_frame *top() { return (stack_frame *)(this + 1); }
|
||||
stack_frame *bottom() { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
|
||||
stack_frame *top() const { return (stack_frame *)(this + 1); }
|
||||
stack_frame *bottom() const { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
|
||||
};
|
||||
|
||||
struct tuple : public object {
|
||||
|
@ -390,7 +392,7 @@ struct tuple : public object {
|
|||
/* tagged layout */
|
||||
cell layout;
|
||||
|
||||
cell *data() { return (cell *)(this + 1); }
|
||||
cell *data() const { return (cell *)(this + 1); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
/* Forward-declare this since it comes up in function prototypes */
|
||||
namespace factor
|
||||
|
|
|
@ -37,8 +37,6 @@ typedef wchar_t vm_char;
|
|||
#define OPEN_READ(path) _wfopen(path,L"rb")
|
||||
#define OPEN_WRITE(path) _wfopen(path,L"wb")
|
||||
|
||||
#define print_native_string(string) wprintf(L"%s",string)
|
||||
|
||||
/* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */
|
||||
#define EPOCH_OFFSET 0x019db1ded53e8000LL
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ bool quotation_jit::stack_frame_p()
|
|||
switch(tagged<object>(obj).type())
|
||||
{
|
||||
case WORD_TYPE:
|
||||
if(!parent->to_boolean(parent->untag<word>(obj)->subprimitive))
|
||||
if(!parent->to_boolean(untag<word>(obj)->subprimitive))
|
||||
return true;
|
||||
break;
|
||||
case QUOTATION_TYPE:
|
||||
|
@ -112,7 +112,7 @@ void quotation_jit::emit_quot(cell quot_)
|
|||
{
|
||||
gc_root<quotation> quot(quot_,parent);
|
||||
|
||||
array *elements = parent->untag<array>(quot->array);
|
||||
array *elements = untag<array>(quot->array);
|
||||
|
||||
/* If the quotation consists of a single word, compile a direct call
|
||||
to the word. */
|
||||
|
|
|
@ -3,20 +3,20 @@
|
|||
namespace factor
|
||||
{
|
||||
|
||||
cell factor_vm::string_nth(string* str, cell index)
|
||||
cell string::nth(cell index) const
|
||||
{
|
||||
/* If high bit is set, the most significant 16 bits of the char
|
||||
come from the aux vector. The least significant bit of the
|
||||
corresponding aux vector entry is negated, so that we can
|
||||
XOR the two components together and get the original code point
|
||||
back. */
|
||||
cell lo_bits = str->data()[index];
|
||||
cell lo_bits = data()[index];
|
||||
|
||||
if((lo_bits & 0x80) == 0)
|
||||
return lo_bits;
|
||||
else
|
||||
{
|
||||
byte_array *aux = untag<byte_array>(str->aux);
|
||||
byte_array *aux = untag<byte_array>(this->aux);
|
||||
cell hi_bits = aux->data<u16>()[index];
|
||||
return (hi_bits << 7) ^ lo_bits;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ void factor_vm::primitive_string_nth()
|
|||
{
|
||||
string *str = untag<string>(dpop());
|
||||
cell index = untag_fixnum(dpop());
|
||||
dpush(tag_fixnum(string_nth(str,index)));
|
||||
dpush(tag_fixnum(str->nth(index)));
|
||||
}
|
||||
|
||||
void factor_vm::primitive_set_string_nth_fast()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace factor
|
||||
{
|
||||
|
||||
inline static cell string_capacity(string *str)
|
||||
inline static cell string_capacity(const string *str)
|
||||
{
|
||||
return untag_fixnum(str->length);
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ template<typename Type> Type *factor_vm::untag_check(cell value)
|
|||
return tagged<Type>(value).untag_check(this);
|
||||
}
|
||||
|
||||
template<typename Type> Type *factor_vm::untag(cell value)
|
||||
template<typename Type> Type *untag(cell value)
|
||||
{
|
||||
return tagged<Type>(value).untagged();
|
||||
}
|
||||
|
|
|
@ -11,38 +11,6 @@ vm_char *safe_strdup(const vm_char *str)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
/* We don't use printf directly, because format directives are not portable.
|
||||
Instead we define the common cases here. */
|
||||
void nl()
|
||||
{
|
||||
fputs("\n",stdout);
|
||||
}
|
||||
|
||||
void print_string(const char *str)
|
||||
{
|
||||
fputs(str,stdout);
|
||||
}
|
||||
|
||||
void print_cell(cell x)
|
||||
{
|
||||
printf(CELL_FORMAT,x);
|
||||
}
|
||||
|
||||
void print_cell_hex(cell x)
|
||||
{
|
||||
printf(CELL_HEX_FORMAT,x);
|
||||
}
|
||||
|
||||
void print_cell_hex_pad(cell x)
|
||||
{
|
||||
printf(CELL_HEX_PAD_FORMAT,x);
|
||||
}
|
||||
|
||||
void print_fixnum(fixnum x)
|
||||
{
|
||||
printf(FIXNUM_FORMAT,x);
|
||||
}
|
||||
|
||||
cell read_cell_hex()
|
||||
{
|
||||
cell cell;
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
namespace factor
|
||||
{
|
||||
vm_char *safe_strdup(const vm_char *str);
|
||||
void print_string(const char *str);
|
||||
void nl();
|
||||
void print_cell(cell x);
|
||||
void print_cell_hex(cell x);
|
||||
void print_cell_hex_pad(cell x);
|
||||
void print_fixnum(fixnum x);
|
||||
cell read_cell_hex();
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ struct factor_vm
|
|||
/* GC is off during heap walking */
|
||||
bool gc_off;
|
||||
|
||||
/* GC logging */
|
||||
bool verbosegc;
|
||||
|
||||
/* Data heap */
|
||||
data_heap *data;
|
||||
|
||||
|
@ -327,7 +330,7 @@ struct factor_vm
|
|||
inline void set_array_nth(array *array, cell slot, cell value);
|
||||
|
||||
//strings
|
||||
cell string_nth(string* str, cell index);
|
||||
cell string_nth(const string *str, cell index);
|
||||
void set_string_nth_fast(string *str, cell index, cell ch);
|
||||
void set_string_nth_slow(string *str_, cell index, cell ch);
|
||||
void set_string_nth(string *str, cell index, cell ch);
|
||||
|
@ -450,8 +453,9 @@ struct factor_vm
|
|||
inline double untag_float_check(cell tagged);
|
||||
inline fixnum float_to_fixnum(cell tagged);
|
||||
inline double fixnum_to_float(cell tagged);
|
||||
|
||||
// tagged
|
||||
template<typename Type> Type *untag_check(cell value);
|
||||
template<typename Type> Type *untag(cell value);
|
||||
|
||||
//io
|
||||
void init_c_io();
|
||||
|
|
Loading…
Reference in New Issue