diff options
Diffstat (limited to 'libgo/runtime/mheapmap32.c')
-rw-r--r-- | libgo/runtime/mheapmap32.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/libgo/runtime/mheapmap32.c b/libgo/runtime/mheapmap32.c new file mode 100644 index 000000000..547c602fe --- /dev/null +++ b/libgo/runtime/mheapmap32.c @@ -0,0 +1,99 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Heap map, 32-bit version +// See malloc.h and mheap.c for overview. + +#include "runtime.h" +#include "malloc.h" + +#if __SIZEOF_POINTER__ == 4 + +// 3-level radix tree mapping page ids to Span*. +void +runtime_MHeapMap_Init(MHeapMap *m, void *(*allocator)(uintptr)) +{ + m->allocator = allocator; +} + +MSpan* +runtime_MHeapMap_Get(MHeapMap *m, PageID k) +{ + int32 i1, i2; + + i2 = k & MHeapMap_Level2Mask; + k >>= MHeapMap_Level2Bits; + i1 = k & MHeapMap_Level1Mask; + k >>= MHeapMap_Level1Bits; + if(k != 0) + runtime_throw("MHeapMap_Get"); + + return m->p[i1]->s[i2]; +} + +MSpan* +runtime_MHeapMap_GetMaybe(MHeapMap *m, PageID k) +{ + int32 i1, i2; + MHeapMapNode2 *p2; + + i2 = k & MHeapMap_Level2Mask; + k >>= MHeapMap_Level2Bits; + i1 = k & MHeapMap_Level1Mask; + k >>= MHeapMap_Level1Bits; + if(k != 0) + runtime_throw("MHeapMap_Get"); + + p2 = m->p[i1]; + if(p2 == nil) + return nil; + return p2->s[i2]; +} + +void +runtime_MHeapMap_Set(MHeapMap *m, PageID k, MSpan *s) +{ + int32 i1, i2; + + i2 = k & MHeapMap_Level2Mask; + k >>= MHeapMap_Level2Bits; + i1 = k & MHeapMap_Level1Mask; + k >>= MHeapMap_Level1Bits; + if(k != 0) + runtime_throw("MHeapMap_Set"); + + m->p[i1]->s[i2] = s; +} + +// Allocate the storage required for entries [k, k+1, ..., k+len-1] +// so that Get and Set calls need not check for nil pointers. +bool +runtime_MHeapMap_Preallocate(MHeapMap *m, PageID k, uintptr len) +{ + uintptr end; + int32 i1; + MHeapMapNode2 *p2; + + end = k+len; + while(k < end) { + if((k >> MHeapMap_TotalBits) != 0) + return false; + i1 = (k >> MHeapMap_Level2Bits) & MHeapMap_Level1Mask; + + // first-level pointer + if(m->p[i1] == nil) { + p2 = m->allocator(sizeof *p2); + if(p2 == nil) + return false; + mstats.heapmap_sys += sizeof *p2; + m->p[i1] = p2; + } + + // advance key past this leaf node + k = ((k >> MHeapMap_Level2Bits) + 1) << MHeapMap_Level2Bits; + } + return true; +} + +#endif /* __SIZEOF_POINTER__ == 4 */ |