Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/runtime/gc/card-map.h
ViewVC logotype

Annotation of /sml/trunk/src/runtime/gc/card-map.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (view) (download) (as text)

1 : monnier 2 /* card-map.h
2 :     *
3 :     * COPYRIGHT (c) 1995 AT&T Bell Laboratories.
4 :     *
5 :     * Card maps for marking object updates.
6 :     */
7 :    
8 :     #ifndef _CARD_MAP_
9 :     #define _CARD_MAP_
10 :    
11 :     #ifndef BIT_CARDS
12 :     typedef struct { /* A dirty card map */
13 :     ml_val_t *baseAddr; /* The base address of the mapped region */
14 :     Word_t numCards; /* The number of cards covered by the map */
15 :     int mapSzB; /* The number of bytes allocated for this */
16 :     /* map. */
17 :     Byte_t map[WORD_SZB]; /* The card map */
18 :     } card_map_t;
19 :    
20 :     #define CARD_CLEAN 0xff
21 :    
22 :     #define CARD_BITS 8 /* 256 byte cards */
23 :     #define CARD_SZB (1<<CARD_BITS)
24 :     #define CARD_SZW (CARD_SZB / WORD_SZB)
25 :     #define CARD_SHIFTW (BITS_PER_WORD-CARD_BITS)
26 :     #define CARD_MAP_SZ(n) \
27 :     (sizeof(card_map_t) + ((((n)+(WORD_SZB-1)) >> LOG_BYTES_PER_WORD)-1)*WORD_SZB)
28 :    
29 :     /* Map an address to a card index */
30 :     #define CARD_INDEX(cm, addr) \
31 :     (((Addr_t)(addr) - (Addr_t)(cm->baseAddr)) >> CARD_BITS)
32 :    
33 :     /* Map a card index to its base address */
34 :     #define CARD_TO_ADDR(cm, index) \
35 :     ((Word_t *)((Addr_t)(cm->baseAddr) + ((index) << CARD_BITS)))
36 :    
37 :     /* Get the value of a card */
38 :     #define CARD(cm, addr) ((cm)->map[CARD_INDEX(cm,addr)])
39 :    
40 :     /* Mark the card containing addr */
41 :     #define MARK_CARD(cm, addr, gen) { \
42 :     card_map_t *__cm = (cm); \
43 :     int __i = CARD_INDEX(__cm, (addr)); \
44 :     int __g = (gen); \
45 :     if (__g < __cm->map[__i]) \
46 :     __cm->map[__i] = __g; \
47 :     }
48 :    
49 :     /* test a card to see if it is marked */
50 :     #define isDIRTY(cm, indx, maxGen) ((cm)->map[(indx)] <= (maxGen))
51 :    
52 :     /* Iterate over the dirty cards of a card map. The argument indexVar
53 :     * should be an integer variable; it is used to pass the index of dirty
54 :     * cards to cmd.
55 :     */
56 :     #ifdef COUNT_CARDS
57 :     #define COUNT_DIRTY(indexVar) \
58 :     if(__cm->map[indexVar] != CARD_CLEAN) cardCnt2[i]++
59 :     #else
60 :     #define COUNT_DIRTY(indexVar) /* null */
61 :     #endif
62 :     #define FOR_DIRTY_CARD(cm, maxGen, indexVar, cmd) { \
63 :     card_map_t *__cm = (cm); \
64 :     int __n = __cm->numCards; \
65 :     int __g = (maxGen); \
66 :     for (indexVar = 0; indexVar < __n; indexVar++) { \
67 :     COUNT_DIRTY(indexVar); \
68 :     if (isDIRTY(__cm, indexVar, __g)) { \
69 :     cmd \
70 :     } \
71 :     } \
72 :     }
73 :    
74 :     #else
75 :     /** Memory cards **
76 :     * The type of "cards" of memory. These are used to keep track of
77 :     * dirty regions in the array arenas.
78 :     * NOTE: we use bitvectors to implement card maps. It has been suggested that
79 :     * byte arrays are more efficient, since they avoid the read-modify-write
80 :     * required when setting a bit, but this doesn't seem to hold for SML. I
81 :     * think that this is because updates are less frequent, so that the savings
82 :     * on marking cards dirty doesn't offset the added cost of sweeping.
83 :     */
84 :     typedef struct { /* A dirty card map */
85 :     ml_val_t *baseAddr; /* The base address of the mapped region */
86 :     Word_t numCards; /* The number of cards covered by the map */
87 :     int mapSzB; /* The number of bytes allocated for this */
88 :     /* map. */
89 :     Word_t map[1]; /* The card map */
90 :     } card_map_t;
91 :    
92 :     /* #define OLD_CARDS */
93 :     #ifdef OLD_CARDS
94 :     #define CARD_BITS 10 /* 1024 byte cards */
95 :     #else
96 :     #define CARD_BITS 8 /* 256 byte cards */
97 :     #endif
98 :     #define CARD_SZB (1<<CARD_BITS)
99 :     #define CARD_SZW (CARD_SZB / WORD_SZB)
100 :     #define CARD_SHIFTW (BITS_PER_WORD-CARD_BITS)
101 :     #define CARD_MAP_SZ(n) \
102 :     (sizeof(card_map_t) + ((((n)+(BITS_PER_WORD-1)) >> LOG_BITS_PER_WORD)-1)*WORD_SZB)
103 :    
104 :     /* Map an address to a card index */
105 :     #define CARD_INDEX(cm, addr) \
106 :     (((Addr_t)(addr) - (Addr_t)(cm->baseAddr)) >> CARD_BITS)
107 :    
108 :     /* Map a card index to its base address */
109 :     #define CARD_TO_ADDR(cm, index) \
110 :     ((Word_t *)((Addr_t)(cm->baseAddr) + ((index) << CARD_BITS)))
111 :    
112 :     /* Mark the card containing addr */
113 :     #define MARK_CARD(cm, addr) { \
114 :     card_map_t *__cm = (cm); \
115 :     Word_t __offset = CARD_INDEX(__cm, addr); \
116 :     __cm->map[__offset >> LOG_BITS_PER_WORD] |= \
117 :     (1 << (__offset & (BITS_PER_WORD-1))); \
118 :     }
119 :    
120 :     /* test a card to see if it is marked */
121 :     #define isDIRTY(cm, indx) \
122 :     ((cm)->map[(indx) >> LOG_BITS_PER_WORD] & (1 << ((indx) & (BITS_PER_WORD-1))))
123 :    
124 :     /* Iterate over the dirty cards of a card map. The argument indexVar
125 :     * should be an integer variable; it is used to pass the index of dirty
126 :     * cards to cmd.
127 :     */
128 :     #define FOR_DIRTY_CARD(cm, indexVar, cmd) { \
129 :     card_map_t *__cm = (cm); \
130 :     int __i = 0, __j = 0; \
131 :     while (__j < __cm->numCards) { \
132 :     Word_t __m = __cm->map[__i]; \
133 :     indexVar = __j; \
134 :     for (; __m != 0; __m >>= 1) { \
135 :     if (__m & 1) { \
136 :     cmd; \
137 :     } \
138 :     indexVar++; \
139 :     } \
140 :     __i++; __j += BITS_PER_WORD; \
141 :     } \
142 :     }
143 :     #endif
144 :    
145 :     #endif /* !_CARD_MAP_ */

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0