elliotgoodrich / SSO-23

Memory optimal Small String Optimization implementation for C++
233 stars 8 forks source link

Alternative solution by using tagged pointer #3

Open phuclv90 opened 6 years ago

phuclv90 commented 6 years ago

Because new operator is

required to return a pointer suitably aligned to hold an object of any fundamental alignment.

the pointer to struct long's char array always have at least 4 low zero bits on a 64-bit OS (3 on a 32-bit OS) and we can take advantage of them to simplify the implementation with the use of tagged pointer

To do that on a big-endian system we just need to move the ptr field to the last position so that ptr's LSB is also the last byte of the struct in memory

struct long {
    size_type size;
    size_type capacity;
    CharT* ptr;
};

Now the least significant bit of ptr becomes a tag bit

notorand-it commented 4 months ago

This is neat. But it is guaranteed to work only when the buffer is allocated by malloc() (used by new operators). It fails if the field points to static data and, possibly, to stack area.

phuclv90 commented 4 months ago

This is neat. But it is guaranteed to work only when the buffer is allocated by malloc() (used by new operators). It fails if the field points to static data and, possibly, to stack area.

How can it point to stack area? The buffer is handled internally by the class by calling new, and just like all other allocations, the caller is required to specify the alignment if required, for example by using std::aligned_alloc if an alignment value larger than new is required. No external objects can modify the pointer to point to some other non-aligned userspace area. We can always specify the alignment because it's required for SIMD code

Or do you mean placement new? It's completely irrelevant to this because it affects the allocation of the object, not the buffer that the object points to