blob: 8cea825c33eac934d7816b81e58ebe89cb697024 [file] [log] [blame]
Russ Cox0d3a0432009-03-30 00:01:07 -07001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Heap map, 32-bit version
6// See malloc.h and mheap.c for overview.
7
8#include "runtime.h"
9#include "malloc.h"
10
11// 3-level radix tree mapping page ids to Span*.
12void
13MHeapMap_Init(MHeapMap *m, void *(*allocator)(size_t))
14{
15 m->allocator = allocator;
16}
17
18MSpan*
19MHeapMap_Get(MHeapMap *m, PageID k)
20{
21 int32 i1, i2;
22
23 i2 = k & MHeapMap_Level2Mask;
24 k >>= MHeapMap_Level2Bits;
25 i1 = k & MHeapMap_Level1Mask;
26 k >>= MHeapMap_Level1Bits;
27 if(k != 0)
28 throw("MHeapMap_Get");
29
30 return m->p[i1]->s[i2];
31}
32
33MSpan*
34MHeapMap_GetMaybe(MHeapMap *m, PageID k)
35{
36 int32 i1, i2;
37 MHeapMapNode2 *p2;
38
39 i2 = k & MHeapMap_Level2Mask;
40 k >>= MHeapMap_Level2Bits;
41 i1 = k & MHeapMap_Level1Mask;
42 k >>= MHeapMap_Level1Bits;
43 if(k != 0)
44 throw("MHeapMap_Get");
45
46 p2 = m->p[i1];
47 if(p2 == nil)
48 return nil;
49 return p2->s[i2];
50}
51
52void
53MHeapMap_Set(MHeapMap *m, PageID k, MSpan *s)
54{
55 int32 i1, i2;
56
57 i2 = k & MHeapMap_Level2Mask;
58 k >>= MHeapMap_Level2Bits;
59 i1 = k & MHeapMap_Level1Mask;
60 k >>= MHeapMap_Level1Bits;
61 if(k != 0)
62 throw("MHeapMap_Set");
63
64 m->p[i1]->s[i2] = s;
65}
66
67// Allocate the storage required for entries [k, k+1, ..., k+len-1]
68// so that Get and Set calls need not check for nil pointers.
69bool
70MHeapMap_Preallocate(MHeapMap *m, PageID k, uintptr len)
71{
72 uintptr end;
73 int32 i1;
74 MHeapMapNode2 *p2;
75
76 end = k+len;
77 while(k < end) {
78 if((k >> MHeapMap_TotalBits) != 0)
79 return false;
80 i1 = (k >> MHeapMap_Level2Bits) & MHeapMap_Level1Mask;
81
82 // first-level pointer
83 if(m->p[i1] == nil) {
84 p2 = m->allocator(sizeof *p2);
85 if(p2 == nil)
86 return false;
Russ Cox22a5c782009-10-15 23:10:49 -070087 runtime_memclr((byte*)p2, sizeof *p2);
Russ Cox0d3a0432009-03-30 00:01:07 -070088 m->p[i1] = p2;
89 }
90
91 // advance key past this leaf node
92 k = ((k >> MHeapMap_Level2Bits) + 1) << MHeapMap_Level2Bits;
93 }
94 return true;
95}
96