File: | projects/compiler-rt/lib/scudo/standalone/secondary.cpp |
Warning: | line 55, column 16 Value stored to 'NewMapEnd' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- secondary.cpp -------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "secondary.h" |
10 | |
11 | #include "string_utils.h" |
12 | |
13 | namespace scudo { |
14 | |
15 | // As with the Primary, the size passed to this function includes any desired |
16 | // alignment, so that the frontend can align the user allocation. The hint |
17 | // parameter allows us to unmap spurious memory when dealing with larger |
18 | // (greater than a page) alignments on 32-bit platforms. |
19 | // Due to the sparsity of address space available on those platforms, requesting |
20 | // an allocation from the Secondary with a large alignment would end up wasting |
21 | // VA space (even though we are not committing the whole thing), hence the need |
22 | // to trim off some of the reserved space. |
23 | // For allocations requested with an alignment greater than or equal to a page, |
24 | // the committed memory will amount to something close to Size - AlignmentHint |
25 | // (pending rounding and headers). |
26 | void *MapAllocator::allocate(uptr Size, uptr AlignmentHint, uptr *BlockEnd) { |
27 | DCHECK_GT(Size, AlignmentHint); |
28 | const uptr PageSize = getPageSizeCached(); |
29 | const uptr MapSize = |
30 | roundUpTo(Size + LargeBlock::getHeaderSize(), PageSize) + 2 * PageSize; |
31 | MapPlatformData Data = {}; |
32 | uptr MapBase = |
33 | reinterpret_cast<uptr>(map(nullptr, MapSize, "scudo:secondary", |
34 | MAP_NOACCESS(1U << 1) | MAP_ALLOWNOMEM(1U << 0), &Data)); |
35 | if (UNLIKELY(!MapBase)__builtin_expect(!!(!MapBase), 0)) |
36 | return nullptr; |
37 | uptr CommitBase = MapBase + PageSize; |
38 | uptr MapEnd = MapBase + MapSize; |
39 | |
40 | // In the unlikely event of alignments larger than a page, adjust the amount |
41 | // of memory we want to commit, and trim the extra memory. |
42 | if (UNLIKELY(AlignmentHint >= PageSize)__builtin_expect(!!(AlignmentHint >= PageSize), 0)) { |
43 | // For alignments greater than or equal to a page, the user pointer (eg: the |
44 | // pointer that is returned by the C or C++ allocation APIs) ends up on a |
45 | // page boundary , and our headers will live in the preceding page. |
46 | CommitBase = roundUpTo(MapBase + PageSize + 1, AlignmentHint) - PageSize; |
47 | const uptr NewMapBase = CommitBase - PageSize; |
48 | DCHECK_GE(NewMapBase, MapBase); |
49 | // We only trim the extra memory on 32-bit platforms: 64-bit platforms |
50 | // are less constrained memory wise, and that saves us two syscalls. |
51 | if (SCUDO_WORDSIZE64U == 32U && NewMapBase != MapBase) { |
52 | unmap(reinterpret_cast<void *>(MapBase), NewMapBase - MapBase, 0, &Data); |
53 | MapBase = NewMapBase; |
54 | } |
55 | const uptr NewMapEnd = CommitBase + PageSize + |
Value stored to 'NewMapEnd' during its initialization is never read | |
56 | roundUpTo((Size - AlignmentHint), PageSize) + |
57 | PageSize; |
58 | DCHECK_LE(NewMapEnd, MapEnd); |
59 | if (SCUDO_WORDSIZE64U == 32U && NewMapEnd != MapEnd) { |
60 | unmap(reinterpret_cast<void *>(NewMapEnd), MapEnd - NewMapEnd, 0, &Data); |
61 | MapEnd = NewMapEnd; |
62 | } |
63 | } |
64 | |
65 | const uptr CommitSize = MapEnd - PageSize - CommitBase; |
66 | const uptr Ptr = |
67 | reinterpret_cast<uptr>(map(reinterpret_cast<void *>(CommitBase), |
68 | CommitSize, "scudo:secondary", 0, &Data)); |
69 | LargeBlock::Header *H = reinterpret_cast<LargeBlock::Header *>(Ptr); |
70 | H->MapBase = MapBase; |
71 | H->MapSize = MapEnd - MapBase; |
72 | H->BlockEnd = CommitBase + CommitSize; |
73 | H->Data = Data; |
74 | { |
75 | ScopedLock L(Mutex); |
76 | if (LIKELY(Tail)__builtin_expect(!!(Tail), 1)) { |
77 | Tail->Next = H; |
78 | H->Prev = Tail; |
79 | } |
80 | Tail = H; |
81 | AllocatedBytes += CommitSize; |
82 | if (LargestSize < CommitSize) |
83 | LargestSize = CommitSize; |
84 | NumberOfAllocs++; |
85 | Stats.add(StatAllocated, CommitSize); |
86 | Stats.add(StatMapped, H->MapSize); |
87 | } |
88 | if (BlockEnd) |
89 | *BlockEnd = CommitBase + CommitSize; |
90 | return reinterpret_cast<void *>(Ptr + LargeBlock::getHeaderSize()); |
91 | } |
92 | |
93 | void MapAllocator::deallocate(void *Ptr) { |
94 | LargeBlock::Header *H = LargeBlock::getHeader(Ptr); |
95 | { |
96 | ScopedLock L(Mutex); |
97 | LargeBlock::Header *Prev = H->Prev; |
98 | LargeBlock::Header *Next = H->Next; |
99 | if (Prev) { |
100 | CHECK_EQ(Prev->Next, H)do { u64 V1 = (u64)((Prev->Next)); u64 V2 = (u64)((H)); if (__builtin_expect(!!(!(V1 == V2)), 0)) { reportCheckFailed("/build/llvm-toolchain-snapshot-10~svn374877/projects/compiler-rt/lib/scudo/standalone/secondary.cpp" , 100, "(" "(Prev->Next)" ") " "==" " (" "(H)" ")", V1, V2 ); die(); } } while (false); |
101 | Prev->Next = Next; |
102 | } |
103 | if (Next) { |
104 | CHECK_EQ(Next->Prev, H)do { u64 V1 = (u64)((Next->Prev)); u64 V2 = (u64)((H)); if (__builtin_expect(!!(!(V1 == V2)), 0)) { reportCheckFailed("/build/llvm-toolchain-snapshot-10~svn374877/projects/compiler-rt/lib/scudo/standalone/secondary.cpp" , 104, "(" "(Next->Prev)" ") " "==" " (" "(H)" ")", V1, V2 ); die(); } } while (false); |
105 | Next->Prev = Prev; |
106 | } |
107 | if (UNLIKELY(Tail == H)__builtin_expect(!!(Tail == H), 0)) { |
108 | CHECK(!Next)do { u64 V1 = (u64)((!Next)); u64 V2 = (u64)(0); if (__builtin_expect (!!(!(V1 != V2)), 0)) { reportCheckFailed("/build/llvm-toolchain-snapshot-10~svn374877/projects/compiler-rt/lib/scudo/standalone/secondary.cpp" , 108, "(" "(!Next)" ") " "!=" " (" "0" ")", V1, V2); die(); } } while (false); |
109 | Tail = Prev; |
110 | } else { |
111 | CHECK(Next)do { u64 V1 = (u64)((Next)); u64 V2 = (u64)(0); if (__builtin_expect (!!(!(V1 != V2)), 0)) { reportCheckFailed("/build/llvm-toolchain-snapshot-10~svn374877/projects/compiler-rt/lib/scudo/standalone/secondary.cpp" , 111, "(" "(Next)" ") " "!=" " (" "0" ")", V1, V2); die(); } } while (false); |
112 | } |
113 | const uptr CommitSize = H->BlockEnd - reinterpret_cast<uptr>(H); |
114 | FreedBytes += CommitSize; |
115 | NumberOfFrees++; |
116 | Stats.sub(StatAllocated, CommitSize); |
117 | Stats.sub(StatMapped, H->MapSize); |
118 | } |
119 | void *Addr = reinterpret_cast<void *>(H->MapBase); |
120 | const uptr Size = H->MapSize; |
121 | MapPlatformData Data; |
122 | Data = H->Data; |
123 | unmap(Addr, Size, UNMAP_ALL(1U << 0), &Data); |
124 | } |
125 | |
126 | void MapAllocator::getStats(ScopedString *Str) const { |
127 | Str->append( |
128 | "Stats: MapAllocator: allocated %zu times (%zuK), freed %zu times " |
129 | "(%zuK), remains %zu (%zuK) max %zuM\n", |
130 | NumberOfAllocs, AllocatedBytes >> 10, NumberOfFrees, FreedBytes >> 10, |
131 | NumberOfAllocs - NumberOfFrees, (AllocatedBytes - FreedBytes) >> 10, |
132 | LargestSize >> 20); |
133 | } |
134 | |
135 | } // namespace scudo |