From cc401c1e5ba3a2286a77e846e8112410471c542f Mon Sep 17 00:00:00 2001 From: Janeczko Jakub <105227351+qbojj@users.noreply.github.com> Date: Wed, 31 Jan 2024 12:19:24 +0100 Subject: [PATCH] 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 --- oi/OITraceCode.cpp | 6 ++++-- types/cxx11_string_type.toml | 9 ++------- types/fb_string_type.toml | 4 +--- types/small_vec_type.toml | 11 +++-------- types/string_type.toml | 9 ++------- 5 files changed, 12 insertions(+), 27 deletions(-) diff --git a/oi/OITraceCode.cpp b/oi/OITraceCode.cpp index 362ce69..af99753 100644 --- a/oi/OITraceCode.cpp +++ b/oi/OITraceCode.cpp @@ -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 { diff --git a/types/cxx11_string_type.toml b/types/cxx11_string_type.toml index c88debd..fbf4788 100644 --- a/types/cxx11_string_type.toml +++ b/types/cxx11_string_type.toml @@ -28,10 +28,7 @@ void getSizeType(const %1% &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%))) - && - ((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))) && - ((uintptr_t)container.data() >= (uintptr_t)&container); + bool sso = isStorageInline(container); return returnArg.write(container.capacity()) .write(sso) diff --git a/types/fb_string_type.toml b/types/fb_string_type.toml index 169be87..c5c9ef5 100644 --- a/types/fb_string_type.toml +++ b/types/fb_string_type.toml @@ -25,9 +25,7 @@ void getSizeType(const %1% &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%))) - && - ((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)); diff --git a/types/small_vec_type.toml b/types/small_vec_type.toml index a5f1694..9f39677 100644 --- a/types/small_vec_type.toml +++ b/types/small_vec_type.toml @@ -22,8 +22,8 @@ void getSizeType(const %1% &container, size_t& returnArg) { SAVE_SIZE(sizeof(%1%)); - bool dataInlined = ((uintptr_t)container.data() >= (uintptr_t)&container) && - ((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%))); + 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% &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) diff --git a/types/string_type.toml b/types/string_type.toml index 0d2ab0d..c221da6 100644 --- a/types/string_type.toml +++ b/types/string_type.toml @@ -28,18 +28,13 @@ void getSizeType(const %1% &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%))) - && - ((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))) && - ((uintptr_t)container.data() >= (uintptr_t)&container); + bool sso = isStorageInline(container); return returnArg.write(container.capacity()) .write(sso)