summaryrefslogtreecommitdiff
path: root/libunwindstack/include/unwindstack/SharedString.h
diff options
context:
space:
mode:
authorDavid Srbecky <dsrbecky@google.com>2020-11-26 16:58:57 +0000
committerDavid Srbecky <dsrbecky@google.com>2021-03-23 13:43:21 +0000
commitfcdc5f2c4084890c2ca48d981f74c6ff7bac4889 (patch)
tree8db6b102dd15f3d88004d481e9b4d62bfd12b4f9 /libunwindstack/include/unwindstack/SharedString.h
parent9bb405dfe2187e892779798b16de0bc782615c68 (diff)
downloadunwinding-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.h70
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