vm: use iostreams instead of printf for debug messages, clean up a few things

db4
Slava Pestov 2009-10-21 20:12:57 -05:00
parent af855b7fa9
commit 40351d40be
21 changed files with 191 additions and 216 deletions

View File

@ -286,7 +286,7 @@ struct literal_references_updater {
if(parent->relocation_type_of(rel) == RT_IMMEDIATE) if(parent->relocation_type_of(rel) == RT_IMMEDIATE)
{ {
cell offset = parent->relocation_offset_of(rel) + (cell)(compiled + 1); 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); fixnum absolute_value = array_nth(literals,index);
parent->store_address_in_code_block(parent->relocation_class_of(rel),offset,absolute_value); 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; cell used, total_free, max_free;
code->allocator->usage(&used,&total_free,&max_free); code->allocator->usage(&used,&total_free,&max_free);
print_string("Code heap stats:\n"); std::cout << "Code heap stats:\n";
print_string("Used: "); print_cell(used); nl(); std::cout << "Used: " << used << "\n";
print_string("Total free space: "); print_cell(total_free); nl(); std::cout << "Total free space: " << total_free << "\n";
print_string("Largest free block: "); print_cell(max_free); nl(); std::cout << "Largest free block: " << max_free << "\n";
fatal_error("Out of memory in add-compiled-block",0); fatal_error("Out of memory in add-compiled-block",0);
} }
} }

View File

@ -38,7 +38,7 @@ template<typename TargetGeneration, typename Policy> struct collector {
if(immediate_p(pointer)) return; if(immediate_p(pointer)) return;
object *untagged = parent->untag<object>(pointer); object *untagged = untag<object>(pointer);
if(!policy.should_copy_p(untagged)) if(!policy.should_copy_p(untagged))
{ {
policy.visited_object(untagged); policy.visited_object(untagged);

View File

@ -120,7 +120,7 @@ cell factor_vm::object_size(cell tagged)
} }
/* Size of the object pointed to by an untagged pointer */ /* 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(); if(free_p()) return ((free_heap_block *)this)->size();

View File

@ -3,36 +3,31 @@
namespace factor namespace factor
{ {
void factor_vm::print_chars(string* str) std::ostream &operator<<(std::ostream &out, const string *str)
{ {
cell i; for(cell i = 0; i < string_capacity(str); i++)
for(i = 0; i < string_capacity(str); i++) out << (char)str->nth(i);
putchar(string_nth(str,i)); return out;
} }
void factor_vm::print_word(word* word, cell nesting) void factor_vm::print_word(word* word, cell nesting)
{ {
if(tagged<object>(word->vocabulary).type_p(STRING_TYPE)) if(tagged<object>(word->vocabulary).type_p(STRING_TYPE))
{ std::cout << untag<string>(word->vocabulary) << ":";
print_chars(untag<string>(word->vocabulary));
print_string(":");
}
if(tagged<object>(word->name).type_p(STRING_TYPE)) if(tagged<object>(word->name).type_p(STRING_TYPE))
print_chars(untag<string>(word->name)); std::cout << untag<string>(word->name);
else else
{ {
print_string("#<not a string: "); std::cout << "#<not a string: ";
print_nested_obj(word->name,nesting); print_nested_obj(word->name,nesting);
print_string(">"); std::cout << ">";
} }
} }
void factor_vm::print_factor_string(string* str) void factor_vm::print_factor_string(string *str)
{ {
putchar('"'); std::cout << '"' << str << '"';
print_chars(str);
putchar('"');
} }
void factor_vm::print_array(array* array, cell nesting) 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++) for(i = 0; i < length; i++)
{ {
print_string(" "); std::cout << " ";
print_nested_obj(array_nth(array,i),nesting); print_nested_obj(array_nth(array,i),nesting);
} }
if(trimmed) if(trimmed)
print_string("..."); std::cout << "...";
} }
void factor_vm::print_tuple(tuple *tuple, cell nesting) 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); tuple_layout *layout = untag<tuple_layout>(tuple->layout);
cell length = to_fixnum(layout->size); cell length = to_fixnum(layout->size);
print_string(" "); std::cout << " ";
print_nested_obj(layout->klass,nesting); print_nested_obj(layout->klass,nesting);
cell i;
bool trimmed; bool trimmed;
if(length > 10 && !full_output) if(length > 10 && !full_output)
{ {
trimmed = true; trimmed = true;
@ -78,21 +71,21 @@ void factor_vm::print_tuple(tuple *tuple, cell nesting)
else else
trimmed = false; 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); print_nested_obj(tuple->data()[i],nesting);
} }
if(trimmed) if(trimmed)
print_string("..."); std::cout << "...";
} }
void factor_vm::print_nested_obj(cell obj, fixnum nesting) void factor_vm::print_nested_obj(cell obj, fixnum nesting)
{ {
if(nesting <= 0 && !full_output) if(nesting <= 0 && !full_output)
{ {
print_string(" ... "); std::cout << " ... ";
return; return;
} }
@ -101,7 +94,7 @@ void factor_vm::print_nested_obj(cell obj, fixnum nesting)
switch(tagged<object>(obj).type()) switch(tagged<object>(obj).type())
{ {
case FIXNUM_TYPE: case FIXNUM_TYPE:
print_fixnum(untag_fixnum(obj)); std::cout << untag_fixnum(obj);
break; break;
case WORD_TYPE: case WORD_TYPE:
print_word(untag<word>(obj),nesting - 1); 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)); print_factor_string(untag<string>(obj));
break; break;
case F_TYPE: case F_TYPE:
print_string("f"); std::cout << "f";
break; break;
case TUPLE_TYPE: case TUPLE_TYPE:
print_string("T{"); std::cout << "T{";
print_tuple(untag<tuple>(obj),nesting - 1); print_tuple(untag<tuple>(obj),nesting - 1);
print_string(" }"); std::cout << " }";
break; break;
case ARRAY_TYPE: case ARRAY_TYPE:
print_string("{"); std::cout << "{";
print_array(untag<array>(obj),nesting - 1); print_array(untag<array>(obj),nesting - 1);
print_string(" }"); std::cout << " }";
break; break;
case QUOTATION_TYPE: case QUOTATION_TYPE:
print_string("["); std::cout << "[";
quot = untag<quotation>(obj); quot = untag<quotation>(obj);
print_array(untag<array>(quot->array),nesting - 1); print_array(untag<array>(quot->array),nesting - 1);
print_string(" ]"); std::cout << " ]";
break; break;
default: default:
print_string("#<type "); std::cout << "#<type " << tagged<object>(obj).type() << " @ ";
print_cell(tagged<object>(obj).type()); std::cout << std::hex << obj << std::dec << ">";
print_string(" @ ");
print_cell_hex(obj);
print_string(">");
break; break;
} }
} }
@ -148,19 +138,19 @@ void factor_vm::print_objects(cell *start, cell *end)
for(; start <= end; start++) for(; start <= end; start++)
{ {
print_obj(*start); print_obj(*start);
nl(); std::cout << std::endl;
} }
} }
void factor_vm::print_datastack() void factor_vm::print_datastack()
{ {
print_string("==== DATA STACK:\n"); std::cout << "==== DATA STACK:\n";
print_objects((cell *)ds_bot,(cell *)ds); print_objects((cell *)ds_bot,(cell *)ds);
} }
void factor_vm::print_retainstack() void factor_vm::print_retainstack()
{ {
print_string("==== RETAIN STACK:\n"); std::cout << "==== RETAIN STACK:\n";
print_objects((cell *)rs_bot,(cell *)rs); print_objects((cell *)rs_bot,(cell *)rs);
} }
@ -171,34 +161,48 @@ struct stack_frame_printer {
void operator()(stack_frame *frame) void operator()(stack_frame *frame)
{ {
parent->print_obj(parent->frame_executing(frame)); parent->print_obj(parent->frame_executing(frame));
print_string("\n"); std::cout << std::endl;
parent->print_obj(parent->frame_scan(frame)); parent->print_obj(parent->frame_scan(frame));
print_string("\n"); std::cout << std::endl;
print_string("word/quot addr: "); std::cout << "word/quot addr: ";
print_cell_hex((cell)parent->frame_executing(frame)); std::cout << std::hex << (cell)parent->frame_executing(frame) << std::dec;
print_string("\n"); std::cout << std::endl;
print_string("word/quot xt: "); std::cout << "word/quot xt: ";
print_cell_hex((cell)frame->xt); std::cout << std::hex << (cell)frame->xt << std::dec;
print_string("\n"); std::cout << std::endl;
print_string("return address: "); std::cout << "return address: ";
print_cell_hex((cell)FRAME_RETURN_ADDRESS(frame,parent)); std::cout << std::hex << (cell)FRAME_RETURN_ADDRESS(frame,parent) << std::dec;
print_string("\n"); std::cout << std::endl;
} }
}; };
void factor_vm::print_callstack() void factor_vm::print_callstack()
{ {
print_string("==== CALL STACK:\n"); std::cout << "==== CALL STACK:\n";
stack_frame_printer printer(this); stack_frame_printer printer(this);
iterate_callstack(ctx,printer); 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) void factor_vm::dump_cell(cell x)
{ {
print_cell_hex_pad(x); print_string(": "); std::cout << padded_address(x) << ": ";
x = *(cell *)x; x = *(cell *)x;
print_cell_hex_pad(x); print_string(" tag "); print_cell(TAG(x)); std::cout << padded_address(x) << " tag " << TAG(x) << std::endl;
nl();
} }
void factor_vm::dump_memory(cell from, cell to) 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> template<typename Generation>
void factor_vm::dump_generation(const char *name, Generation *gen) void factor_vm::dump_generation(const char *name, Generation *gen)
{ {
print_string(name); print_string(": "); std::cout << name << ": ";
print_string("Start="); print_cell(gen->start); std::cout << "Start=" << gen->start;
print_string(", size="); print_cell(gen->size); std::cout << ", size=" << gen->size;
print_string(", end="); print_cell(gen->end); std::cout << ", end=" << gen->end;
nl(); std::cout << std::endl;
} }
void factor_vm::dump_generations() void factor_vm::dump_generations()
@ -225,11 +229,9 @@ void factor_vm::dump_generations()
dump_generation("Aging",data->aging); dump_generation("Aging",data->aging);
dump_generation("Tenured",data->tenured); dump_generation("Tenured",data->tenured);
print_string("Cards: base="); std::cout << "Cards:";
print_cell((cell)data->cards); std::cout << "base=" << (cell)data->cards << ", ";
print_string(", size="); std::cout << "size=" << (cell)(data->cards_end - data->cards) << std::endl;
print_cell((cell)(data->cards_end - data->cards));
nl();
} }
void factor_vm::dump_objects(cell type) 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)) if(type == TYPE_COUNT || tagged<object>(obj).type_p(type))
{ {
print_cell_hex_pad(obj); std::cout << padded_address(obj) << " ";
print_string(" ");
print_nested_obj(obj,2); print_nested_obj(obj,2);
nl(); std::cout << std::endl;
} }
} }
@ -263,10 +264,9 @@ struct data_references_finder {
{ {
if(look_for == *scan) if(look_for == *scan)
{ {
print_cell_hex_pad(obj); std::cout << padded_address(obj) << " ";
print_string(" ");
parent->print_nested_obj(obj,2); parent->print_nested_obj(obj,2);
nl(); std::cout << std::endl;
} }
} }
}; };
@ -311,9 +311,9 @@ struct code_block_printer {
status = "allocated"; status = "allocated";
} }
print_cell_hex((cell)scan); print_string(" "); std::cout << std::hex << (cell)scan << std::dec << " ";
print_cell_hex(size); print_string(" "); std::cout << std::hex << size << std::dec << " ";
print_string(status); print_string("\n"); std::cout << status << std::endl;
} }
}; };
@ -322,40 +322,40 @@ void factor_vm::dump_code_heap()
{ {
code_block_printer printer(this); code_block_printer printer(this);
code->allocator->iterate(printer); code->allocator->iterate(printer);
print_cell(printer.reloc_size); print_string(" bytes of relocation data\n"); std::cout << printer.reloc_size << " bytes of relocation data\n";
print_cell(printer.literal_size); print_string(" bytes of literal data\n"); std::cout << printer.literal_size << " bytes of literal data\n";
} }
void factor_vm::factorbug() void factor_vm::factorbug()
{ {
if(fep_disabled) if(fep_disabled)
{ {
print_string("Low level debugger disabled\n"); std::cout << "Low level debugger disabled\n";
exit(1); exit(1);
} }
/* open_console(); */ /* open_console(); */
print_string("Starting low level debugger...\n"); std::cout << "Starting low level debugger...\n";
print_string(" Basic commands:\n"); std::cout << " Basic commands:\n";
print_string("q -- continue executing Factor - NOT SAFE\n"); std::cout << "q -- continue executing Factor - NOT SAFE\n";
print_string("im -- save image to fep.image\n"); std::cout << "im -- save image to fep.image\n";
print_string("x -- exit Factor\n"); std::cout << "x -- exit Factor\n";
print_string(" Advanced commands:\n"); std::cout << " Advanced commands:\n";
print_string("d <addr> <count> -- dump memory\n"); std::cout << "d <addr> <count> -- dump memory\n";
print_string("u <addr> -- dump object at tagged <addr>\n"); std::cout << "u <addr> -- dump object at tagged <addr>\n";
print_string(". <addr> -- print object at tagged <addr>\n"); std::cout << ". <addr> -- print object at tagged <addr>\n";
print_string("t -- toggle output trimming\n"); std::cout << "t -- toggle output trimming\n";
print_string("s r -- dump data, retain stacks\n"); std::cout << "s r -- dump data, retain stacks\n";
print_string(".s .r .c -- print data, retain, call stacks\n"); std::cout << ".s .r .c -- print data, retain, call stacks\n";
print_string("e -- dump environment\n"); std::cout << "e -- dump environment\n";
print_string("g -- dump generations\n"); std::cout << "g -- dump generations\n";
print_string("data -- data heap dump\n"); std::cout << "data -- data heap dump\n";
print_string("words -- words dump\n"); std::cout << "words -- words dump\n";
print_string("tuples -- tuples dump\n"); std::cout << "tuples -- tuples dump\n";
print_string("refs <addr> -- find data heap references to object\n"); std::cout << "refs <addr> -- find data heap references to object\n";
print_string("push <addr> -- push object on data stack - NOT SAFE\n"); std::cout << "push <addr> -- push object on data stack - NOT SAFE\n";
print_string("code -- code heap dump\n"); std::cout << "code -- code heap dump\n";
bool seen_command = false; bool seen_command = false;
@ -363,7 +363,7 @@ void factor_vm::factorbug()
{ {
char cmd[1024]; char cmd[1024];
print_string("READY\n"); std::cout << "READY\n";
fflush(stdout); fflush(stdout);
if(scanf("%1000s",cmd) <= 0) if(scanf("%1000s",cmd) <= 0)
@ -403,7 +403,7 @@ void factor_vm::factorbug()
{ {
cell addr = read_cell_hex(); cell addr = read_cell_hex();
print_obj(addr); print_obj(addr);
print_string("\n"); std::cout << std::endl;
} }
else if(strcmp(cmd,"t") == 0) else if(strcmp(cmd,"t") == 0)
full_output = !full_output; full_output = !full_output;
@ -436,9 +436,9 @@ void factor_vm::factorbug()
else if(strcmp(cmd,"refs") == 0) else if(strcmp(cmd,"refs") == 0)
{ {
cell addr = read_cell_hex(); cell addr = read_cell_hex();
print_string("Data heap references:\n"); std::cout << "Data heap references:\n";
find_data_references(addr); find_data_references(addr);
nl(); std::cout << std::endl;
} }
else if(strcmp(cmd,"words") == 0) else if(strcmp(cmd,"words") == 0)
dump_objects(WORD_TYPE); dump_objects(WORD_TYPE);
@ -452,14 +452,14 @@ void factor_vm::factorbug()
else if(strcmp(cmd,"code") == 0) else if(strcmp(cmd,"code") == 0)
dump_code_heap(); dump_code_heap();
else else
print_string("unknown command\n"); std::cout << "unknown command\n";
} }
} }
void factor_vm::primitive_die() void factor_vm::primitive_die()
{ {
print_string("The die word was called by the library. Unless you called it yourself,\n"); std::cout << "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 << "you have triggered a bug in Factor. Please report.\n";
factorbug(); factorbug();
} }

View File

@ -5,22 +5,24 @@ namespace factor
void fatal_error(const char *msg, cell tagged) void fatal_error(const char *msg, cell tagged)
{ {
print_string("fatal_error: "); print_string(msg); std::cout << "fatal_error: " << msg;
print_string(": "); print_cell_hex(tagged); nl(); std::cout << ": " << std::hex << tagged << std::dec;
std::cout << std::endl;
exit(1); exit(1);
} }
void critical_error(const char *msg, cell tagged) void critical_error(const char *msg, cell tagged)
{ {
print_string("You have triggered a bug in Factor. Please report.\n"); std::cout << "You have triggered a bug in Factor. Please report.\n";
print_string("critical_error: "); print_string(msg); std::cout << "critical_error: " << msg;
print_string(": "); print_cell_hex(tagged); nl(); std::cout << ": " << std::hex << tagged << std::dec;
std::cout << std::endl;
tls_vm()->factorbug(); tls_vm()->factorbug();
} }
void out_of_memory() void out_of_memory()
{ {
print_string("Out of memory\n\n"); std::cout << "Out of memory\n\n";
tls_vm()->dump_generations(); tls_vm()->dump_generations();
exit(1); exit(1);
} }
@ -59,10 +61,10 @@ void factor_vm::throw_error(cell error, stack_frame *callstack_top)
crash. */ crash. */
else else
{ {
print_string("You have triggered a bug in Factor. Please report.\n"); std::cout << "You have triggered a bug in Factor. Please report.\n";
print_string("early_error: "); std::cout << "early_error: ";
print_obj(error); print_obj(error);
nl(); std::cout << std::endl;
factorbug(); factorbug();
} }
} }

View File

@ -38,6 +38,7 @@ void factor_vm::default_parameters(vm_parameters *p)
p->max_pic_size = 3; p->max_pic_size = 3;
p->fep = false; p->fep = false;
p->verbosegc = false;
p->signals = true; p->signals = true;
#ifdef WINDOWS #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(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("-fep")) == 0) p->fep = true;
else if(STRCMP(arg,STRING_LITERAL("-nosignals")) == 0) p->signals = false; 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(STRNCMP(arg,STRING_LITERAL("-i="),3) == 0) p->image_path = arg + 3;
else if(STRCMP(arg,STRING_LITERAL("-console")) == 0) p->console = true; 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 */ /* Do some initialization that we do once only */
void factor_vm::do_stage1_init() void factor_vm::do_stage1_init()
{ {
print_string("*** Stage 2 early init... "); std::cout << "*** Stage 2 early init... ";
fflush(stdout); fflush(stdout);
compile_all_words(); compile_all_words();
userenv[STAGE2_ENV] = true_object; userenv[STAGE2_ENV] = true_object;
print_string("done\n"); std::cout << "done\n";
fflush(stdout);
} }
void factor_vm::init_factor(vm_parameters *p) void factor_vm::init_factor(vm_parameters *p)
@ -141,6 +142,8 @@ void factor_vm::init_factor(vm_parameters *p)
if(p->signals) if(p->signals)
init_signals(); init_signals();
verbosegc = p->verbosegc;
if(p->console) if(p->console)
open_console(); open_console();

View File

@ -37,6 +37,9 @@ void factor_vm::gc(gc_op op,
current_gc = new gc_state(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 /* Keep trying to GC higher and higher generations until we don't run out
of space */ of space */
if(setjmp(current_gc->gc_unwind)) if(setjmp(current_gc->gc_unwind))
@ -60,6 +63,9 @@ void factor_vm::gc(gc_op op,
critical_error("Bad GC op\n",op); critical_error("Bad GC op\n",op);
break; break;
} }
if(verbosegc)
std::cout << "GC rewind, op=" << op << std::endl;
} }
switch(current_gc->op) switch(current_gc->op)
@ -91,11 +97,14 @@ void factor_vm::gc(gc_op op,
delete current_gc; delete current_gc;
current_gc = NULL; current_gc = NULL;
if(verbosegc)
std::cout << "GC done, op=" << op << std::endl;
} }
void factor_vm::primitive_minor_gc() void factor_vm::primitive_minor_gc()
{ {
gc(collect_nursery_op, gc(collect_full_op,
0, /* requested size */ 0, /* requested size */
true, /* trace contexts? */ true, /* trace contexts? */
false /* compact code heap? */); false /* compact code heap? */);

View File

@ -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) if((cell)bytes_read != h->data_size)
{ {
print_string("truncated image: "); std::cout << "truncated image: " << bytes_read << " bytes read, ";
print_fixnum(bytes_read); std::cout << h->data_size << " bytes expected\n";
print_string(" bytes read, ");
print_cell(h->data_size);
print_string(" bytes expected\n");
fatal_error("load_data_heap failed",0); 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); size_t bytes_read = fread(code->allocator->first_block(),1,h->code_size,file);
if(bytes_read != h->code_size) if(bytes_read != h->code_size)
{ {
print_string("truncated image: "); std::cout << "truncated image: " << bytes_read << " bytes read, ";
print_fixnum(bytes_read); std::cout << h->code_size << " bytes expected\n";
print_string(" bytes read, ");
print_cell(h->code_size);
print_string(" bytes expected\n");
fatal_error("load_code_heap failed",0); 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); FILE *file = OPEN_READ(p->image_path);
if(file == NULL) if(file == NULL)
{ {
print_string("Cannot open image file: "); print_native_string(p->image_path); nl(); std::cout << "Cannot open image file: " << p->image_path << std::endl;
print_string(strerror(errno)); nl(); std::cout << strerror(errno) << std::endl;
exit(1); exit(1);
} }
@ -281,8 +275,8 @@ bool factor_vm::save_image(const vm_char *filename)
file = OPEN_WRITE(filename); file = OPEN_WRITE(filename);
if(file == NULL) if(file == NULL)
{ {
print_string("Cannot open image file: "); print_native_string(filename); nl(); std::cout << "Cannot open image file: " << filename << std::endl;
print_string(strerror(errno)); nl(); std::cout << strerror(errno) << std::endl;
return false; return false;
} }
@ -309,9 +303,7 @@ bool factor_vm::save_image(const vm_char *filename)
if(fclose(file)) ok = false; if(fclose(file)) ok = false;
if(!ok) if(!ok)
{ std::cout << "save-image failed: " << strerror(errno) << std::endl;
print_string("save-image failed: "); print_string(strerror(errno)); nl();
}
return ok; return ok;
} }

View File

@ -35,6 +35,7 @@ struct vm_parameters {
cell young_size, aging_size, tenured_size; cell young_size, aging_size, tenured_size;
cell code_size; cell code_size;
bool fep; bool fep;
bool verbosegc;
bool console; bool console;
bool signals; bool signals;
cell max_pic_size; cell max_pic_size;

View File

@ -233,10 +233,10 @@ void *factor_vm::inline_cache_miss(cell return_address)
set_call_target(return_address,xt); set_call_target(return_address,xt);
#ifdef PIC_DEBUG #ifdef PIC_DEBUG
printf("Updated %s call site 0x%lx with 0x%lx\n", std::cout << "Updated "
tail_call_site_p(return_address) ? "tail" : "non-tail", << (tail_call_site_p(return_address) ? "tail" : "non-tail")
return_address, << " call site 0x" << std::hex << return_address << std::dec
(cell)xt); << " with " << std::hex << (cell)xt << std::dec;
#endif #endif
return xt; return xt;

View File

@ -43,7 +43,7 @@ struct jit {
void emit_subprimitive(cell word_) { void emit_subprimitive(cell word_) {
gc_root<word> word(word_,parent); gc_root<word> word(word_,parent);
gc_root<array> code_pair(word->subprimitive,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)); emit(array_nth(code_pair.untagged(),1));
} }

View File

@ -112,25 +112,25 @@ struct header {
explicit header(cell value_) : value(value_ << TAG_BITS) {} explicit header(cell value_) : value(value_ << TAG_BITS) {}
void check_header() void check_header() const
{ {
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
assert(TAG(value) == FIXNUM_TYPE && untag_fixnum(value) < TYPE_COUNT); assert(TAG(value) == FIXNUM_TYPE && untag_fixnum(value) < TYPE_COUNT);
#endif #endif
} }
cell hi_tag() cell hi_tag() const
{ {
check_header(); check_header();
return value >> TAG_BITS; return value >> TAG_BITS;
} }
bool forwarding_pointer_p() bool forwarding_pointer_p() const
{ {
return TAG(value) == GC_COLLECTED; return TAG(value) == GC_COLLECTED;
} }
object *forwarding_pointer() object *forwarding_pointer() const
{ {
return (object *)UNTAG(value); return (object *)UNTAG(value);
} }
@ -147,13 +147,13 @@ struct object {
NO_TYPE_CHECK; NO_TYPE_CHECK;
header h; 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 /* Only valid for objects in tenured space; must fast to free_heap_block
to do anything with it if its free */ to do anything with it if its free */
bool free_p() bool free_p() const
{ {
return h.value & 1 == 1; return h.value & 1 == 1;
} }
@ -166,7 +166,7 @@ struct array : public object {
/* tagged */ /* tagged */
cell capacity; 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 /* These are really just arrays, but certain elements have special
@ -187,7 +187,7 @@ struct bignum : public object {
/* tagged */ /* tagged */
cell capacity; cell capacity;
cell *data() { return (cell *)(this + 1); } cell *data() const { return (cell *)(this + 1); }
}; };
struct byte_array : public object { struct byte_array : public object {
@ -201,7 +201,7 @@ struct byte_array : public object {
cell padding1; cell padding1;
#endif #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 */ /* Assembly code makes assumptions about the layout of this struct */
@ -214,7 +214,9 @@ struct string : public object {
/* tagged */ /* tagged */
cell hashcode; 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. */ /* The compiled code heap is structured into blocks. */
@ -222,12 +224,12 @@ struct heap_block
{ {
cell header; cell header;
bool free_p() bool free_p() const
{ {
return header & 1 == 1; return header & 1 == 1;
} }
cell size() cell size() const
{ {
cell bytes = header >> 3; cell bytes = header >> 3;
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
@ -258,12 +260,12 @@ struct code_block : public heap_block
cell literals; /* tagged pointer to array or f */ cell literals; /* tagged pointer to array or f */
cell relocation; /* tagged pointer to byte-array or f */ cell relocation; /* tagged pointer to byte-array or f */
void *xt() void *xt() const
{ {
return (void *)(this + 1); return (void *)(this + 1);
} }
code_block_type type() code_block_type type() const
{ {
return (code_block_type)((header >> 1) & 0x3); return (code_block_type)((header >> 1) & 0x3);
} }
@ -273,12 +275,12 @@ struct code_block : public heap_block
header = ((header & ~0x7) | (type << 1)); header = ((header & ~0x7) | (type << 1));
} }
bool pic_p() bool pic_p() const
{ {
return type() == code_block_pic; return type() == code_block_pic;
} }
bool optimized_p() bool optimized_p() const
{ {
return type() == code_block_optimized; return type() == code_block_optimized;
} }
@ -376,13 +378,13 @@ struct callstack : public object {
/* tagged */ /* tagged */
cell length; cell length;
stack_frame *frame_at(cell offset) stack_frame *frame_at(cell offset) const
{ {
return (stack_frame *)((char *)(this + 1) + offset); return (stack_frame *)((char *)(this + 1) + offset);
} }
stack_frame *top() { return (stack_frame *)(this + 1); } stack_frame *top() const { return (stack_frame *)(this + 1); }
stack_frame *bottom() { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); } stack_frame *bottom() const { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
}; };
struct tuple : public object { struct tuple : public object {
@ -390,7 +392,7 @@ struct tuple : public object {
/* tagged layout */ /* tagged layout */
cell layout; cell layout;
cell *data() { return (cell *)(this + 1); } cell *data() const { return (cell *)(this + 1); }
}; };
} }

View File

@ -28,6 +28,7 @@
#include <map> #include <map>
#include <set> #include <set>
#include <vector> #include <vector>
#include <iostream>
/* Forward-declare this since it comes up in function prototypes */ /* Forward-declare this since it comes up in function prototypes */
namespace factor namespace factor

View File

@ -37,8 +37,6 @@ typedef wchar_t vm_char;
#define OPEN_READ(path) _wfopen(path,L"rb") #define OPEN_READ(path) _wfopen(path,L"rb")
#define OPEN_WRITE(path) _wfopen(path,L"wb") #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 */ /* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */
#define EPOCH_OFFSET 0x019db1ded53e8000LL #define EPOCH_OFFSET 0x019db1ded53e8000LL

View File

@ -88,7 +88,7 @@ bool quotation_jit::stack_frame_p()
switch(tagged<object>(obj).type()) switch(tagged<object>(obj).type())
{ {
case WORD_TYPE: case WORD_TYPE:
if(!parent->to_boolean(parent->untag<word>(obj)->subprimitive)) if(!parent->to_boolean(untag<word>(obj)->subprimitive))
return true; return true;
break; break;
case QUOTATION_TYPE: case QUOTATION_TYPE:
@ -112,7 +112,7 @@ void quotation_jit::emit_quot(cell quot_)
{ {
gc_root<quotation> quot(quot_,parent); 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 /* If the quotation consists of a single word, compile a direct call
to the word. */ to the word. */

View File

@ -3,20 +3,20 @@
namespace factor 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 /* If high bit is set, the most significant 16 bits of the char
come from the aux vector. The least significant bit of the come from the aux vector. The least significant bit of the
corresponding aux vector entry is negated, so that we can corresponding aux vector entry is negated, so that we can
XOR the two components together and get the original code point XOR the two components together and get the original code point
back. */ back. */
cell lo_bits = str->data()[index]; cell lo_bits = data()[index];
if((lo_bits & 0x80) == 0) if((lo_bits & 0x80) == 0)
return lo_bits; return lo_bits;
else else
{ {
byte_array *aux = untag<byte_array>(str->aux); byte_array *aux = untag<byte_array>(this->aux);
cell hi_bits = aux->data<u16>()[index]; cell hi_bits = aux->data<u16>()[index];
return (hi_bits << 7) ^ lo_bits; return (hi_bits << 7) ^ lo_bits;
} }
@ -166,7 +166,7 @@ void factor_vm::primitive_string_nth()
{ {
string *str = untag<string>(dpop()); string *str = untag<string>(dpop());
cell index = untag_fixnum(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() void factor_vm::primitive_set_string_nth_fast()

View File

@ -1,7 +1,7 @@
namespace factor namespace factor
{ {
inline static cell string_capacity(string *str) inline static cell string_capacity(const string *str)
{ {
return untag_fixnum(str->length); return untag_fixnum(str->length);
} }

View File

@ -75,7 +75,7 @@ template<typename Type> Type *factor_vm::untag_check(cell value)
return tagged<Type>(value).untag_check(this); 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(); return tagged<Type>(value).untagged();
} }

View File

@ -11,38 +11,6 @@ vm_char *safe_strdup(const vm_char *str)
return ptr; 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 read_cell_hex()
{ {
cell cell; cell cell;

View File

@ -1,11 +1,6 @@
namespace factor namespace factor
{ {
vm_char *safe_strdup(const vm_char *str); 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_cell_hex_pad(cell x);
void print_fixnum(fixnum x);
cell read_cell_hex(); cell read_cell_hex();
} }

View File

@ -46,6 +46,9 @@ struct factor_vm
/* GC is off during heap walking */ /* GC is off during heap walking */
bool gc_off; bool gc_off;
/* GC logging */
bool verbosegc;
/* Data heap */ /* Data heap */
data_heap *data; data_heap *data;
@ -327,7 +330,7 @@ struct factor_vm
inline void set_array_nth(array *array, cell slot, cell value); inline void set_array_nth(array *array, cell slot, cell value);
//strings //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_fast(string *str, cell index, cell ch);
void set_string_nth_slow(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); 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 double untag_float_check(cell tagged);
inline fixnum float_to_fixnum(cell tagged); inline fixnum float_to_fixnum(cell tagged);
inline double fixnum_to_float(cell tagged); inline double fixnum_to_float(cell tagged);
// tagged
template<typename Type> Type *untag_check(cell value); template<typename Type> Type *untag_check(cell value);
template<typename Type> Type *untag(cell value);
//io //io
void init_c_io(); void init_c_io();