potion  0.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gc.h
Go to the documentation of this file.
1 
5 #ifndef POTION_GC_H
6 #define POTION_GC_H
7 
8 #ifndef POTION_BIRTH_SIZE
9 #define POTION_BIRTH_SIZE (PN_SIZE_T << 21)
10 #endif
11 
12 #ifndef POTION_MIN_BIRTH_SIZE
13 #define POTION_MIN_BIRTH_SIZE (PN_SIZE_T << 15)
14 #endif
15 
16 #ifndef POTION_MAX_BIRTH_SIZE
17 #define POTION_MAX_BIRTH_SIZE (16 * POTION_BIRTH_SIZE)
18 #endif
19 
20 #if POTION_MAX_BIRTH_SIZE < 4 * POTION_BIRTH_SIZE
21 #error invalid min and max birth sizes
22 #endif
23 
24 #define POTION_GC_THRESHOLD (3 * POTION_BIRTH_SIZE)
25 #define POTION_GC_PERIOD 256
26 #define POTION_NB_ROOTS 64
27 
28 #define SET_GEN(t, p, s) \
29  M->t##_lo = p; \
30  M->t##_cur = p + (sizeof(PN) * 2); \
31  M->t##_hi = p + (s); \
32  p = 0
33 
34 #define SET_STOREPTR(n) \
35  M->birth_storeptr = (void *)(((void **)M->birth_hi) - (n))
36 
37 #define GC_KEEP(p) \
38  *(M->birth_storeptr--) = (void *)p
39 
40 #define DEL_BIRTH_REGION() \
41  if (M->birth_lo == M && IN_BIRTH_REGION(M->protect)) { \
42  void *protend = (void *)PN_ALIGN((_PN)M->protect, POTION_PAGESIZE); \
43  pngc_page_delete(protend, (char *)M->birth_hi - (char *)protend); \
44  } else { \
45  void *protend = (void *)M->birth_lo; \
46  pngc_page_delete(protend, (char *)M->birth_hi - (char *)protend); \
47  }
48 
49 #define IS_GC_PROTECTED(p) \
50  ((_PN)(p) >= (_PN)M && (_PN)(p) < (_PN)M->protect)
51 
52 #define IN_BIRTH_REGION(p) \
53  ((_PN)(p) > (_PN)M->birth_lo && (_PN)(p) < (_PN)M->birth_hi)
54 
55 #define IN_OLDER_REGION(p) \
56  ((_PN)(p) > (_PN)M->old_lo && (_PN)(p) < (_PN)M->old_hi)
57 
58 #define IS_NEW_PTR(p) \
59  (PN_IS_PTR(p) && IN_BIRTH_REGION(p) && !IS_GC_PROTECTED(p))
60 
61 #define GC_FORWARD(p, v) do { \
62  struct PNFwd *_pnobj = (struct PNFwd *)v; \
63  if (_pnobj->fwd == POTION_COPIED) \
64  *(p) = _pnobj->ptr; \
65  else \
66  *(p) = (_PN)potion_gc_copy(P, (struct PNObject *)v); \
67 } while(0)
68 
69 #define GC_MINOR_UPDATE(p) do { \
70  if (PN_IS_PTR(p)) { \
71  PN _pnv = potion_fwd((_PN)p); \
72  if (IN_BIRTH_REGION(_pnv) && !IS_GC_PROTECTED(_pnv)) \
73  { GC_FORWARD((_PN *)&(p), _pnv); } \
74  } \
75 } while(0)
76 
77 #define GC_MAJOR_UPDATE(p) do { \
78  if (PN_IS_PTR(p)) { \
79  PN _pnv = potion_fwd((_PN)p); \
80  if (!IS_GC_PROTECTED(_pnv) && \
81  (IN_BIRTH_REGION(_pnv) || IN_OLDER_REGION(_pnv))) \
82  {GC_FORWARD((_PN *)&(p), _pnv);} \
83  } \
84 } while(0)
85 
86 #define GC_MINOR_UPDATE_TABLE(name, kh, is_map) do { \
87  unsigned k; \
88  for (k = kh_begin(kh); k != kh_end(kh); ++k) \
89  if (kh_exist(name, kh, k)) { \
90  PN v1 = kh_key(name, kh, k); \
91  GC_MINOR_UPDATE(v1); \
92  kh_key(name, kh, k) = v1; \
93  if (is_map) { \
94  PN v2 = kh_val(name, kh, k); \
95  GC_MINOR_UPDATE(v2); \
96  kh_val(name, kh, k) = v2; \
97  } \
98  } \
99 } while (0)
100 
101 #define GC_MAJOR_UPDATE_TABLE(name, kh, is_map) do { \
102  unsigned k; \
103  for (k = kh_begin(kh); k != kh_end(kh); ++k) \
104  if (kh_exist(name, kh, k)) { \
105  PN v1 = kh_key(name, kh, k); \
106  GC_MAJOR_UPDATE(v1); \
107  kh_key(name, kh, k) = v1; \
108  if (is_map) { \
109  PN v2 = kh_val(name, kh, k); \
110  GC_MAJOR_UPDATE(v2); \
111  kh_val(name, kh, k) = v2; \
112  } \
113  } \
114 } while (0)
115 
116 #define GC_MINOR_STRINGS() do { \
117  unsigned k; \
118  GC_MINOR_UPDATE(P->strings); \
119  for (k = kh_begin(P->strings); k != kh_end(P->strings); ++k) \
120  if (kh_exist(str, P->strings, k)) { \
121  PN v = kh_key(str, P->strings, k); \
122  if (IN_BIRTH_REGION(v) && !IS_GC_PROTECTED(v)) { \
123  if (((struct PNFwd *)v)->fwd == POTION_COPIED) \
124  kh_key(str, P->strings, k) = ((struct PNFwd *)v)->ptr; \
125  else \
126  kh_del(str, P->strings, k); \
127  } \
128  } \
129 } while (0)
130 
131 #define GC_MAJOR_STRINGS() do { \
132  unsigned k; \
133  GC_MAJOR_UPDATE(P->strings); \
134  for (k = kh_begin(P->strings); k != kh_end(P->strings); ++k) \
135  if (kh_exist(str, P->strings, k)) { \
136  PN v = kh_key(str, P->strings, k); \
137  if (!IS_GC_PROTECTED(v) && \
138  (IN_BIRTH_REGION(v) || IN_OLDER_REGION(v))) { \
139  if (((struct PNFwd *)v)->fwd == POTION_COPIED) \
140  kh_key(str, P->strings, k) = ((struct PNFwd *)v)->ptr; \
141  else \
142  kh_del(str, P->strings, k); \
143  } \
144  } \
145 } while (0)
146 
147 static inline int potion_birth_suggest(int need, volatile void *oldlo, volatile void *oldhi) {
148  int suggest = ((char *)oldhi - (char *)oldlo) / 2;
149  if (need * 2 > suggest) suggest = need * 2;
150  if (POTION_MIN_BIRTH_SIZE > suggest)
151  suggest = POTION_MIN_BIRTH_SIZE;
152  else if (POTION_BIRTH_SIZE < suggest)
153  suggest = POTION_BIRTH_SIZE;
154  return PN_ALIGN(suggest, POTION_MIN_BIRTH_SIZE);
155 }
156 
159 void *potion_gc_copy(Potion *, struct PNObject *);
160 void *pngc_page_new(int *, const char);
161 void *potion_mark_minor(Potion *, const struct PNObject *);
162 void *potion_mark_major(Potion *, const struct PNObject *);
163 void potion_gc_release(Potion *);
164 
165 #endif
void * potion_mark_major(Potion *, const struct PNObject *)
Definition: gc.c:519
void potion_gc_release(Potion *)
Definition: gc.c:691
unsigned long _PN
Definition: potion.h:78
static int potion_birth_suggest(int need, volatile void *oldlo, volatile void *oldhi)
Definition: gc.h:147
#define POTION_MIN_BIRTH_SIZE
Definition: gc.h:13
#define PN_ALIGN(o, x)
Definition: potion.h:223
#define POTION_BIRTH_SIZE
Definition: gc.h:9
unsigned int PN_SIZE
Definition: potion.h:79
standard objects act like C structs the fields are defined by the type and it's a fixed size...
Definition: potion.h:295
void * pngc_page_new(int *, const char)
Definition: gc.c:114
void * potion_gc_copy(Potion *, struct PNObject *)
Definition: gc.c:394
the global interpreter state P. currently singleton (not threads yet)
Definition: potion.h:644
void * potion_mark_minor(Potion *, const struct PNObject *)
Definition: gc.c:413
PN_SIZE potion_mark_stack(Potion *, int)
Definition: gc.c:98
PN_SIZE potion_stack_len(Potion *, _PN **)
Definition: gc.c:50