Revert large deck change for now, fix PowerPC write barrier

db4
Slava Pestov 2008-05-09 17:30:32 -05:00
parent 4ffac018a1
commit c035f86ca2
5 changed files with 32 additions and 30 deletions

View File

@ -4,8 +4,8 @@ USING: math kernel layouts system ;
IN: compiler.constants IN: compiler.constants
! These constants must match vm/memory.h ! These constants must match vm/memory.h
: card-bits 8 ; : card-bits 6 ;
: deck-bits 18 ; : deck-bits 12 ;
: card-mark HEX: 40 HEX: 80 bitor ; : card-mark HEX: 40 HEX: 80 bitor ;
! These constants must match vm/layouts.h ! These constants must match vm/layouts.h

View File

@ -66,12 +66,12 @@ IN: cpu.ppc.intrinsics
! Mark the card ! Mark the card
"val" operand load-cards-offset "val" operand load-cards-offset
"obj" operand "scratch2" operand card-bits SRWI "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 ! Mark the card deck
"val" operand load-decks-offset "val" operand load-decks-offset
"obj" operand "scratch" operand deck-bits SRWI "obj" operand "scratch2" operand deck-bits SRWI
"val" operand "scratch" operand "val" operand STBX "scratch1" operand "scratch2" operand "val" operand STBX
] unless ; ] unless ;
\ set-slot { \ set-slot {

View File

@ -7,6 +7,8 @@
#define END_AGING_GC "end_gc: aging_collections=%ld, cards_scanned=%ld\n" #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 END_NURSERY_GC "end_gc: nursery_collections=%ld, cards_scanned=%ld\n"
/* #define GC_DEBUG */
#ifdef GC_DEBUG #ifdef GC_DEBUG
#define GC_PRINT printf #define GC_PRINT printf
#else #else
@ -23,7 +25,7 @@ CELL init_zone(F_ZONE *z, CELL size, CELL start)
void init_card_decks(void) 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); allot_markers_offset = (CELL)data_heap->allot_markers - (start >> CARD_BITS);
cards_offset = (CELL)data_heap->cards - (start >> CARD_BITS); cards_offset = (CELL)data_heap->cards - (start >> CARD_BITS);
decks_offset = (CELL)data_heap->decks - (start >> DECK_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->generations = safe_malloc(sizeof(F_ZONE) * data_heap->gen_count);
data_heap->semispaces = 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 = safe_malloc(cards_size);
data_heap->allot_markers_end = data_heap->allot_markers + cards_size; data_heap->allot_markers_end = data_heap->allot_markers + cards_size;
data_heap->cards = safe_malloc(cards_size); data_heap->cards = safe_malloc(cards_size);
data_heap->cards_end = data_heap->cards + 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 = safe_malloc(decks_size);
data_heap->decks_end = data_heap->decks + 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->generations[TENURED],tenured_size,alloter);
alloter = init_zone(&data_heap->semispaces[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); 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) void clear_cards(CELL from, CELL to)
{ {
/* NOTE: reverse order due to heap layout. */ /* 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) void clear_decks(CELL from, CELL to)
{ {
/* NOTE: reverse order due to heap layout. */ /* NOTE: reverse order due to heap layout. */
F_CARD *first_deck = ADDR_TO_CARD(data_heap->generations[to].start); F_DECK *first_deck = ADDR_TO_DECK(data_heap->generations[to].start);
F_CARD *last_deck = ADDR_TO_CARD(data_heap->generations[from].end); F_DECK *last_deck = ADDR_TO_DECK(data_heap->generations[from].end);
F_CARD *ptr; F_DECK *ptr;
for(ptr = first_deck; ptr < last_deck; ptr++) *ptr = 0; 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 *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 *last_card = ADDR_TO_ALLOT_MARKER(data_heap->generations[from].end);
F_CARD *ptr; 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_) 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); 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_scan = (CELL)CARD_TO_ADDR(ptr) + offset;
CELL card_end = (CELL)CARD_TO_ADDR(ptr + 1); CELL card_end = (CELL)CARD_TO_ADDR(ptr + 1);

View File

@ -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_NURSERY 0x80
#define CARD_POINTS_TO_AGING 0x40 #define CARD_POINTS_TO_AGING 0x40
#define CARD_MARK_MASK (CARD_POINTS_TO_NURSERY | CARD_POINTS_TO_AGING) #define CARD_MARK_MASK (CARD_POINTS_TO_NURSERY | CARD_POINTS_TO_AGING)
#define CARD_BASE_MASK 0xff
typedef u8 F_CARD; typedef u8 F_CARD;
#define CARD_BITS 8 #define CARD_BITS 6
#define CARD_SIZE (1<<CARD_BITS) #define CARD_SIZE (1<<CARD_BITS)
#define ADDR_CARD_MASK (CARD_SIZE-1) #define ADDR_CARD_MASK (CARD_SIZE-1)
DLLEXPORT CELL cards_offset; DLLEXPORT CELL cards_offset;
DLLEXPORT CELL allot_markers_offset;
#define ADDR_TO_CARD(a) (F_CARD*)(((CELL)(a) >> CARD_BITS) + cards_offset) #define ADDR_TO_CARD(a) (F_CARD*)(((CELL)(a) >> CARD_BITS) + cards_offset)
#define CARD_TO_ADDR(c) (CELL*)(((CELL)(c) - cards_offset)<<CARD_BITS) #define CARD_TO_ADDR(c) (CELL*)(((CELL)(c) - cards_offset)<<CARD_BITS)
typedef u8 F_DECK; typedef u8 F_DECK;
#define DECK_BITS (CARD_BITS + 10) #define DECK_BITS (CARD_BITS + 6)
#define DECK_SIZE (1<<DECK_BITS) #define DECK_SIZE (1<<DECK_BITS)
#define ADDR_DECK_MASK (DECK_SIZE-1) #define ADDR_DECK_MASK (DECK_SIZE-1)
@ -97,12 +95,14 @@ DLLEXPORT CELL decks_offset;
#define ADDR_TO_ALLOT_MARKER(a) (F_CARD*)(((CELL)(a) >> CARD_BITS) + allot_markers_offset) #define ADDR_TO_ALLOT_MARKER(a) (F_CARD*)(((CELL)(a) >> CARD_BITS) + allot_markers_offset)
#define CARD_OFFSET(c) (*((c) - (CELL)data_heap->cards + (CELL)data_heap->allot_markers)) #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); void init_card_decks(void);
/* this is an inefficient write barrier. compiled definitions use a more /* the write barrier must be called any time we are potentially storing a
efficient one hand-coded in assembly. the write barrier must be called pointer from an older generation to a younger one */
any time we are potentially storing a pointer from an older generation
to a younger one */
INLINE void write_barrier(CELL address) INLINE void write_barrier(CELL address)
{ {
*ADDR_TO_CARD(address) = CARD_MARK_MASK; *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) INLINE void allot_barrier(CELL address)
{ {
F_CARD *ptr = ADDR_TO_ALLOT_MARKER(address); F_CARD *ptr = ADDR_TO_ALLOT_MARKER(address);
F_CARD b = *ptr; if(*ptr == INVALID_ALLOT_MARKER)
F_CARD a = (address & ADDR_CARD_MASK); *ptr = (address & ADDR_CARD_MASK);
*ptr = (b < a ? b : a);
} }
void clear_cards(CELL from, CELL to); void clear_cards(CELL from, CELL to);

View File

@ -103,11 +103,11 @@ INLINE void bput(CELL where, CELL what)
INLINE CELL align(CELL a, CELL b) INLINE CELL align(CELL a, CELL b)
{ {
return (a + b) & ~b; return (a + (b-1)) & ~(b-1);
} }
#define align8(a) align(a,7) #define align8(a) align(a,8)
#define align_page(a) align(a,getpagesize() - 1) #define align_page(a) align(a,getpagesize())
/* Canonical T object. It's just a word */ /* Canonical T object. It's just a word */
CELL T; CELL T;