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.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs binary-search classes
classes.struct combinators combinators.smart continuations fry
generalizations generic grouping io io.styles kernel make math
math.order math.parser math.statistics memory layouts namespaces
parser prettyprint sequences sequences.generalizations sorting
splitting strings system vm words hints hashtables ;
USING: accessors arrays assocs binary-search classes classes.struct
combinators combinators.smart continuations fry grouping hashtables
hints io io.styles kernel layouts math math.order math.parser
math.statistics memory namespaces prettyprint sequences
sequences.generalizations sorting vm ;
IN: tools.memory
<PRIVATE
@ -186,6 +185,9 @@ SYMBOL: gc-events
: gc-stats. ( -- )
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-events get {
{ "Collections:" [ length commas ] }
@ -193,11 +195,11 @@ SYMBOL: gc-events
{ "Decks scanned:" [ [ decks-scanned>> ] map-sum commas ] }
{ "Code blocks scanned:" [ [ code-blocks-scanned>> ] map-sum commas ] }
{ "Total time:" [ [ total-time>> ] map-sum nanos>string ] }
{ "Card scan time:" [ [ card-scan-time>> ] map-sum nanos>string ] }
{ "Code block scan time:" [ [ code-scan-time>> ] map-sum nanos>string ] }
{ "Data heap sweep time:" [ [ data-sweep-time>> ] map-sum nanos>string ] }
{ "Code heap sweep time:" [ [ code-sweep-time>> ] map-sum nanos>string ] }
{ "Compaction time:" [ [ compaction-time>> ] map-sum nanos>string ] }
{ "Card scan time:" [ PHASE-CARD-SCAN sum-phase-times ] }
{ "Code block scan time:" [ PHASE-CODE-SCAN sum-phase-times ] }
{ "Data heap sweep time:" [ PHASE-DATA-SWEEP sum-phase-times ] }
{ "Code heap sweep time:" [ PHASE-CODE-SWEEP sum-phase-times ] }
{ "Data compaction time:" [ PHASE-DATA-COMPACTION sum-phase-times ] }
} object-table. ;
SINGLETONS: +unoptimized+ +optimized+ +profiling+ +pic+ ;

View File

@ -81,23 +81,27 @@ STRUCT: data-heap-room
{ decks 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
{ op uint }
{ data-heap-before data-heap-room }
{ code-heap-before mark-sweep-sizes }
{ data-heap-after data-heap-room }
{ code-heap-after mark-sweep-sizes }
{ cards-scanned cell_t }
{ decks-scanned cell_t }
{ code-blocks-scanned cell_t }
{ start-time ulonglong }
{ total-time cell_t }
{ card-scan-time cell_t }
{ code-scan-time cell_t }
{ data-sweep-time cell_t }
{ code-sweep-time cell_t }
{ compaction-time cell_t }
{ temp-time ulonglong } ;
{ op uint }
{ data-heap-before data-heap-room }
{ code-heap-before mark-sweep-sizes }
{ data-heap-after data-heap-room }
{ code-heap-after mark-sweep-sizes }
{ cards-scanned cell_t }
{ decks-scanned cell_t }
{ code-blocks-scanned cell_t }
{ start-time ulonglong }
{ total-time cell_t }
{ times cell_t[5] }
{ temp-time ulonglong } ;
! gc-info should be kept in sync with:
! vm/gc_info.hpp

View File

@ -51,15 +51,19 @@ void factor_vm::collect_aging() {
if (event)
event->reset_timer();
visitor.visit_cards(data->tenured, card_points_to_aging, 0xff);
if (event)
event->ended_card_scan(visitor.cards_scanned, visitor.decks_scanned);
if (event) {
event->ended_phase(PHASE_CARD_SCAN);
event->cards_scanned += visitor.cards_scanned;
event->decks_scanned += visitor.decks_scanned;
}
if (event)
event->reset_timer();
visitor.visit_code_heap_roots(&code->points_to_aging);
if (event)
event->ended_code_scan(code->points_to_aging.size());
if (event) {
event->ended_phase(PHASE_CODE_SCAN);
event->code_blocks_scanned += code->points_to_aging.size();
}
visitor.visit_mark_stack(&mark_stack);
}
{

View File

@ -143,7 +143,7 @@ void factor_vm::collect_compact_impl() {
code->initialize_all_blocks_set();
if (event)
event->ended_compaction();
event->ended_phase(PHASE_DATA_COMPACTION);
}
void factor_vm::collect_compact() {

View File

@ -84,7 +84,7 @@ void factor_vm::collect_sweep_impl() {
event->reset_timer();
data->tenured->sweep();
if (event)
event->ended_data_sweep();
event->ended_phase(PHASE_DATA_SWEEP);
// 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,
@ -102,7 +102,7 @@ void factor_vm::collect_sweep_impl() {
event->reset_timer();
code->sweep();
if (event)
event->ended_code_sweep();
event->ended_phase(PHASE_CODE_SWEEP);
}
void factor_vm::collect_full() {

View File

@ -8,11 +8,7 @@ gc_event::gc_event(gc_op op, factor_vm* parent)
decks_scanned(0),
code_blocks_scanned(0),
start_time(nano_count()),
card_scan_time(0),
code_scan_time(0),
data_sweep_time(0),
code_sweep_time(0),
compaction_time(0) {
times{0} {
data_heap_before = parent->data_room();
code_heap_before = parent->code->allocator->as_allocator_room();
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::ended_card_scan(cell cards_scanned_, cell decks_scanned_) {
cards_scanned += cards_scanned_;
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_phase(gc_phase phase) {
times[phase] = (cell)(nano_count() - temp_time);
}
void gc_event::ended_gc(factor_vm* parent) {

View File

@ -12,6 +12,15 @@ enum gc_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 {
gc_op op;
data_heap_room data_heap_before;
@ -23,20 +32,12 @@ struct gc_event {
cell code_blocks_scanned;
uint64_t start_time;
cell total_time;
cell card_scan_time;
cell code_scan_time;
cell data_sweep_time;
cell code_sweep_time;
cell compaction_time;
cell times[5];
uint64_t temp_time;
gc_event(gc_op op, factor_vm* parent);
void reset_timer();
void ended_card_scan(cell cards_scanned_, cell decks_scanned_);
void ended_code_scan(cell code_blocks_scanned_);
void ended_data_sweep();
void ended_code_sweep();
void ended_compaction();
void ended_phase(gc_phase phase);
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,
card_points_to_nursery);
visitor.visit_cards(data->aging, card_points_to_nursery, 0xff);
if (event)
event->ended_card_scan(visitor.cards_scanned, visitor.decks_scanned);
if (event) {
event->ended_phase(PHASE_CARD_SCAN);
event->cards_scanned += visitor.cards_scanned;
event->decks_scanned += visitor.decks_scanned;
}
if (event)
event->reset_timer();
visitor.visit_code_heap_roots(&code->points_to_nursery);
if (event)
event->ended_code_scan(code->points_to_nursery.size());
if (event) {
event->ended_phase(PHASE_CODE_SCAN);
event->code_blocks_scanned += code->points_to_nursery.size();
}
visitor.cheneys_algorithm(data->aging, scan);

View File

@ -14,15 +14,19 @@ void factor_vm::collect_to_tenured() {
if (event)
event->reset_timer();
visitor.visit_cards(data->tenured, card_points_to_aging, 0xff);
if (event)
event->ended_card_scan(visitor.cards_scanned, visitor.decks_scanned);
if (event) {
event->ended_phase(PHASE_CARD_SCAN);
event->cards_scanned += visitor.cards_scanned;
event->decks_scanned += visitor.decks_scanned;
}
if (event)
event->reset_timer();
visitor.visit_code_heap_roots(&code->points_to_aging);
if (event)
event->ended_code_scan(code->points_to_aging.size());
if (event) {
event->ended_phase(PHASE_CODE_SCAN);
event->code_blocks_scanned += code->points_to_aging.size();
}
visitor.visit_mark_stack(&mark_stack);
data->reset_nursery();