[clang][extract-api] Emit "navigator" property of "name" in SymbolGraph
[llvm-project.git] / compiler-rt / lib / sanitizer_common / tests / sanitizer_quarantine_test.cpp
blobee0ac6abcc40ea59ba7b7e70ad789d3bbb2f984d
1 //===-- sanitizer_quarantine_test.cpp -------------------------------------===//
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 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
11 //===----------------------------------------------------------------------===//
12 #include "sanitizer_common/sanitizer_common.h"
13 #include "sanitizer_common/sanitizer_quarantine.h"
14 #include "gtest/gtest.h"
16 #include <stdlib.h>
18 namespace __sanitizer {
20 struct QuarantineCallback {
21 void Recycle(void *m) {}
22 void *Allocate(uptr size) {
23 return malloc(size);
25 void Deallocate(void *p) {
26 free(p);
30 typedef QuarantineCache<QuarantineCallback> Cache;
32 static void* kFakePtr = reinterpret_cast<void*>(0xFA83FA83);
33 static const size_t kBlockSize = 8;
35 static QuarantineCallback cb;
37 static void DeallocateCache(Cache *cache) {
38 while (QuarantineBatch *batch = cache->DequeueBatch())
39 cb.Deallocate(batch);
42 TEST(SanitizerCommon, QuarantineBatchMerge) {
43 // Verify the trivial case.
44 QuarantineBatch into;
45 into.init(kFakePtr, 4UL);
46 QuarantineBatch from;
47 from.init(kFakePtr, 8UL);
49 into.merge(&from);
51 ASSERT_EQ(into.count, 2UL);
52 ASSERT_EQ(into.batch[0], kFakePtr);
53 ASSERT_EQ(into.batch[1], kFakePtr);
54 ASSERT_EQ(into.size, 12UL + sizeof(QuarantineBatch));
55 ASSERT_EQ(into.quarantined_size(), 12UL);
57 ASSERT_EQ(from.count, 0UL);
58 ASSERT_EQ(from.size, sizeof(QuarantineBatch));
59 ASSERT_EQ(from.quarantined_size(), 0UL);
61 // Merge the batch to the limit.
62 for (uptr i = 2; i < QuarantineBatch::kSize; ++i)
63 from.push_back(kFakePtr, 8UL);
64 ASSERT_TRUE(into.count + from.count == QuarantineBatch::kSize);
65 ASSERT_TRUE(into.can_merge(&from));
67 into.merge(&from);
68 ASSERT_TRUE(into.count == QuarantineBatch::kSize);
70 // No more space, not even for one element.
71 from.init(kFakePtr, 8UL);
73 ASSERT_FALSE(into.can_merge(&from));
76 TEST(SanitizerCommon, QuarantineCacheMergeBatchesEmpty) {
77 Cache cache;
78 Cache to_deallocate;
79 cache.MergeBatches(&to_deallocate);
81 ASSERT_EQ(to_deallocate.Size(), 0UL);
82 ASSERT_EQ(to_deallocate.DequeueBatch(), nullptr);
85 TEST(SanitizerCommon, QuarantineCacheMergeBatchesOneBatch) {
86 Cache cache;
87 cache.Enqueue(cb, kFakePtr, kBlockSize);
88 ASSERT_EQ(kBlockSize + sizeof(QuarantineBatch), cache.Size());
90 Cache to_deallocate;
91 cache.MergeBatches(&to_deallocate);
93 // Nothing to merge, nothing to deallocate.
94 ASSERT_EQ(kBlockSize + sizeof(QuarantineBatch), cache.Size());
96 ASSERT_EQ(to_deallocate.Size(), 0UL);
97 ASSERT_EQ(to_deallocate.DequeueBatch(), nullptr);
99 DeallocateCache(&cache);
102 TEST(SanitizerCommon, QuarantineCacheMergeBatchesSmallBatches) {
103 // Make a cache with two batches small enough to merge.
104 Cache from;
105 from.Enqueue(cb, kFakePtr, kBlockSize);
106 Cache cache;
107 cache.Enqueue(cb, kFakePtr, kBlockSize);
109 cache.Transfer(&from);
110 ASSERT_EQ(kBlockSize * 2 + sizeof(QuarantineBatch) * 2, cache.Size());
112 Cache to_deallocate;
113 cache.MergeBatches(&to_deallocate);
115 // Batches merged, one batch to deallocate.
116 ASSERT_EQ(kBlockSize * 2 + sizeof(QuarantineBatch), cache.Size());
117 ASSERT_EQ(to_deallocate.Size(), sizeof(QuarantineBatch));
119 DeallocateCache(&cache);
120 DeallocateCache(&to_deallocate);
123 TEST(SanitizerCommon, QuarantineCacheMergeBatchesTooBigToMerge) {
124 const uptr kNumBlocks = QuarantineBatch::kSize - 1;
126 // Make a cache with two batches small enough to merge.
127 Cache from;
128 Cache cache;
129 for (uptr i = 0; i < kNumBlocks; ++i) {
130 from.Enqueue(cb, kFakePtr, kBlockSize);
131 cache.Enqueue(cb, kFakePtr, kBlockSize);
133 cache.Transfer(&from);
134 ASSERT_EQ(kBlockSize * kNumBlocks * 2 +
135 sizeof(QuarantineBatch) * 2, cache.Size());
137 Cache to_deallocate;
138 cache.MergeBatches(&to_deallocate);
140 // Batches cannot be merged.
141 ASSERT_EQ(kBlockSize * kNumBlocks * 2 +
142 sizeof(QuarantineBatch) * 2, cache.Size());
143 ASSERT_EQ(to_deallocate.Size(), 0UL);
145 DeallocateCache(&cache);
148 TEST(SanitizerCommon, QuarantineCacheMergeBatchesALotOfBatches) {
149 const uptr kNumBatchesAfterMerge = 3;
150 const uptr kNumBlocks = QuarantineBatch::kSize * kNumBatchesAfterMerge;
151 const uptr kNumBatchesBeforeMerge = kNumBlocks;
153 // Make a cache with many small batches.
154 Cache cache;
155 for (uptr i = 0; i < kNumBlocks; ++i) {
156 Cache from;
157 from.Enqueue(cb, kFakePtr, kBlockSize);
158 cache.Transfer(&from);
161 ASSERT_EQ(kBlockSize * kNumBlocks +
162 sizeof(QuarantineBatch) * kNumBatchesBeforeMerge, cache.Size());
164 Cache to_deallocate;
165 cache.MergeBatches(&to_deallocate);
167 // All blocks should fit into 3 batches.
168 ASSERT_EQ(kBlockSize * kNumBlocks +
169 sizeof(QuarantineBatch) * kNumBatchesAfterMerge, cache.Size());
171 ASSERT_EQ(to_deallocate.Size(),
172 sizeof(QuarantineBatch) *
173 (kNumBatchesBeforeMerge - kNumBatchesAfterMerge));
175 DeallocateCache(&cache);
176 DeallocateCache(&to_deallocate);
179 } // namespace __sanitizer