Merge branch 'master' of git://factorcode.org/git/factor
commit
a8cf31d125
|
@ -31,9 +31,8 @@ HELP: dlopen ( path -- dll )
|
||||||
{ $notes "This is the low-level facility used to implement " { $link load-library } ". Use the latter instead." } ;
|
{ $notes "This is the low-level facility used to implement " { $link load-library } ". Use the latter instead." } ;
|
||||||
|
|
||||||
HELP: dlsym ( name dll -- alien )
|
HELP: dlsym ( name dll -- alien )
|
||||||
{ $values { "name" "a C symbol name" } { "dll" "a DLL handle" } { "alien" "an alien pointer" } }
|
{ $values { "name" "a C symbol name" } { "dll" "a DLL handle" } { "alien" { $maybe alien } } }
|
||||||
{ $description "Looks up a symbol in a native library. If " { $snippet "dll" } " is " { $link f } " looks for the symbol in the runtime executable." }
|
{ $description "Looks up a symbol in a native library. If " { $snippet "dll" } " is " { $link f } " looks for the symbol in the runtime executable. If the symbol was not found, outputs " { $link f } "." } ;
|
||||||
{ $errors "Throws an error if the symbol could not be found." } ;
|
|
||||||
|
|
||||||
HELP: dlclose ( dll -- )
|
HELP: dlclose ( dll -- )
|
||||||
{ $values { "dll" "a DLL handle" } }
|
{ $values { "dll" "a DLL handle" } }
|
||||||
|
|
|
@ -25,6 +25,18 @@ M: x86.32 rs-reg EDI ;
|
||||||
M: x86.32 stack-reg ESP ;
|
M: x86.32 stack-reg ESP ;
|
||||||
M: x86.32 temp-reg ECX ;
|
M: x86.32 temp-reg ECX ;
|
||||||
|
|
||||||
|
M: x86.32 %mark-card
|
||||||
|
drop HEX: ffffffff [+] card-mark <byte> MOV
|
||||||
|
building get pop
|
||||||
|
rc-absolute-cell rel-cards-offset
|
||||||
|
building get push ;
|
||||||
|
|
||||||
|
M: x86.32 %mark-deck
|
||||||
|
drop HEX: ffffffff [+] card-mark <byte> MOV
|
||||||
|
building get pop
|
||||||
|
rc-absolute-cell rel-decks-offset
|
||||||
|
building get push ;
|
||||||
|
|
||||||
M:: x86.32 %dispatch ( src temp -- )
|
M:: x86.32 %dispatch ( src temp -- )
|
||||||
! Load jump table base.
|
! Load jump table base.
|
||||||
temp src HEX: ffffffff [+] LEA
|
temp src HEX: ffffffff [+] LEA
|
||||||
|
|
|
@ -21,6 +21,20 @@ M: x86.64 ds-reg R14 ;
|
||||||
M: x86.64 rs-reg R15 ;
|
M: x86.64 rs-reg R15 ;
|
||||||
M: x86.64 stack-reg RSP ;
|
M: x86.64 stack-reg RSP ;
|
||||||
|
|
||||||
|
: load-cards-offset ( dst -- )
|
||||||
|
0 MOV rc-absolute-cell rel-cards-offset ;
|
||||||
|
|
||||||
|
M: x86.64 %mark-card
|
||||||
|
dup load-cards-offset
|
||||||
|
[+] card-mark <byte> MOV ;
|
||||||
|
|
||||||
|
: load-decks-offset ( dst -- )
|
||||||
|
0 MOV rc-absolute-cell rel-decks-offset ;
|
||||||
|
|
||||||
|
M: x86.64 %mark-deck
|
||||||
|
dup load-cards-offset
|
||||||
|
[+] card-mark <byte> MOV ;
|
||||||
|
|
||||||
M:: x86.64 %dispatch ( src temp -- )
|
M:: x86.64 %dispatch ( src temp -- )
|
||||||
building get length :> start
|
building get length :> start
|
||||||
! Load jump table base.
|
! Load jump table base.
|
||||||
|
|
|
@ -387,31 +387,21 @@ M: x86 %vm-field-ptr ( dst field -- )
|
||||||
: store-tagged ( dst tag -- )
|
: store-tagged ( dst tag -- )
|
||||||
tag-number OR ;
|
tag-number OR ;
|
||||||
|
|
||||||
: load-cards-offset ( dst -- )
|
|
||||||
0 MOV rc-absolute-cell rel-cards-offset ;
|
|
||||||
|
|
||||||
: load-decks-offset ( dst -- )
|
|
||||||
0 MOV rc-absolute-cell rel-decks-offset ;
|
|
||||||
|
|
||||||
M:: x86 %allot ( dst size class nursery-ptr -- )
|
M:: x86 %allot ( dst size class nursery-ptr -- )
|
||||||
nursery-ptr dst load-allot-ptr
|
nursery-ptr dst load-allot-ptr
|
||||||
dst class store-header
|
dst class store-header
|
||||||
dst class store-tagged
|
dst class store-tagged
|
||||||
nursery-ptr size inc-allot-ptr ;
|
nursery-ptr size inc-allot-ptr ;
|
||||||
|
|
||||||
|
HOOK: %mark-card cpu ( card temp -- )
|
||||||
|
HOOK: %mark-deck cpu ( card temp -- )
|
||||||
|
|
||||||
:: (%write-barrier) ( src slot temp1 temp2 -- )
|
:: (%write-barrier) ( src slot temp1 temp2 -- )
|
||||||
! Compute slot address.
|
|
||||||
temp1 src slot [+] LEA
|
temp1 src slot [+] LEA
|
||||||
|
|
||||||
! Mark the card
|
|
||||||
temp1 card-bits SHR
|
temp1 card-bits SHR
|
||||||
temp2 load-cards-offset
|
temp1 temp2 %mark-card
|
||||||
temp2 temp1 [+] card-mark <byte> MOV
|
|
||||||
|
|
||||||
! Mark the card deck
|
|
||||||
temp1 deck-bits card-bits - SHR
|
temp1 deck-bits card-bits - SHR
|
||||||
temp2 load-decks-offset
|
temp1 temp2 %mark-deck ;
|
||||||
temp2 temp1 [+] card-mark <byte> MOV ;
|
|
||||||
|
|
||||||
M: x86 %write-barrier ( src slot temp1 temp2 -- ) (%write-barrier) ;
|
M: x86 %write-barrier ( src slot temp1 temp2 -- ) (%write-barrier) ;
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@ locals math sequences sorting system unicode.case vocabs.loader ;
|
||||||
IN: io.directories.search
|
IN: io.directories.search
|
||||||
|
|
||||||
: qualified-directory-entries ( path -- seq )
|
: qualified-directory-entries ( path -- seq )
|
||||||
normalize-path
|
(normalize-path)
|
||||||
dup directory-entries [ [ append-path ] change-name ] with map ;
|
dup directory-entries [ [ append-path ] change-name ] with map ;
|
||||||
|
|
||||||
: qualified-directory-files ( path -- seq )
|
: qualified-directory-files ( path -- seq )
|
||||||
normalize-path
|
(normalize-path)
|
||||||
dup directory-files [ append-path ] with map ;
|
dup directory-files [ append-path ] with map ;
|
||||||
|
|
||||||
: with-qualified-directory-files ( path quot -- )
|
: with-qualified-directory-files ( path quot -- )
|
||||||
|
|
|
@ -14,4 +14,5 @@ USING: alien sequences alien.libraries ;
|
||||||
{ "glu" "glu32.dll" "stdcall" }
|
{ "glu" "glu32.dll" "stdcall" }
|
||||||
{ "ole32" "ole32.dll" "stdcall" }
|
{ "ole32" "ole32.dll" "stdcall" }
|
||||||
{ "usp10" "usp10.dll" "stdcall" }
|
{ "usp10" "usp10.dll" "stdcall" }
|
||||||
|
{ "psapi" "psapi.dll" "stdcall" }
|
||||||
} [ first3 add-library ] each
|
} [ first3 add-library ] each
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Doug Coleman
|
|
@ -0,0 +1,12 @@
|
||||||
|
! Copyright (C) 2009 Doug Coleman.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: alien.syntax windows.types ;
|
||||||
|
IN: windows.psapi
|
||||||
|
|
||||||
|
LIBRARY: psapi
|
||||||
|
|
||||||
|
FUNCTION: BOOL EnumDeviceDrivers ( LPVOID* lpImageBase, DWORD cb, LPDWORD lpcbNeeded ) ;
|
||||||
|
|
||||||
|
FUNCTION: DWORD GetDeviceDriverBaseNameW ( LPVOID ImageBase, LPTSTR lpBaseName, DWORD nSize ) ;
|
||||||
|
|
||||||
|
ALIAS: GetDeviceDriverBaseName GetDeviceDriverBaseNameW
|
|
@ -38,7 +38,7 @@ void factor_vm::collect_aging()
|
||||||
collector.trace_contexts();
|
collector.trace_contexts();
|
||||||
collector.trace_code_heap_roots(&code->points_to_aging);
|
collector.trace_code_heap_roots(&code->points_to_aging);
|
||||||
collector.cheneys_algorithm();
|
collector.cheneys_algorithm();
|
||||||
update_dirty_code_blocks(&code->points_to_aging);
|
update_code_heap_for_minor_gc(&code->points_to_aging);
|
||||||
|
|
||||||
nursery.here = nursery.start;
|
nursery.here = nursery.start;
|
||||||
code->points_to_nursery.clear();
|
code->points_to_nursery.clear();
|
||||||
|
|
|
@ -3,10 +3,6 @@ namespace factor
|
||||||
|
|
||||||
struct aging_space : old_space {
|
struct aging_space : old_space {
|
||||||
aging_space(cell size, cell start) : old_space(size,start) {}
|
aging_space(cell size, cell start) : old_space(size,start) {}
|
||||||
|
|
||||||
bool is_nursery_p() { return false; }
|
|
||||||
bool is_aging_p() { return true; }
|
|
||||||
bool is_tenured_p() { return false; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,6 +356,41 @@ void factor_vm::update_word_references(code_block *compiled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This runs after a full collection */
|
||||||
|
struct literal_and_word_references_updater {
|
||||||
|
factor_vm *myvm;
|
||||||
|
|
||||||
|
explicit literal_and_word_references_updater(factor_vm *myvm_) : myvm(myvm_) {}
|
||||||
|
|
||||||
|
void operator()(relocation_entry rel, cell index, code_block *compiled)
|
||||||
|
{
|
||||||
|
relocation_type type = myvm->relocation_type_of(rel);
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case RT_IMMEDIATE:
|
||||||
|
case RT_XT:
|
||||||
|
case RT_XT_PIC:
|
||||||
|
case RT_XT_PIC_TAIL:
|
||||||
|
myvm->relocate_code_block_step(rel,index,compiled);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void factor_vm::update_code_block_for_full_gc(code_block *compiled)
|
||||||
|
{
|
||||||
|
if(code->needs_fixup_p(compiled))
|
||||||
|
relocate_code_block(compiled);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
literal_and_word_references_updater updater(this);
|
||||||
|
iterate_relocations(compiled,updater);
|
||||||
|
flush_icache_for(compiled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void factor_vm::check_code_address(cell address)
|
void factor_vm::check_code_address(cell address)
|
||||||
{
|
{
|
||||||
#ifdef FACTOR_DEBUG
|
#ifdef FACTOR_DEBUG
|
||||||
|
|
|
@ -153,19 +153,13 @@ end: this->myvm->gc_stats.card_scan_time += (current_micros() - start_time);
|
||||||
for(; iter != end; iter++) trace_literal_references(*iter);
|
for(; iter != end; iter++) trace_literal_references(*iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename SourceGeneration>
|
|
||||||
void trace_objects_between(SourceGeneration *gen, cell scan, cell *end)
|
|
||||||
{
|
|
||||||
while(scan && scan < *end)
|
|
||||||
{
|
|
||||||
this->trace_slots((object *)scan);
|
|
||||||
scan = gen->next_object_after(this->myvm,scan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cheneys_algorithm()
|
void cheneys_algorithm()
|
||||||
{
|
{
|
||||||
trace_objects_between(this->target,scan,&this->target->here);
|
while(scan && scan < this->target->here)
|
||||||
|
{
|
||||||
|
this->trace_slots((object *)scan);
|
||||||
|
scan = this->target->next_object_after(this->myvm,scan);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -211,7 +211,7 @@ void factor_vm::dump_memory(cell from, cell to)
|
||||||
dump_cell(from);
|
dump_cell(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::dump_zone(char *name, zone *z)
|
void factor_vm::dump_zone(const char *name, zone *z)
|
||||||
{
|
{
|
||||||
print_string(name); print_string(": ");
|
print_string(name); print_string(": ");
|
||||||
print_string("Start="); print_cell(z->start);
|
print_string("Start="); print_cell(z->start);
|
||||||
|
|
|
@ -97,10 +97,12 @@ void full_collector::cheneys_algorithm()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct full_updater {
|
/* After growing the heap, we have to perform a full relocation to update
|
||||||
|
references to card and deck arrays. */
|
||||||
|
struct after_growing_heap_updater {
|
||||||
factor_vm *myvm;
|
factor_vm *myvm;
|
||||||
|
|
||||||
full_updater(factor_vm *myvm_) : myvm(myvm_) {}
|
after_growing_heap_updater(factor_vm *myvm_) : myvm(myvm_) {}
|
||||||
|
|
||||||
void operator()(heap_block *block)
|
void operator()(heap_block *block)
|
||||||
{
|
{
|
||||||
|
@ -108,29 +110,29 @@ struct full_updater {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct literal_and_word_reference_updater {
|
/* After a full GC that did not grow the heap, we have to update references
|
||||||
|
to literals and other words. */
|
||||||
|
struct after_full_updater {
|
||||||
factor_vm *myvm;
|
factor_vm *myvm;
|
||||||
|
|
||||||
literal_and_word_reference_updater(factor_vm *myvm_) : myvm(myvm_) {}
|
after_full_updater(factor_vm *myvm_) : myvm(myvm_) {}
|
||||||
|
|
||||||
void operator()(heap_block *block)
|
void operator()(heap_block *block)
|
||||||
{
|
{
|
||||||
code_block *compiled = (code_block *)block;
|
myvm->update_code_block_for_full_gc((code_block *)block);
|
||||||
myvm->update_literal_references(compiled);
|
|
||||||
myvm->update_word_references(compiled);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void factor_vm::free_unmarked_code_blocks(bool growing_data_heap)
|
void factor_vm::update_code_heap_for_full_gc(bool growing_data_heap)
|
||||||
{
|
{
|
||||||
if(growing_data_heap)
|
if(growing_data_heap)
|
||||||
{
|
{
|
||||||
full_updater updater(this);
|
after_growing_heap_updater updater(this);
|
||||||
code->free_unmarked(updater);
|
code->free_unmarked(updater);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
literal_and_word_reference_updater updater(this);
|
after_full_updater updater(this);
|
||||||
code->free_unmarked(updater);
|
code->free_unmarked(updater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +162,7 @@ void factor_vm::collect_growing_heap(cell requested_bytes, bool trace_contexts_p
|
||||||
data_heap *old = data;
|
data_heap *old = data;
|
||||||
set_data_heap(data->grow(requested_bytes));
|
set_data_heap(data->grow(requested_bytes));
|
||||||
collect_full_impl(trace_contexts_p);
|
collect_full_impl(trace_contexts_p);
|
||||||
free_unmarked_code_blocks(true);
|
update_code_heap_for_full_gc(true);
|
||||||
delete old;
|
delete old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +171,7 @@ void factor_vm::collect_full(bool trace_contexts_p)
|
||||||
std::swap(data->tenured,data->tenured_semispace);
|
std::swap(data->tenured,data->tenured_semispace);
|
||||||
reset_generation(data->tenured);
|
reset_generation(data->tenured);
|
||||||
collect_full_impl(trace_contexts_p);
|
collect_full_impl(trace_contexts_p);
|
||||||
free_unmarked_code_blocks(false);
|
update_code_heap_for_full_gc(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ gc_state::gc_state(gc_op op_) : op(op_), start_time(current_micros()) {}
|
||||||
|
|
||||||
gc_state::~gc_state() {}
|
gc_state::~gc_state() {}
|
||||||
|
|
||||||
void factor_vm::update_dirty_code_blocks(std::set<code_block *> *remembered_set)
|
void factor_vm::update_code_heap_for_minor_gc(std::set<code_block *> *remembered_set)
|
||||||
{
|
{
|
||||||
/* The youngest generation that any code block can now reference */
|
/* The youngest generation that any code block can now reference */
|
||||||
std::set<code_block *>::const_iterator iter = remembered_set->begin();
|
std::set<code_block *>::const_iterator iter = remembered_set->begin();
|
||||||
|
|
|
@ -24,7 +24,7 @@ void factor_vm::collect_nursery()
|
||||||
simple_unmarker(card_mark_mask));
|
simple_unmarker(card_mark_mask));
|
||||||
collector.trace_code_heap_roots(&code->points_to_nursery);
|
collector.trace_code_heap_roots(&code->points_to_nursery);
|
||||||
collector.cheneys_algorithm();
|
collector.cheneys_algorithm();
|
||||||
update_dirty_code_blocks(&code->points_to_nursery);
|
update_code_heap_for_minor_gc(&code->points_to_nursery);
|
||||||
|
|
||||||
nursery.here = nursery.start;
|
nursery.here = nursery.start;
|
||||||
code->points_to_nursery.clear();
|
code->points_to_nursery.clear();
|
||||||
|
|
|
@ -68,7 +68,7 @@ cell old_space::next_object_after(factor_vm *myvm, cell scan)
|
||||||
if(scan + size < here)
|
if(scan + size < here)
|
||||||
return scan + size;
|
return scan + size;
|
||||||
else
|
else
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,6 @@ namespace factor
|
||||||
|
|
||||||
struct tenured_space : old_space {
|
struct tenured_space : old_space {
|
||||||
tenured_space(cell size, cell start) : old_space(size,start) {}
|
tenured_space(cell size, cell start) : old_space(size,start) {}
|
||||||
|
|
||||||
bool is_nursery_p() { return false; }
|
|
||||||
bool is_aging_p() { return false; }
|
|
||||||
bool is_tenured_p() { return true; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ void factor_vm::collect_to_tenured()
|
||||||
dummy_unmarker());
|
dummy_unmarker());
|
||||||
collector.trace_code_heap_roots(&code->points_to_aging);
|
collector.trace_code_heap_roots(&code->points_to_aging);
|
||||||
collector.cheneys_algorithm();
|
collector.cheneys_algorithm();
|
||||||
update_dirty_code_blocks(&code->points_to_aging);
|
update_code_heap_for_minor_gc(&code->points_to_aging);
|
||||||
|
|
||||||
nursery.here = nursery.start;
|
nursery.here = nursery.start;
|
||||||
reset_generation(data->aging);
|
reset_generation(data->aging);
|
||||||
|
|
|
@ -234,11 +234,11 @@ struct factor_vm
|
||||||
}
|
}
|
||||||
|
|
||||||
// gc
|
// gc
|
||||||
void update_dirty_code_blocks(std::set<code_block *> *remembered_set);
|
void update_code_heap_for_minor_gc(std::set<code_block *> *remembered_set);
|
||||||
void collect_nursery();
|
void collect_nursery();
|
||||||
void collect_aging();
|
void collect_aging();
|
||||||
void collect_to_tenured();
|
void collect_to_tenured();
|
||||||
void free_unmarked_code_blocks(bool growing_data_heap);
|
void update_code_heap_for_full_gc(bool growing_data_heap);
|
||||||
void collect_full_impl(bool trace_contexts_p);
|
void collect_full_impl(bool trace_contexts_p);
|
||||||
void collect_growing_heap(cell requested_bytes, bool trace_contexts_p);
|
void collect_growing_heap(cell requested_bytes, bool trace_contexts_p);
|
||||||
void collect_full(bool trace_contexts_p);
|
void collect_full(bool trace_contexts_p);
|
||||||
|
@ -301,7 +301,7 @@ struct factor_vm
|
||||||
void print_callstack();
|
void print_callstack();
|
||||||
void dump_cell(cell x);
|
void dump_cell(cell x);
|
||||||
void dump_memory(cell from, cell to);
|
void dump_memory(cell from, cell to);
|
||||||
void dump_zone(char *name, zone *z);
|
void dump_zone(const char *name, zone *z);
|
||||||
void dump_generations();
|
void dump_generations();
|
||||||
void dump_objects(cell type);
|
void dump_objects(cell type);
|
||||||
void find_data_references_step(cell *scan);
|
void find_data_references_step(cell *scan);
|
||||||
|
@ -479,6 +479,7 @@ struct factor_vm
|
||||||
void update_literal_references(code_block *compiled);
|
void update_literal_references(code_block *compiled);
|
||||||
void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled);
|
void relocate_code_block_step(relocation_entry rel, cell index, code_block *compiled);
|
||||||
void update_word_references(code_block *compiled);
|
void update_word_references(code_block *compiled);
|
||||||
|
void update_code_block_for_full_gc(code_block *compiled);
|
||||||
void check_code_address(cell address);
|
void check_code_address(cell address);
|
||||||
void relocate_code_block(code_block *compiled);
|
void relocate_code_block(code_block *compiled);
|
||||||
void fixup_labels(array *labels, code_block *compiled);
|
void fixup_labels(array *labels, code_block *compiled);
|
||||||
|
|
Loading…
Reference in New Issue