File: | projects/compiler-rt/lib/scudo/standalone/secondary.cc |
Warning: | line 55, column 16 Value stored to 'NewMapEnd' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- secondary.cc --------------------------------------------*- 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 (!MapBase) |
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 (AlignmentHint >= PageSize) { |
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 | SpinMutexLock L(&Mutex); |
76 | if (!Tail) { |
77 | Tail = H; |
78 | } else { |
79 | Tail->Next = H; |
80 | H->Prev = Tail; |
81 | Tail = H; |
82 | } |
83 | AllocatedBytes += CommitSize; |
84 | if (LargestSize < CommitSize) |
85 | LargestSize = CommitSize; |
86 | NumberOfAllocs++; |
87 | Stats.add(StatAllocated, CommitSize); |
88 | Stats.add(StatMapped, H->MapSize); |
89 | } |
90 | if (BlockEnd) |
91 | *BlockEnd = CommitBase + CommitSize; |
92 | return reinterpret_cast<void *>(Ptr + LargeBlock::getHeaderSize()); |
93 | } |
94 | |
95 | void MapAllocator::deallocate(void *Ptr) { |
96 | LargeBlock::Header *H = LargeBlock::getHeader(Ptr); |
97 | { |
98 | SpinMutexLock L(&Mutex); |
99 | LargeBlock::Header *Prev = H->Prev; |
100 | LargeBlock::Header *Next = H->Next; |
101 | if (Prev) { |
102 | 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-9~svn362543/projects/compiler-rt/lib/scudo/standalone/secondary.cc" , 102, "(" "(Prev->Next)" ") " "==" " (" "(H)" ")", V1, V2 ); die(); } } while (false); |
103 | Prev->Next = Next; |
104 | } |
105 | if (Next) { |
106 | 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-9~svn362543/projects/compiler-rt/lib/scudo/standalone/secondary.cc" , 106, "(" "(Next->Prev)" ") " "==" " (" "(H)" ")", V1, V2 ); die(); } } while (false); |
107 | Next->Prev = Prev; |
108 | } |
109 | if (Tail == H) { |
110 | CHECK(!Next)do { u64 V1 = (u64)((!Next)); u64 V2 = (u64)(0); if (__builtin_expect (!!(!(V1 != V2)), 0)) { reportCheckFailed("/build/llvm-toolchain-snapshot-9~svn362543/projects/compiler-rt/lib/scudo/standalone/secondary.cc" , 110, "(" "(!Next)" ") " "!=" " (" "0" ")", V1, V2); die(); } } while (false); |
111 | Tail = Prev; |
112 | } else { |
113 | CHECK(Next)do { u64 V1 = (u64)((Next)); u64 V2 = (u64)(0); if (__builtin_expect (!!(!(V1 != V2)), 0)) { reportCheckFailed("/build/llvm-toolchain-snapshot-9~svn362543/projects/compiler-rt/lib/scudo/standalone/secondary.cc" , 113, "(" "(Next)" ") " "!=" " (" "0" ")", V1, V2); die(); } } while (false); |
114 | } |
115 | const uptr CommitSize = H->BlockEnd - reinterpret_cast<uptr>(H); |
116 | FreedBytes += CommitSize; |
117 | NumberOfFrees++; |
118 | Stats.sub(StatAllocated, CommitSize); |
119 | Stats.sub(StatMapped, H->MapSize); |
120 | } |
121 | void *Addr = reinterpret_cast<void *>(H->MapBase); |
122 | const uptr Size = H->MapSize; |
123 | MapPlatformData Data; |
124 | Data = H->Data; |
125 | unmap(Addr, Size, UNMAP_ALL(1U << 0), &Data); |
126 | } |
127 | |
128 | void MapAllocator::printStats() const { |
129 | Printf("Stats: MapAllocator: allocated %zd times (%zdK), freed %zd times " |
130 | "(%zdK), remains %zd (%zdK) max %zdM\n", |
131 | NumberOfAllocs, AllocatedBytes >> 10, NumberOfFrees, FreedBytes >> 10, |
132 | NumberOfAllocs - NumberOfFrees, (AllocatedBytes - FreedBytes) >> 10, |
133 | LargestSize >> 20); |
134 | } |
135 | |
136 | } // namespace scudo |