| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 | 48 |
| 49 #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 49 #if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
| 50 | 50 |
| 51 namespace { | 51 namespace { |
| 52 | 52 |
| 53 static const size_t kTestMaxAllocation = 4096; | 53 static const size_t kTestMaxAllocation = 4096; |
| 54 static SizeSpecificPartitionAllocator<kTestMaxAllocation> allocator; | 54 static SizeSpecificPartitionAllocator<kTestMaxAllocation> allocator; |
| 55 static PartitionAllocatorGeneric genericAllocator; | 55 static PartitionAllocatorGeneric genericAllocator; |
| 56 | 56 |
| 57 static const size_t kTestAllocSize = 16; | 57 static const size_t kTestAllocSize = 16; |
| 58 #ifdef NDEBUG | 58 #if !ENABLE(ASSERT) |
| 59 static const size_t kPointerOffset = 0; | 59 static const size_t kPointerOffset = 0; |
| 60 static const size_t kExtraAllocSize = 0; | 60 static const size_t kExtraAllocSize = 0; |
| 61 #else | 61 #else |
| 62 static const size_t kPointerOffset = WTF::kCookieSize; | 62 static const size_t kPointerOffset = WTF::kCookieSize; |
| 63 static const size_t kExtraAllocSize = WTF::kCookieSize * 2; | 63 static const size_t kExtraAllocSize = WTF::kCookieSize * 2; |
| 64 #endif | 64 #endif |
| 65 static const size_t kRealAllocSize = kTestAllocSize + kExtraAllocSize; | 65 static const size_t kRealAllocSize = kTestAllocSize + kExtraAllocSize; |
| 66 static const size_t kTestBucketIndex = kRealAllocSize >> WTF::kBucketShift; | 66 static const size_t kTestBucketIndex = kRealAllocSize >> WTF::kBucketShift; |
| 67 | 67 |
| 68 static void TestSetup() | 68 static void TestSetup() |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 EXPECT_EQ(ptr, newPtr); | 447 EXPECT_EQ(ptr, newPtr); |
| 448 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGeneric
SmallestBucket); | 448 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGeneric
SmallestBucket); |
| 449 EXPECT_EQ(ptr, newPtr); | 449 EXPECT_EQ(ptr, newPtr); |
| 450 | 450 |
| 451 // Change the size of the realloc, switching buckets. | 451 // Change the size of the realloc, switching buckets. |
| 452 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGeneric
SmallestBucket + 1); | 452 newPtr = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGeneric
SmallestBucket + 1); |
| 453 EXPECT_NE(newPtr, ptr); | 453 EXPECT_NE(newPtr, ptr); |
| 454 // Check that the realloc copied correctly. | 454 // Check that the realloc copied correctly. |
| 455 char* newCharPtr = static_cast<char*>(newPtr); | 455 char* newCharPtr = static_cast<char*>(newPtr); |
| 456 EXPECT_EQ(*newCharPtr, 'A'); | 456 EXPECT_EQ(*newCharPtr, 'A'); |
| 457 #ifndef NDEBUG | 457 #if ENABLE(ASSERT) |
| 458 // Subtle: this checks for an old bug where we copied too much from the | 458 // Subtle: this checks for an old bug where we copied too much from the |
| 459 // source of the realloc. The condition can be detected by a trashing of | 459 // source of the realloc. The condition can be detected by a trashing of |
| 460 // the uninitialized value in the space of the upsized allocation. | 460 // the uninitialized value in the space of the upsized allocation. |
| 461 EXPECT_EQ(WTF::kUninitializedByte, static_cast<unsigned char>(*(newCharPtr +
WTF::kGenericSmallestBucket))); | 461 EXPECT_EQ(WTF::kUninitializedByte, static_cast<unsigned char>(*(newCharPtr +
WTF::kGenericSmallestBucket))); |
| 462 #endif | 462 #endif |
| 463 *newCharPtr = 'B'; | 463 *newCharPtr = 'B'; |
| 464 // The realloc moved. To check that the old allocation was freed, we can | 464 // The realloc moved. To check that the old allocation was freed, we can |
| 465 // do an alloc of the old allocation size and check that the old allocation | 465 // do an alloc of the old allocation size and check that the old allocation |
| 466 // address is at the head of the freelist and reused. | 466 // address is at the head of the freelist and reused. |
| 467 void* reusedPtr = partitionAllocGeneric(genericAllocator.root(), 1); | 467 void* reusedPtr = partitionAllocGeneric(genericAllocator.root(), 1); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 partitionFreeGeneric(genericAllocator.root(), ptr3); | 550 partitionFreeGeneric(genericAllocator.root(), ptr3); |
| 551 partitionFreeGeneric(genericAllocator.root(), ptr2); | 551 partitionFreeGeneric(genericAllocator.root(), ptr2); |
| 552 // Should be freeable at this point. | 552 // Should be freeable at this point. |
| 553 EXPECT_NE(-1, page->freeCacheIndex); | 553 EXPECT_NE(-1, page->freeCacheIndex); |
| 554 EXPECT_EQ(0, page->numAllocatedSlots); | 554 EXPECT_EQ(0, page->numAllocatedSlots); |
| 555 EXPECT_EQ(0, page->numUnprovisionedSlots); | 555 EXPECT_EQ(0, page->numUnprovisionedSlots); |
| 556 void* newPtr = partitionAllocGeneric(genericAllocator.root(), size); | 556 void* newPtr = partitionAllocGeneric(genericAllocator.root(), size); |
| 557 EXPECT_EQ(ptr3, newPtr); | 557 EXPECT_EQ(ptr3, newPtr); |
| 558 newPtr = partitionAllocGeneric(genericAllocator.root(), size); | 558 newPtr = partitionAllocGeneric(genericAllocator.root(), size); |
| 559 EXPECT_EQ(ptr2, newPtr); | 559 EXPECT_EQ(ptr2, newPtr); |
| 560 #if OS(LINUX) && defined(NDEBUG) | 560 #if OS(LINUX) && !ENABLE(ASSERT) |
| 561 // On Linux, we have a guarantee that freelisting a page should cause its | 561 // On Linux, we have a guarantee that freelisting a page should cause its |
| 562 // contents to be nulled out. We check for null here to detect an bug we | 562 // contents to be nulled out. We check for null here to detect an bug we |
| 563 // had where a large slot size was causing us to not properly free all | 563 // had where a large slot size was causing us to not properly free all |
| 564 // resources back to the system. | 564 // resources back to the system. |
| 565 // We only run the check in optimized builds because the debug build | 565 // We only run the check when asserts are disabled because when they are |
| 566 // writes over the allocated area with an "uninitialized" byte pattern. | 566 // enabled, the allocated area is overwritten with an "uninitialized" |
| 567 // byte pattern. |
| 567 EXPECT_EQ(0, *(reinterpret_cast<char*>(newPtr) + (size - 1))); | 568 EXPECT_EQ(0, *(reinterpret_cast<char*>(newPtr) + (size - 1))); |
| 568 #endif | 569 #endif |
| 569 partitionFreeGeneric(genericAllocator.root(), newPtr); | 570 partitionFreeGeneric(genericAllocator.root(), newPtr); |
| 570 partitionFreeGeneric(genericAllocator.root(), ptr3); | 571 partitionFreeGeneric(genericAllocator.root(), ptr3); |
| 571 partitionFreeGeneric(genericAllocator.root(), ptr4); | 572 partitionFreeGeneric(genericAllocator.root(), ptr4); |
| 572 | 573 |
| 573 // Can we allocate a massive (512MB) size? | 574 // Can we allocate a massive (512MB) size? |
| 574 ptr = partitionAllocGeneric(genericAllocator.root(), 512 * 1024 * 1024); | 575 ptr = partitionAllocGeneric(genericAllocator.root(), 512 * 1024 * 1024); |
| 575 partitionFreeGeneric(genericAllocator.root(), ptr); | 576 partitionFreeGeneric(genericAllocator.root(), ptr); |
| 576 | 577 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 // old allocation. | 675 // old allocation. |
| 675 size_t size = WTF::kSystemPageSize - kExtraAllocSize; | 676 size_t size = WTF::kSystemPageSize - kExtraAllocSize; |
| 676 EXPECT_EQ(size, partitionAllocActualSize(genericAllocator.root(), size)); | 677 EXPECT_EQ(size, partitionAllocActualSize(genericAllocator.root(), size)); |
| 677 ptr = partitionAllocGeneric(genericAllocator.root(), size); | 678 ptr = partitionAllocGeneric(genericAllocator.root(), size); |
| 678 memset(ptr, 'A', size); | 679 memset(ptr, 'A', size); |
| 679 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, size + 1); | 680 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, size + 1); |
| 680 EXPECT_NE(ptr, ptr2); | 681 EXPECT_NE(ptr, ptr2); |
| 681 char* charPtr2 = static_cast<char*>(ptr2); | 682 char* charPtr2 = static_cast<char*>(ptr2); |
| 682 EXPECT_EQ('A', charPtr2[0]); | 683 EXPECT_EQ('A', charPtr2[0]); |
| 683 EXPECT_EQ('A', charPtr2[size - 1]); | 684 EXPECT_EQ('A', charPtr2[size - 1]); |
| 684 #ifndef NDEBUG | 685 #if ENABLE(ASSERT) |
| 685 EXPECT_EQ(WTF::kUninitializedByte, static_cast<unsigned char>(charPtr2[size]
)); | 686 EXPECT_EQ(WTF::kUninitializedByte, static_cast<unsigned char>(charPtr2[size]
)); |
| 686 #endif | 687 #endif |
| 687 | 688 |
| 688 // Test that shrinking an allocation with realloc() also copies everything | 689 // Test that shrinking an allocation with realloc() also copies everything |
| 689 // from the old allocation. | 690 // from the old allocation. |
| 690 ptr = partitionReallocGeneric(genericAllocator.root(), ptr2, size - 1); | 691 ptr = partitionReallocGeneric(genericAllocator.root(), ptr2, size - 1); |
| 691 EXPECT_NE(ptr2, ptr); | 692 EXPECT_NE(ptr2, ptr); |
| 692 char* charPtr = static_cast<char*>(ptr); | 693 char* charPtr = static_cast<char*>(ptr); |
| 693 EXPECT_EQ('A', charPtr[0]); | 694 EXPECT_EQ('A', charPtr[0]); |
| 694 EXPECT_EQ('A', charPtr[size - 2]); | 695 EXPECT_EQ('A', charPtr[size - 2]); |
| 695 #ifndef NDEBUG | 696 #if ENABLE(ASSERT) |
| 696 EXPECT_EQ(WTF::kUninitializedByte, static_cast<unsigned char>(charPtr[size -
1])); | 697 EXPECT_EQ(WTF::kUninitializedByte, static_cast<unsigned char>(charPtr[size -
1])); |
| 697 #endif | 698 #endif |
| 698 | 699 |
| 699 partitionFreeGeneric(genericAllocator.root(), ptr); | 700 partitionFreeGeneric(genericAllocator.root(), ptr); |
| 700 | 701 |
| 701 // Test that shrinking a direct mapped allocation happens in-place. | 702 // Test that shrinking a direct mapped allocation happens in-place. |
| 702 size = WTF::kGenericMaxBucketed + 16 * WTF::kSystemPageSize; | 703 size = WTF::kGenericMaxBucketed + 16 * WTF::kSystemPageSize; |
| 703 ptr = partitionAllocGeneric(genericAllocator.root(), size); | 704 ptr = partitionAllocGeneric(genericAllocator.root(), size); |
| 704 size_t actualSize = partitionAllocGetSize(ptr); | 705 size_t actualSize = partitionAllocGetSize(ptr); |
| 705 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGenericMa
xBucketed + 8 * WTF::kSystemPageSize); | 706 ptr2 = partitionReallocGeneric(genericAllocator.root(), ptr, WTF::kGenericMa
xBucketed + 8 * WTF::kSystemPageSize); |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 EXPECT_EQ(32u, WTF::countLeadingZerosSizet(0u)); | 1189 EXPECT_EQ(32u, WTF::countLeadingZerosSizet(0u)); |
| 1189 EXPECT_EQ(31u, WTF::countLeadingZerosSizet(1u)); | 1190 EXPECT_EQ(31u, WTF::countLeadingZerosSizet(1u)); |
| 1190 EXPECT_EQ(1u, WTF::countLeadingZerosSizet(1u << 30)); | 1191 EXPECT_EQ(1u, WTF::countLeadingZerosSizet(1u << 30)); |
| 1191 EXPECT_EQ(0u, WTF::countLeadingZerosSizet(1u << 31)); | 1192 EXPECT_EQ(0u, WTF::countLeadingZerosSizet(1u << 31)); |
| 1192 #endif | 1193 #endif |
| 1193 } | 1194 } |
| 1194 | 1195 |
| 1195 } // namespace | 1196 } // namespace |
| 1196 | 1197 |
| 1197 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 1198 #endif // !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
| OLD | NEW |