diff options
| author | Russ Cox <rsc@golang.org> | 2009-01-28 15:22:16 -0800 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2009-01-28 15:22:16 -0800 |
| commit | 9f726c2c8ba98d55935acc1143d2b792ca74e303 (patch) | |
| tree | ca165b4900d9d103778758fd1058a85d4658a235 /src/runtime/malloc.h | |
| parent | cb659ece0e9a74dd330d774552a1f26c4a4d4ee3 (diff) | |
| download | go-9f726c2c8ba98d55935acc1143d2b792ca74e303.tar.xz | |
Use explicit allspan list instead of
trying to find all the places where
spans might be recorded.
Free can cascade into complicated
span manipulations that move them
from list to list; the old code had the
possibility of accidentally processing
a span twice or jumping to a different
list, causing an infinite loop.
R=r
DELTA=70 (28 added, 25 deleted, 17 changed)
OCL=23704
CL=23710
Diffstat (limited to 'src/runtime/malloc.h')
| -rw-r--r-- | src/runtime/malloc.h | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/runtime/malloc.h b/src/runtime/malloc.h index 1da9f980de..d1d9e95e98 100644 --- a/src/runtime/malloc.h +++ b/src/runtime/malloc.h @@ -131,16 +131,20 @@ void SysUnused(void *v, uintptr nbytes); // // Memory returned by FixAlloc_Alloc is not zeroed. // The caller is responsible for locking around FixAlloc calls. +// Callers can keep state in the object but the first word is +// smashed by freeing and reallocating. struct FixAlloc { uintptr size; void *(*alloc)(uintptr); + void (*first)(void *arg, byte *p); // called first time p is returned + void *arg; MLink *list; byte *chunk; uint32 nchunk; }; -void FixAlloc_Init(FixAlloc *f, uintptr size, void *(*alloc)(uintptr)); +void FixAlloc_Init(FixAlloc *f, uintptr size, void *(*alloc)(uintptr), void (*first)(void*, byte*), void *arg); void* FixAlloc_Alloc(FixAlloc *f); void FixAlloc_Free(FixAlloc *f, void *p); @@ -203,18 +207,21 @@ void MCache_Free(MCache *c, void *p, int32 sizeclass, uintptr size); enum { MSpanInUse = 0, - MSpanFree + MSpanFree, + MSpanListHead, + MSpanDead, }; struct MSpan { MSpan *next; // in a span linked list MSpan *prev; // in a span linked list + MSpan *allnext; // in the list of all spans PageID start; // starting page number uintptr npages; // number of pages in span MLink *freelist; // list of free objects uint32 ref; // number of allocated objects in this span uint32 sizeclass; // size class - uint32 state; // MSpanInUse or MSpanFree + uint32 state; // MSpanInUse etc union { uint32 *gcref; // sizeclass > 0 uint32 gcref0; // sizeclass == 0 @@ -349,6 +356,7 @@ struct MHeap Lock; MSpan free[MaxMHeapList]; // free lists of given length MSpan large; // free lists length >= MaxMHeapList + MSpan *allspans; // span lookup MHeapMap map; |
