changes
[IRC.git] / Robust / src / Runtime / bamboo / markbit.h
1 #ifndef MARKBIT_H
2 #define MARKBIT_H
3 #include "bambooalign.h"
4
5 extern unsigned int markmappingarray[];
6 extern unsigned int bitmarkmappingarray[];
7 extern unsigned int revmarkmappingarray[];
8
9 #define CONVERTTABLEINDEXTOPTR(x) (((unsigned INTPTR)((x)<<(ALIGNMENTSHIFT+4)))+gcbaseva)
10 //Minimum alignment unit
11
12
13
14 #define OBJMASK 0x40000000UL  //set towhatever smallest object mark is
15 #define MARKMASK 0xc0000000UL  //set towhatever smallest object mark is
16
17 /* 
18    The bitmap mark array uses 2 mark bits per alignment unit.
19
20    The clever trick is that we encode the length of the object (in
21    units of alignment units) using just these two bits.  The basic
22    idea is to generate a variable length encoding of the length in
23    which the length of the encoding is shorter than number of mark
24    bits taken up by the object.
25
26    To make this efficient, it is table driven for objects that are
27    less than 16 alignment units in length.  For larger objects, we
28    just use addition.
29 */
30
31 /* Return length in units of ALIGNSIZE */
32
33 static inline unsigned int getMarkedLength(void *ptr) {
34   unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
35   unsigned INTPTR hibits=alignsize>>4;
36   unsigned INTPTR lobits=(alignsize&15)<<1;
37   unsigned INTPTR val;
38   if (lobits==0)
39     val=gcmarktbl[hibits];
40   else {
41     unsigned INTPTR revlobits=32-lobits;
42     val=(gcmarktbl[hibits]<<lobits)|(gcmarktbl[hibits+1]>>(revlobits));
43   }
44   unsigned int index=val>>26;
45   if (index>48)
46     return (val-0xc4000000)+16;
47   else
48     return markmappingarray[index];
49 }
50
51 /* Return non-zero value if the object is marked */
52
53 static inline unsigned int checkMark(void *ptr) {
54   unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
55   unsigned INTPTR hibits=alignsize>>4;
56   unsigned INTPTR lobits=(alignsize&15)<<1;
57
58   return (gcmarktbl[hibits]<<lobits)&MARKMASK;
59 }
60
61 /* Return non-zero value if the object is marked */
62
63 static inline unsigned int checkAndCondSetMark(void *ptr) {
64   unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
65   unsigned INTPTR hibits=alignsize>>4;
66   unsigned INTPTR lobits=(alignsize&15)<<1;
67   unsigned INTPTR mask=MARKMASK>>lobits;
68   BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
69   unsigned INTPTR mark=(gcmarktbl[hibits])&mask;
70   if (!mark) {
71     gcmarktbl[hibits]|=(OBJMASK>>lobits);    
72   }
73   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
74   return mark;
75 }
76
77 /* Set length in units of ALIGNSIZE */
78
79 static inline void setLength(void *ptr, unsigned int length) {
80   unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
81   unsigned INTPTR hibits=alignsize>>4;
82   unsigned INTPTR lobits=(alignsize&15)<<1;
83   unsigned int ormask=(length>=16)?0xc4000000+(length-16):revmarkmappingarray[length];
84   if (lobits==0) {
85     gcmarktbl[hibits]|=ormask;
86   } else {
87     gcmarktbl[hibits]|=ormask>>lobits;
88     unsigned INTPTR lowormask=ormask<<(32-lobits);
89     if (lowormask)
90       gcmarktbl[hibits+1]|=lowormask;
91   }
92 }
93
94 /* Set length for premarked object */
95
96 static inline void setLengthMarked_I(void *ptr, unsigned int length) {
97   unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
98   unsigned INTPTR hibits=alignsize>>4;
99   unsigned INTPTR lobits=(alignsize&15)<<1;
100   unsigned int ormask=(length>=16)?0xc4000000+(length-16):revmarkmappingarray[length];
101   if (lobits==0) {
102     gcmarktbl[hibits]=(gcmarktbl[hibits]^(OBJMASK))|ormask;
103   } else {
104     gcmarktbl[hibits]=(gcmarktbl[hibits]^(OBJMASK>>lobits))|(ormask>>lobits);
105     unsigned INTPTR lowormask=ormask<<(32-lobits);
106     if (lowormask)
107       gcmarktbl[hibits+1]|=lowormask;
108   }
109 }
110
111 static inline void setLengthMarked(void *ptr, unsigned int length) {
112   BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
113   setLengthMarked_I(ptr, length);
114   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
115 }
116
117 /* Set length in units of ALIGNSIZE */
118
119 static inline void setMark_I(void *ptr) {
120   unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
121   unsigned INTPTR hibits=alignsize>>4;
122   unsigned INTPTR lobits=(alignsize&15)<<1;
123   gcmarktbl[hibits]|=(OBJMASK>>lobits);
124 }
125
126 static inline void setMark(void *ptr) {
127   BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
128   setMark_I(ptr);
129   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
130 }
131
132 static inline void clearMark(void *ptr) {
133   unsigned INTPTR alignsize=ALIGNOBJSIZE((unsigned INTPTR)(ptr-gcbaseva));
134   unsigned INTPTR hibits=alignsize>>4;
135   unsigned INTPTR lobits=(alignsize&15)<<1;
136
137   if (lobits==0) {
138     unsigned int hipart=gcmarktbl[hibits];
139     unsigned int index=hipart>>26;
140     unsigned int bits=(index>48)?32:bitmarkmappingarray[index];
141     unsigned int bitstotoss=32-bits;
142     gcmarktbl[hibits]^=((hipart>>(bitstotoss))<<(bitstotoss));
143   } else {
144     unsigned int orighi=gcmarktbl[hibits];
145     unsigned int hipart=orighi<<lobits;
146     unsigned INTPTR revlobits=32-lobits;
147     unsigned int lowpart=gcmarktbl[hibits+1]>>revlobits;
148     unsigned INTPTR val=hipart|lowpart;
149     
150     unsigned int index=val>>26;
151     unsigned int bits=(index>48)?32:bitmarkmappingarray[index];
152
153     unsigned int bitstotoss=32-bits;
154
155     if ((bits+lobits)<32) {
156       unsigned int bitstotossminuslobits=bitstotoss-lobits;      
157       gcmarktbl[hibits]^=(hipart>>bitstotoss)<<bitstotossminuslobits;
158     } else
159       gcmarktbl[hibits]^=hipart>>lobits;
160     unsigned int xormask=(lowpart>>bitstotoss)<<(bitstotoss+revlobits);
161     if (xormask)
162       gcmarktbl[hibits+1]^=xormask;
163   }
164 }
165
166 #endif