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 | |
38 | namespace bmalloc { |
39 | |
40 | // Repository for malloc sizing constants and calculations. |
41 | |
42 | namespace Sizes { |
43 | static constexpr size_t kB = 1024; |
44 | static constexpr size_t MB = kB * kB; |
45 | static constexpr size_t GB = kB * kB * kB; |
46 | |
47 | static constexpr size_t alignment = 8; |
48 | static constexpr size_t alignmentMask = alignment - 1ul; |
49 | |
50 | static constexpr size_t chunkSize = 1 * MB; |
51 | static constexpr size_t chunkMask = ~(chunkSize - 1ul); |
52 | |
53 | static constexpr size_t smallLineSize = 256; |
54 | static constexpr size_t smallPageSize = 4 * kB; |
55 | static constexpr size_t smallPageLineCount = smallPageSize / smallLineSize; |
56 | |
57 | static constexpr size_t maskSizeClassMax = 512; |
58 | static constexpr size_t smallMax = 32 * kB; |
59 | |
60 | static constexpr size_t pageSizeMax = smallMax * 2; |
61 | static constexpr size_t pageClassCount = pageSizeMax / smallPageSize; |
62 | |
63 | static constexpr size_t pageSizeWasteFactor = 8; |
64 | static constexpr size_t logWasteFactor = 8; |
65 | |
66 | static constexpr size_t largeAlignment = smallMax / pageSizeWasteFactor; |
67 | static constexpr size_t largeAlignmentMask = largeAlignment - 1; |
68 | |
69 | static constexpr size_t deallocatorLogCapacity = 512; |
70 | static constexpr size_t bumpRangeCacheCapacity = 3; |
71 | |
72 | static constexpr size_t scavengerBytesPerMemoryPressureCheck = 16 * MB; |
73 | static constexpr double memoryPressureThreshold = 0.75; |
74 | |
75 | static constexpr size_t maskSizeClassCount = maskSizeClassMax / alignment; |
76 | |
77 | constexpr size_t maskSizeClass(size_t size) |
78 | { |
79 | // We mask to accommodate zero. |
80 | return mask((size - 1) / alignment, maskSizeClassCount - 1); |
81 | } |
82 | |
83 | inline size_t maskObjectSize(size_t maskSizeClass) |
84 | { |
85 | return (maskSizeClass + 1) * alignment; |
86 | } |
87 | |
88 | static constexpr size_t logAlignmentMin = maskSizeClassMax / logWasteFactor; |
89 | |
90 | static constexpr size_t logSizeClassCount = (log2(smallMax) - log2(maskSizeClassMax)) * logWasteFactor; |
91 | |
92 | inline 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 | |
99 | inline 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 | |
106 | static constexpr size_t sizeClassCount = maskSizeClassCount + logSizeClassCount; |
107 | |
108 | inline size_t sizeClass(size_t size) |
109 | { |
110 | if (size <= maskSizeClassMax) |
111 | return maskSizeClass(size); |
112 | return maskSizeClassCount + logSizeClass(size); |
113 | } |
114 | |
115 | inline size_t objectSize(size_t sizeClass) |
116 | { |
117 | if (sizeClass < maskSizeClassCount) |
118 | return maskObjectSize(sizeClass); |
119 | return logObjectSize(sizeClass - maskSizeClassCount); |
120 | } |
121 | |
122 | inline size_t pageSize(size_t pageClass) |
123 | { |
124 | return (pageClass + 1) * smallPageSize; |
125 | } |
126 | } // namespace Sizes |
127 | |
128 | using namespace Sizes; |
129 | |
130 | } // namespace bmalloc |
131 | |
132 | #endif // Sizes_h |
133 | |