OLD | NEW |
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) |
(...skipping 70 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. |
| 150 void |
| 151 runtime·MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *e
nd) |
| 152 { |
| 153 int32 size; |
| 154 |
| 155 runtime·lock(c); |
| 156 |
| 157 // Move to nonempty if necessary. |
| 158 if(s->freelist == nil) { |
| 159 runtime·MSpanList_Remove(s); |
| 160 runtime·MSpanList_Insert(&c->nonempty, s); |
| 161 } |
| 162 |
| 163 // Add the objects back to s's free list. |
| 164 end->next = s->freelist; |
| 165 s->freelist = start; |
| 166 s->ref -= n; |
| 167 c->nfree += n; |
| 168 |
| 169 // If s is completely freed, return it to the heap. |
| 170 if(s->ref == 0) { |
| 171 size = runtime·class_to_size[c->sizeclass]; |
| 172 runtime·MSpanList_Remove(s); |
| 173 *(uintptr*)(s->start<<PageShift) = 1; // needs zeroing |
| 174 s->freelist = nil; |
| 175 c->nfree -= (s->npages << PageShift) / size; |
| 176 runtime·unlock(c); |
| 177 runtime·unmarkspan((byte*)(s->start<<PageShift), s->npages<<Page
Shift); |
| 178 runtime·MHeap_Free(&runtime·mheap, s, 0); |
| 179 } else { |
| 180 runtime·unlock(c); |
| 181 } |
| 182 } |
| 183 |
151 void | 184 void |
152 runtime·MGetSizeClassInfo(int32 sizeclass, uintptr *sizep, int32 *npagesp, int32
*nobj) | 185 runtime·MGetSizeClassInfo(int32 sizeclass, uintptr *sizep, int32 *npagesp, int32
*nobj) |
153 { | 186 { |
154 int32 size; | 187 int32 size; |
155 int32 npages; | 188 int32 npages; |
156 | 189 |
157 npages = runtime·class_to_allocnpages[sizeclass]; | 190 npages = runtime·class_to_allocnpages[sizeclass]; |
158 size = runtime·class_to_size[sizeclass]; | 191 size = runtime·class_to_size[sizeclass]; |
159 *npagesp = npages; | 192 *npagesp = npages; |
160 *sizep = size; | 193 *sizep = size; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 p += size; | 225 p += size; |
193 } | 226 } |
194 *tailp = nil; | 227 *tailp = nil; |
195 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)); |
196 | 229 |
197 runtime·lock(c); | 230 runtime·lock(c); |
198 c->nfree += n; | 231 c->nfree += n; |
199 runtime·MSpanList_Insert(&c->nonempty, s); | 232 runtime·MSpanList_Insert(&c->nonempty, s); |
200 return true; | 233 return true; |
201 } | 234 } |
OLD | NEW |