From 6686e68a16380099ed805f804380b84f9d2610a1 Mon Sep 17 00:00:00 2001 From: "sub.mohanty@samsung.com" Date: Sat, 26 Sep 2020 09:21:29 +0900 Subject: [PATCH] refcator demangler to avoid temporary vector and string creation. -this patch reduces heap allocation by 130,000 Change-Id: Ic095319c11aea9e5235683f409b7ee846087d702 --- dali/internal/event/common/demangler-unix.cpp | 104 ++++++++--------------- dali/internal/event/common/demangler-windows.cpp | 3 +- dali/internal/event/common/demangler.h | 2 +- 3 files changed, 38 insertions(+), 71 deletions(-) diff --git a/dali/internal/event/common/demangler-unix.cpp b/dali/internal/event/common/demangler-unix.cpp index 07a63a1..773b653 100644 --- a/dali/internal/event/common/demangler-unix.cpp +++ b/dali/internal/event/common/demangler-unix.cpp @@ -15,38 +15,27 @@ * */ +// EXTERNAL HEADER +#include + // FILE HEADER #include -// INTERNAL HEADERS -#include - namespace { - -// true if character represent a digit -inline bool IsDigit(char c) -{ - return (c >= '0' && c <= '9'); -} - -// Gets the number of characters (number is in string) -// start The start position to look for a number -// result The number as an integer -// returns the number of characters used to define the number ie '12' is 2 -size_t GetNumberOfCharacters(const std::string& s, const size_t& start, int& result) +// Extracts the number from the src view and update the view. +size_t ExtractNumber(std::string_view& src) { - size_t size = s.size(); - - size_t i = start; - - int number = 0; + auto IsDigit = [](char c) { return (c >= '0' && c <= '9'); }; + size_t number = 0; - for( ; i < size; ++i ) + for(auto i = 0u; i < src.size(); ++i) { - char c = s.at(i); + char c = src[i]; if( !IsDigit( c ) ) { + //update the src view. + src.remove_prefix(i); break; } else @@ -55,53 +44,41 @@ size_t GetNumberOfCharacters(const std::string& s, const size_t& start, int& res } } - if( i - start ) - { - result = number; - } - - return i - start; + return number; } /** - * @brief Demangle a nested typeid name into its component parts. + * @brief Demangle a nested typeid name into its component parts and return + * the last component. * A nested type name is one containing namespaces and class names only. - * eg DemangleNestedNames(typeid(Dali::Actor).name()); + * eg ExtractDemangleNestedName(typeid(Dali::Actor).name()); * @param[in] typeIdName The type id name string to demangle. - * @returns the demangled list of names ie ["Dali","Actor"] or an empty list + * @returns the last component "Actor" or an empty string_view */ -std::vector DemangleNestedNames(const char *typeIdName) +std::string_view ExtractDemangleNestedName(std::string_view mangledName) { - // Demangle class name mangled according to the Itanium C++ ABI - // Returns demangled names ie "N4Dali8Internal5ActorE" is ["Dali","Internal","Actor"] - std::vector ret; - - const std::string mangledName(typeIdName); - - - size_t size = mangledName.size(); - - if( size >= 2 ) + if(mangledName.empty()) { - int number = 0; - size_t start = 0; - - // If the class isnt nested in a namespace then it just starts with the - // number of characters - if(mangledName[0] == 'N' && mangledName[size-1] == 'E') - { - start = 1; - } + return {}; + } - while( size_t chars = GetNumberOfCharacters(mangledName, start, number) ) - { - ret.push_back( mangledName.substr( start + chars, number ) ); + // classes nested inside a namespace starts with 'N' and ends with 'E' + // so trim those + if(mangledName.front() == 'N' && mangledName.back() == 'E') + { + mangledName.remove_prefix(1); + mangledName.remove_suffix(1); + } - start += chars + number; - } + std::string_view result; + while(!mangledName.empty()) + { + auto length = ExtractNumber(mangledName); + result = {mangledName.data(), length}; + mangledName.remove_prefix(length); } - return ret; + return result; } } // anon namespace @@ -111,18 +88,9 @@ namespace Dali namespace Internal { - -const std::string DemangleClassName(const char *typeIdName) +std::string DemangleClassName(const char* typeIdName) { - std::string name; - std::vector names = DemangleNestedNames(typeIdName); - - if( names.size() ) - { - name = names[ names.size() - 1 ]; - } - - return name; + return std::string(ExtractDemangleNestedName(typeIdName)); } } // namespace Internal diff --git a/dali/internal/event/common/demangler-windows.cpp b/dali/internal/event/common/demangler-windows.cpp index 9d6612a..cdfc58b 100644 --- a/dali/internal/event/common/demangler-windows.cpp +++ b/dali/internal/event/common/demangler-windows.cpp @@ -23,8 +23,7 @@ namespace Dali namespace Internal { - -const std::string DemangleClassName(const char *typeIdName) +std::string DemangleClassName(const char* typeIdName) { std::string name = typeIdName; int index = name.find_last_of(' '); diff --git a/dali/internal/event/common/demangler.h b/dali/internal/event/common/demangler.h index 4d9790b..647e015 100644 --- a/dali/internal/event/common/demangler.h +++ b/dali/internal/event/common/demangler.h @@ -32,7 +32,7 @@ namespace Internal * @param[in] typeIdName The type id name string to demangle. * @returns the class name ie "Actor" or an empty string */ -const std::string DemangleClassName(const char *typeIdName); +std::string DemangleClassName(const char* typeIdName); } // namespace Internal -- 2.7.4