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 {};
bool isStorageInline(const auto& c) {
return (uintptr_t)std::data(c) < (uintptr_t)(&c + sizeof(c)) &&
(uintptr_t)std::data(c) >= (uintptr_t)&c;
uintptr_t data_p = (uintptr_t)std::data(c);
uintptr_t container_p = (uintptr_t)&c;
return data_p >= container_p && data_p < container_p + sizeof(c);
}
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
// contained within the string object.
SAVE_SIZE(
(((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<T>)))
&&
((uintptr_t)container.data() >= (uintptr_t)&container))
? 0 : (container.capacity() * sizeof(T))
isStorageInline(container) ? 0 : (container.capacity() * sizeof(T))
);
}
"""
@ -55,9 +52,7 @@ class CaptureKeyHandler<Ctx, std::__cxx11::basic_string<CharT, Traits, Allocator
"""
traversal_func = """
bool sso = ((uintptr_t)container.data() <
(uintptr_t)(&container + sizeof(std::__cxx11::basic_string<T0>))) &&
((uintptr_t)container.data() >= (uintptr_t)&container);
bool sso = isStorageInline(container);
return returnArg.write(container.capacity())
.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.size());
bool inlined = ((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<E, T, A, Storage>)))
&&
((uintptr_t)container.data() >= (uintptr_t)&container);
bool inlined = isStorageInline(container);
if (!inlined && ctx.pointers.add((uintptr_t)container.data())) {
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>));
bool dataInlined = ((uintptr_t)container.data() >= (uintptr_t)&container) &&
((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<V, N, P>)));
bool dataInlined = isStorageInline(container);
if (dataInlined) {
// Don't double count inlined elements
SAVE_SIZE(-(container.size() * sizeof(V)));
@ -43,12 +43,7 @@ void getSizeType(const %1%<V, N, P> &container, size_t& returnArg)
"""
traversal_func = """
// If `container.data()` pointer is within the container struct,
// 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));
bool uses_intern_storage = isStorageInline(container);
auto tail = returnArg
.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
// contained within the string object.
SAVE_SIZE(
((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<T>)))
&&
((uintptr_t)container.data() >= (uintptr_t)&container)
? 0 : (container.capacity() * sizeof(T))
isStorageInline(container) ? 0 : (container.capacity() * sizeof(T))
);
}
"""
traversal_func = """
bool sso = ((uintptr_t)container.data() <
(uintptr_t)(&container + sizeof(std::__cxx11::basic_string<T0>))) &&
((uintptr_t)container.data() >= (uintptr_t)&container);
bool sso = isStorageInline(container);
return returnArg.write(container.capacity())
.write(sso)