VM: refactor gc_event so that the phase times are stored in an array
So that you don't need a new method for each gc phase to time.char-rename
parent
51408b66cb
commit
752c895d23
|
@ -1,11 +1,10 @@
|
||||||
! Copyright (C) 2005, 2011 Slava Pestov.
|
! Copyright (C) 2005, 2011 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors arrays assocs binary-search classes
|
USING: accessors arrays assocs binary-search classes classes.struct
|
||||||
classes.struct combinators combinators.smart continuations fry
|
combinators combinators.smart continuations fry grouping hashtables
|
||||||
generalizations generic grouping io io.styles kernel make math
|
hints io io.styles kernel layouts math math.order math.parser
|
||||||
math.order math.parser math.statistics memory layouts namespaces
|
math.statistics memory namespaces prettyprint sequences
|
||||||
parser prettyprint sequences sequences.generalizations sorting
|
sequences.generalizations sorting vm ;
|
||||||
splitting strings system vm words hints hashtables ;
|
|
||||||
IN: tools.memory
|
IN: tools.memory
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
@ -186,6 +185,9 @@ SYMBOL: gc-events
|
||||||
: gc-stats. ( -- )
|
: gc-stats. ( -- )
|
||||||
gc-events get compute-gc-stats gc-stats-table simple-table. ;
|
gc-events get compute-gc-stats gc-stats-table simple-table. ;
|
||||||
|
|
||||||
|
: sum-phase-times ( events phase -- n )
|
||||||
|
'[ times>> _ swap nth ] map-sum nanos>string ; inline
|
||||||
|
|
||||||
: gc-summary. ( -- )
|
: gc-summary. ( -- )
|
||||||
gc-events get {
|
gc-events get {
|
||||||
{ "Collections:" [ length commas ] }
|
{ "Collections:" [ length commas ] }
|
||||||
|
@ -193,11 +195,11 @@ SYMBOL: gc-events
|
||||||
{ "Decks scanned:" [ [ decks-scanned>> ] map-sum commas ] }
|
{ "Decks scanned:" [ [ decks-scanned>> ] map-sum commas ] }
|
||||||
{ "Code blocks scanned:" [ [ code-blocks-scanned>> ] map-sum commas ] }
|
{ "Code blocks scanned:" [ [ code-blocks-scanned>> ] map-sum commas ] }
|
||||||
{ "Total time:" [ [ total-time>> ] map-sum nanos>string ] }
|
{ "Total time:" [ [ total-time>> ] map-sum nanos>string ] }
|
||||||
{ "Card scan time:" [ [ card-scan-time>> ] map-sum nanos>string ] }
|
{ "Card scan time:" [ PHASE-CARD-SCAN sum-phase-times ] }
|
||||||
{ "Code block scan time:" [ [ code-scan-time>> ] map-sum nanos>string ] }
|
{ "Code block scan time:" [ PHASE-CODE-SCAN sum-phase-times ] }
|
||||||
{ "Data heap sweep time:" [ [ data-sweep-time>> ] map-sum nanos>string ] }
|
{ "Data heap sweep time:" [ PHASE-DATA-SWEEP sum-phase-times ] }
|
||||||
{ "Code heap sweep time:" [ [ code-sweep-time>> ] map-sum nanos>string ] }
|
{ "Code heap sweep time:" [ PHASE-CODE-SWEEP sum-phase-times ] }
|
||||||
{ "Compaction time:" [ [ compaction-time>> ] map-sum nanos>string ] }
|
{ "Data compaction time:" [ PHASE-DATA-COMPACTION sum-phase-times ] }
|
||||||
} object-table. ;
|
} object-table. ;
|
||||||
|
|
||||||
SINGLETONS: +unoptimized+ +optimized+ +profiling+ +pic+ ;
|
SINGLETONS: +unoptimized+ +optimized+ +profiling+ +pic+ ;
|
||||||
|
|
|
@ -81,6 +81,14 @@ STRUCT: data-heap-room
|
||||||
{ decks cell_t }
|
{ decks cell_t }
|
||||||
{ mark-stack cell_t } ;
|
{ mark-stack cell_t } ;
|
||||||
|
|
||||||
|
CONSTANT: PHASE-CARD-SCAN 0
|
||||||
|
CONSTANT: PHASE-CODE-SCAN 1
|
||||||
|
CONSTANT: PHASE-DATA-SWEEP 2
|
||||||
|
CONSTANT: PHASE-CODE-SWEEP 3
|
||||||
|
CONSTANT: PHASE-DATA-COMPACTION 4
|
||||||
|
|
||||||
|
! gc-event should be kept in sync with:
|
||||||
|
! vm/gc.hpp
|
||||||
STRUCT: gc-event
|
STRUCT: gc-event
|
||||||
{ op uint }
|
{ op uint }
|
||||||
{ data-heap-before data-heap-room }
|
{ data-heap-before data-heap-room }
|
||||||
|
@ -92,11 +100,7 @@ STRUCT: gc-event
|
||||||
{ code-blocks-scanned cell_t }
|
{ code-blocks-scanned cell_t }
|
||||||
{ start-time ulonglong }
|
{ start-time ulonglong }
|
||||||
{ total-time cell_t }
|
{ total-time cell_t }
|
||||||
{ card-scan-time cell_t }
|
{ times cell_t[5] }
|
||||||
{ code-scan-time cell_t }
|
|
||||||
{ data-sweep-time cell_t }
|
|
||||||
{ code-sweep-time cell_t }
|
|
||||||
{ compaction-time cell_t }
|
|
||||||
{ temp-time ulonglong } ;
|
{ temp-time ulonglong } ;
|
||||||
|
|
||||||
! gc-info should be kept in sync with:
|
! gc-info should be kept in sync with:
|
||||||
|
|
|
@ -51,15 +51,19 @@ void factor_vm::collect_aging() {
|
||||||
if (event)
|
if (event)
|
||||||
event->reset_timer();
|
event->reset_timer();
|
||||||
visitor.visit_cards(data->tenured, card_points_to_aging, 0xff);
|
visitor.visit_cards(data->tenured, card_points_to_aging, 0xff);
|
||||||
if (event)
|
if (event) {
|
||||||
event->ended_card_scan(visitor.cards_scanned, visitor.decks_scanned);
|
event->ended_phase(PHASE_CARD_SCAN);
|
||||||
|
event->cards_scanned += visitor.cards_scanned;
|
||||||
|
event->decks_scanned += visitor.decks_scanned;
|
||||||
|
}
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
event->reset_timer();
|
event->reset_timer();
|
||||||
visitor.visit_code_heap_roots(&code->points_to_aging);
|
visitor.visit_code_heap_roots(&code->points_to_aging);
|
||||||
if (event)
|
if (event) {
|
||||||
event->ended_code_scan(code->points_to_aging.size());
|
event->ended_phase(PHASE_CODE_SCAN);
|
||||||
|
event->code_blocks_scanned += code->points_to_aging.size();
|
||||||
|
}
|
||||||
visitor.visit_mark_stack(&mark_stack);
|
visitor.visit_mark_stack(&mark_stack);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
|
@ -143,7 +143,7 @@ void factor_vm::collect_compact_impl() {
|
||||||
code->initialize_all_blocks_set();
|
code->initialize_all_blocks_set();
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
event->ended_compaction();
|
event->ended_phase(PHASE_DATA_COMPACTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::collect_compact() {
|
void factor_vm::collect_compact() {
|
||||||
|
|
|
@ -84,7 +84,7 @@ void factor_vm::collect_sweep_impl() {
|
||||||
event->reset_timer();
|
event->reset_timer();
|
||||||
data->tenured->sweep();
|
data->tenured->sweep();
|
||||||
if (event)
|
if (event)
|
||||||
event->ended_data_sweep();
|
event->ended_phase(PHASE_DATA_SWEEP);
|
||||||
|
|
||||||
// After a sweep, invalidate any code heap roots which are not
|
// After a sweep, invalidate any code heap roots which are not
|
||||||
// marked, so that if a block makes a tail call to a generic word,
|
// marked, so that if a block makes a tail call to a generic word,
|
||||||
|
@ -102,7 +102,7 @@ void factor_vm::collect_sweep_impl() {
|
||||||
event->reset_timer();
|
event->reset_timer();
|
||||||
code->sweep();
|
code->sweep();
|
||||||
if (event)
|
if (event)
|
||||||
event->ended_code_sweep();
|
event->ended_phase(PHASE_CODE_SWEEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::collect_full() {
|
void factor_vm::collect_full() {
|
||||||
|
|
29
vm/gc.cpp
29
vm/gc.cpp
|
@ -8,11 +8,7 @@ gc_event::gc_event(gc_op op, factor_vm* parent)
|
||||||
decks_scanned(0),
|
decks_scanned(0),
|
||||||
code_blocks_scanned(0),
|
code_blocks_scanned(0),
|
||||||
start_time(nano_count()),
|
start_time(nano_count()),
|
||||||
card_scan_time(0),
|
times{0} {
|
||||||
code_scan_time(0),
|
|
||||||
data_sweep_time(0),
|
|
||||||
code_sweep_time(0),
|
|
||||||
compaction_time(0) {
|
|
||||||
data_heap_before = parent->data_room();
|
data_heap_before = parent->data_room();
|
||||||
code_heap_before = parent->code->allocator->as_allocator_room();
|
code_heap_before = parent->code->allocator->as_allocator_room();
|
||||||
start_time = nano_count();
|
start_time = nano_count();
|
||||||
|
@ -20,27 +16,8 @@ gc_event::gc_event(gc_op op, factor_vm* parent)
|
||||||
|
|
||||||
void gc_event::reset_timer() { temp_time = nano_count(); }
|
void gc_event::reset_timer() { temp_time = nano_count(); }
|
||||||
|
|
||||||
void gc_event::ended_card_scan(cell cards_scanned_, cell decks_scanned_) {
|
void gc_event::ended_phase(gc_phase phase) {
|
||||||
cards_scanned += cards_scanned_;
|
times[phase] = (cell)(nano_count() - temp_time);
|
||||||
decks_scanned += decks_scanned_;
|
|
||||||
card_scan_time = (cell)(nano_count() - temp_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gc_event::ended_code_scan(cell code_blocks_scanned_) {
|
|
||||||
code_blocks_scanned += code_blocks_scanned_;
|
|
||||||
code_scan_time = (cell)(nano_count() - temp_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gc_event::ended_data_sweep() {
|
|
||||||
data_sweep_time = (cell)(nano_count() - temp_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gc_event::ended_code_sweep() {
|
|
||||||
code_sweep_time = (cell)(nano_count() - temp_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gc_event::ended_compaction() {
|
|
||||||
compaction_time = (cell)(nano_count() - temp_time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gc_event::ended_gc(factor_vm* parent) {
|
void gc_event::ended_gc(factor_vm* parent) {
|
||||||
|
|
21
vm/gc.hpp
21
vm/gc.hpp
|
@ -12,6 +12,15 @@ enum gc_op {
|
||||||
COLLECT_GROWING_DATA_HEAP_OP
|
COLLECT_GROWING_DATA_HEAP_OP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// These are the phases of the gc cycles we record the times of.
|
||||||
|
enum gc_phase {
|
||||||
|
PHASE_CARD_SCAN,
|
||||||
|
PHASE_CODE_SCAN,
|
||||||
|
PHASE_DATA_SWEEP,
|
||||||
|
PHASE_CODE_SWEEP,
|
||||||
|
PHASE_DATA_COMPACTION,
|
||||||
|
};
|
||||||
|
|
||||||
struct gc_event {
|
struct gc_event {
|
||||||
gc_op op;
|
gc_op op;
|
||||||
data_heap_room data_heap_before;
|
data_heap_room data_heap_before;
|
||||||
|
@ -23,20 +32,12 @@ struct gc_event {
|
||||||
cell code_blocks_scanned;
|
cell code_blocks_scanned;
|
||||||
uint64_t start_time;
|
uint64_t start_time;
|
||||||
cell total_time;
|
cell total_time;
|
||||||
cell card_scan_time;
|
cell times[5];
|
||||||
cell code_scan_time;
|
|
||||||
cell data_sweep_time;
|
|
||||||
cell code_sweep_time;
|
|
||||||
cell compaction_time;
|
|
||||||
uint64_t temp_time;
|
uint64_t temp_time;
|
||||||
|
|
||||||
gc_event(gc_op op, factor_vm* parent);
|
gc_event(gc_op op, factor_vm* parent);
|
||||||
void reset_timer();
|
void reset_timer();
|
||||||
void ended_card_scan(cell cards_scanned_, cell decks_scanned_);
|
void ended_phase(gc_phase phase);
|
||||||
void ended_code_scan(cell code_blocks_scanned_);
|
|
||||||
void ended_data_sweep();
|
|
||||||
void ended_code_sweep();
|
|
||||||
void ended_compaction();
|
|
||||||
void ended_gc(factor_vm* parent);
|
void ended_gc(factor_vm* parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,14 +50,19 @@ void factor_vm::collect_nursery() {
|
||||||
visitor.visit_cards(data->tenured, card_points_to_nursery,
|
visitor.visit_cards(data->tenured, card_points_to_nursery,
|
||||||
card_points_to_nursery);
|
card_points_to_nursery);
|
||||||
visitor.visit_cards(data->aging, card_points_to_nursery, 0xff);
|
visitor.visit_cards(data->aging, card_points_to_nursery, 0xff);
|
||||||
if (event)
|
if (event) {
|
||||||
event->ended_card_scan(visitor.cards_scanned, visitor.decks_scanned);
|
event->ended_phase(PHASE_CARD_SCAN);
|
||||||
|
event->cards_scanned += visitor.cards_scanned;
|
||||||
|
event->decks_scanned += visitor.decks_scanned;
|
||||||
|
}
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
event->reset_timer();
|
event->reset_timer();
|
||||||
visitor.visit_code_heap_roots(&code->points_to_nursery);
|
visitor.visit_code_heap_roots(&code->points_to_nursery);
|
||||||
if (event)
|
if (event) {
|
||||||
event->ended_code_scan(code->points_to_nursery.size());
|
event->ended_phase(PHASE_CODE_SCAN);
|
||||||
|
event->code_blocks_scanned += code->points_to_nursery.size();
|
||||||
|
}
|
||||||
|
|
||||||
visitor.cheneys_algorithm(data->aging, scan);
|
visitor.cheneys_algorithm(data->aging, scan);
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,19 @@ void factor_vm::collect_to_tenured() {
|
||||||
if (event)
|
if (event)
|
||||||
event->reset_timer();
|
event->reset_timer();
|
||||||
visitor.visit_cards(data->tenured, card_points_to_aging, 0xff);
|
visitor.visit_cards(data->tenured, card_points_to_aging, 0xff);
|
||||||
if (event)
|
if (event) {
|
||||||
event->ended_card_scan(visitor.cards_scanned, visitor.decks_scanned);
|
event->ended_phase(PHASE_CARD_SCAN);
|
||||||
|
event->cards_scanned += visitor.cards_scanned;
|
||||||
|
event->decks_scanned += visitor.decks_scanned;
|
||||||
|
}
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
event->reset_timer();
|
event->reset_timer();
|
||||||
visitor.visit_code_heap_roots(&code->points_to_aging);
|
visitor.visit_code_heap_roots(&code->points_to_aging);
|
||||||
if (event)
|
if (event) {
|
||||||
event->ended_code_scan(code->points_to_aging.size());
|
event->ended_phase(PHASE_CODE_SCAN);
|
||||||
|
event->code_blocks_scanned += code->points_to_aging.size();
|
||||||
|
}
|
||||||
visitor.visit_mark_stack(&mark_stack);
|
visitor.visit_mark_stack(&mark_stack);
|
||||||
|
|
||||||
data->reset_nursery();
|
data->reset_nursery();
|
||||||
|
|
Loading…
Reference in New Issue