LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Central free lists. | 5 // Central free lists. |
6 // | 6 // |
7 // See malloc.h for an overview. | 7 // See malloc.h for an overview. |
8 // | 8 // |
9 // The MCentral doesn't actually contain the list of free objects; the MSpan doe
s. | 9 // The MCentral doesn't actually contain the list of free objects; the MSpan doe
s. |
10 // Each MCentral is two lists of MSpans: those with free objects (c->nonempty) | 10 // Each MCentral is two lists of MSpans: those with free objects (c->nonempty) |
11 // and those that are completely allocated (c->empty). | 11 // and those that are completely allocated (c->empty). |
12 // | 12 // |
13 // TODO(rsc): tcmalloc uses a "transfer cache" to split the list | 13 // TODO(rsc): tcmalloc uses a "transfer cache" to split the list |
14 // into sections of class_to_transfercount[sizeclass] objects | 14 // into sections of class_to_transfercount[sizeclass] objects |
15 // so that it is faster to move those lists between MCaches and MCentrals. | 15 // so that it is faster to move those lists between MCaches and MCentrals. |
16 | 16 |
17 #include "runtime.h" | 17 #include "runtime.h" |
18 #include "arch.h" | 18 #include "arch_GOARCH.h" |
19 #include "malloc.h" | 19 #include "malloc.h" |
20 | 20 |
21 static bool MCentral_Grow(MCentral *c); | 21 static bool MCentral_Grow(MCentral *c); |
22 static void* MCentral_Alloc(MCentral *c); | 22 static void* MCentral_Alloc(MCentral *c); |
23 static void MCentral_Free(MCentral *c, void *v); | 23 static void MCentral_Free(MCentral *c, void *v); |
24 | 24 |
25 // Initialize a single central free list. | 25 // Initialize a single central free list. |
26 void | 26 void |
27 runtime·MCentral_Init(MCentral *c, int32 sizeclass) | 27 runtime·MCentral_Init(MCentral *c, int32 sizeclass) |
28 { | 28 { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 v = s->freelist; | 81 v = s->freelist; |
82 s->freelist = v->next; | 82 s->freelist = v->next; |
83 if(s->freelist == nil) { | 83 if(s->freelist == nil) { |
84 runtime·MSpanList_Remove(s); | 84 runtime·MSpanList_Remove(s); |
85 runtime·MSpanList_Insert(&c->empty, s); | 85 runtime·MSpanList_Insert(&c->empty, s); |
86 } | 86 } |
87 return v; | 87 return v; |
88 } | 88 } |
89 | 89 |
90 // Free n objects back into the central free list. | 90 // Free n objects back into the central free list. |
91 // Return the number of objects allocated. | |
92 // The objects are linked together by their first words. | |
93 // On return, *pstart points at the first object and *pend at the last. | |
94 void | 91 void |
95 runtime·MCentral_FreeList(MCentral *c, int32 n, MLink *start) | 92 runtime·MCentral_FreeList(MCentral *c, int32 n, MLink *start) |
96 { | 93 { |
97 MLink *v, *next; | 94 MLink *v, *next; |
98 | 95 |
99 // Assume next == nil marks end of list. | 96 // Assume next == nil marks end of list. |
100 // n and end would be useful if we implemented | 97 // n and end would be useful if we implemented |
101 // the transfer cache optimization in the TODO above. | 98 // the transfer cache optimization in the TODO above. |
102 USED(n); | 99 USED(n); |
103 | 100 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 runtime·unmarkspan((byte*)(s->start<<PageShift), s->npages<<Page
Shift); | 138 runtime·unmarkspan((byte*)(s->start<<PageShift), s->npages<<Page
Shift); |
142 *(uintptr*)(s->start<<PageShift) = 1; // needs zeroing | 139 *(uintptr*)(s->start<<PageShift) = 1; // needs zeroing |
143 s->freelist = nil; | 140 s->freelist = nil; |
144 c->nfree -= (s->npages << PageShift) / size; | 141 c->nfree -= (s->npages << PageShift) / size; |
145 runtime·unlock(c); | 142 runtime·unlock(c); |
146 runtime·MHeap_Free(&runtime·mheap, s, 0); | 143 runtime·MHeap_Free(&runtime·mheap, s, 0); |
147 runtime·lock(c); | 144 runtime·lock(c); |
148 } | 145 } |
149 } | 146 } |
150 | 147 |
| 148 // Free n objects from a span s back into the central free list c. |
| 149 // Called from GC. |
151 void | 150 void |
152 runtime·MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *e
nd) | 151 runtime·MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *e
nd) |
153 { | 152 { |
154 int32 size; | 153 int32 size; |
155 | 154 |
156 runtime·lock(c); | 155 runtime·lock(c); |
157 | 156 |
158 // Move to nonempty if necessary. | 157 // Move to nonempty if necessary. |
159 if(s->freelist == nil) { | 158 if(s->freelist == nil) { |
160 runtime·MSpanList_Remove(s); | 159 runtime·MSpanList_Remove(s); |
161 runtime·MSpanList_Insert(&c->nonempty, s); | 160 runtime·MSpanList_Insert(&c->nonempty, s); |
162 } | 161 } |
163 | 162 |
164 » // Add v back to s's free list. | 163 » // Add the objects back to s's free list. |
165 end->next = s->freelist; | 164 end->next = s->freelist; |
166 s->freelist = start; | 165 s->freelist = start; |
167 s->ref -= n; | 166 s->ref -= n; |
168 c->nfree += n; | 167 c->nfree += n; |
169 | 168 |
170 // If s is completely freed, return it to the heap. | 169 // If s is completely freed, return it to the heap. |
171 if(s->ref == 0) { | 170 if(s->ref == 0) { |
172 size = runtime·class_to_size[c->sizeclass]; | 171 size = runtime·class_to_size[c->sizeclass]; |
173 runtime·MSpanList_Remove(s); | 172 runtime·MSpanList_Remove(s); |
174 *(uintptr*)(s->start<<PageShift) = 1; // needs zeroing | 173 *(uintptr*)(s->start<<PageShift) = 1; // needs zeroing |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 p += size; | 225 p += size; |
227 } | 226 } |
228 *tailp = nil; | 227 *tailp = nil; |
229 runtime·markspan((byte*)(s->start<<PageShift), size, n, size*n < (s->npa
ges<<PageShift)); | 228 runtime·markspan((byte*)(s->start<<PageShift), size, n, size*n < (s->npa
ges<<PageShift)); |
230 | 229 |
231 runtime·lock(c); | 230 runtime·lock(c); |
232 c->nfree += n; | 231 c->nfree += n; |
233 runtime·MSpanList_Insert(&c->nonempty, s); | 232 runtime·MSpanList_Insert(&c->nonempty, s); |
234 return true; | 233 return true; |
235 } | 234 } |
LEFT | RIGHT |