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
Björn Lindqvist 2016-10-19 10:31:53 +02:00
parent 51408b66cb
commit 752c895d23
9 changed files with 77 additions and 80 deletions

View File

@ -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+ ;

View File

@ -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:

View File

@ -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);
} }
{ {

View File

@ -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() {

View File

@ -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() {

View File

@ -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) {

View File

@ -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);
}; };

View File

@ -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);

View File

@ -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();