fix string type sso computation (#469)

* fix string type sso computation

* fix rest of sbo/sso calculation

* make placement of uintptr_t cast consistent

* separate check-inline into function
This commit is contained in:
Janeczko Jakub 2024-01-31 12:19:24 +01:00 committed by GitHub
parent b5b94ed236
commit cc401c1e5b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 12 additions and 27 deletions

View File

@ -185,8 +185,10 @@ struct validate_offset {
enum class StubbedPointer : uintptr_t {}; enum class StubbedPointer : uintptr_t {};
bool isStorageInline(const auto& c) { bool isStorageInline(const auto& c) {
return (uintptr_t)std::data(c) < (uintptr_t)(&c + sizeof(c)) && uintptr_t data_p = (uintptr_t)std::data(c);
(uintptr_t)std::data(c) >= (uintptr_t)&c; uintptr_t container_p = (uintptr_t)&c;
return data_p >= container_p && data_p < container_p + sizeof(c);
} }
namespace { namespace {

View File

@ -28,10 +28,7 @@ void getSizeType(const %1%<T, Traits, Allocator> &container, size_t& returnArg)
// Test for small string optimisation - whether the underlying string is // Test for small string optimisation - whether the underlying string is
// contained within the string object. // contained within the string object.
SAVE_SIZE( SAVE_SIZE(
(((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<T>))) isStorageInline(container) ? 0 : (container.capacity() * sizeof(T))
&&
((uintptr_t)container.data() >= (uintptr_t)&container))
? 0 : (container.capacity() * sizeof(T))
); );
} }
""" """
@ -55,9 +52,7 @@ class CaptureKeyHandler<Ctx, std::__cxx11::basic_string<CharT, Traits, Allocator
""" """
traversal_func = """ traversal_func = """
bool sso = ((uintptr_t)container.data() < bool sso = isStorageInline(container);
(uintptr_t)(&container + sizeof(std::__cxx11::basic_string<T0>))) &&
((uintptr_t)container.data() >= (uintptr_t)&container);
return returnArg.write(container.capacity()) return returnArg.write(container.capacity())
.write(sso) .write(sso)

View File

@ -25,9 +25,7 @@ void getSizeType(const %1%<E, T, A, Storage> &container, size_t& returnArg)
SAVE_DATA((uintptr_t)container.capacity()); SAVE_DATA((uintptr_t)container.capacity());
SAVE_DATA((uintptr_t)container.size()); SAVE_DATA((uintptr_t)container.size());
bool inlined = ((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<E, T, A, Storage>))) bool inlined = isStorageInline(container);
&&
((uintptr_t)container.data() >= (uintptr_t)&container);
if (!inlined && ctx.pointers.add((uintptr_t)container.data())) { if (!inlined && ctx.pointers.add((uintptr_t)container.data())) {
SAVE_SIZE(container.capacity() * sizeof(T)); SAVE_SIZE(container.capacity() * sizeof(T));

View File

@ -22,8 +22,8 @@ void getSizeType(const %1%<V, N, P> &container, size_t& returnArg)
{ {
SAVE_SIZE(sizeof(%1%<V, N, P>)); SAVE_SIZE(sizeof(%1%<V, N, P>));
bool dataInlined = ((uintptr_t)container.data() >= (uintptr_t)&container) && bool dataInlined = isStorageInline(container);
((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<V, N, P>)));
if (dataInlined) { if (dataInlined) {
// Don't double count inlined elements // Don't double count inlined elements
SAVE_SIZE(-(container.size() * sizeof(V))); SAVE_SIZE(-(container.size() * sizeof(V)));
@ -43,12 +43,7 @@ void getSizeType(const %1%<V, N, P> &container, size_t& returnArg)
""" """
traversal_func = """ traversal_func = """
// If `container.data()` pointer is within the container struct, bool uses_intern_storage = isStorageInline(container);
// then the container's storage is inlined and doesn't uses the heap.
// TODO: Is there an API to get this information?
bool uses_intern_storage =
(uintptr_t)&container <= (uintptr_t)container.data() &&
(uintptr_t)container.data() < ((uintptr_t)&container + sizeof(container));
auto tail = returnArg auto tail = returnArg
.write((uintptr_t)uses_intern_storage) .write((uintptr_t)uses_intern_storage)

View File

@ -28,18 +28,13 @@ void getSizeType(const %1%<T, Traits, Allocator> &container, size_t& returnArg)
// Test for small string optimisation - whether the underlying string is // Test for small string optimisation - whether the underlying string is
// contained within the string object. // contained within the string object.
SAVE_SIZE( SAVE_SIZE(
((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<T>))) isStorageInline(container) ? 0 : (container.capacity() * sizeof(T))
&&
((uintptr_t)container.data() >= (uintptr_t)&container)
? 0 : (container.capacity() * sizeof(T))
); );
} }
""" """
traversal_func = """ traversal_func = """
bool sso = ((uintptr_t)container.data() < bool sso = isStorageInline(container);
(uintptr_t)(&container + sizeof(std::__cxx11::basic_string<T0>))) &&
((uintptr_t)container.data() >= (uintptr_t)&container);
return returnArg.write(container.capacity()) return returnArg.write(container.capacity())
.write(sso) .write(sso)