From 45cbee7c0e45c952aa99b2d924a6649e8d5427ae Mon Sep 17 00:00:00 2001 From: Aleksandar Fabijanic Date: Mon, 18 Apr 2022 14:28:27 -0500 Subject: [PATCH] refactor(Placeholder): ifdef POCO_NO_SOO only in Placeholder and remove it anywhere else (#3566) --- .github/workflows/ci.yml | 11 ++ Foundation/include/Poco/Any.h | 199 +++++--------------- Foundation/include/Poco/Config.h | 2 +- Foundation/include/Poco/Dynamic/Var.h | 37 ---- Foundation/include/Poco/Dynamic/VarHolder.h | 8 - Foundation/src/Var.cpp | 33 +--- configure | 7 + 7 files changed, 65 insertions(+), 232 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8e73a280..71e006d6b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,17 @@ jobs: EXCLUDE_TESTS="Data/MySQL Data/ODBC Data/PostgreSQL MongoDB" ./ci/runtests.sh + linux-gcc-make-asan-no-soo: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - run: sudo apt update && sudo apt install libssl-dev unixodbc-dev libmysqlclient-dev redis-server + - run: ./configure --everything --omit=PDF --no-soo && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install + - run: >- + sudo -s + EXCLUDE_TESTS="Data/MySQL Data/ODBC Data/PostgreSQL MongoDB" + ./ci/runtests.sh + linux-gcc-make-ubsan: runs-on: ubuntu-20.04 steps: diff --git a/Foundation/include/Poco/Any.h b/Foundation/include/Poco/Any.h index 165b8a3ff..a3d3e3679 100644 --- a/Foundation/include/Poco/Any.h +++ b/Foundation/include/Poco/Any.h @@ -48,9 +48,6 @@ struct TypeSizeGT: std::integral_constant S)>{}; -#ifndef POCO_NO_SOO - - template union Placeholder /// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small @@ -73,6 +70,8 @@ public: Placeholder& operator=(const Placeholder&) = delete; Placeholder& operator=(Placeholder&&) = delete; +#ifndef POCO_NO_SOO + Placeholder(): pHolder(0) { std::memset(holder, 0, sizeof(Placeholder)); @@ -154,51 +153,62 @@ private: } } - PlaceholderT* pHolder; mutable unsigned char holder[SizeV+1]; AlignerType aligner; -}; +#else // POCO_NO_SOO -#else // !POCO_NO_SOO - - -template -union Placeholder - /// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small - /// object optimization, when enabled). - /// - /// If Holder fits into POCO_SMALL_OBJECT_SIZE bytes of storage, - /// it will be placement-new-allocated into the local buffer - /// (i.e. there will be no heap-allocation). The local buffer size is one byte - /// larger - [POCO_SMALL_OBJECT_SIZE + 1], additional byte value indicating - /// where the object was allocated (0 => heap, 1 => local). -{ -public: - Placeholder () + Placeholder(): pHolder(0) { } + ~Placeholder() + { + delete pHolder; + } + + void swap(Placeholder& other) + { + std::swap(pHolder, other.pHolder); + } + + void erase() + { + delete pHolder; + pHolder = 0; + } + + bool isEmpty() const + { + return 0 == pHolder; + } + + bool isLocal() const + { + return false; + } + + template + PlaceholderT* assignStack(const V& value) + { + return assignHeap(value); + } + + template + PlaceholderT* assignHeap(const V& value) + { + erase(); + return pHolder = new T(value); + } + PlaceholderT* content() const { return pHolder; } -// MSVC71,80 won't extend friendship to nested class (Any::Holder) -#if !defined(POCO_MSVC_VERSION) || (defined(POCO_MSVC_VERSION) && (POCO_MSVC_VERSION > 80)) -private: -#endif - - PlaceholderT* pHolder; - - friend class Any; - friend class Dynamic::Var; - friend class Dynamic::VarHolder; - template friend class Dynamic::VarHolderImpl; -}; - - #endif // POCO_NO_SOO + PlaceholderT* pHolder; +}; class Any @@ -213,8 +223,6 @@ class Any { public: -#ifndef POCO_NO_SOO - Any() /// Creates an empty any type. { @@ -391,123 +399,6 @@ private: Placeholder _valueHolder; - -#else // if POCO_NO_SOO - - - Any(): _pHolder(0) - /// Creates an empty any type. - { - } - - template - Any(const ValueType& value): - _pHolder(new Holder(value)) - /// Creates an any which stores the init parameter inside. - /// - /// Example: - /// Any a(13); - /// Any a(string("12345")); - { - } - - Any(const Any& other): - _pHolder(other._pHolder ? other._pHolder->clone() : 0) - /// Copy constructor, works with both empty and initialized Any values. - { - } - - ~Any() - { - delete _pHolder; - } - - Any& swap(Any& rhs) - /// Swaps the content of the two Anys. - { - std::swap(_pHolder, rhs._pHolder); - return *this; - } - - template - Any& operator = (const ValueType& rhs) - /// Assignment operator for all types != Any. - /// - /// Example: - /// Any a = 13; - /// Any a = string("12345"); - { - Any(rhs).swap(*this); - return *this; - } - - Any& operator = (const Any& rhs) - /// Assignment operator for Any. - { - Any(rhs).swap(*this); - return *this; - } - - bool empty() const - /// Returns true if the Any is empty. - { - return !_pHolder; - } - - const std::type_info& type() const - /// Returns the type information of the stored content. - /// If the Any is empty typeid(void) is returned. - /// It is recommended to always query an Any for its type info before - /// trying to extract data via an AnyCast/RefAnyCast. - { - return _pHolder ? _pHolder->type() : typeid(void); - } - -private: - class ValueHolder - { - public: - virtual ~ValueHolder() = default; - - virtual const std::type_info& type() const = 0; - virtual ValueHolder* clone() const = 0; - }; - - template - class Holder: public ValueHolder - { - public: - Holder(const ValueType& value): - _held(value) - { - } - - virtual const std::type_info& type() const - { - return typeid(ValueType); - } - - virtual ValueHolder* clone() const - { - return new Holder(_held); - } - - ValueType _held; - - private: - Holder & operator = (const Holder &); - }; - - ValueHolder* content() const - { - return _pHolder; - } - -private: - ValueHolder* _pHolder; - -#endif // POCO_NO_SOO - template friend ValueType* AnyCast(Any*); diff --git a/Foundation/include/Poco/Config.h b/Foundation/include/Poco/Config.h index 4027a2bee..de545f6c3 100644 --- a/Foundation/include/Poco/Config.h +++ b/Foundation/include/Poco/Config.h @@ -83,7 +83,7 @@ // objects larger than this value will be alocated on the heap, // while those smaller will be placement new-ed into an // internal stack-auto-allocated buffer. -#if !defined(POCO_SMALL_OBJECT_SIZE) && !defined(POCO_NO_SOO) +#if !defined(POCO_SMALL_OBJECT_SIZE) #define POCO_SMALL_OBJECT_SIZE 32 #endif diff --git a/Foundation/include/Poco/Dynamic/Var.h b/Foundation/include/Poco/Dynamic/Var.h index a6667a90b..905162b13 100644 --- a/Foundation/include/Poco/Dynamic/Var.h +++ b/Foundation/include/Poco/Dynamic/Var.h @@ -91,15 +91,9 @@ public: template Var(const T& val) /// Creates the Var from the given value. -#ifdef POCO_NO_SOO - : _pHolder(new VarHolderImpl(val)) - { - } -#else { construct(val); } -#endif Var(const char* pVal); // Convenience constructor for const char* which gets mapped to a std::string internally, i.e. pVal is deep-copied. @@ -231,12 +225,7 @@ public: Var& operator = (const T& other) /// Assignment operator for assigning POD to Var { -#ifdef POCO_NO_SOO - Var tmp(other); - swap(tmp); -#else construct(other); -#endif return *this; } @@ -612,22 +601,6 @@ private: return pStr->operator[](n); } -#ifdef POCO_NO_SOO - - VarHolder* content() const - { - return _pHolder; - } - - void destruct() - { - delete _pHolder; - } - - VarHolder* _pHolder = nullptr; - -#else - VarHolder* content() const { return _placeholder.content(); @@ -671,8 +644,6 @@ private: } Placeholder _placeholder; - -#endif // POCO_NO_SOO }; @@ -687,12 +658,6 @@ private: inline void Var::swap(Var& other) { -#ifdef POCO_NO_SOO - - std::swap(_pHolder, other._pHolder); - -#else - if (this == &other) return; if (!_placeholder.isLocal() && !other._placeholder.isLocal()) @@ -713,8 +678,6 @@ inline void Var::swap(Var& other) throw; } } - -#endif } diff --git a/Foundation/include/Poco/Dynamic/VarHolder.h b/Foundation/include/Poco/Dynamic/VarHolder.h index 7688cd50a..38dfc24ea 100644 --- a/Foundation/include/Poco/Dynamic/VarHolder.h +++ b/Foundation/include/Poco/Dynamic/VarHolder.h @@ -305,13 +305,8 @@ protected: /// the heap, otherwise it is instantiated in-place (in the /// pre-allocated buffer inside the holder). { -#ifdef POCO_NO_SOO - (void)pVarHolder; - return new VarHolderImpl(val); -#else poco_check_ptr (pVarHolder); return makeSOOHolder(pVarHolder, val); -#endif } template @@ -411,8 +406,6 @@ protected: } private: - -#ifndef POCO_NO_SOO template, Placeholder::Size::value>::value>::type* = nullptr> VarHolder* makeSOOHolder(Placeholder* pVarHolder, const T& val) const @@ -428,7 +421,6 @@ private: poco_check_ptr (pVarHolder); return pVarHolder->assignHeap, T>(val); } -#endif template void checkUpperLimit(const F& from) const diff --git a/Foundation/src/Var.cpp b/Foundation/src/Var.cpp index b3f4e6d89..47eb618e1 100644 --- a/Foundation/src/Var.cpp +++ b/Foundation/src/Var.cpp @@ -26,38 +26,21 @@ namespace Dynamic { Var::Var() -#ifdef POCO_NO_SOO - : _pHolder(0) -#endif { } Var::Var(const char* pVal) -#ifdef POCO_NO_SOO - : _pHolder(new VarHolderImpl(pVal)) -{ -} -#else { construct(std::string(pVal)); } -#endif Var::Var(const Var& other) -#ifdef POCO_NO_SOO - :_pHolder((this != &other) ? - (other._pHolder ? other._pHolder->clone() : nullptr) : - other._pHolder) -{ -} -#else { if ((this != &other) && !other.isEmpty()) construct(other); } -#endif Var::~Var() @@ -68,16 +51,12 @@ Var::~Var() Var& Var::operator = (const Var& rhs) { -#ifdef POCO_NO_SOO - Var tmp(rhs); - swap(tmp); -#else if (this == &rhs) return *this; if (!rhs.isEmpty()) construct(rhs); else _placeholder.erase(); -#endif + return *this; } @@ -329,23 +308,13 @@ bool Var::operator && (const Var& other) const void Var::empty() { -#ifdef POCO_NO_SOO - delete _pHolder; - _pHolder = 0; -#else _placeholder.erase(); -#endif } void Var::clear() { -#ifdef POCO_NO_SOO - delete _pHolder; - _pHolder = 0; -#else _placeholder.erase(); -#endif } diff --git a/configure b/configure index 24f03ec0c..c07ff40ff 100755 --- a/configure +++ b/configure @@ -74,6 +74,10 @@ Options: Compile with -DPOCO_NET_NO_IPv6. For systems that don't support IPv6. + --no-soo + Compile with -DPOCO_NO_SOO. + Disables small object optimization. + --sqlite-fts= Compile with -DPOCO_DATA_SQLITE_FTS. Compile SQLite with Full Text Search support. @@ -226,6 +230,9 @@ while [ $# -ge 1 ]; do --no-ipv6) flags="$flags -DPOCO_NET_NO_IPv6" ;; + --no-soo) + flags="$flags -DPOCO_NO_SOO" ;; + --sqlite-thread-safe=*) flags="$flags -DSQLITE_THREADSAFE=`echo ${1} | awk '{print substr($0,22)}'`" ;;