@@ -29,13 +29,19 @@ object Translator {
29
29
|
30
30
|struct PCR {
31
31
| void *obj;
32
- | int scc;
33
32
| void (*markGray)(void *);
34
33
| void (*scan)(void *);
35
34
| void (*collectWhite)(void *);
36
35
| struct PCR *next;
37
36
|};
38
37
|
38
+ |struct PCRBucket {
39
+ | int scc;
40
+ | struct PCR *first;
41
+ | struct PCR *last;
42
+ | struct PCRBucket *next;
43
+ |};
44
+ |
39
45
|// Common object header
40
46
|typedef struct {
41
47
| int $RcField;
@@ -49,17 +55,9 @@ object Translator {
49
55
| void (*free)(void *);
50
56
|};
51
57
|
52
- |struct PCR *pcrs ;
58
+ |struct PCRBucket *pcrBuckets = NULL ;
53
59
|struct $FreeCell *freeList = NULL;
54
60
|
55
- |void printPCRs() {
56
- | fprintf(stderr, "[printPCRs] pcrs: ");
57
- | for (struct PCR *head = pcrs; head != NULL; head = head->next) {
58
- | fprintf(stderr, "%p, ", head);
59
- | }
60
- | fprintf(stderr, "\n");
61
- |}
62
- |
63
61
|void addPCR(
64
62
| Common *obj,
65
63
| int scc,
@@ -69,29 +67,46 @@ object Translator {
69
67
|) {
70
68
| if (obj->addedPCR) return;
71
69
| obj->addedPCR = 1;
72
- | struct PCR **prev = &pcrs;
73
- | while (*prev != NULL && (*prev)->scc <= scc) {
70
+ |
71
+ | struct PCRBucket **prev = &pcrBuckets;
72
+ | while (*prev != NULL && (*prev)->scc < scc) {
74
73
| // fprintf(stderr, "[addPCR] prev scc: %d\n", (*prev)->scc);
75
74
| prev = &(*prev)->next;
76
75
| }
76
+ |
77
77
| struct PCR *pcr = malloc(sizeof(struct PCR));
78
78
| fprintf(stderr, "[addPCR] Added PCR %p, prev = %p, scc: %d\n", pcr, *prev, scc);
79
79
| pcr->obj = obj;
80
- | pcr->scc = scc;
81
80
| pcr->markGray = markGray;
82
81
| pcr->scan = scan;
83
82
| pcr->collectWhite = collectWhite;
84
- | pcr->next = *prev;
85
- | *prev = pcr;
86
- | printPCRs();
83
+ | pcr->next = NULL;
84
+ |
85
+ | if (*prev == NULL || scc < (*prev)->scc) {
86
+ | struct PCRBucket *newBucket = malloc(sizeof(struct PCRBucket));
87
+ | newBucket->scc = scc;
88
+ | newBucket->first = pcr;
89
+ | newBucket->last = pcr;
90
+ | newBucket->next = *prev;
91
+ | *prev = newBucket;
92
+ | } else {
93
+ | (*prev)->last->next = pcr;
94
+ | (*prev)->last = pcr;
95
+ | }
87
96
|}
88
97
|
89
- |void removePCR(Common *obj) {
98
+ |void removePCR(Common *obj, int scc ) {
90
99
| if (!obj->addedPCR) return;
91
100
| obj->addedPCR = 0;
92
- | struct PCR *head = pcrs;
93
- | struct PCR **prev = &pcrs;
94
101
| fprintf(stderr, "[removePCR] Trying to remove %p\n", obj);
102
+ |
103
+ | struct PCRBucket *bucket = pcrBuckets;
104
+ | while (bucket->scc != scc) {
105
+ | bucket = bucket->next;
106
+ | }
107
+ |
108
+ | struct PCR *head = bucket->first;
109
+ | struct PCR **prev = &bucket->first;
95
110
| while (head != NULL) {
96
111
| fprintf(stderr, "[removePCR] head = %p\n", head);
97
112
| if (head->obj == obj) {
@@ -107,30 +122,26 @@ object Translator {
107
122
| }
108
123
|}
109
124
|
110
- |void markGrayAllPCRs(struct PCR *head, int scc ) {
111
- | if (head == NULL || head->scc != scc ) return;
125
+ |void markGrayAllPCRs(struct PCR *head) {
126
+ | if (head == NULL) return;
112
127
| struct PCR *next = head->next;
113
128
| head->markGray(head->obj);
114
- | markGrayAllPCRs(next, scc );
129
+ | markGrayAllPCRs(next);
115
130
|}
116
131
|
117
- |void scanAllPCRs(struct PCR *head, int scc ) {
118
- | if (head == NULL || head->scc != scc ) return;
132
+ |void scanAllPCRs(struct PCR *head) {
133
+ | if (head == NULL) return;
119
134
| struct PCR *next = head->next;
120
135
| head->scan(head->obj);
121
- | scanAllPCRs(next, scc );
136
+ | scanAllPCRs(next);
122
137
|}
123
138
|
124
- |void collectWhiteAllPCRs(int scc) {
125
- | if (pcrs == NULL || pcrs->scc != scc) return;
126
- | fprintf(stderr, "[collectWhiteAllPCRs] pcr: %p, scc: %d\n", pcrs, scc);
127
- | printPCRs();
128
- | struct PCR *next = pcrs->next;
129
- | pcrs->collectWhite(pcrs->obj);
130
- | free(pcrs);
131
- | fprintf(stderr, "Removed a PCR %p\n", pcrs);
132
- | pcrs = next;
133
- | collectWhiteAllPCRs(scc);
139
+ |void collectWhiteAllPCRs(struct PCR *head) {
140
+ | if (head == NULL) return;
141
+ | struct PCR *next = head->next;
142
+ | head->collectWhite(head->obj);
143
+ | free(head);
144
+ | collectWhiteAllPCRs(next);
134
145
|}
135
146
|
136
147
|void collectFreeList() {
@@ -143,19 +154,19 @@ object Translator {
143
154
|}
144
155
|
145
156
|void processAllPCRs() {
146
- | if (pcrs == NULL) return;
147
- | int firstScc = pcrs->scc ;
148
- | markGrayAllPCRs(pcrs, firstScc );
149
- | scanAllPCRs(pcrs, firstScc);
150
- | if (freeList != NULL) {
151
- | fprintf(stderr, "Free list should be null\n" );
152
- | exit(1);
153
- | }
154
- | collectWhiteAllPCRs(firstScc );
155
- | collectFreeList( );
156
- | fprintf(stderr, "firstScc: %d\n", firstScc) ;
157
- | if (pcrs != NULL) {
158
- | processAllPCRs() ;
157
+ | while (pcrBuckets != NULL) {
158
+ | markGrayAllPCRs(pcrBuckets->first) ;
159
+ | scanAllPCRs(pcrBuckets->first );
160
+ | if (freeList != NULL) {
161
+ | fprintf(stderr, "Free list should be null\n");
162
+ | exit(1 );
163
+ | }
164
+ | collectWhiteAllPCRs(pcrBuckets->first);
165
+ | collectFreeList( );
166
+ | fprintf(stderr, "[processAllPCRs]: Processed scc %d\n", pcrBuckets->scc );
167
+ | struct PCRBucket *next = pcrBuckets->next ;
168
+ | free(pcrBuckets);
169
+ | pcrBuckets = next ;
159
170
| }
160
171
|}
161
172
| """ .stripMargin
@@ -249,16 +260,17 @@ object Translator {
249
260
.mkString(" \n " )
250
261
}
251
262
}
263
+ val scc = cycles.sccMap(typ)
252
264
253
265
raw """ |fprintf(stderr, "Decrementing ${typ.name} (%p)\n", $This);
254
266
|if (-- $This-> $RcField == 0) {
255
267
| $deleteCases
256
- | removePCR((void *) $This);
268
+ | removePCR((void *) $This, $scc );
257
269
| free( $This);
258
270
|} else {
259
271
| addPCR(
260
272
| (void *) $This,
261
- | ${cycles.sccMap(typ)} ,
273
+ | $scc ,
262
274
| (void *) ${MarkGray .name(typ)},
263
275
| (void *) ${Scan .name(typ)},
264
276
| (void *) ${CollectWhite .name(typ)});
0 commit comments