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." } ;
|
||||
|
||||
HELP: dlsym ( name dll -- alien )
|
||||
{ $values { "name" "a C symbol name" } { "dll" "a DLL handle" } { "alien" "an alien pointer" } }
|
||||
{ $description "Looks up a symbol in a native library. If " { $snippet "dll" } " is " { $link f } " looks for the symbol in the runtime executable." }
|
||||
{ $errors "Throws an error if the symbol could not be found." } ;
|
||||
{ $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. If the symbol was not found, outputs " { $link f } "." } ;
|
||||
|
||||
HELP: dlclose ( dll -- )
|
||||
{ $values { "dll" "a DLL handle" } }
|
||||
|
|
|
@ -25,6 +25,18 @@ M: x86.32 rs-reg EDI ;
|
|||
M: x86.32 stack-reg ESP ;
|
||||
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 -- )
|
||||
! Load jump table base.
|
||||
temp src HEX: ffffffff [+] LEA
|
||||
|
|
|
@ -21,6 +21,20 @@ M: x86.64 ds-reg R14 ;
|
|||
M: x86.64 rs-reg R15 ;
|
||||
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 -- )
|
||||
building get length :> start
|
||||
! Load jump table base.
|
||||
|
|
|
@ -387,31 +387,21 @@ M: x86 %vm-field-ptr ( dst field -- )
|
|||
: store-tagged ( dst tag -- )
|
||||
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 -- )
|
||||
nursery-ptr dst load-allot-ptr
|
||||
dst class store-header
|
||||
dst class store-tagged
|
||||
nursery-ptr size inc-allot-ptr ;
|
||||
|
||||
HOOK: %mark-card cpu ( card temp -- )
|
||||
HOOK: %mark-deck cpu ( card temp -- )
|
||||
|
||||
:: (%write-barrier) ( src slot temp1 temp2 -- )
|
||||
! Compute slot address.
|
||||
temp1 src slot [+] LEA
|
||||
|
||||
! Mark the card
|
||||
temp1 card-bits SHR
|
||||
temp2 load-cards-offset
|
||||
temp2 temp1 [+] card-mark <byte> MOV
|
||||
|
||||
! Mark the card deck
|
||||
temp1 temp2 %mark-card
|
||||
temp1 deck-bits card-bits - SHR
|
||||
temp2 load-decks-offset
|
||||
temp2 temp1 [+] card-mark <byte> MOV ;
|
||||
temp1 temp2 %mark-deck ;
|
||||
|
||||
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
|
||||
|
||||
: qualified-directory-entries ( path -- seq )
|
||||
normalize-path
|
||||
(normalize-path)
|
||||
dup directory-entries [ [ append-path ] change-name ] with map ;
|
||||
|
||||
: qualified-directory-files ( path -- seq )
|
||||
normalize-path
|
||||
(normalize-path)
|
||||
dup directory-files [ append-path ] with map ;
|
||||
|
||||
: with-qualified-directory-files ( path quot -- )
|
||||
|
|
|
@ -14,4 +14,5 @@ USING: alien sequences alien.libraries ;
|
|||
{ "glu" "glu32.dll" "stdcall" }
|
||||
{ "ole32" "ole32.dll" "stdcall" }
|
||||
{ "usp10" "usp10.dll" "stdcall" }
|
||||
{ "psapi" "psapi.dll" "stdcall" }
|
||||
} [ 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_code_heap_roots(&code->points_to_aging);
|
||||
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;
|
||||
code->points_to_nursery.clear();
|
||||
|
|
|
@ -3,10 +3,6 @@ namespace factor
|
|||
|
||||
struct aging_space : old_space {
|
||||
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)
|
||||
{
|
||||
#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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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("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;
|
||||
|
||||
full_updater(factor_vm *myvm_) : myvm(myvm_) {}
|
||||
after_growing_heap_updater(factor_vm *myvm_) : myvm(myvm_) {}
|
||||
|
||||
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;
|
||||
|
||||
literal_and_word_reference_updater(factor_vm *myvm_) : myvm(myvm_) {}
|
||||
after_full_updater(factor_vm *myvm_) : myvm(myvm_) {}
|
||||
|
||||
void operator()(heap_block *block)
|
||||
{
|
||||
code_block *compiled = (code_block *)block;
|
||||
myvm->update_literal_references(compiled);
|
||||
myvm->update_word_references(compiled);
|
||||
myvm->update_code_block_for_full_gc((code_block *)block);
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
full_updater updater(this);
|
||||
after_growing_heap_updater updater(this);
|
||||
code->free_unmarked(updater);
|
||||
}
|
||||
else
|
||||
{
|
||||
literal_and_word_reference_updater updater(this);
|
||||
after_full_updater updater(this);
|
||||
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;
|
||||
set_data_heap(data->grow(requested_bytes));
|
||||
collect_full_impl(trace_contexts_p);
|
||||
free_unmarked_code_blocks(true);
|
||||
update_code_heap_for_full_gc(true);
|
||||
delete old;
|
||||
}
|
||||
|
||||
|
@ -169,7 +171,7 @@ void factor_vm::collect_full(bool trace_contexts_p)
|
|||
std::swap(data->tenured,data->tenured_semispace);
|
||||
reset_generation(data->tenured);
|
||||
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() {}
|
||||
|
||||
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 */
|
||||
std::set<code_block *>::const_iterator iter = remembered_set->begin();
|
||||
|
|
|
@ -24,7 +24,7 @@ void factor_vm::collect_nursery()
|
|||
simple_unmarker(card_mark_mask));
|
||||
collector.trace_code_heap_roots(&code->points_to_nursery);
|
||||
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;
|
||||
code->points_to_nursery.clear();
|
||||
|
|
|
@ -68,7 +68,7 @@ cell old_space::next_object_after(factor_vm *myvm, cell scan)
|
|||
if(scan + size < here)
|
||||
return scan + size;
|
||||
else
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,10 +3,6 @@ namespace factor
|
|||
|
||||
struct tenured_space : old_space {
|
||||
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());
|
||||
collector.trace_code_heap_roots(&code->points_to_aging);
|
||||
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;
|
||||
reset_generation(data->aging);
|
||||
|
|
|
@ -234,11 +234,11 @@ struct factor_vm
|
|||
}
|
||||
|
||||
// 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_aging();
|
||||
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_growing_heap(cell requested_bytes, bool trace_contexts_p);
|
||||
void collect_full(bool trace_contexts_p);
|
||||
|
@ -301,7 +301,7 @@ struct factor_vm
|
|||
void print_callstack();
|
||||
void dump_cell(cell x);
|
||||
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_objects(cell type);
|
||||
void find_data_references_step(cell *scan);
|
||||
|
@ -479,6 +479,7 @@ struct factor_vm
|
|||
void update_literal_references(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_code_block_for_full_gc(code_block *compiled);
|
||||
void check_code_address(cell address);
|
||||
void relocate_code_block(code_block *compiled);
|
||||
void fixup_labels(array *labels, code_block *compiled);
|
||||
|
|
Loading…
Reference in New Issue