summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/wtf/text/movable_string.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/wtf/text/movable_string.cc')
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/movable_string.cc147
1 files changed, 147 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/movable_string.cc b/chromium/third_party/blink/renderer/platform/wtf/text/movable_string.cc
new file mode 100644
index 00000000000..fdfa440ea96
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/movable_string.cc
@@ -0,0 +1,147 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/wtf/text/movable_string.h"
+
+#include "base/metrics/histogram_macros.h"
+
+namespace WTF {
+
+namespace {
+
+bool IsLargeEnough(const StringImpl* impl) {
+ // Don't attempt to park strings smaller than this size.
+ static constexpr unsigned int kSizeThreshold = 10000;
+ return impl && impl->length() > kSizeThreshold;
+}
+
+void RecordParkingAction(MovableStringImpl::ParkingAction action) {
+ UMA_HISTOGRAM_ENUMERATION("Memory.MovableStringParkingAction", action);
+}
+
+} // namespace
+
+MovableStringImpl::MovableStringImpl() = default;
+
+MovableStringImpl::MovableStringImpl(scoped_refptr<StringImpl>&& impl)
+ : string_(std::move(impl)), is_parked_(false) {}
+
+MovableStringImpl::~MovableStringImpl() {
+ MovableStringTable::Instance().Remove(string_.Impl());
+}
+
+bool MovableStringImpl::Is8Bit() const {
+ return string_.Is8Bit();
+}
+
+bool MovableStringImpl::IsNull() const {
+ return string_.IsNull();
+}
+
+const String& MovableStringImpl::ToString() {
+ Unpark();
+ return string_;
+}
+
+unsigned MovableStringImpl::CharactersSizeInBytes() const {
+ return string_.CharactersSizeInBytes();
+}
+
+bool MovableStringImpl::Park() {
+ // Cannot park strings with several references.
+ if (string_.Impl()->HasOneRef()) {
+ RecordParkingAction(ParkingAction::kParkedInBackground);
+ is_parked_ = true;
+ }
+ return is_parked_;
+}
+
+void MovableStringImpl::Unpark() {
+ if (!is_parked_)
+ return;
+
+ bool backgrounded = MovableStringTable::Instance().IsRendererBackgrounded();
+ RecordParkingAction(backgrounded ? ParkingAction::kUnparkedInBackground
+ : ParkingAction::kUnparkedInForeground);
+ is_parked_ = false;
+}
+
+MovableString::MovableString(scoped_refptr<StringImpl>&& impl) {
+ // Don't move small strings.
+ if (IsLargeEnough(impl.get())) {
+ impl_ = MovableStringTable::Instance().Add(std::move(impl));
+ } else {
+ impl_ = base::MakeRefCounted<MovableStringImpl>(std::move(impl));
+ }
+}
+
+MovableString::~MovableString() = default;
+
+bool MovableString::Is8Bit() const {
+ return impl_->Is8Bit();
+}
+
+bool MovableString::IsNull() const {
+ return impl_->IsNull();
+}
+const String& MovableString::ToString() const {
+ return impl_->ToString();
+}
+
+unsigned MovableString::CharactersSizeInBytes() const {
+ return impl_->CharactersSizeInBytes();
+}
+
+MovableStringTable::MovableStringTable() = default;
+MovableStringTable::~MovableStringTable() = default;
+
+scoped_refptr<MovableStringImpl> MovableStringTable::Add(
+ scoped_refptr<StringImpl>&& string) {
+ StringImpl* raw_ptr = string.get();
+ auto it = table_.find(raw_ptr);
+ if (it != table_.end()) {
+ return it->second;
+ }
+ auto new_movable_string =
+ base::MakeRefCounted<MovableStringImpl>(std::move(string));
+ table_.emplace(raw_ptr, new_movable_string.get());
+ return new_movable_string;
+}
+
+void MovableStringTable::Remove(StringImpl* string) {
+ if (!IsLargeEnough(string))
+ return;
+
+ auto it = table_.find(string);
+ DCHECK(it != table_.end());
+ table_.erase(it);
+}
+
+void MovableStringTable::SetRendererBackgrounded(bool backgrounded) {
+ backgrounded_ = backgrounded;
+}
+
+bool MovableStringTable::IsRendererBackgrounded() const {
+ return backgrounded_;
+}
+
+void MovableStringTable::MaybeParkAll() {
+ if (!IsRendererBackgrounded())
+ return;
+
+ size_t total_size = 0, count = 0;
+ for (auto& kv : table_) {
+ MovableStringImpl* str = kv.second;
+ str->Park();
+ total_size += str->CharactersSizeInBytes();
+ count += 1;
+ }
+
+ size_t total_size_kb = total_size / 1000;
+ UMA_HISTOGRAM_COUNTS_100000("Memory.MovableStringsTotalSizeKb",
+ total_size_kb);
+ UMA_HISTOGRAM_COUNTS_1000("Memory.MovableStringsCount", table_.size());
+}
+
+} // namespace WTF