| OLD | NEW |
| 1 // Copyright 2014 Google Inc. All Rights Reserved. | 1 // Copyright 2014 Google Inc. All Rights Reserved. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 TEST(ZebraBlockHeapTest, AllocateEmptyBlock) { | 89 TEST(ZebraBlockHeapTest, AllocateEmptyBlock) { |
| 90 TestZebraBlockHeap h; | 90 TestZebraBlockHeap h; |
| 91 BlockLayout layout = {}; | 91 BlockLayout layout = {}; |
| 92 BlockInfo block = {}; | 92 BlockInfo block = {}; |
| 93 | 93 |
| 94 // Allocate and free a zero-sized allocation. This should succeed | 94 // Allocate and free a zero-sized allocation. This should succeed |
| 95 // by definition. | 95 // by definition. |
| 96 void* alloc = h.AllocateBlock(0, 0, 0, &layout); | 96 void* alloc = h.AllocateBlock(0, 0, 0, &layout); |
| 97 EXPECT_NE(reinterpret_cast<void*>(NULL), alloc); | 97 EXPECT_NE(reinterpret_cast<void*>(NULL), alloc); |
| 98 EXPECT_TRUE(IsAligned(alloc, kShadowRatio)); | 98 EXPECT_TRUE(IsAligned(alloc, kShadowRatio)); |
| 99 BlockInitialize(layout, alloc, false, &block); | 99 BlockInitialize(layout, alloc, &block); |
| 100 EXPECT_TRUE(h.FreeBlock(block)); | 100 EXPECT_TRUE(h.FreeBlock(block)); |
| 101 } | 101 } |
| 102 | 102 |
| 103 TEST(ZebraBlockHeapTest, EndToEnd) { | 103 TEST(ZebraBlockHeapTest, EndToEnd) { |
| 104 TestZebraBlockHeap h; | 104 TestZebraBlockHeap h; |
| 105 BlockLayout layout = {}; | 105 BlockLayout layout = {}; |
| 106 BlockInfo block = {}; | 106 BlockInfo block = {}; |
| 107 | 107 |
| 108 // Make a bunch of different sized allocations. | 108 // Make a bunch of different sized allocations. |
| 109 std::vector<BlockInfo> blocks; | 109 std::vector<BlockInfo> blocks; |
| 110 for (uint32_t i = 1; i < 100; i++) { | 110 for (uint32_t i = 1; i < 100; i++) { |
| 111 void* alloc = h.AllocateBlock(i, 0, 0, &layout); | 111 void* alloc = h.AllocateBlock(i, 0, 0, &layout); |
| 112 EXPECT_NE(reinterpret_cast<void*>(NULL), alloc); | 112 EXPECT_NE(reinterpret_cast<void*>(NULL), alloc); |
| 113 EXPECT_TRUE(IsAligned(alloc, kShadowRatio)); | 113 EXPECT_TRUE(IsAligned(alloc, kShadowRatio)); |
| 114 BlockInitialize(layout, alloc, false, &block); | 114 BlockInitialize(layout, alloc, &block); |
| 115 blocks.push_back(block); | 115 blocks.push_back(block); |
| 116 } | 116 } |
| 117 | 117 |
| 118 // Now free them. | 118 // Now free them. |
| 119 for (size_t i = 0; i < blocks.size(); ++i) | 119 for (size_t i = 0; i < blocks.size(); ++i) |
| 120 EXPECT_TRUE(h.FreeBlock(blocks[i])); | 120 EXPECT_TRUE(h.FreeBlock(blocks[i])); |
| 121 } | 121 } |
| 122 | 122 |
| 123 TEST(ZebraBlockHeapTest, BlocksHaveCorrectAlignment) { | 123 TEST(ZebraBlockHeapTest, BlocksHaveCorrectAlignment) { |
| 124 TestZebraBlockHeap h; | 124 TestZebraBlockHeap h; |
| 125 BlockLayout layout = {}; | 125 BlockLayout layout = {}; |
| 126 BlockInfo block = {}; | 126 BlockInfo block = {}; |
| 127 | 127 |
| 128 // Allocate blocks with different header, body and trailer sizes . | 128 // Allocate blocks with different header, body and trailer sizes . |
| 129 for (uint32_t header_size = 0; header_size < 100; header_size += 3) { | 129 for (uint32_t header_size = 0; header_size < 100; header_size += 3) { |
| 130 for (uint32_t trailer_size = 0; trailer_size < 100; trailer_size += 3) { | 130 for (uint32_t trailer_size = 0; trailer_size < 100; trailer_size += 3) { |
| 131 for (uint32_t body_size = 0; body_size < 100; body_size += 3) { | 131 for (uint32_t body_size = 0; body_size < 100; body_size += 3) { |
| 132 void* alloc = h.AllocateBlock(body_size, header_size, | 132 void* alloc = h.AllocateBlock(body_size, header_size, |
| 133 trailer_size, &layout); | 133 trailer_size, &layout); |
| 134 | 134 |
| 135 EXPECT_NE(reinterpret_cast<void*>(NULL), alloc); | 135 EXPECT_NE(reinterpret_cast<void*>(NULL), alloc); |
| 136 EXPECT_TRUE(IsAligned(alloc, kShadowRatio)); | 136 EXPECT_TRUE(IsAligned(alloc, kShadowRatio)); |
| 137 | 137 |
| 138 BlockInitialize(layout, alloc, false, &block); | 138 BlockInitialize(layout, alloc, &block); |
| 139 | 139 |
| 140 // The header (== block), body and the end of the trailer must be | 140 // The header (== block), body and the end of the trailer must be |
| 141 // kShadowRatio aligned. | 141 // kShadowRatio aligned. |
| 142 EXPECT_TRUE(IsAligned(block.body, kShadowRatio)); | 142 EXPECT_TRUE(IsAligned(block.body, kShadowRatio)); |
| 143 EXPECT_TRUE(IsAligned(block.header, kShadowRatio)); | 143 EXPECT_TRUE(IsAligned(block.header, kShadowRatio)); |
| 144 EXPECT_TRUE(IsAligned(block.header, GetPageSize())); | 144 EXPECT_TRUE(IsAligned(block.header, GetPageSize())); |
| 145 EXPECT_TRUE(IsAligned(block.trailer + 1, GetPageSize())); | 145 EXPECT_TRUE(IsAligned(block.trailer + 1, GetPageSize())); |
| 146 | 146 |
| 147 uint32_t right_redzone_size = block.TotalTrailerSize(); | 147 uint32_t right_redzone_size = block.TotalTrailerSize(); |
| 148 | 148 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 | 187 |
| 188 const uint32_t kMaxAllowedBlockSize = static_cast<uint32_t>(GetPageSize()) - | 188 const uint32_t kMaxAllowedBlockSize = static_cast<uint32_t>(GetPageSize()) - |
| 189 sizeof(BlockHeader); | 189 sizeof(BlockHeader); |
| 190 | 190 |
| 191 // Allocate all possible block sizes. | 191 // Allocate all possible block sizes. |
| 192 for (uint32_t i = 0; i <= kMaxAllowedBlockSize; ++i) { | 192 for (uint32_t i = 0; i <= kMaxAllowedBlockSize; ++i) { |
| 193 uint8_t* alloc = reinterpret_cast<uint8_t*>( | 193 uint8_t* alloc = reinterpret_cast<uint8_t*>( |
| 194 h.AllocateBlock(i, sizeof(BlockHeader), sizeof(BlockTrailer), &layout)); | 194 h.AllocateBlock(i, sizeof(BlockHeader), sizeof(BlockTrailer), &layout)); |
| 195 | 195 |
| 196 EXPECT_NE(reinterpret_cast<void*>(NULL), alloc); | 196 EXPECT_NE(reinterpret_cast<void*>(NULL), alloc); |
| 197 BlockInitialize(layout, alloc, false, &block); | 197 BlockInitialize(layout, alloc, &block); |
| 198 EXPECT_TRUE(h.FreeBlock(block)); | 198 EXPECT_TRUE(h.FreeBlock(block)); |
| 199 } | 199 } |
| 200 | 200 |
| 201 // Impossible block sizes. | 201 // Impossible block sizes. |
| 202 for (uint32_t delta = 1; delta < 10000; delta += 7) | 202 for (uint32_t delta = 1; delta < 10000; delta += 7) |
| 203 EXPECT_EQ(reinterpret_cast<uint8_t*>(NULL), | 203 EXPECT_EQ(reinterpret_cast<uint8_t*>(NULL), |
| 204 h.AllocateBlock(kMaxAllowedBlockSize + delta, sizeof(BlockHeader), | 204 h.AllocateBlock(kMaxAllowedBlockSize + delta, sizeof(BlockHeader), |
| 205 sizeof(BlockTrailer), &layout)); | 205 sizeof(BlockTrailer), &layout)); |
| 206 } | 206 } |
| 207 | 207 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 218 EXPECT_TRUE(IsAligned(mem1, kShadowRatio)); | 218 EXPECT_TRUE(IsAligned(mem1, kShadowRatio)); |
| 219 | 219 |
| 220 void* mem2 = h.AllocateBlock(0, sizeof(BlockHeader), sizeof(BlockTrailer), | 220 void* mem2 = h.AllocateBlock(0, sizeof(BlockHeader), sizeof(BlockTrailer), |
| 221 &layout2); | 221 &layout2); |
| 222 EXPECT_NE(reinterpret_cast<void*>(NULL), mem2); | 222 EXPECT_NE(reinterpret_cast<void*>(NULL), mem2); |
| 223 EXPECT_TRUE(IsAligned(mem2, kShadowRatio)); | 223 EXPECT_TRUE(IsAligned(mem2, kShadowRatio)); |
| 224 | 224 |
| 225 // Empty blocks cannot have the same address. | 225 // Empty blocks cannot have the same address. |
| 226 EXPECT_NE(mem1, mem2); | 226 EXPECT_NE(mem1, mem2); |
| 227 | 227 |
| 228 BlockInitialize(layout1, mem1, false, &block1); | 228 BlockInitialize(layout1, mem1, &block1); |
| 229 BlockInitialize(layout2, mem2, false, &block2); | 229 BlockInitialize(layout2, mem2, &block2); |
| 230 | 230 |
| 231 EXPECT_TRUE(h.FreeBlock(block1)); | 231 EXPECT_TRUE(h.FreeBlock(block1)); |
| 232 EXPECT_TRUE(h.FreeBlock(block2)); | 232 EXPECT_TRUE(h.FreeBlock(block2)); |
| 233 } | 233 } |
| 234 | 234 |
| 235 | 235 |
| 236 TEST(ZebraBlockHeapTest, AllocateUntilFull) { | 236 TEST(ZebraBlockHeapTest, AllocateUntilFull) { |
| 237 TestZebraBlockHeap h; | 237 TestZebraBlockHeap h; |
| 238 // Test maximum number of allocations. | 238 // Test maximum number of allocations. |
| 239 std::vector<uint8_t*> buffers; | 239 std::vector<uint8_t*> buffers; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 if (alloc != NULL) { | 358 if (alloc != NULL) { |
| 359 // Check that the block is well formed. | 359 // Check that the block is well formed. |
| 360 EXPECT_TRUE(header_size + body_size <= GetPageSize()); | 360 EXPECT_TRUE(header_size + body_size <= GetPageSize()); |
| 361 EXPECT_TRUE(trailer_size <= GetPageSize()); | 361 EXPECT_TRUE(trailer_size <= GetPageSize()); |
| 362 | 362 |
| 363 size_t body_end_offset = layout.header_size + | 363 size_t body_end_offset = layout.header_size + |
| 364 layout.header_padding_size + layout.body_size; | 364 layout.header_padding_size + layout.body_size; |
| 365 | 365 |
| 366 EXPECT_EQ(GetPageSize(), | 366 EXPECT_EQ(GetPageSize(), |
| 367 ::common::AlignUp(body_end_offset, kShadowRatio)); | 367 ::common::AlignUp(body_end_offset, kShadowRatio)); |
| 368 BlockInitialize(layout, alloc, false, &block); | 368 BlockInitialize(layout, alloc, &block); |
| 369 EXPECT_TRUE(h.FreeBlock(block)); | 369 EXPECT_TRUE(h.FreeBlock(block)); |
| 370 } else { | 370 } else { |
| 371 size_t body_end_offset = layout.header_size + | 371 size_t body_end_offset = layout.header_size + |
| 372 layout.header_padding_size + layout.body_size; | 372 layout.header_padding_size + layout.body_size; |
| 373 | 373 |
| 374 // Check the cause of the unsuccessful allocation. | 374 // Check the cause of the unsuccessful allocation. |
| 375 EXPECT_TRUE( | 375 EXPECT_TRUE( |
| 376 // Even page overflow. | 376 // Even page overflow. |
| 377 (header_size + body_size > GetPageSize()) || | 377 (header_size + body_size > GetPageSize()) || |
| 378 // Odd page overflow. | 378 // Odd page overflow. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 TestZebraBlockHeap h; | 412 TestZebraBlockHeap h; |
| 413 BlockLayout layout = {}; | 413 BlockLayout layout = {}; |
| 414 BlockInfo block = {}; | 414 BlockInfo block = {}; |
| 415 | 415 |
| 416 // Fill the heap. | 416 // Fill the heap. |
| 417 std::vector<BlockInfo> blocks; | 417 std::vector<BlockInfo> blocks; |
| 418 for (size_t i = 0; i < h.slab_count_; i++) { | 418 for (size_t i = 0; i < h.slab_count_; i++) { |
| 419 void* alloc = h.AllocateBlock(0xFF, 0, 0, &layout); | 419 void* alloc = h.AllocateBlock(0xFF, 0, 0, &layout); |
| 420 EXPECT_NE(reinterpret_cast<void*>(NULL), alloc); | 420 EXPECT_NE(reinterpret_cast<void*>(NULL), alloc); |
| 421 EXPECT_TRUE(IsAligned(alloc, kShadowRatio)); | 421 EXPECT_TRUE(IsAligned(alloc, kShadowRatio)); |
| 422 BlockInitialize(layout, alloc, false, &block); | 422 BlockInitialize(layout, alloc, &block); |
| 423 blocks.push_back(block); | 423 blocks.push_back(block); |
| 424 CompactBlockInfo compact = {}; | 424 CompactBlockInfo compact = {}; |
| 425 ConvertBlockInfo(block, &compact); | 425 ConvertBlockInfo(block, &compact); |
| 426 EXPECT_TRUE(h.Push(compact).push_successful); | 426 EXPECT_TRUE(h.Push(compact).push_successful); |
| 427 } | 427 } |
| 428 | 428 |
| 429 for (size_t i = 0; i < h.slab_count_; i++) { | 429 for (size_t i = 0; i < h.slab_count_; i++) { |
| 430 CompactBlockInfo dummy = {}; | 430 CompactBlockInfo dummy = {}; |
| 431 bool old_invariant = h.QuarantineInvariantIsSatisfied(); | 431 bool old_invariant = h.QuarantineInvariantIsSatisfied(); |
| 432 if (h.Pop(&dummy).pop_successful) { | 432 if (h.Pop(&dummy).pop_successful) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 | 469 |
| 470 h.Lock(); | 470 h.Lock(); |
| 471 EXPECT_TRUE(h.TryLock()); | 471 EXPECT_TRUE(h.TryLock()); |
| 472 h.Unlock(); | 472 h.Unlock(); |
| 473 h.Unlock(); | 473 h.Unlock(); |
| 474 } | 474 } |
| 475 | 475 |
| 476 } // namespace heaps | 476 } // namespace heaps |
| 477 } // namespace asan | 477 } // namespace asan |
| 478 } // namespace agent | 478 } // namespace agent |
| OLD | NEW |