Skip to content

Commit 9b129bb

Browse files
Pranav Bhandarifacebook-github-bot
Pranav Bhandari
authored andcommitted
use 5-byte compressed pointer in FreeList in AllocationClass
Summary: We set 5-byte compressed pointer as default when managing free allocations in this allocation class. This allows us to avoid templating this class which can lead to cascading templates which would make the codebase complex. Ran a canary with the change: https://www.internalfb.com/canvas/document/1516951625859179 Now can we warm roll this change? To know this we will look at the codepath that persists and loads the code back. 1. The list of allocation for an allocation class is stored as a SList. This is where we saveState() of an SList so that we can load it back up. https://www.internalfb.com/code/fbsource/[1cf1875e8c22]/fbcode/cachelib/allocator/datastruct/SList.h?lines=109. It converts a CompressedPointer to a int64_t to store as thrift object. 2. This int64_t that was serialized is read back here: https://www.internalfb.com/code/fbsource/[1cf1875e8c22]/fbcode/cachelib/allocator/datastruct/SList.h?lines=88. We have shown in the tests that if we persist with a 4-byte compressed pointer which will be stored as int64_t and read it back as a 5-byte compressed pointer, the value will be equivalent meaning both 4-byte and 5-byte compressed pointer will point to the same slab. Note that an item still uses the 4-byte compressed pointer so during serializing everything will be considered a 4-byte compressed pointer except for the list of allocations in AllocationClass. Reviewed By: haowu14 Differential Revision: D64539341 fbshipit-source-id: c141ace3655deed62f2c22bfaddbb2917ae2684a
1 parent fb50ef8 commit 9b129bb

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

cachelib/allocator/memory/AllocationClass.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ AllocationClass::AllocationClass(ClassId classId,
5151
allocationSize_(allocSize),
5252
slabAlloc_(s),
5353
freedAllocations_{
54-
slabAlloc_.createPtrCompressor<FreeAlloc, CompressedPtr4B>()} {
54+
slabAlloc_.createPtrCompressor<FreeAlloc, CompressedPtr5B>()} {
5555
checkState();
5656
}
5757

@@ -104,7 +104,7 @@ AllocationClass::AllocationClass(
104104
slabAlloc_(s),
105105
freedAllocations_(
106106
*object.freedAllocationsObject(),
107-
slabAlloc_.createPtrCompressor<FreeAlloc, CompressedPtr4B>()),
107+
slabAlloc_.createPtrCompressor<FreeAlloc, CompressedPtr5B>()),
108108
canAllocate_(*object.canAllocate()) {
109109
if (!slabAlloc_.isRestorable()) {
110110
throw std::logic_error("The allocation class cannot be restored.");
@@ -359,10 +359,10 @@ std::pair<bool, std::vector<void*>> AllocationClass::pruneFreeAllocs(
359359
// Set the bit to true if the corresponding allocation is freed, false
360360
// otherwise.
361361
FreeList freeAllocs{
362-
slabAlloc_.createPtrCompressor<FreeAlloc, CompressedPtr4B>()};
362+
slabAlloc_.createPtrCompressor<FreeAlloc, CompressedPtr5B>()};
363363
FreeList notInSlab{
364-
slabAlloc_.createPtrCompressor<FreeAlloc, CompressedPtr4B>()};
365-
FreeList inSlab{slabAlloc_.createPtrCompressor<FreeAlloc, CompressedPtr4B>()};
364+
slabAlloc_.createPtrCompressor<FreeAlloc, CompressedPtr5B>()};
365+
FreeList inSlab{slabAlloc_.createPtrCompressor<FreeAlloc, CompressedPtr5B>()};
366366

367367
lock_->lock_combine([&]() {
368368
// Take the allocation class free list offline

cachelib/allocator/memory/AllocationClass.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ class AllocationClass {
443443
// void* is re-interpreted as FreeAlloc* before being stored in the free
444444
// list.
445445
struct CACHELIB_PACKED_ATTR FreeAlloc {
446-
using CompressedPtrType = facebook::cachelib::CompressedPtr4B;
446+
using CompressedPtrType = facebook::cachelib::CompressedPtr5B;
447447
using PtrCompressor = facebook::cachelib::
448448
PtrCompressor<FreeAlloc, SlabAllocator, CompressedPtrType>;
449449
SListHook<FreeAlloc> hook_{};

cachelib/allocator/memory/tests/CompressedPtrTest.cpp

+37-5
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,48 @@ TEST_F(CompressedPtrTest, Compare) {
187187
// Both pointer should not be null
188188
ASSERT_FALSE((ptr.isNull()) || (ptr5b.isNull()));
189189

190+
// Both pointer should be able to read the serialized value and create
191+
// an equivalent compressed pointer.
192+
int64_t serialized4b = ptr.saveState();
193+
int64_t serialized5b = ptr5b.saveState();
194+
190195
// Both pointer types should return the same raw value when uncompressed
191-
ASSERT_EQ(ptr.getRaw(), ptr5b.getRaw());
196+
ASSERT_EQ(serialized4b, serialized5b);
192197

193-
// Both pointers should return the input value when compressed and
194-
// uncompressed immediately.
195-
ASSERT_EQ(alloc,
198+
// We load 4-byte with 5-byte serialized value and vice versa.
199+
CompressedPtr4B newPtr4b = CompressedPtr4B(serialized5b);
200+
CompressedPtr5B newPtr5b = CompressedPtr5B(serialized4b);
201+
202+
// Both compressed pointers when uncompressed should return the same
203+
// value even 4-byte compressed pointer is loaded with the value
204+
// of 5-byte compressed pointer when serialized and vice versa.
205+
ASSERT_EQ(
206+
m.unCompress<CompressedPtr5B>(newPtr5b, false /* isMultiTiered */),
207+
m.unCompress<CompressedPtr4B>(newPtr4b, false /* isMultiTiered */));
208+
209+
// All the pointer types should return the same value when uncompressed.
210+
ASSERT_EQ(m.unCompress<CompressedPtr5B>(ptr5b, false /* isMultiTiered */),
196211
m.unCompress<CompressedPtr4B>(ptr, false /* isMultiTiered */));
212+
213+
ASSERT_EQ(
214+
m.unCompress<CompressedPtr5B>(ptr5b, false /* isMultiTiered */),
215+
m.unCompress<CompressedPtr5B>(newPtr5b, false /* isMultiTiered */));
216+
217+
ASSERT_EQ(
218+
m.unCompress<CompressedPtr5B>(ptr5b, false /* isMultiTiered */),
219+
m.unCompress<CompressedPtr4B>(newPtr4b, false /* isMultiTiered */));
220+
197221
ASSERT_EQ(
198-
alloc,
222+
m.unCompress<CompressedPtr4B>(ptr, false /* isMultiTiered */),
223+
m.unCompress<CompressedPtr4B>(newPtr4b, false /* isMultiTiered */));
224+
225+
ASSERT_EQ(
226+
m.unCompress<CompressedPtr4B>(ptr, false /* isMultiTiered */),
199227
m.unCompress<CompressedPtr5B>(ptr5b, false /* isMultiTiered */));
228+
229+
ASSERT_EQ(
230+
m.unCompress<CompressedPtr4B>(ptr, false /* isMultiTiered */),
231+
m.unCompress<CompressedPtr5B>(newPtr5b, false /* isMultiTiered */));
200232
}
201233
}
202234

0 commit comments

Comments
 (0)