diff options
author | David Srbecky <dsrbecky@google.com> | 2020-11-26 16:58:57 +0000 |
---|---|---|
committer | David Srbecky <dsrbecky@google.com> | 2021-03-23 13:43:21 +0000 |
commit | fcdc5f2c4084890c2ca48d981f74c6ff7bac4889 (patch) | |
tree | 8db6b102dd15f3d88004d481e9b4d62bfd12b4f9 /libunwindstack/include/unwindstack/SharedString.h | |
parent | 9bb405dfe2187e892779798b16de0bc782615c68 (diff) | |
download | unwinding-fcdc5f2c4084890c2ca48d981f74c6ff7bac4889.tar.gz |
Add shared symbol name cache.
The symbol name related reads and memory operations
take about half of the symbol name reading cost now.
This CL adds ref-counted read-only shared string cache,
which essentially eliminates all of the costs.
BM_symbol_find_single_many_times is >10% faster on ARM.
(which is 20% if we exclude the fixed ELF loading cost)
Real-world profiles seem even more encouraging.
The extra memory cost is negligible (by definition,
a small fraction of the decompressed mini-debug-info:
specifically, the subset of strtab for hit functions).
Furthermore, this effectively dedups strings when
consecutive unwinds hit similar set of functions.
(perfetto might keep several unwind results live)
Test: m libunwindstack_unit_test
Change-Id: I5cf600bb972fdb9d0f3a57ed0997bead2efa38f4
Diffstat (limited to 'libunwindstack/include/unwindstack/SharedString.h')
-rw-r--r-- | libunwindstack/include/unwindstack/SharedString.h | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/libunwindstack/include/unwindstack/SharedString.h b/libunwindstack/include/unwindstack/SharedString.h new file mode 100644 index 0000000..1fc4d49 --- /dev/null +++ b/libunwindstack/include/unwindstack/SharedString.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBUNWINDSTACK_SYMBOLNAME_H +#define _LIBUNWINDSTACK_SYMBOLNAME_H + +#include <memory> +#include <string> + +namespace unwindstack { + +// Ref-counted read-only string. Used to avoid string allocations/copies. +// It is intended to be transparent std::string replacement in most cases. +class SharedString { + public: + SharedString() : data_() {} + SharedString(std::string&& s) : data_(std::make_shared<const std::string>(std::move(s))) {} + SharedString(const std::string& s) : SharedString(std::string(s)) {} + SharedString(const char* s) : SharedString(std::string(s)) {} + + void clear() { data_.reset(); } + bool is_null() const { return data_.get() == nullptr; } + bool empty() const { return is_null() ? true : data_->empty(); } + const char* c_str() const { return is_null() ? "" : data_->c_str(); } + + operator const std::string&() const { + [[clang::no_destroy]] static const std::string empty; + return data_ ? *data_.get() : empty; + } + + operator std::string_view() const { return static_cast<const std::string&>(*this); } + + private: + std::shared_ptr<const std::string> data_; +}; + +static inline bool operator==(const SharedString& a, SharedString& b) { + return static_cast<std::string_view>(a) == static_cast<std::string_view>(b); +} +static inline bool operator==(const SharedString& a, std::string_view b) { + return static_cast<std::string_view>(a) == b; +} +static inline bool operator==(std::string_view a, const SharedString& b) { + return a == static_cast<std::string_view>(b); +} +static inline bool operator!=(const SharedString& a, SharedString& b) { + return !(a == b); +} +static inline bool operator!=(const SharedString& a, std::string_view b) { + return !(a == b); +} +static inline bool operator!=(std::string_view a, const SharedString& b) { + return !(a == b); +} + +} // namespace unwindstack +#endif // _LIBUNWINDSTACK_SYMBOLNAME_H |