1/*
2 * Copyright (C) 2014 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef Sizes_h
27#define Sizes_h
28
29#include "Algorithm.h"
30#include "BPlatform.h"
31#include <algorithm>
32#include <cstdint>
33#include <cstddef>
34#include <limits>
35#include <type_traits>
36#include <chrono>
37
38namespace bmalloc {
39
40// Repository for malloc sizing constants and calculations.
41
42namespace Sizes {
43static constexpr size_t kB = 1024;
44static constexpr size_t MB = kB * kB;
45static constexpr size_t GB = kB * kB * kB;
46
47static constexpr size_t alignment = 8;
48static constexpr size_t alignmentMask = alignment - 1ul;
49
50static constexpr size_t chunkSize = 1 * MB;
51static constexpr size_t chunkMask = ~(chunkSize - 1ul);
52
53static constexpr size_t smallLineSize = 256;
54static constexpr size_t smallPageSize = 4 * kB;
55static constexpr size_t smallPageLineCount = smallPageSize / smallLineSize;
56
57static constexpr size_t maskSizeClassMax = 512;
58static constexpr size_t smallMax = 32 * kB;
59
60static constexpr size_t pageSizeMax = smallMax * 2;
61static constexpr size_t pageClassCount = pageSizeMax / smallPageSize;
62
63static constexpr size_t pageSizeWasteFactor = 8;
64static constexpr size_t logWasteFactor = 8;
65
66static constexpr size_t largeAlignment = smallMax / pageSizeWasteFactor;
67static constexpr size_t largeAlignmentMask = largeAlignment - 1;
68
69static constexpr size_t deallocatorLogCapacity = 512;
70static constexpr size_t bumpRangeCacheCapacity = 3;
71
72static constexpr size_t scavengerBytesPerMemoryPressureCheck = 16 * MB;
73static constexpr double memoryPressureThreshold = 0.75;
74
75static constexpr size_t maskSizeClassCount = maskSizeClassMax / alignment;
76
77constexpr size_t maskSizeClass(size_t size)
78{
79 // We mask to accommodate zero.
80 return mask((size - 1) / alignment, maskSizeClassCount - 1);
81}
82
83inline size_t maskObjectSize(size_t maskSizeClass)
84{
85 return (maskSizeClass + 1) * alignment;
86}
87
88static constexpr size_t logAlignmentMin = maskSizeClassMax / logWasteFactor;
89
90static constexpr size_t logSizeClassCount = (log2(smallMax) - log2(maskSizeClassMax)) * logWasteFactor;
91
92inline size_t logSizeClass(size_t size)
93{
94 size_t base = log2(size - 1) - log2(maskSizeClassMax);
95 size_t offset = (size - 1 - (maskSizeClassMax << base));
96 return base * logWasteFactor + offset / (logAlignmentMin << base);
97}
98
99inline size_t logObjectSize(size_t logSizeClass)
100{
101 size_t base = logSizeClass / logWasteFactor;
102 size_t offset = logSizeClass % logWasteFactor;
103 return (maskSizeClassMax << base) + (offset + 1) * (logAlignmentMin << base);
104}
105
106static constexpr size_t sizeClassCount = maskSizeClassCount + logSizeClassCount;
107
108inline size_t sizeClass(size_t size)
109{
110 if (size <= maskSizeClassMax)
111 return maskSizeClass(size);
112 return maskSizeClassCount + logSizeClass(size);
113}
114
115inline size_t objectSize(size_t sizeClass)
116{
117 if (sizeClass < maskSizeClassCount)
118 return maskObjectSize(sizeClass);
119 return logObjectSize(sizeClass - maskSizeClassCount);
120}
121
122inline size_t pageSize(size_t pageClass)
123{
124 return (pageClass + 1) * smallPageSize;
125}
126} // namespace Sizes
127
128using namespace Sizes;
129
130} // namespace bmalloc
131
132#endif // Sizes_h
133