1 // 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.
5 // Heap map, 64-bit version
6 // See malloc.h and mheap.c for overview.
11 #if __SIZEOF_POINTER__ == 8
13 // 3-level radix tree mapping page ids to Span*.
15 runtime_MHeapMap_Init(MHeapMap
*m
, void *(*allocator
)(uintptr
))
17 m
->allocator
= allocator
;
21 runtime_MHeapMap_Get(MHeapMap
*m
, PageID k
)
25 i3
= k
& MHeapMap_Level3Mask
;
26 k
>>= MHeapMap_Level3Bits
;
27 i2
= k
& MHeapMap_Level2Mask
;
28 k
>>= MHeapMap_Level2Bits
;
29 i1
= k
& MHeapMap_Level1Mask
;
30 k
>>= MHeapMap_Level1Bits
;
32 runtime_throw("MHeapMap_Get");
34 return m
->p
[i1
]->p
[i2
]->s
[i3
];
38 runtime_MHeapMap_GetMaybe(MHeapMap
*m
, PageID k
)
44 i3
= k
& MHeapMap_Level3Mask
;
45 k
>>= MHeapMap_Level3Bits
;
46 i2
= k
& MHeapMap_Level2Mask
;
47 k
>>= MHeapMap_Level2Bits
;
48 i1
= k
& MHeapMap_Level1Mask
;
49 k
>>= MHeapMap_Level1Bits
;
51 runtime_throw("MHeapMap_Get");
63 runtime_MHeapMap_Set(MHeapMap
*m
, PageID k
, MSpan
*s
)
67 i3
= k
& MHeapMap_Level3Mask
;
68 k
>>= MHeapMap_Level3Bits
;
69 i2
= k
& MHeapMap_Level2Mask
;
70 k
>>= MHeapMap_Level2Bits
;
71 i1
= k
& MHeapMap_Level1Mask
;
72 k
>>= MHeapMap_Level1Bits
;
74 runtime_throw("MHeapMap_Set");
76 m
->p
[i1
]->p
[i2
]->s
[i3
] = s
;
79 // Allocate the storage required for entries [k, k+1, ..., k+len-1]
80 // so that Get and Set calls need not check for nil pointers.
82 runtime_MHeapMap_Preallocate(MHeapMap
*m
, PageID k
, uintptr len
)
91 if((k
>> MHeapMap_TotalBits
) != 0)
93 i2
= (k
>> MHeapMap_Level3Bits
) & MHeapMap_Level2Mask
;
94 i1
= (k
>> (MHeapMap_Level3Bits
+ MHeapMap_Level2Bits
)) & MHeapMap_Level1Mask
;
96 // first-level pointer
97 if((p2
= m
->p
[i1
]) == nil
) {
98 p2
= m
->allocator(sizeof *p2
);
101 mstats
.heapmap_sys
+= sizeof *p2
;
105 // second-level pointer
106 if(p2
->p
[i2
] == nil
) {
107 p3
= m
->allocator(sizeof *p3
);
110 mstats
.heapmap_sys
+= sizeof *p3
;
114 // advance key past this leaf node
115 k
= ((k
>> MHeapMap_Level3Bits
) + 1) << MHeapMap_Level3Bits
;
120 #endif /* __SIZEOF_POINTER__ == 8 */