From c035f86ca28865921a0cbccf82651197d8031574 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 9 May 2008 17:30:32 -0500 Subject: [PATCH] Revert large deck change for now, fix PowerPC write barrier --- core/compiler/constants/constants.factor | 4 ++-- core/cpu/ppc/intrinsics/intrinsics.factor | 6 +++--- vm/data_gc.c | 25 +++++++++++++---------- vm/data_gc.h | 21 +++++++++---------- vm/run.h | 6 +++--- 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/core/compiler/constants/constants.factor b/core/compiler/constants/constants.factor index 8610f490ec..9594cf7b23 100755 --- a/core/compiler/constants/constants.factor +++ b/core/compiler/constants/constants.factor @@ -4,8 +4,8 @@ USING: math kernel layouts system ; IN: compiler.constants ! These constants must match vm/memory.h -: card-bits 8 ; -: deck-bits 18 ; +: card-bits 6 ; +: deck-bits 12 ; : card-mark HEX: 40 HEX: 80 bitor ; ! These constants must match vm/layouts.h diff --git a/core/cpu/ppc/intrinsics/intrinsics.factor b/core/cpu/ppc/intrinsics/intrinsics.factor index d85c70577e..ac59deb8bb 100755 --- a/core/cpu/ppc/intrinsics/intrinsics.factor +++ b/core/cpu/ppc/intrinsics/intrinsics.factor @@ -66,12 +66,12 @@ IN: cpu.ppc.intrinsics ! Mark the card "val" operand load-cards-offset "obj" operand "scratch2" operand card-bits SRWI - "val" operand "scratch2" operand "val" operand STBX + "scratch1" operand "scratch2" operand "val" operand STBX ! Mark the card deck "val" operand load-decks-offset - "obj" operand "scratch" operand deck-bits SRWI - "val" operand "scratch" operand "val" operand STBX + "obj" operand "scratch2" operand deck-bits SRWI + "scratch1" operand "scratch2" operand "val" operand STBX ] unless ; \ set-slot { diff --git a/vm/data_gc.c b/vm/data_gc.c index c12c65aaff..9a39642cde 100755 --- a/vm/data_gc.c +++ b/vm/data_gc.c @@ -7,6 +7,8 @@ #define END_AGING_GC "end_gc: aging_collections=%ld, cards_scanned=%ld\n" #define END_NURSERY_GC "end_gc: nursery_collections=%ld, cards_scanned=%ld\n" +/* #define GC_DEBUG */ + #ifdef GC_DEBUG #define GC_PRINT printf #else @@ -23,7 +25,7 @@ CELL init_zone(F_ZONE *z, CELL size, CELL start) void init_card_decks(void) { - CELL start = data_heap->segment->start & ~(DECK_SIZE - 1); + CELL start = align(data_heap->segment->start,DECK_SIZE); allot_markers_offset = (CELL)data_heap->allot_markers - (start >> CARD_BITS); cards_offset = (CELL)data_heap->cards - (start >> CARD_BITS); decks_offset = (CELL)data_heap->decks - (start >> DECK_BITS); @@ -66,18 +68,18 @@ F_DATA_HEAP *alloc_data_heap(CELL gens, data_heap->generations = safe_malloc(sizeof(F_ZONE) * data_heap->gen_count); data_heap->semispaces = safe_malloc(sizeof(F_ZONE) * data_heap->gen_count); - CELL cards_size = (total_size + DECK_SIZE) / CARD_SIZE; + CELL cards_size = total_size >> CARD_BITS; data_heap->allot_markers = safe_malloc(cards_size); data_heap->allot_markers_end = data_heap->allot_markers + cards_size; data_heap->cards = safe_malloc(cards_size); data_heap->cards_end = data_heap->cards + cards_size; - CELL decks_size = (total_size + DECK_SIZE) / DECK_SIZE; + CELL decks_size = total_size >> DECK_BITS; data_heap->decks = safe_malloc(decks_size); data_heap->decks_end = data_heap->decks + decks_size; - CELL alloter = (data_heap->segment->start + DECK_SIZE - 1) & ~(DECK_SIZE - 1); + CELL alloter = align(data_heap->segment->start,DECK_SIZE); alloter = init_zone(&data_heap->generations[TENURED],tenured_size,alloter); alloter = init_zone(&data_heap->semispaces[TENURED],tenured_size,alloter); @@ -121,8 +123,6 @@ void dealloc_data_heap(F_DATA_HEAP *data_heap) free(data_heap); } -/* Every card stores the offset of the first object in that card, which must be -cleared when a generation has been cleared */ void clear_cards(CELL from, CELL to) { /* NOTE: reverse order due to heap layout. */ @@ -135,9 +135,9 @@ void clear_cards(CELL from, CELL to) void clear_decks(CELL from, CELL to) { /* NOTE: reverse order due to heap layout. */ - F_CARD *first_deck = ADDR_TO_CARD(data_heap->generations[to].start); - F_CARD *last_deck = ADDR_TO_CARD(data_heap->generations[from].end); - F_CARD *ptr; + F_DECK *first_deck = ADDR_TO_DECK(data_heap->generations[to].start); + F_DECK *last_deck = ADDR_TO_DECK(data_heap->generations[from].end); + F_DECK *ptr; for(ptr = first_deck; ptr < last_deck; ptr++) *ptr = 0; } @@ -147,7 +147,7 @@ void clear_allot_markers(CELL from, CELL to) F_CARD *first_card = ADDR_TO_ALLOT_MARKER(data_heap->generations[to].start); F_CARD *last_card = ADDR_TO_ALLOT_MARKER(data_heap->generations[from].end); F_CARD *ptr; - for(ptr = first_card; ptr < last_card; ptr++) *ptr = CARD_BASE_MASK; + for(ptr = first_card; ptr < last_card; ptr++) *ptr = INVALID_ALLOT_MARKER; } void set_data_heap(F_DATA_HEAP *data_heap_) @@ -330,8 +330,11 @@ void collect_card(F_CARD *ptr, CELL gen, CELL here) { CELL offset = CARD_OFFSET(ptr); - if(offset != CARD_BASE_MASK) + if(offset != INVALID_ALLOT_MARKER) { + if(offset & TAG_MASK) + critical_error("Bad card",(CELL)ptr); + CELL card_scan = (CELL)CARD_TO_ADDR(ptr) + offset; CELL card_end = (CELL)CARD_TO_ADDR(ptr + 1); diff --git a/vm/data_gc.h b/vm/data_gc.h index 301821bb7a..30a4aee6ee 100755 --- a/vm/data_gc.h +++ b/vm/data_gc.h @@ -68,22 +68,20 @@ the offset of the first object is set by the allocator. */ #define CARD_POINTS_TO_NURSERY 0x80 #define CARD_POINTS_TO_AGING 0x40 #define CARD_MARK_MASK (CARD_POINTS_TO_NURSERY | CARD_POINTS_TO_AGING) -#define CARD_BASE_MASK 0xff typedef u8 F_CARD; -#define CARD_BITS 8 +#define CARD_BITS 6 #define CARD_SIZE (1<> CARD_BITS) + cards_offset) #define CARD_TO_ADDR(c) (CELL*)(((CELL)(c) - cards_offset)<> CARD_BITS) + allot_markers_offset) #define CARD_OFFSET(c) (*((c) - (CELL)data_heap->cards + (CELL)data_heap->allot_markers)) +#define INVALID_ALLOT_MARKER 0xff + +DLLEXPORT CELL allot_markers_offset; + void init_card_decks(void); -/* this is an inefficient write barrier. compiled definitions use a more -efficient one hand-coded in assembly. the write barrier must be called -any time we are potentially storing a pointer from an older generation -to a younger one */ +/* the write barrier must be called any time we are potentially storing a +pointer from an older generation to a younger one */ INLINE void write_barrier(CELL address) { *ADDR_TO_CARD(address) = CARD_MARK_MASK; @@ -121,9 +121,8 @@ INLINE void set_slot(CELL obj, CELL slot, CELL value) INLINE void allot_barrier(CELL address) { F_CARD *ptr = ADDR_TO_ALLOT_MARKER(address); - F_CARD b = *ptr; - F_CARD a = (address & ADDR_CARD_MASK); - *ptr = (b < a ? b : a); + if(*ptr == INVALID_ALLOT_MARKER) + *ptr = (address & ADDR_CARD_MASK); } void clear_cards(CELL from, CELL to); diff --git a/vm/run.h b/vm/run.h index e2afb08525..cc980453cf 100755 --- a/vm/run.h +++ b/vm/run.h @@ -103,11 +103,11 @@ INLINE void bput(CELL where, CELL what) INLINE CELL align(CELL a, CELL b) { - return (a + b) & ~b; + return (a + (b-1)) & ~(b-1); } -#define align8(a) align(a,7) -#define align_page(a) align(a,getpagesize() - 1) +#define align8(a) align(a,8) +#define align_page(a) align(a,getpagesize()) /* Canonical T object. It's just a word */ CELL T;