summaryrefslogtreecommitdiff
path: root/chromium-125-debian-bad-font-gc2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'chromium-125-debian-bad-font-gc2.patch')
-rw-r--r--chromium-125-debian-bad-font-gc2.patch3727
1 files changed, 3727 insertions, 0 deletions
diff --git a/chromium-125-debian-bad-font-gc2.patch b/chromium-125-debian-bad-font-gc2.patch
new file mode 100644
index 0000000..b718479
--- /dev/null
+++ b/chromium-125-debian-bad-font-gc2.patch
@@ -0,0 +1,3727 @@
+Chromium 123 was buggy, with tabs regularly hanging/crashing. The culprit
+was the GC cleaning up font cache stuff, and deadlocking in a FontCacheKey
+destructor:
+
+Thread 54 (Thread 0x7fffc55fe6c0 (LWP 413811) "Chrome_InProcRe"):
+#0 0x00007ffff6720719 in syscall () from /lib/x86_64-linux-gnu/libc.so.6
+#1 0x000055555c1752d9 in partition_alloc::internal::SpinningMutex::LockSlow() ()
+#2 0x000055555c185529 in allocator_shim::internal::PartitionFree(allocator_shim::AllocatorDispatch const*, void*, void*) ()
+#3 0x000055555f7db46b in blink::FontCacheKey::~FontCacheKey() ()
+#4 0x000055555f7db6f4 in WTF::WeakProcessingHashTableHelper<(WTF::WeakHandlingFlag)1, blink::FontCacheKey, WTF::KeyValuePair<blink::FontCacheKey, cppgc::internal::BasicMember<blink::SegmentedFontData const, cppgc::internal::WeakMemberTag, cppgc::internal::DijkstraWriteBarrierPolicy, cppgc::internal::DisabledCheckingPolicy, cppgc::internal::CompressedPointer> >, WTF::KeyValuePairExtractor, WTF::HashMapValueTraits<WTF::HashTraits<blink::FontCacheKey>, WTF::HashTraits<cppgc::internal::BasicMember<blink::SegmentedFontData const, cppgc::internal::WeakMemberTag, cppgc::internal::DijkstraWriteBarrierPolicy, cppgc::internal::DisabledCheckingPolicy, cppgc::internal::CompressedPointer> > >, WTF::HashTraits<blink::FontCacheKey>, blink::HeapAllocator>::Process(cppgc::LivenessBroker const&, void const*) ()
+#5 0x0000555559544bef in cppgc::internal::MarkerBase::ProcessWeakness() ()
+#6 0x000055555954487e in cppgc::internal::MarkerBase::LeaveAtomicPause() ()
+#7 0x0000555558e8115a in v8::internal::CppHeap::FinishMarkingAndStartSweeping() ()
+#8 0x0000555558ebcdc0 in v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::internal::GarbageCollectionReason, char const*) ()
+#9 0x0000555558ecfe14 in v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags)::$_0::operator()() const ()
+#10 0x0000555558ecfb65 in void heap::base::Stack::SetMarkerAndCallbackImpl<v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags)::$_0>(heap::base::Stack*, void*, void const*) ()
+--Type <RET> for more, q to quit, c to continue without paging--
+#11 0x000055555955216b in PushAllRegistersAndIterateStack ()
+#12 0x0000555558eb8c19 in v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) ()
+#13 0x0000555558eba3eb in v8::internal::Heap::FinalizeIncrementalMarkingAtomically(v8::internal::GarbageCollectionReason) ()
+#14 0x0000555558ed20db in v8::internal::IncrementalMarkingJob::Task::RunInternal() ()
+#15 0x000055555c0c49d6 in base::TaskAnnotator::RunTaskImpl(base::PendingTask&) ()
+#16 0x000055555c0daf88 in base::sequence_manager::internal::ThreadControllerImpl::DoWork(base::sequence_manager::internal::ThreadControllerImpl::WorkType) ()
+#17 0x000055555c0c49d6 in base::TaskAnnotator::RunTaskImpl(base::PendingTask&) ()
+#18 0x000055555c0dd8f9 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow*) ()
+#19 0x000055555c0dd3bf in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() ()
+#20 0x000055555c0ddd75 in non-virtual thunk to base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() ()
+#21 0x000055555c07eb4f in base::MessagePumpDefault::Run(base::MessagePump::Delegate*) ()
+#22 0x000055555c0de110 in base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool, base::TimeDelta) ()
+#23 0x000055555c0a4c26 in base::RunLoop::Run(base::Location const&) ()
+#24 0x000055555c100155 in base::Thread::Run(base::RunLoop*) ()
+#25 0x000055555c100342 in base::Thread::ThreadMain() ()
+
+
+The commit below modified font stuff to go from using scoped_refptrs to
+getting cleaned up via GC. Reverting it fixes chromium's behavior for us.
+It would be good to get a proper fix for this, but reverting this will
+have to do for now.
+
+
+commit bff9ec6754f7bf97c61d84663ee2ccc5055e9eb3
+Author: Ian Kilpatrick <ikilpatrick@chromium.org>
+Date: Tue Feb 13 19:15:19 2024 +0000
+
+ [gc] Make SimpleFontData & FontPlatformData & friends gc'd.
+
+ The largest change is making the associated caches for these objects
+ weak collections instead of relying on the relatively complex purging
+ logic.
+
+ https://variable-lizards.glitch.me/ appears not to leak.
+
+ There should be no user-visible behaviour change.
+
+ Bug: 41490008
+ Change-Id: Iba581842459cf31f7f4fe60d83665f393a7d06a3
+ Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5262982
+ Reviewed-by: Caleb Raitto <caraitto@chromium.org>
+ Reviewed-by: Dominik Röttsches <drott@chromium.org>
+ Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
+ Cr-Commit-Position: refs/heads/main@{#1259965}
+
+--- a/third_party/blink/renderer/core/css/binary_data_font_face_source.cc
++++ b/third_party/blink/renderer/core/css/binary_data_font_face_source.cc
+@@ -36,10 +36,10 @@ bool BinaryDataFontFaceSource::IsValid()
+ return custom_platform_data_.get();
+ }
+
+-SimpleFontData* BinaryDataFontFaceSource::CreateFontData(
++scoped_refptr<SimpleFontData> BinaryDataFontFaceSource::CreateFontData(
+ const FontDescription& font_description,
+ const FontSelectionCapabilities& font_selection_capabilities) {
+- return MakeGarbageCollected<SimpleFontData>(
++ return SimpleFontData::Create(
+ custom_platform_data_->GetFontPlatformData(
+ font_description.EffectiveFontSize(),
+ font_description.AdjustedSpecifiedSize(),
+@@ -56,7 +56,7 @@ SimpleFontData* BinaryDataFontFaceSource
+ : ResolvedFontFeatures(),
+ font_description.Orientation(), font_description.VariationSettings(),
+ font_description.GetFontPalette()),
+- MakeGarbageCollected<CustomFontData>());
++ CustomFontData::Create());
+ }
+
+ } // namespace blink
+--- a/third_party/blink/renderer/core/css/binary_data_font_face_source.h
++++ b/third_party/blink/renderer/core/css/binary_data_font_face_source.h
+@@ -20,8 +20,9 @@ class BinaryDataFontFaceSource final : p
+ bool IsValid() const override;
+
+ private:
+- SimpleFontData* CreateFontData(const FontDescription&,
+- const FontSelectionCapabilities&) override;
++ scoped_refptr<SimpleFontData> CreateFontData(
++ const FontDescription&,
++ const FontSelectionCapabilities&) override;
+
+ scoped_refptr<FontCustomPlatformData> custom_platform_data_;
+ };
+--- a/third_party/blink/renderer/core/css/css_custom_font_data.h
++++ b/third_party/blink/renderer/core/css/css_custom_font_data.h
+@@ -31,18 +31,13 @@ class CSSCustomFontData final : public C
+ public:
+ enum FallbackVisibility { kInvisibleFallback, kVisibleFallback };
+
+- CSSCustomFontData(CSSFontFaceSource* source, FallbackVisibility visibility)
+- : font_face_source_(source), fallback_visibility_(visibility) {
+- if (source) {
+- is_loading_ = source->IsLoading();
+- }
++ static scoped_refptr<CSSCustomFontData> Create(
++ CSSFontFaceSource* source,
++ FallbackVisibility visibility) {
++ return base::AdoptRef(new CSSCustomFontData(source, visibility));
+ }
+- ~CSSCustomFontData() override = default;
+
+- void Trace(Visitor* visitor) const override {
+- visitor->Trace(font_face_source_);
+- CustomFontData::Trace(visitor);
+- }
++ ~CSSCustomFontData() override = default;
+
+ bool ShouldSkipDrawing() const override {
+ if (font_face_source_) {
+@@ -66,7 +61,16 @@ class CSSCustomFontData final : public C
+ }
+
+ private:
+- Member<CSSFontFaceSource> font_face_source_;
++ CSSCustomFontData(CSSFontFaceSource* source, FallbackVisibility visibility)
++ : font_face_source_(source), fallback_visibility_(visibility) {
++ if (source) {
++ is_loading_ = source->IsLoading();
++ }
++ }
++
++ // TODO(Oilpan): consider moving (Custom)FontFace hierarchy to the heap,
++ // thereby making this reference a Member<>.
++ WeakPersistent<CSSFontFaceSource> font_face_source_;
+ FallbackVisibility fallback_visibility_;
+ mutable bool is_loading_ = false;
+ };
+--- a/third_party/blink/renderer/core/css/css_font_face.cc
++++ b/third_party/blink/renderer/core/css/css_font_face.cc
+@@ -114,7 +114,7 @@ bool CSSFontFace::FallbackVisibilityChan
+ return true;
+ }
+
+-const SimpleFontData* CSSFontFace::GetFontData(
++scoped_refptr<SimpleFontData> CSSFontFace::GetFontData(
+ const FontDescription& font_description) {
+ if (!IsValid()) {
+ return nullptr;
+@@ -140,7 +140,7 @@ const SimpleFontData* CSSFontFace::GetFo
+ return nullptr;
+ }
+
+- if (const SimpleFontData* result =
++ if (scoped_refptr<SimpleFontData> result =
+ source->GetFontData(size_adjusted_description,
+ font_face_->GetFontSelectionCapabilities())) {
+ // The font data here is created using the primary font's description.
+@@ -149,7 +149,7 @@ const SimpleFontData* CSSFontFace::GetFo
+ if (size_adjusted_description.HasSizeAdjust()) {
+ if (auto adjusted_size =
+ FontSizeFunctions::MetricsMultiplierAdjustedFontSize(
+- result, size_adjusted_description)) {
++ result.get(), size_adjusted_description)) {
+ size_adjusted_description.SetAdjustedSize(adjusted_size.value());
+ result =
+ source->GetFontData(size_adjusted_description,
+--- a/third_party/blink/renderer/core/css/css_font_face.h
++++ b/third_party/blink/renderer/core/css/css_font_face.h
+@@ -76,7 +76,7 @@ class CORE_EXPORT CSSFontFace final : pu
+ bool FontLoaded(CSSFontFaceSource*);
+ bool FallbackVisibilityChanged(RemoteFontFaceSource*);
+
+- const SimpleFontData* GetFontData(const FontDescription&);
++ scoped_refptr<SimpleFontData> GetFontData(const FontDescription&);
+
+ FontFace::LoadStatusType LoadStatus() const {
+ return font_face_->LoadStatus();
+--- a/third_party/blink/renderer/core/css/css_font_face_source.cc
++++ b/third_party/blink/renderer/core/css/css_font_face_source.cc
+@@ -31,11 +31,22 @@
+ #include "third_party/blink/renderer/platform/fonts/font_face_creation_params.h"
+ #include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
+
++namespace {
++// An excessive amount of SimpleFontData objects is generated from
++// CSSFontFaceSource if a lot of varying FontDescriptions point to a web
++// font. These FontDescriptions can vary in size, font-feature-settings or
++// font-variation settings. Well known cases are animations of font-variation
++// settings, compare crbug.com/778352. For a start, let's reduce this number to
++// 1024, which is still a large number and should have enough steps for font
++// animations from the same font face source, but avoids unbounded growth.
++const size_t kMaxCachedFontData = 1024;
++} // namespace
++
+ namespace blink {
+
+ CSSFontFaceSource::~CSSFontFaceSource() = default;
+
+-const SimpleFontData* CSSFontFaceSource::GetFontData(
++scoped_refptr<SimpleFontData> CSSFontFaceSource::GetFontData(
+ const FontDescription& font_description,
+ const FontSelectionCapabilities& font_selection_capabilities) {
+ // If the font hasn't loaded or an error occurred, then we've got nothing.
+@@ -53,12 +64,52 @@ const SimpleFontData* CSSFontFaceSource:
+ FontCacheKey key =
+ font_description.CacheKey(FontFaceCreationParams(), is_unique_match);
+
+- auto result = font_data_table_.insert(key, nullptr);
+- if (result.is_new_entry) {
+- result.stored_value->value =
+- CreateFontData(font_description, font_selection_capabilities);
++ // Get or create the font data. Take care to avoid dangling references into
++ // font_data_table_, because it is modified below during pruning.
++ scoped_refptr<SimpleFontData> font_data;
++ {
++ auto* it = font_data_table_.insert(key, nullptr).stored_value;
++ if (!it->value) {
++ it->value = CreateFontData(font_description, font_selection_capabilities);
++ }
++ font_data = it->value;
++ }
++
++ font_cache_key_age.PrependOrMoveToFirst(key);
++ PruneOldestIfNeeded();
++
++ DCHECK_LE(font_data_table_.size(), kMaxCachedFontData);
++ // No release, because fontData is a reference to a RefPtr that is held in the
++ // font_data_table_.
++ return font_data;
++}
++
++void CSSFontFaceSource::PruneOldestIfNeeded() {
++ if (font_cache_key_age.size() > kMaxCachedFontData) {
++ DCHECK_EQ(font_cache_key_age.size() - 1, kMaxCachedFontData);
++ const FontCacheKey& key = font_cache_key_age.back();
++ auto font_data_entry = font_data_table_.Take(key);
++ font_cache_key_age.pop_back();
++ DCHECK_EQ(font_cache_key_age.size(), kMaxCachedFontData);
++ if (font_data_entry && font_data_entry->GetCustomFontData()) {
++ font_data_entry->GetCustomFontData()->ClearFontFaceSource();
++ }
++ }
++}
++
++void CSSFontFaceSource::PruneTable() {
++ if (font_data_table_.empty()) {
++ return;
++ }
++
++ for (const auto& item : font_data_table_) {
++ SimpleFontData* font_data = item.value.get();
++ if (font_data && font_data->GetCustomFontData()) {
++ font_data->GetCustomFontData()->ClearFontFaceSource();
++ }
+ }
+- return result.stored_value->value.Get();
++ font_cache_key_age.clear();
++ font_data_table_.clear();
+ }
+
+ } // namespace blink
+--- a/third_party/blink/renderer/core/css/css_font_face_source.h
++++ b/third_party/blink/renderer/core/css/css_font_face_source.h
+@@ -30,9 +30,7 @@
+ #include "third_party/blink/renderer/core/css/font_display.h"
+ #include "third_party/blink/renderer/platform/fonts/font_cache_key.h"
+ #include "third_party/blink/renderer/platform/fonts/font_selection_types.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
+ #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+-#include "third_party/blink/renderer/platform/heap/member.h"
+ #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+ #include "third_party/blink/renderer/platform/wtf/hash_map.h"
+ #include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
+@@ -71,8 +69,8 @@ class CORE_EXPORT CSSFontFaceSource
+ return nullptr;
+ }
+
+- const SimpleFontData* GetFontData(const FontDescription&,
+- const FontSelectionCapabilities&);
++ scoped_refptr<SimpleFontData> GetFontData(const FontDescription&,
++ const FontSelectionCapabilities&);
+
+ // TODO(https://crbug.com/947461): IsLocalFontAvailable must not have a
+ // FontDescription argument.
+@@ -93,29 +91,28 @@ class CORE_EXPORT CSSFontFaceSource
+ virtual bool HadBlankText() { return false; }
+ virtual void PaintRequested() {}
+
+- virtual void Trace(Visitor* visitor) const {
+- visitor->Trace(font_data_table_);
+- }
++ virtual void Trace(Visitor* visitor) const {}
+
+ protected:
+ CSSFontFaceSource() = default;
+- virtual const SimpleFontData* CreateFontData(
++ virtual scoped_refptr<SimpleFontData> CreateFontData(
+ const FontDescription&,
+ const FontSelectionCapabilities&) = 0;
+-
+- void ClearTable() { font_data_table_.clear(); }
++ void PruneTable();
+
+ // Report the font lookup for metrics collection. Only used for local font
+ // face sources currently.
+ virtual void ReportFontLookup(const FontDescription& font_description,
+- const SimpleFontData* font_data,
++ SimpleFontData* font_data,
+ bool is_loading_fallback = false) {}
+
+ private:
+- using FontDataTable =
+- HeapHashMap<FontCacheKey, WeakMember<const SimpleFontData>>;
++ void PruneOldestIfNeeded();
++ using FontDataTable = HashMap<FontCacheKey, scoped_refptr<SimpleFontData>>;
++ using FontCacheKeyAgeList = LinkedHashSet<FontCacheKey>;
+
+ FontDataTable font_data_table_;
++ FontCacheKeyAgeList font_cache_key_age;
+ };
+
+ } // namespace blink
+--- a/third_party/blink/renderer/core/css/css_font_selector.cc
++++ b/third_party/blink/renderer/core/css/css_font_selector.cc
+@@ -162,7 +162,7 @@ void CSSFontSelector::FontCacheInvalidat
+ DispatchInvalidationCallbacks(FontInvalidationReason::kGeneralInvalidation);
+ }
+
+-const FontData* CSSFontSelector::GetFontData(
++scoped_refptr<FontData> CSSFontSelector::GetFontData(
+ const FontDescription& font_description,
+ const FontFamily& font_family) {
+ const auto& family_name = font_family.FamilyName();
+@@ -252,13 +252,13 @@ const FontData* CSSFontSelector::GetFont
+ family_name, request_description.GetScript(),
+ request_description.GenericFamily(), settings_family_name);
+
+- const SimpleFontData* font_data =
++ scoped_refptr<SimpleFontData> font_data =
+ FontCache::Get().GetFontData(request_description, settings_family_name);
+ if (font_data && request_description.HasSizeAdjust()) {
+ DCHECK(RuntimeEnabledFeatures::CSSFontSizeAdjustEnabled());
+ if (auto adjusted_size =
+ FontSizeFunctions::MetricsMultiplierAdjustedFontSize(
+- font_data, request_description)) {
++ font_data.get(), request_description)) {
+ FontDescription size_adjusted_description(request_description);
+ size_adjusted_description.SetAdjustedSize(adjusted_size.value());
+ font_data = FontCache::Get().GetFontData(size_adjusted_description,
+--- a/third_party/blink/renderer/core/css/css_font_selector.h
++++ b/third_party/blink/renderer/core/css/css_font_selector.h
+@@ -49,8 +49,8 @@ class CORE_EXPORT CSSFontSelector : publ
+
+ unsigned Version() const override { return font_face_cache_->Version(); }
+
+- const FontData* GetFontData(const FontDescription&,
+- const FontFamily&) override;
++ scoped_refptr<FontData> GetFontData(const FontDescription&,
++ const FontFamily&) override;
+
+ void FontFaceInvalidated(FontInvalidationReason) override;
+
+--- a/third_party/blink/renderer/core/css/css_font_selector_base.cc
++++ b/third_party/blink/renderer/core/css/css_font_selector_base.cc
+@@ -87,21 +87,21 @@ void CSSFontSelectorBase::ReportFailedLo
+ void CSSFontSelectorBase::ReportFontLookupByUniqueOrFamilyName(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) {
++ scoped_refptr<SimpleFontData> resulting_font_data) {
+ if (FontMatchingMetrics* font_matching_metrics = GetFontMatchingMetrics()) {
+ font_matching_metrics->ReportFontLookupByUniqueOrFamilyName(
+- name, font_description, resulting_font_data);
++ name, font_description, resulting_font_data.get());
+ }
+ }
+
+ void CSSFontSelectorBase::ReportFontLookupByUniqueNameOnly(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data,
++ scoped_refptr<SimpleFontData> resulting_font_data,
+ bool is_loading_fallback) {
+ if (FontMatchingMetrics* font_matching_metrics = GetFontMatchingMetrics()) {
+ font_matching_metrics->ReportFontLookupByUniqueNameOnly(
+- name, font_description, resulting_font_data, is_loading_fallback);
++ name, font_description, resulting_font_data.get(), is_loading_fallback);
+ }
+ }
+
+@@ -109,20 +109,20 @@ void CSSFontSelectorBase::ReportFontLook
+ UChar32 fallback_character,
+ FontFallbackPriority fallback_priority,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) {
++ scoped_refptr<SimpleFontData> resulting_font_data) {
+ if (FontMatchingMetrics* font_matching_metrics = GetFontMatchingMetrics()) {
+ font_matching_metrics->ReportFontLookupByFallbackCharacter(
+ fallback_character, fallback_priority, font_description,
+- resulting_font_data);
++ resulting_font_data.get());
+ }
+ }
+
+ void CSSFontSelectorBase::ReportLastResortFallbackFontLookup(
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) {
++ scoped_refptr<SimpleFontData> resulting_font_data) {
+ if (FontMatchingMetrics* font_matching_metrics = GetFontMatchingMetrics()) {
+ font_matching_metrics->ReportLastResortFallbackFontLookup(
+- font_description, resulting_font_data);
++ font_description, resulting_font_data.get());
+ }
+ }
+
+--- a/third_party/blink/renderer/core/css/css_font_selector_base.h
++++ b/third_party/blink/renderer/core/css/css_font_selector_base.h
+@@ -46,23 +46,23 @@ class CORE_EXPORT CSSFontSelectorBase :
+ void ReportFontLookupByUniqueOrFamilyName(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) override;
++ scoped_refptr<SimpleFontData> resulting_font_data) override;
+
+ void ReportFontLookupByUniqueNameOnly(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data,
++ scoped_refptr<SimpleFontData> resulting_font_data,
+ bool is_loading_fallback = false) override;
+
+ void ReportFontLookupByFallbackCharacter(
+ UChar32 fallback_character,
+ FontFallbackPriority fallback_priority,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) override;
++ scoped_refptr<SimpleFontData> resulting_font_data) override;
+
+ void ReportLastResortFallbackFontLookup(
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) override;
++ scoped_refptr<SimpleFontData> resulting_font_data) override;
+
+ void ReportFontFamilyLookupByGenericFamily(
+ const AtomicString& generic_font_family_name,
+--- a/third_party/blink/renderer/core/css/css_segmented_font_face.cc
++++ b/third_party/blink/renderer/core/css/css_segmented_font_face.cc
+@@ -38,16 +38,42 @@
+ #include "third_party/blink/renderer/platform/fonts/segmented_font_data.h"
+ #include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
+
++// See comment below in CSSSegmentedFontFace::GetFontData - the cache from
++// CSSSegmentedFontFace (which represents a group of @font-face declarations
++// with identical FontSelectionCapabilities but differing by unicode-range) to
++// FontData/SegmentedFontData, (i.e. the actual font blobs that can be used for
++// shaping and painting retrieved from a CSSFontFaceSource) is usually small
++// (less than a dozen, up to tens) for non-animation-cases, but grows fast to
++// thousands when animating variable font parameters. Set a limit until we start
++// dropping cache entries in animation scenarios.
++static constexpr size_t kFontDataTableMaxSize = 250;
++
+ namespace blink {
+
++// static
++CSSSegmentedFontFace* CSSSegmentedFontFace::Create(
++ FontSelectionCapabilities capabilities) {
++ return MakeGarbageCollected<CSSSegmentedFontFace>(capabilities);
++}
++
+ CSSSegmentedFontFace::CSSSegmentedFontFace(
+ FontSelectionCapabilities font_selection_capabilities)
+ : font_selection_capabilities_(font_selection_capabilities),
++ font_data_table_(kFontDataTableMaxSize),
+ font_faces_(MakeGarbageCollected<FontFaceList>()),
+ approximate_character_count_(0) {}
+
+ CSSSegmentedFontFace::~CSSSegmentedFontFace() = default;
+
++void CSSSegmentedFontFace::PruneTable() {
++ // Make sure the glyph page tree prunes out all uses of this custom font.
++ if (!font_data_table_.size()) {
++ return;
++ }
++
++ font_data_table_.Clear();
++}
++
+ bool CSSSegmentedFontFace::IsValid() const {
+ // Valid if at least one font face is valid.
+ return font_faces_->ForEachUntilTrue(
+@@ -57,12 +83,12 @@ bool CSSSegmentedFontFace::IsValid() con
+ }
+
+ void CSSSegmentedFontFace::FontFaceInvalidated() {
+- font_data_table_.clear();
++ PruneTable();
+ }
+
+ void CSSSegmentedFontFace::AddFontFace(FontFace* font_face,
+ bool css_connected) {
+- font_data_table_.clear();
++ PruneTable();
+ font_face->CssFontFace()->AddSegmentedFontFace(this);
+ font_faces_->Insert(font_face, css_connected);
+ }
+@@ -72,11 +98,11 @@ void CSSSegmentedFontFace::RemoveFontFac
+ return;
+ }
+
+- font_data_table_.clear();
++ PruneTable();
+ font_face->CssFontFace()->RemoveSegmentedFontFace(this);
+ }
+
+-const FontData* CSSSegmentedFontFace::GetFontData(
++scoped_refptr<FontData> CSSSegmentedFontFace::GetFontData(
+ const FontDescription& font_description) {
+ if (!IsValid()) {
+ return nullptr;
+@@ -98,16 +124,16 @@ const FontData* CSSSegmentedFontFace::Ge
+ // usually only a small number of FontData/SegmentedFontData instances created
+ // per CSSSegmentedFontFace. Whereas in variable font animations, this number
+ // grows rapidly.
+- auto it = font_data_table_.find(key);
++ auto it = font_data_table_.Get(key);
+ if (it != font_data_table_.end()) {
+- const SegmentedFontData* cached_font_data = it->value.Get();
++ scoped_refptr<SegmentedFontData> cached_font_data = it->second;
+ if (cached_font_data && cached_font_data->NumFaces()) {
+ return cached_font_data;
+ }
+ }
+
+- SegmentedFontData* created_font_data =
+- MakeGarbageCollected<SegmentedFontData>();
++ scoped_refptr<SegmentedFontData> created_font_data =
++ SegmentedFontData::Create();
+
+ FontDescription requested_font_description(font_description);
+ const FontSelectionRequest& font_selection_request =
+@@ -126,16 +152,26 @@ const FontData* CSSSegmentedFontFace::Ge
+ if (!font_face->CssFontFace()->IsValid()) {
+ return;
+ }
+- if (const SimpleFontData* face_font_data =
++ if (scoped_refptr<SimpleFontData> face_font_data =
+ font_face->CssFontFace()->GetFontData(requested_font_description)) {
+ DCHECK(!face_font_data->IsSegmented());
+- created_font_data->AppendFace(MakeGarbageCollected<FontDataForRangeSet>(
+- std::move(face_font_data), font_face->CssFontFace()->Ranges()));
++ if (face_font_data->IsCustomFont()) {
++ created_font_data->AppendFace(base::AdoptRef(new FontDataForRangeSet(
++ std::move(face_font_data), font_face->CssFontFace()->Ranges())));
++ } else {
++ created_font_data->AppendFace(
++ base::AdoptRef(new FontDataForRangeSetFromCache(
++ std::move(face_font_data),
++ font_face->CssFontFace()->Ranges())));
++ }
+ }
+ });
+
+ if (created_font_data->NumFaces()) {
+- font_data_table_.insert(std::move(key), created_font_data);
++ scoped_refptr<SegmentedFontData> put_to_cache(created_font_data);
++ font_data_table_.Put(std::move(key), std::move(put_to_cache));
++ // No release, we have a reference to an object in the cache which should
++ // retain the ref count it has.
+ return created_font_data;
+ }
+
+@@ -186,7 +222,6 @@ void CSSSegmentedFontFace::Match(const S
+ }
+
+ void CSSSegmentedFontFace::Trace(Visitor* visitor) const {
+- visitor->Trace(font_data_table_);
+ visitor->Trace(font_faces_);
+ }
+
+--- a/third_party/blink/renderer/core/css/css_segmented_font_face.h
++++ b/third_party/blink/renderer/core/css/css_segmented_font_face.h
+@@ -32,7 +32,6 @@
+ #include "third_party/blink/renderer/platform/fonts/font_cache_key.h"
+ #include "third_party/blink/renderer/platform/fonts/font_selection_types.h"
+ #include "third_party/blink/renderer/platform/fonts/segmented_font_data.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
+ #include "third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h"
+ #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
+ #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+@@ -84,6 +83,8 @@ class FontFaceList : public GarbageColle
+ class CSSSegmentedFontFace final
+ : public GarbageCollected<CSSSegmentedFontFace> {
+ public:
++ static CSSSegmentedFontFace* Create(FontSelectionCapabilities);
++
+ explicit CSSSegmentedFontFace(FontSelectionCapabilities);
+ ~CSSSegmentedFontFace();
+
+@@ -99,7 +100,7 @@ class CSSSegmentedFontFace final
+ void RemoveFontFace(FontFace*);
+ bool IsEmpty() const { return font_faces_->IsEmpty(); }
+
+- const FontData* GetFontData(const FontDescription&);
++ scoped_refptr<FontData> GetFontData(const FontDescription&);
+
+ bool CheckFont(UChar32) const;
+ void Match(const String&, HeapVector<Member<FontFace>>*) const;
+@@ -112,11 +113,12 @@ class CSSSegmentedFontFace final
+ void Trace(Visitor*) const;
+
+ private:
++ void PruneTable();
+ bool IsValid() const;
+
+ FontSelectionCapabilities font_selection_capabilities_;
+
+- HeapHashMap<FontCacheKey, WeakMember<const SegmentedFontData>>
++ base::HashingLRUCache<FontCacheKey, scoped_refptr<SegmentedFontData>>
+ font_data_table_;
+
+ // All non-CSS-connected FontFaces are stored after the CSS-connected ones.
+--- a/third_party/blink/renderer/core/css/font_face_cache.cc
++++ b/third_party/blink/renderer/core/css/font_face_cache.cc
+@@ -85,8 +85,8 @@ void FontFaceCache::CapabilitiesSet::Add
+ const auto result =
+ map_.insert(font_face->GetFontSelectionCapabilities(), nullptr);
+ if (result.is_new_entry) {
+- result.stored_value->value = MakeGarbageCollected<CSSSegmentedFontFace>(
+- font_face->GetFontSelectionCapabilities());
++ result.stored_value->value =
++ CSSSegmentedFontFace::Create(font_face->GetFontSelectionCapabilities());
+ }
+
+ result.stored_value->value->AddFontFace(font_face, css_connected);
+--- a/third_party/blink/renderer/core/css/local_font_face_source.cc
++++ b/third_party/blink/renderer/core/css/local_font_face_source.cc
+@@ -52,22 +52,23 @@ bool LocalFontFaceSource::IsLocalFontAva
+ return font_available;
+ }
+
+-const SimpleFontData* LocalFontFaceSource::CreateLoadingFallbackFontData(
++scoped_refptr<SimpleFontData>
++LocalFontFaceSource::CreateLoadingFallbackFontData(
+ const FontDescription& font_description) {
+ FontCachePurgePreventer font_cache_purge_preventer;
+- const SimpleFontData* temporary_font =
+- FontCache::Get().GetLastResortFallbackFont(font_description);
++ scoped_refptr<SimpleFontData> temporary_font =
++ FontCache::Get().GetLastResortFallbackFont(font_description,
++ kDoNotRetain);
+ if (!temporary_font) {
+ NOTREACHED();
+ return nullptr;
+ }
+- CSSCustomFontData* css_font_data = MakeGarbageCollected<CSSCustomFontData>(
+- this, CSSCustomFontData::kVisibleFallback);
+- return MakeGarbageCollected<SimpleFontData>(&temporary_font->PlatformData(),
+- css_font_data);
++ scoped_refptr<CSSCustomFontData> css_font_data =
++ CSSCustomFontData::Create(this, CSSCustomFontData::kVisibleFallback);
++ return SimpleFontData::Create(temporary_font->PlatformData(), css_font_data);
+ }
+
+-const SimpleFontData* LocalFontFaceSource::CreateFontData(
++scoped_refptr<SimpleFontData> LocalFontFaceSource::CreateFontData(
+ const FontDescription& font_description,
+ const FontSelectionCapabilities&) {
+ if (!IsValid()) {
+@@ -84,9 +85,9 @@ const SimpleFontData* LocalFontFaceSourc
+ }
+
+ if (IsValid() && IsLoading()) {
+- const SimpleFontData* fallback_font_data =
++ scoped_refptr<SimpleFontData> fallback_font_data =
+ CreateLoadingFallbackFontData(font_description);
+- ReportFontLookup(font_description, fallback_font_data,
++ ReportFontLookup(font_description, fallback_font_data.get(),
+ true /* is_loading_fallback */);
+ return fallback_font_data;
+ }
+@@ -110,10 +111,10 @@ const SimpleFontData* LocalFontFaceSourc
+ #endif
+ // TODO(https://crbug.com/1302264): Enable passing down of font-palette
+ // information here (font_description.GetFontPalette()).
+- const SimpleFontData* font_data = FontCache::Get().GetFontData(
++ scoped_refptr<SimpleFontData> font_data = FontCache::Get().GetFontData(
+ unstyled_description, font_name_, AlternateFontName::kLocalUniqueFace);
+- histograms_.Record(font_data);
+- ReportFontLookup(unstyled_description, font_data);
++ histograms_.Record(font_data.get());
++ ReportFontLookup(unstyled_description, font_data.get());
+ return font_data;
+ }
+
+@@ -132,7 +133,7 @@ void LocalFontFaceSource::BeginLoadIfNee
+ }
+
+ void LocalFontFaceSource::NotifyFontUniqueNameLookupReady() {
+- ClearTable();
++ PruneTable();
+
+ if (face_->FontLoaded(this)) {
+ font_selector_->FontFaceInvalidated(
+@@ -168,7 +169,7 @@ void LocalFontFaceSource::Trace(Visitor*
+
+ void LocalFontFaceSource::ReportFontLookup(
+ const FontDescription& font_description,
+- const SimpleFontData* font_data,
++ SimpleFontData* font_data,
+ bool is_loading_fallback) {
+ font_selector_->ReportFontLookupByUniqueNameOnly(
+ font_name_, font_description, font_data, is_loading_fallback);
+--- a/third_party/blink/renderer/core/css/local_font_face_source.h
++++ b/third_party/blink/renderer/core/css/local_font_face_source.h
+@@ -48,15 +48,16 @@ class LocalFontFaceSource final : public
+ void NotifyFontUniqueNameLookupReady();
+
+ protected:
+- const SimpleFontData* CreateLoadingFallbackFontData(const FontDescription&);
++ scoped_refptr<SimpleFontData> CreateLoadingFallbackFontData(
++ const FontDescription&);
+
+ private:
+- const SimpleFontData* CreateFontData(
++ scoped_refptr<SimpleFontData> CreateFontData(
+ const FontDescription&,
+ const FontSelectionCapabilities&) override;
+
+ void ReportFontLookup(const FontDescription& font_description,
+- const SimpleFontData* font_data,
++ SimpleFontData* font_data,
+ bool is_loading_fallback = false) override;
+
+ class LocalFontHistograms {
+--- a/third_party/blink/renderer/core/css/offscreen_font_selector.cc
++++ b/third_party/blink/renderer/core/css/offscreen_font_selector.cc
+@@ -39,7 +39,7 @@ void OffscreenFontSelector::RegisterForI
+ void OffscreenFontSelector::UnregisterForInvalidationCallbacks(
+ FontSelectorClient* client) {}
+
+-const FontData* OffscreenFontSelector::GetFontData(
++scoped_refptr<FontData> OffscreenFontSelector::GetFontData(
+ const FontDescription& font_description,
+ const FontFamily& font_family) {
+ const auto& family_name = font_family.FamilyName();
+@@ -60,11 +60,11 @@ const FontData* OffscreenFontSelector::G
+ family_name, font_description.GetScript(),
+ font_description.GenericFamily(), settings_family_name);
+
+- const auto* font_data =
++ auto font_data =
+ FontCache::Get().GetFontData(font_description, settings_family_name);
+
+ ReportFontLookupByUniqueOrFamilyName(settings_family_name, font_description,
+- font_data);
++ font_data.get());
+
+ return font_data;
+ }
+--- a/third_party/blink/renderer/core/css/offscreen_font_selector.h
++++ b/third_party/blink/renderer/core/css/offscreen_font_selector.h
+@@ -26,8 +26,8 @@ class CORE_EXPORT OffscreenFontSelector
+
+ unsigned Version() const override { return 1; }
+
+- const FontData* GetFontData(const FontDescription&,
+- const FontFamily&) override;
++ scoped_refptr<FontData> GetFontData(const FontDescription&,
++ const FontFamily&) override;
+
+ void RegisterForInvalidationCallbacks(FontSelectorClient*) override;
+ void UnregisterForInvalidationCallbacks(FontSelectorClient*) override;
+--- a/third_party/blink/renderer/core/css/remote_font_face_source.cc
++++ b/third_party/blink/renderer/core/css/remote_font_face_source.cc
+@@ -240,7 +240,8 @@ void RemoteFontFaceSource::NotifyFinishe
+ }
+
+ ClearResource();
+- ClearTable();
++
++ PruneTable();
+
+ if (GetDocument()) {
+ if (!GetDocument()->RenderingHasBegun()) {
+@@ -305,7 +306,7 @@ bool RemoteFontFaceSource::UpdatePeriod(
+ // Invalidate the font if its fallback visibility has changed.
+ if (IsLoading() && period_ != new_period &&
+ (period_ == kBlockPeriod || new_period == kBlockPeriod)) {
+- ClearTable();
++ PruneTable();
+ if (face_->FallbackVisibilityChanged(this)) {
+ font_selector_->FontFaceInvalidated(
+ FontInvalidationReason::kGeneralInvalidation);
+@@ -349,7 +350,7 @@ bool RemoteFontFaceSource::IsLowPriority
+ return is_intervention_triggered_;
+ }
+
+-const SimpleFontData* RemoteFontFaceSource::CreateFontData(
++scoped_refptr<SimpleFontData> RemoteFontFaceSource::CreateFontData(
+ const FontDescription& font_description,
+ const FontSelectionCapabilities& font_selection_capabilities) {
+ if (period_ == kFailurePeriod || !IsValid()) {
+@@ -362,7 +363,7 @@ const SimpleFontData* RemoteFontFaceSour
+
+ histograms_.RecordFallbackTime();
+
+- return MakeGarbageCollected<SimpleFontData>(
++ return SimpleFontData::Create(
+ custom_font_data_->GetFontPlatformData(
+ font_description.EffectiveFontSize(),
+ font_description.AdjustedSpecifiedSize(),
+@@ -379,24 +380,25 @@ const SimpleFontData* RemoteFontFaceSour
+ : ResolvedFontFeatures(),
+ font_description.Orientation(), font_description.VariationSettings(),
+ font_description.GetFontPalette()),
+- MakeGarbageCollected<CustomFontData>());
++ CustomFontData::Create());
+ }
+
+-const SimpleFontData* RemoteFontFaceSource::CreateLoadingFallbackFontData(
++scoped_refptr<SimpleFontData>
++RemoteFontFaceSource::CreateLoadingFallbackFontData(
+ const FontDescription& font_description) {
+ // This temporary font is not retained and should not be returned.
+ FontCachePurgePreventer font_cache_purge_preventer;
+- const SimpleFontData* temporary_font =
+- FontCache::Get().GetLastResortFallbackFont(font_description);
++ scoped_refptr<SimpleFontData> temporary_font =
++ FontCache::Get().GetLastResortFallbackFont(font_description,
++ kDoNotRetain);
+ if (!temporary_font) {
+ DUMP_WILL_BE_NOTREACHED_NORETURN();
+ return nullptr;
+ }
+- CSSCustomFontData* css_font_data = MakeGarbageCollected<CSSCustomFontData>(
++ scoped_refptr<CSSCustomFontData> css_font_data = CSSCustomFontData::Create(
+ this, period_ == kBlockPeriod ? CSSCustomFontData::kInvisibleFallback
+ : CSSCustomFontData::kVisibleFallback);
+- return MakeGarbageCollected<SimpleFontData>(&temporary_font->PlatformData(),
+- css_font_data);
++ return SimpleFontData::Create(temporary_font->PlatformData(), css_font_data);
+ }
+
+ void RemoteFontFaceSource::BeginLoadIfNeeded() {
+--- a/third_party/blink/renderer/core/css/remote_font_face_source.h
++++ b/third_party/blink/renderer/core/css/remote_font_face_source.h
+@@ -66,10 +66,11 @@ class RemoteFontFaceSource final : publi
+ void Trace(Visitor*) const override;
+
+ protected:
+- const SimpleFontData* CreateFontData(
++ scoped_refptr<SimpleFontData> CreateFontData(
+ const FontDescription&,
+ const FontSelectionCapabilities&) override;
+- const SimpleFontData* CreateLoadingFallbackFontData(const FontDescription&);
++ scoped_refptr<SimpleFontData> CreateLoadingFallbackFontData(
++ const FontDescription&);
+
+ private:
+ // Periods of the Font Display Timeline.
+--- a/third_party/blink/renderer/core/frame/font_matching_metrics.cc
++++ b/third_party/blink/renderer/core/frame/font_matching_metrics.cc
+@@ -127,7 +127,7 @@ void FontMatchingMetrics::ReportLocalFon
+ }
+
+ void FontMatchingMetrics::InsertFontHashIntoMap(IdentifiableTokenKey input_key,
+- const SimpleFontData* font_data,
++ SimpleFontData* font_data,
+ TokenToTokenHashMap& hash_map) {
+ DCHECK(IdentifiabilityStudyShouldSampleFonts());
+ if (hash_map.Contains(input_key)) {
+@@ -160,7 +160,7 @@ FontMatchingMetrics::GetTokenBuilderWith
+ void FontMatchingMetrics::ReportFontLookupByUniqueOrFamilyName(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) {
++ SimpleFontData* resulting_font_data) {
+ Dactyloscoper::TraceFontLookup(
+ execution_context_, name, font_description,
+ Dactyloscoper::FontLookupType::kUniqueOrFamilyName);
+@@ -184,7 +184,7 @@ void FontMatchingMetrics::ReportFontLook
+ void FontMatchingMetrics::ReportFontLookupByUniqueNameOnly(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data,
++ SimpleFontData* resulting_font_data,
+ bool is_loading_fallback) {
+ // We ignore lookups that result in loading fallbacks for now as they should
+ // only be temporary.
+@@ -217,7 +217,7 @@ void FontMatchingMetrics::ReportFontLook
+ UChar32 fallback_character,
+ FontFallbackPriority fallback_priority,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) {
++ SimpleFontData* resulting_font_data) {
+ if (!IdentifiabilityStudySettings::Get()->ShouldSampleType(
+ IdentifiableSurface::Type::kLocalFontLookupByFallbackCharacter)) {
+ return;
+@@ -236,7 +236,7 @@ void FontMatchingMetrics::ReportFontLook
+
+ void FontMatchingMetrics::ReportLastResortFallbackFontLookup(
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) {
++ SimpleFontData* resulting_font_data) {
+ if (!IdentifiabilityStudySettings::Get()->ShouldSampleType(
+ IdentifiableSurface::Type::kLocalFontLookupAsLastResort)) {
+ return;
+@@ -361,8 +361,7 @@ void FontMatchingMetrics::PublishAllMetr
+ PublishEmojiGlyphMetrics();
+ }
+
+-int64_t FontMatchingMetrics::GetHashForFontData(
+- const SimpleFontData* font_data) {
++int64_t FontMatchingMetrics::GetHashForFontData(SimpleFontData* font_data) {
+ return font_data ? FontGlobalContext::Get()
+ .GetOrComputeTypefaceDigest(font_data->PlatformData())
+ .ToUkmMetricValue()
+@@ -370,7 +369,7 @@ int64_t FontMatchingMetrics::GetHashForF
+ }
+
+ IdentifiableToken FontMatchingMetrics::GetPostScriptNameTokenForFontData(
+- const SimpleFontData* font_data) {
++ SimpleFontData* font_data) {
+ DCHECK(font_data);
+ return FontGlobalContext::Get().GetOrComputePostScriptNameDigest(
+ font_data->PlatformData());
+--- a/third_party/blink/renderer/core/frame/font_matching_metrics.h
++++ b/third_party/blink/renderer/core/frame/font_matching_metrics.h
+@@ -100,16 +100,15 @@ class FontMatchingMetrics {
+ void ReportFontLookupByUniqueOrFamilyName(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data);
++ SimpleFontData* resulting_font_data);
+
+ // Reports a local font was looked up by a name and font description. This
+ // only includes lookups where the name is allowed to match PostScript names
+ // and full font names, but not family names.
+- void ReportFontLookupByUniqueNameOnly(
+- const AtomicString& name,
+- const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data,
+- bool is_loading_fallback = false);
++ void ReportFontLookupByUniqueNameOnly(const AtomicString& name,
++ const FontDescription& font_description,
++ SimpleFontData* resulting_font_data,
++ bool is_loading_fallback = false);
+
+ // Reports a font was looked up by a fallback character, fallback priority,
+ // and a font description.
+@@ -117,12 +116,12 @@ class FontMatchingMetrics {
+ UChar32 fallback_character,
+ FontFallbackPriority fallback_priority,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data);
++ SimpleFontData* resulting_font_data);
+
+ // Reports a last-resort fallback font was looked up by a font description.
+ void ReportLastResortFallbackFontLookup(
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data);
++ SimpleFontData* resulting_font_data);
+
+ // Reports a generic font family name was matched according to the script and
+ // the user's preferences to a font family name.
+@@ -171,7 +170,7 @@ class FontMatchingMetrics {
+ // nullptr, then the typeface digest will also be saved with its PostScript
+ // name in |font_load_postscript_name_|.
+ void InsertFontHashIntoMap(IdentifiableTokenKey input_key,
+- const SimpleFontData* font_data,
++ SimpleFontData* font_data,
+ TokenToTokenHashMap& hash_map);
+
+ // Reports a local font's existence was looked up by a name, but its actual
+@@ -194,14 +193,14 @@ class FontMatchingMetrics {
+
+ // Get a hash that uniquely represents the font data. Returns 0 if |font_data|
+ // is nullptr.
+- int64_t GetHashForFontData(const SimpleFontData* font_data);
++ int64_t GetHashForFontData(SimpleFontData* font_data);
+
+ void Initialize();
+
+ // Get a token that uniquely represents the typeface's PostScript name. May
+ // represent the empty string if no PostScript name was found.
+ IdentifiableToken GetPostScriptNameTokenForFontData(
+- const SimpleFontData* font_data);
++ SimpleFontData* font_data);
+
+ TokenToTokenHashMap font_lookups_by_unique_or_family_name_;
+ TokenToTokenHashMap font_lookups_by_unique_name_only_;
+--- a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
++++ b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
+@@ -132,8 +132,8 @@ class PopupMenuCSSFontSelector : public
+
+ // We don't override willUseFontData() for now because the old PopupListBox
+ // only worked with fonts loaded when opening the popup.
+- const FontData* GetFontData(const FontDescription&,
+- const FontFamily&) override;
++ scoped_refptr<FontData> GetFontData(const FontDescription&,
++ const FontFamily&) override;
+
+ void Trace(Visitor*) const override;
+
+@@ -152,7 +152,7 @@ PopupMenuCSSFontSelector::PopupMenuCSSFo
+
+ PopupMenuCSSFontSelector::~PopupMenuCSSFontSelector() = default;
+
+-const FontData* PopupMenuCSSFontSelector::GetFontData(
++scoped_refptr<FontData> PopupMenuCSSFontSelector::GetFontData(
+ const FontDescription& description,
+ const FontFamily& font_family) {
+ return owner_font_selector_->GetFontData(description, font_family);
+--- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
++++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
+@@ -122,7 +122,6 @@
+ #include "third_party/blink/renderer/platform/fonts/font_custom_platform_data.h"
+ #include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h"
+ #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h"
+ #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+ #include "third_party/blink/renderer/platform/text/text_run.h"
+ #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+@@ -200,10 +199,10 @@ HeapVector<Member<CSSStyleRule>> FilterD
+ }
+
+ void CollectPlatformFontsFromRunFontDataList(
+- const HeapVector<ShapeResult::RunFontData>& run_font_data_list,
++ const Vector<ShapeResult::RunFontData>& run_font_data_list,
+ HashMap<std::pair<int, String>, std::pair<int, String>>* font_stats) {
+ for (const auto& run_font_data : run_font_data_list) {
+- const auto* simple_font_data = run_font_data.font_data_.Get();
++ const auto* simple_font_data = run_font_data.font_data_;
+ String family_name = simple_font_data->PlatformData().FontFamilyName();
+ if (family_name.IsNull())
+ family_name = "";
+@@ -1733,8 +1732,7 @@ void InspectorCSSAgent::CollectPlatformF
+ if (!shape_result) {
+ continue;
+ }
+- HeapVector<ShapeResult::RunFontData> run_font_data_list;
+- ClearCollectionScope clear_scope(&run_font_data_list);
++ Vector<ShapeResult::RunFontData> run_font_data_list;
+ shape_result->GetRunFontData(&run_font_data_list);
+ CollectPlatformFontsFromRunFontDataList(run_font_data_list, font_stats);
+ }
+--- a/third_party/blink/renderer/core/layout/inline/inline_box_state.cc
++++ b/third_party/blink/renderer/core/layout/inline/inline_box_state.cc
+@@ -19,7 +19,6 @@
+ #include "third_party/blink/renderer/core/style/computed_style.h"
+ #include "third_party/blink/renderer/core/svg/svg_length_functions.h"
+ #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h"
+
+ namespace blink {
+
+@@ -169,8 +168,7 @@ void InlineBoxState::EnsureTextMetrics(c
+
+ void InlineBoxState::AccumulateUsedFonts(const ShapeResultView* shape_result) {
+ const auto baseline_type = style->GetFontBaseline();
+- HeapHashSet<Member<const SimpleFontData>> fallback_fonts;
+- ClearCollectionScope clear_scope(&fallback_fonts);
++ HashSet<const SimpleFontData*> fallback_fonts;
+ shape_result->FallbackFonts(&fallback_fonts);
+ for (const SimpleFontData* const fallback_font : fallback_fonts) {
+ FontHeight fallback_metrics =
+--- a/third_party/blink/renderer/core/layout/inline/ruby_utils.cc
++++ b/third_party/blink/renderer/core/layout/inline/ruby_utils.cc
+@@ -12,7 +12,6 @@
+ #include "third_party/blink/renderer/core/layout/layout_object_inlines.h"
+ #include "third_party/blink/renderer/core/layout/physical_box_fragment.h"
+ #include "third_party/blink/renderer/platform/fonts/font_height.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h"
+
+ namespace blink {
+
+@@ -33,10 +32,11 @@ std::tuple<LayoutUnit, LayoutUnit> Adjus
+ primary_font_data->GetFontMetrics().FixedAscent(font_baseline);
+ const LayoutUnit primary_descent = line_height - primary_ascent;
+
++ DCHECK(IsMainThread());
++ DEFINE_STATIC_LOCAL(Vector<ShapeResult::RunFontData>, run_fonts, ());
++ DCHECK_EQ(run_fonts.size(), 0u);
+ // We don't use ShapeResultView::FallbackFonts() because we can't know if the
+ // primary font is actually used with FallbackFonts().
+- HeapVector<ShapeResult::RunFontData> run_fonts;
+- ClearCollectionScope clear_scope(&run_fonts);
+ shape_view.GetRunFontData(&run_fonts);
+ const LayoutUnit kNoDiff = LayoutUnit::Max();
+ LayoutUnit over_diff = kNoDiff;
+@@ -60,6 +60,7 @@ std::tuple<LayoutUnit, LayoutUnit> Adjus
+ over_diff = std::min(over_diff, current_over_diff);
+ under_diff = std::min(under_diff, current_under_diff);
+ }
++ run_fonts.resize(0);
+ if (over_diff == kNoDiff)
+ over_diff = LayoutUnit();
+ if (under_diff == kNoDiff)
+@@ -956,8 +957,7 @@ FontHeight ComputeEmHeight(const Logical
+ FontHeight result_height;
+ // We don't use ShapeResultView::FallbackFonts() because we can't know if
+ // the primary font is actually used with FallbackFonts().
+- HeapVector<ShapeResult::RunFontData> run_fonts;
+- ClearCollectionScope clear_scope(&run_fonts);
++ Vector<ShapeResult::RunFontData> run_fonts;
+ shape_result_view->GetRunFontData(&run_fonts);
+ for (const auto& run_font : run_fonts) {
+ const SimpleFontData* font_data = run_font.font_data_;
+--- a/third_party/blink/renderer/core/layout/layout_font_accessor_win.cc
++++ b/third_party/blink/renderer/core/layout/layout_font_accessor_win.cc
+@@ -16,7 +16,6 @@
+ #include "third_party/blink/renderer/platform/fonts/font_platform_data.h"
+ #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h"
+ #include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h"
+
+ namespace blink {
+
+@@ -36,8 +35,7 @@ void GetFontsUsedByFragment(const Physic
+ shape_result_view->PrimaryFont()->PlatformData().FontFamilyName();
+ if (!font_family.empty())
+ result.font_names.insert(font_family);
+- HeapHashSet<Member<const SimpleFontData>> fallback_font_data;
+- ClearCollectionScope clear_scope(&fallback_font_data);
++ HashSet<const SimpleFontData*> fallback_font_data;
+ shape_result_view->FallbackFonts(&fallback_font_data);
+ for (const SimpleFontData* font_data : fallback_font_data) {
+ result.font_names.insert(font_data->PlatformData().FontFamilyName());
+--- a/third_party/blink/renderer/modules/font_access/font_metadata.cc
++++ b/third_party/blink/renderer/modules/font_access/font_metadata.cc
+@@ -77,7 +77,7 @@ void FontMetadata::BlobImpl(ScriptPromis
+ SetUpFontUniqueLookupIfNecessary();
+
+ FontDescription description;
+- const SimpleFontData* font_data =
++ scoped_refptr<SimpleFontData> font_data =
+ FontCache::Get().GetFontData(description, AtomicString(postscriptName),
+ AlternateFontName::kLocalUniqueFace);
+ if (!font_data) {
+--- a/third_party/blink/renderer/platform/BUILD.gn
++++ b/third_party/blink/renderer/platform/BUILD.gn
+@@ -621,6 +621,7 @@ component("platform") {
+ "fonts/font_cache_memory_dump_provider.h",
+ "fonts/font_custom_platform_data.cc",
+ "fonts/font_custom_platform_data.h",
++ "fonts/font_data.cc",
+ "fonts/font_data.h",
+ "fonts/font_data_cache.cc",
+ "fonts/font_data_cache.h",
+--- a/third_party/blink/renderer/platform/fonts/android/font_cache_android.cc
++++ b/third_party/blink/renderer/platform/fonts/android/font_cache_android.cc
+@@ -127,7 +127,7 @@ sk_sp<SkTypeface> FontCache::CreateLocal
+ return nullptr;
+ }
+
+-const SimpleFontData* FontCache::PlatformFallbackFontForCharacter(
++scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
+ const FontDescription& font_description,
+ UChar32 c,
+ const SimpleFontData*,
+@@ -158,7 +158,7 @@ const SimpleFontData* FontCache::Platfor
+ if (fallback_priority == FontFallbackPriority::kEmojiEmoji &&
+ base::FeatureList::IsEnabled(features::kGMSCoreEmoji)) {
+ auto skia_fallback_is_noto_color_emoji = [&]() {
+- const FontPlatformData* skia_fallback_result = GetFontPlatformData(
++ FontPlatformData* skia_fallback_result = GetFontPlatformData(
+ font_description, FontFaceCreationParams(family_name));
+
+ // Determining the PostScript name is required as Skia on Android gives
+@@ -175,14 +175,15 @@ const SimpleFontData* FontCache::Platfor
+ };
+
+ if (family_name.empty() || skia_fallback_is_noto_color_emoji()) {
+- const FontPlatformData* emoji_gms_core_font = GetFontPlatformData(
++ FontPlatformData* emoji_gms_core_font = GetFontPlatformData(
+ font_description,
+ FontFaceCreationParams(AtomicString(kNotoColorEmojiCompat)));
+ if (emoji_gms_core_font) {
+ SkTypeface* probe_coverage_typeface = emoji_gms_core_font->Typeface();
+ if (probe_coverage_typeface &&
+ probe_coverage_typeface->unicharToGlyph(c)) {
+- return FontDataFromFontPlatformData(emoji_gms_core_font);
++ return FontDataFromFontPlatformData(emoji_gms_core_font,
++ kDoNotRetain);
+ }
+ }
+ }
+@@ -192,10 +193,12 @@ const SimpleFontData* FontCache::Platfor
+ // font was not found or an OEM emoji font was not to be overridden.
+
+ if (family_name.empty())
+- return GetLastResortFallbackFont(font_description);
++ return GetLastResortFallbackFont(font_description, kDoNotRetain);
+
+- return FontDataFromFontPlatformData(GetFontPlatformData(
+- font_description, FontFaceCreationParams(family_name)));
++ return FontDataFromFontPlatformData(
++ GetFontPlatformData(font_description,
++ FontFaceCreationParams(family_name)),
++ kDoNotRetain);
+ }
+
+ // static
+--- a/third_party/blink/renderer/platform/fonts/custom_font_data.h
++++ b/third_party/blink/renderer/platform/fonts/custom_font_data.h
+@@ -22,8 +22,8 @@
+ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_CUSTOM_FONT_DATA_H_
+
+ #include "base/memory/scoped_refptr.h"
+-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+ #include "third_party/blink/renderer/platform/platform_export.h"
++#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
+
+ namespace blink {
+
+@@ -34,17 +34,22 @@ namespace blink {
+ // * `BinaryDataFontFaceSource` as loaded font resource
+ // * `LocalFontFaceSource` as derived class `CSSCustomFontData`
+ // * `RemoteFontFaceSource` as derived class `CSSCustomFontData`
+-class PLATFORM_EXPORT CustomFontData : public GarbageCollected<CustomFontData> {
++class PLATFORM_EXPORT CustomFontData : public RefCounted<CustomFontData> {
+ public:
+- CustomFontData() = default;
++ static scoped_refptr<CustomFontData> Create() {
++ return base::AdoptRef(new CustomFontData());
++ }
++
+ virtual ~CustomFontData() = default;
+- virtual void Trace(Visitor*) const {}
+
+ virtual void BeginLoadIfNeeded() const {}
+ virtual bool IsLoading() const { return false; }
+ virtual bool IsLoadingFallback() const { return false; }
+ virtual bool ShouldSkipDrawing() const { return false; }
+ virtual bool IsPendingDataUrl() const { return false; }
++
++ protected:
++ CustomFontData() = default;
+ };
+
+ } // namespace blink
+--- a/third_party/blink/renderer/platform/fonts/font_cache.cc
++++ b/third_party/blink/renderer/platform/fonts/font_cache.cc
+@@ -87,7 +87,10 @@ FontCache& FontCache::Get() {
+ return FontGlobalContext::GetFontCache();
+ }
+
+-FontCache::FontCache() : font_manager_(sk_ref_sp(static_font_manager_)) {
++FontCache::FontCache()
++ : font_manager_(sk_ref_sp(static_font_manager_)),
++ font_platform_data_cache_(FontPlatformDataCache::Create()),
++ font_data_cache_(FontDataCache::Create()) {
+ #if BUILDFLAG(IS_WIN)
+ if (!font_manager_ || should_use_test_font_mgr) {
+ // This code path is only for unit tests. This SkFontMgr does not work in
+@@ -113,14 +116,12 @@ FontCache::~FontCache() = default;
+
+ void FontCache::Trace(Visitor* visitor) const {
+ visitor->Trace(font_cache_clients_);
+- visitor->Trace(font_platform_data_cache_);
+- visitor->Trace(fallback_list_shaper_cache_);
+- visitor->Trace(font_data_cache_);
+ visitor->Trace(font_fallback_map_);
++ visitor->Trace(fallback_list_shaper_cache_);
+ }
+
+ #if !BUILDFLAG(IS_MAC)
+-const FontPlatformData* FontCache::SystemFontPlatformData(
++FontPlatformData* FontCache::SystemFontPlatformData(
+ const FontDescription& font_description) {
+ const AtomicString& family = FontCache::SystemFontFamily();
+ #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA) || \
+@@ -135,7 +136,7 @@ const FontPlatformData* FontCache::Syste
+ }
+ #endif
+
+-const FontPlatformData* FontCache::GetFontPlatformData(
++FontPlatformData* FontCache::GetFontPlatformData(
+ const FontDescription& font_description,
+ const FontFaceCreationParams& creation_params,
+ AlternateFontName alternate_font_name) {
+@@ -153,7 +154,7 @@ const FontPlatformData* FontCache::GetFo
+ }
+ #endif
+
+- return font_platform_data_cache_.GetOrCreateFontPlatformData(
++ return font_platform_data_cache_->GetOrCreateFontPlatformData(
+ this, font_description, creation_params, alternate_font_name);
+ }
+
+@@ -175,26 +176,34 @@ void FontCache::AcceptLanguagesChanged(c
+ Get().InvalidateShapeCache();
+ }
+
+-const SimpleFontData* FontCache::GetFontData(
++scoped_refptr<SimpleFontData> FontCache::GetFontData(
+ const FontDescription& font_description,
+ const AtomicString& family,
+- AlternateFontName altername_font_name) {
+- if (const FontPlatformData* platform_data = GetFontPlatformData(
++ AlternateFontName altername_font_name,
++ ShouldRetain should_retain) {
++ if (FontPlatformData* platform_data = GetFontPlatformData(
+ font_description,
+ FontFaceCreationParams(
+ AdjustFamilyNameToAvoidUnsupportedFonts(family)),
+ altername_font_name)) {
+ return FontDataFromFontPlatformData(
+- platform_data, font_description.SubpixelAscentDescent());
++ platform_data, should_retain, font_description.SubpixelAscentDescent());
+ }
+
+ return nullptr;
+ }
+
+-const SimpleFontData* FontCache::FontDataFromFontPlatformData(
++scoped_refptr<SimpleFontData> FontCache::FontDataFromFontPlatformData(
+ const FontPlatformData* platform_data,
++ ShouldRetain should_retain,
+ bool subpixel_ascent_descent) {
+- return font_data_cache_.Get(platform_data, subpixel_ascent_descent);
++#if DCHECK_IS_ON()
++ if (should_retain == kDoNotRetain)
++ DCHECK(purge_prevent_count_);
++#endif
++
++ return font_data_cache_->Get(platform_data, should_retain,
++ subpixel_ascent_descent);
+ }
+
+ bool FontCache::IsPlatformFamilyMatchAvailable(
+@@ -223,7 +232,15 @@ String FontCache::FirstAvailableOrFirst(
+ gfx::FontList::FirstAvailableOrFirst(families.Utf8().c_str()));
+ }
+
+-const SimpleFontData* FontCache::FallbackFontForCharacter(
++SimpleFontData* FontCache::GetNonRetainedLastResortFallbackFont(
++ const FontDescription& font_description) {
++ auto font = GetLastResortFallbackFont(font_description, kDoNotRetain);
++ if (font)
++ font->AddRef();
++ return font.get();
++}
++
++scoped_refptr<SimpleFontData> FontCache::FallbackFontForCharacter(
+ const FontDescription& description,
+ UChar32 lookup_char,
+ const SimpleFontData* font_data_to_substitute,
+@@ -240,12 +257,21 @@ const SimpleFontData* FontCache::Fallbac
+ Character::IsNonCharacter(lookup_char))
+ return nullptr;
+ base::ElapsedTimer timer;
+- const SimpleFontData* result = PlatformFallbackFontForCharacter(
++ scoped_refptr<SimpleFontData> result = PlatformFallbackFontForCharacter(
+ description, lookup_char, font_data_to_substitute, fallback_priority);
+ FontPerformance::AddSystemFallbackFontTime(timer.Elapsed());
+ return result;
+ }
+
++void FontCache::ReleaseFontData(const SimpleFontData* font_data) {
++ font_data_cache_->Release(font_data);
++}
++
++void FontCache::PurgePlatformFontDataCache() {
++ TRACE_EVENT0("fonts,ui", "FontCache::PurgePlatformFontDataCache");
++ font_platform_data_cache_->Purge(*font_data_cache_);
++}
++
+ void FontCache::PurgeFallbackListShaperCache() {
+ TRACE_EVENT0("fonts,ui", "FontCache::PurgeFallbackListShaperCache");
+ for (auto& shape_cache : fallback_list_shaper_cache_.Values()) {
+@@ -257,13 +283,17 @@ void FontCache::InvalidateShapeCache() {
+ PurgeFallbackListShaperCache();
+ }
+
+-void FontCache::Purge() {
++void FontCache::Purge(PurgeSeverity purge_severity) {
+ // Ideally we should never be forcing the purge while the
+ // FontCachePurgePreventer is in scope, but we call purge() at any timing
+ // via MemoryPressureListenerRegistry.
+ if (purge_prevent_count_)
+ return;
+
++ if (!font_data_cache_->Purge(purge_severity))
++ return;
++
++ PurgePlatformFontDataCache();
+ PurgeFallbackListShaperCache();
+ }
+
+@@ -279,15 +309,14 @@ uint16_t FontCache::Generation() {
+
+ void FontCache::Invalidate() {
+ TRACE_EVENT0("fonts,ui", "FontCache::Invalidate");
+- font_platform_data_cache_.Clear();
+- font_data_cache_.Clear();
++ font_platform_data_cache_->Clear();
+ generation_++;
+
+ for (const auto& client : font_cache_clients_) {
+ client->FontCacheInvalidated();
+ }
+
+- Purge();
++ Purge(kForcePurge);
+ }
+
+ void FontCache::CrashWithFontInfo(const FontDescription* font_description) {
+@@ -320,6 +349,16 @@ void FontCache::CrashWithFontInfo(const
+ CHECK(false);
+ }
+
++void FontCache::DumpFontPlatformDataCache(
++ base::trace_event::ProcessMemoryDump* memory_dump) {
++ DCHECK(IsMainThread());
++ base::trace_event::MemoryAllocatorDump* dump =
++ memory_dump->CreateAllocatorDump("font_caches/font_platform_data_cache");
++ dump->AddScalar("size", "bytes", font_platform_data_cache_->ByteSize());
++ memory_dump->AddSuballocation(dump->guid(),
++ WTF::Partitions::kAllocatedObjectPoolName);
++}
++
+ void FontCache::DumpShapeResultCache(
+ base::trace_event::ProcessMemoryDump* memory_dump) {
+ DCHECK(IsMainThread());
+--- a/third_party/blink/renderer/platform/fonts/font_cache.h
++++ b/third_party/blink/renderer/platform/fonts/font_cache.h
+@@ -36,13 +36,13 @@
+ #include <string>
+
+ #include "base/gtest_prod_util.h"
++#include "base/memory/scoped_refptr.h"
+ #include "build/build_config.h"
+ #include "third_party/blink/renderer/platform/fonts/fallback_list_composite_key.h"
+ #include "third_party/blink/renderer/platform/fonts/font_cache_client.h"
+ #include "third_party/blink/renderer/platform/fonts/font_data_cache.h"
+ #include "third_party/blink/renderer/platform/fonts/font_face_creation_params.h"
+ #include "third_party/blink/renderer/platform/fonts/font_fallback_priority.h"
+-#include "third_party/blink/renderer/platform/fonts/font_platform_data_cache.h"
+ #include "third_party/blink/renderer/platform/fonts/shaping/shape_cache.h"
+ #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
+ #include "third_party/blink/renderer/platform/platform_export.h"
+@@ -75,6 +75,7 @@ class FontFaceCreationParams;
+ class FontFallbackMap;
+ class FontGlobalContext;
+ class FontPlatformData;
++class FontPlatformDataCache;
+ class SimpleFontData;
+ class WebFontPrewarmer;
+
+@@ -106,7 +107,9 @@ class PLATFORM_EXPORT FontCache final {
+
+ void Trace(Visitor*) const;
+
+- const SimpleFontData* FallbackFontForCharacter(
++ void ReleaseFontData(const SimpleFontData*);
++
++ scoped_refptr<SimpleFontData> FallbackFontForCharacter(
+ const FontDescription&,
+ UChar32,
+ const SimpleFontData* font_data_to_substitute,
+@@ -115,11 +118,14 @@ class PLATFORM_EXPORT FontCache final {
+ // Also implemented by the platform.
+ void PlatformInit();
+
+- const SimpleFontData* GetFontData(
++ scoped_refptr<SimpleFontData> GetFontData(
+ const FontDescription&,
+ const AtomicString&,
+- AlternateFontName = AlternateFontName::kAllowAlternate);
+- const SimpleFontData* GetLastResortFallbackFont(const FontDescription&);
++ AlternateFontName = AlternateFontName::kAllowAlternate,
++ ShouldRetain = kRetain);
++ scoped_refptr<SimpleFontData> GetLastResortFallbackFont(const FontDescription&,
++ ShouldRetain = kRetain);
++ SimpleFontData* GetNonRetainedLastResortFallbackFont(const FontDescription&);
+
+ // Should be used in determining whether family names listed in font-family:
+ // ... are available locally. Only returns true if family name matches.
+@@ -212,12 +218,12 @@ class PLATFORM_EXPORT FontCache final {
+ return *status_font_family_name_;
+ }
+
+- const SimpleFontData* GetFallbackFamilyNameFromHardcodedChoices(
++ scoped_refptr<SimpleFontData> GetFallbackFamilyNameFromHardcodedChoices(
+ const FontDescription&,
+ UChar32 codepoint,
+ FontFallbackPriority fallback_priority);
+
+- const SimpleFontData* GetDWriteFallbackFamily(
++ scoped_refptr<SimpleFontData> GetDWriteFallbackFamily(
+ const FontDescription&,
+ UChar32 codepoint,
+ FontFallbackPriority fallback_priority);
+@@ -245,8 +251,9 @@ class PLATFORM_EXPORT FontCache final {
+ gfx::FallbackFontData*);
+ #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+
+- const SimpleFontData* FontDataFromFontPlatformData(
++ scoped_refptr<SimpleFontData> FontDataFromFontPlatformData(
+ const FontPlatformData*,
++ ShouldRetain = kRetain,
+ bool subpixel_ascent_descent = false);
+
+ void InvalidateShapeCache();
+@@ -254,6 +261,7 @@ class PLATFORM_EXPORT FontCache final {
+ static void CrashWithFontInfo(const FontDescription*);
+
+ // Memory reporting
++ void DumpFontPlatformDataCache(base::trace_event::ProcessMemoryDump*);
+ void DumpShapeResultCache(base::trace_event::ProcessMemoryDump*);
+
+ FontFallbackMap& GetFontFallbackMap();
+@@ -268,7 +276,7 @@ class PLATFORM_EXPORT FontCache final {
+ // elements.
+ using Bcp47Vector = WTF::Vector<const char*, 4>;
+
+- const SimpleFontData* PlatformFallbackFontForCharacter(
++ scoped_refptr<SimpleFontData> PlatformFallbackFontForCharacter(
+ const FontDescription&,
+ UChar32,
+ const SimpleFontData* font_data_to_substitute,
+@@ -283,26 +291,26 @@ class PLATFORM_EXPORT FontCache final {
+ friend class FontGlobalContext;
+ FontCache();
+
+- void Purge();
++ void Purge(PurgeSeverity = kPurgeIfNeeded);
+
+ void DisablePurging() { purge_prevent_count_++; }
+ void EnablePurging() {
+ DCHECK(purge_prevent_count_);
+ if (!--purge_prevent_count_)
+- Purge();
++ Purge(kPurgeIfNeeded);
+ }
+
+ // FIXME: This method should eventually be removed.
+- const FontPlatformData* GetFontPlatformData(
++ FontPlatformData* GetFontPlatformData(
+ const FontDescription&,
+ const FontFaceCreationParams&,
+ AlternateFontName = AlternateFontName::kAllowAlternate);
+ #if !BUILDFLAG(IS_MAC)
+- const FontPlatformData* SystemFontPlatformData(const FontDescription&);
++ FontPlatformData* SystemFontPlatformData(const FontDescription&);
+ #endif // !BUILDFLAG(IS_MAC)
+
+ // These methods are implemented by each platform.
+- const FontPlatformData* CreateFontPlatformData(
++ std::unique_ptr<FontPlatformData> CreateFontPlatformData(
+ const FontDescription&,
+ const FontFaceCreationParams&,
+ float font_size,
+@@ -321,8 +329,9 @@ class PLATFORM_EXPORT FontCache final {
+ #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) ||
+ // BUILDFLAG(IS_CHROMEOS)
+
+- const SimpleFontData* FallbackOnStandardFontStyle(const FontDescription&,
+- UChar32);
++ scoped_refptr<SimpleFontData> FallbackOnStandardFontStyle(
++ const FontDescription&,
++ UChar32);
+
+ // Don't purge if this count is > 0;
+ int purge_prevent_count_ = 0;
+@@ -356,16 +365,17 @@ class PLATFORM_EXPORT FontCache final {
+ uint16_t generation_ = 0;
+ bool platform_init_ = false;
+ HeapHashSet<WeakMember<FontCacheClient>> font_cache_clients_;
+- FontPlatformDataCache font_platform_data_cache_;
++ std::unique_ptr<FontPlatformDataCache> font_platform_data_cache_;
+ HeapHashMap<FallbackListCompositeKey,
+ WeakMember<ShapeCache>,
+ FallbackListCompositeKeyTraits>
+ fallback_list_shaper_cache_;
+
+- FontDataCache font_data_cache_;
++ std::unique_ptr<FontDataCache> font_data_cache_;
+
+ Member<FontFallbackMap> font_fallback_map_;
+
++ void PurgePlatformFontDataCache();
+ void PurgeFallbackListShaperCache();
+
+ friend class SimpleFontData; // For fontDataFromFontPlatformData
+--- a/third_party/blink/renderer/platform/fonts/font_cache_memory_dump_provider.cc
++++ b/third_party/blink/renderer/platform/fonts/font_cache_memory_dump_provider.cc
+@@ -21,6 +21,7 @@ bool FontCacheMemoryDumpProvider::OnMemo
+ DCHECK(IsMainThread());
+ if (auto* context = FontGlobalContext::TryGet()) {
+ FontCache& cache = context->GetFontCache();
++ cache.DumpFontPlatformDataCache(memory_dump);
+ cache.DumpShapeResultCache(memory_dump);
+ }
+ return true;
+--- a/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc
++++ b/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc
+@@ -103,7 +103,7 @@ FontCustomPlatformData::~FontCustomPlatf
+ }
+ }
+
+-const FontPlatformData* FontCustomPlatformData::GetFontPlatformData(
++FontPlatformData FontCustomPlatformData::GetFontPlatformData(
+ float size,
+ float adjusted_specified_size,
+ bool bold,
+@@ -276,11 +276,10 @@ const FontPlatformData* FontCustomPlatfo
+ return_typeface = palette_typeface;
+ }
+ }
+- return MakeGarbageCollected<FontPlatformData>(
+- std::move(return_typeface), std::string(), size,
+- synthetic_bold && !base_typeface_->isBold(),
+- synthetic_italic && !base_typeface_->isItalic(), text_rendering,
+- resolved_font_features, orientation);
++ return FontPlatformData(std::move(return_typeface), std::string(), size,
++ synthetic_bold && !base_typeface_->isBold(),
++ synthetic_italic && !base_typeface_->isItalic(),
++ text_rendering, resolved_font_features, orientation);
+ }
+
+ Vector<VariationAxis> FontCustomPlatformData::GetVariationAxes() const {
+--- a/third_party/blink/renderer/platform/fonts/font_custom_platform_data.h
++++ b/third_party/blink/renderer/platform/fonts/font_custom_platform_data.h
+@@ -68,7 +68,7 @@ class PLATFORM_EXPORT FontCustomPlatform
+ // adjusted_specified_size should come from AdjustedSpecifiedSize() of
+ // FontDescription. The latter is needed for correctly applying
+ // font-optical-sizing: auto; independent of zoom level.
+- const FontPlatformData* GetFontPlatformData(
++ FontPlatformData GetFontPlatformData(
+ float size,
+ float adjusted_specified_size,
+ bool bold,
+--- /dev/null
++++ b/third_party/blink/renderer/platform/fonts/font_data.cc
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (C) 2008 Apple Inc. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
++ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include "third_party/blink/renderer/platform/fonts/font_data.h"
++
++namespace blink {
++
++FontData::~FontData() = default;
++
++} // namespace blink
+--- a/third_party/blink/renderer/platform/fonts/font_data.h
++++ b/third_party/blink/renderer/platform/fonts/font_data.h
+@@ -27,24 +27,23 @@
+ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_DATA_H_
+
+ #include "base/memory/scoped_refptr.h"
+-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+ #include "third_party/blink/renderer/platform/platform_export.h"
+ #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+ #include "third_party/blink/renderer/platform/wtf/forward.h"
+ #include "third_party/blink/renderer/platform/wtf/text/wtf_uchar.h"
++#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
+
+ namespace blink {
+
+ class SimpleFontData;
+
+-class PLATFORM_EXPORT FontData : public GarbageCollected<FontData> {
++class PLATFORM_EXPORT FontData : public RefCounted<FontData> {
+ public:
+ FontData() = default;
+ FontData(const FontData&) = delete;
+ FontData& operator=(const FontData&) = delete;
+- virtual ~FontData() = default;
+
+- virtual void Trace(Visitor*) const {}
++ virtual ~FontData();
+
+ virtual const SimpleFontData* FontDataForCharacter(UChar32) const = 0;
+ virtual bool IsCustomFont() const = 0;
+--- a/third_party/blink/renderer/platform/fonts/font_data_cache.cc
++++ b/third_party/blink/renderer/platform/fonts/font_data_cache.cc
+@@ -36,8 +36,23 @@
+
+ namespace blink {
+
+-const SimpleFontData* FontDataCache::Get(const FontPlatformData* platform_data,
+- bool subpixel_ascent_descent) {
++#if !BUILDFLAG(IS_ANDROID)
++const unsigned kCMaxInactiveFontData = 250;
++const unsigned kCTargetInactiveFontData = 200;
++#else
++const unsigned kCMaxInactiveFontData = 225;
++const unsigned kCTargetInactiveFontData = 200;
++#endif
++
++// static
++std::unique_ptr<FontDataCache> FontDataCache::Create() {
++ return std::make_unique<FontDataCache>();
++}
++
++scoped_refptr<SimpleFontData> FontDataCache::Get(
++ const FontPlatformData* platform_data,
++ ShouldRetain should_retain,
++ bool subpixel_ascent_descent) {
+ if (!platform_data)
+ return nullptr;
+
+@@ -50,12 +65,98 @@ const SimpleFontData* FontDataCache::Get
+ return nullptr;
+ }
+
+- auto add_result = cache_.insert(platform_data, nullptr);
+- if (add_result.is_new_entry) {
+- add_result.stored_value->value = MakeGarbageCollected<SimpleFontData>(
+- platform_data, nullptr, subpixel_ascent_descent);
++ Cache::iterator result = cache_.find(platform_data);
++ if (result == cache_.end()) {
++ std::pair<scoped_refptr<SimpleFontData>, unsigned> new_value(
++ SimpleFontData::Create(*platform_data, nullptr,
++ subpixel_ascent_descent),
++ should_retain == kRetain ? 1 : 0);
++ // The new SimpleFontData takes a copy of the incoming FontPlatformData
++ // object. The incoming key may be temporary. So, for cache storage, take
++ // the address of the newly created FontPlatformData that is copied an owned
++ // by SimpleFontData.
++ cache_.Set(&new_value.first->PlatformData(), new_value);
++ if (should_retain == kDoNotRetain)
++ inactive_font_data_.insert(new_value.first);
++ return std::move(new_value.first);
++ }
++
++ if (!result.Get()->value.second) {
++ DCHECK(inactive_font_data_.Contains(result.Get()->value.first));
++ inactive_font_data_.erase(result.Get()->value.first);
++ }
++
++ if (should_retain == kRetain) {
++ result.Get()->value.second++;
++ } else if (!result.Get()->value.second) {
++ // If shouldRetain is DoNotRetain and count is 0, we want to remove the
++ // fontData from m_inactiveFontData (above) and re-add here to update LRU
++ // position.
++ inactive_font_data_.insert(result.Get()->value.first);
++ }
++
++ return result.Get()->value.first;
++}
++
++bool FontDataCache::Contains(const FontPlatformData* font_platform_data) const {
++ return cache_.Contains(font_platform_data);
++}
++
++void FontDataCache::Release(const SimpleFontData* font_data) {
++ DCHECK(!font_data->IsCustomFont());
++
++ Cache::iterator it = cache_.find(&(font_data->PlatformData()));
++ if (it == cache_.end())
++ return;
++
++ DCHECK(it->value.second);
++ if (!--it->value.second)
++ inactive_font_data_.insert(it->value.first);
++}
++
++bool FontDataCache::Purge(PurgeSeverity purge_severity) {
++ if (purge_severity == kForcePurge)
++ return PurgeLeastRecentlyUsed(INT_MAX);
++
++ if (inactive_font_data_.size() > kCMaxInactiveFontData)
++ return PurgeLeastRecentlyUsed(inactive_font_data_.size() -
++ kCTargetInactiveFontData);
++
++ return false;
++}
++
++bool FontDataCache::PurgeLeastRecentlyUsed(int count) {
++ // Guard against reentry when e.g. a deleted FontData releases its small caps
++ // FontData.
++ if (is_purging_)
++ return false;
++
++ base::AutoReset<bool> is_purging_auto_reset(&is_purging_, true);
++
++ Vector<scoped_refptr<SimpleFontData>, 20> font_data_to_delete;
++ auto end = inactive_font_data_.end();
++ auto it = inactive_font_data_.begin();
++ for (int i = 0; i < count && it != end; ++it, ++i) {
++ const scoped_refptr<SimpleFontData>& font_data = *it;
++ cache_.erase(&(font_data->PlatformData()));
++ // We should not delete SimpleFontData here because deletion can modify
++ // m_inactiveFontData. See http://trac.webkit.org/changeset/44011
++ font_data_to_delete.push_back(font_data);
++ }
++
++ if (it == end) {
++ // Removed everything
++ inactive_font_data_.clear();
++ } else {
++ for (int i = 0; i < count; ++i)
++ inactive_font_data_.erase(inactive_font_data_.begin());
+ }
+- return add_result.stored_value->value;
++
++ bool did_work = font_data_to_delete.size();
++
++ font_data_to_delete.clear();
++
++ return did_work;
+ }
+
+ } // namespace blink
+--- a/third_party/blink/renderer/platform/fonts/font_data_cache.h
++++ b/third_party/blink/renderer/platform/fonts/font_data_cache.h
+@@ -33,10 +33,14 @@
+
+ #include "third_party/blink/renderer/platform/fonts/font_platform_data.h"
+ #include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
++#include "third_party/blink/renderer/platform/wtf/hash_map.h"
++#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
+
+ namespace blink {
+
++enum ShouldRetain { kRetain, kDoNotRetain };
++enum PurgeSeverity { kPurgeIfNeeded, kForcePurge };
++
+ struct FontDataCacheKeyHashTraits : GenericHashTraits<const FontPlatformData*> {
+ STATIC_ONLY(FontDataCacheKeyHashTraits);
+ static unsigned GetHash(const FontPlatformData* platform_data) {
+@@ -51,24 +55,36 @@ struct FontDataCacheKeyHashTraits : Gene
+ };
+
+ class FontDataCache final {
+- DISALLOW_NEW();
++ USING_FAST_MALLOC(FontDataCache);
+
+ public:
++ static std::unique_ptr<FontDataCache> Create();
++
+ FontDataCache() = default;
+ FontDataCache(const FontDataCache&) = delete;
+ FontDataCache& operator=(const FontDataCache&) = delete;
+
+- void Trace(Visitor* visitor) const { visitor->Trace(cache_); }
+-
+- const SimpleFontData* Get(const FontPlatformData*,
+- bool subpixel_ascent_descent = false);
+- void Clear() { cache_.clear(); }
++ scoped_refptr<SimpleFontData> Get(const FontPlatformData*,
++ ShouldRetain = kRetain,
++ bool subpixel_ascent_descent = false);
++ bool Contains(const FontPlatformData*) const;
++ void Release(const SimpleFontData*);
++
++ // Purges items in FontDataCache according to provided severity.
++ // Returns true if any removal of cache items actually occurred.
++ bool Purge(PurgeSeverity);
+
+ private:
+- HeapHashMap<Member<const FontPlatformData>,
+- WeakMember<const SimpleFontData>,
+- FontDataCacheKeyHashTraits>
+- cache_;
++ bool PurgeLeastRecentlyUsed(int count);
++
++ typedef HashMap<const FontPlatformData*,
++ std::pair<scoped_refptr<SimpleFontData>, unsigned>,
++ FontDataCacheKeyHashTraits>
++ Cache;
++
++ Cache cache_;
++ LinkedHashSet<scoped_refptr<SimpleFontData>> inactive_font_data_;
++ bool is_purging_ = false;
+ };
+
+ } // namespace blink
+--- a/third_party/blink/renderer/platform/fonts/font_data_for_range_set.cc
++++ b/third_party/blink/renderer/platform/fonts/font_data_for_range_set.cc
+@@ -13,4 +13,10 @@ FontDataForRangeSet::FontDataForRangeSet
+ range_set_ = other.range_set_;
+ }
+
++FontDataForRangeSetFromCache::~FontDataForRangeSetFromCache() {
++ if (font_data_ && !font_data_->IsCustomFont()) {
++ FontCache::Get().ReleaseFontData(font_data_.get());
++ }
++}
++
+ } // namespace blink
+--- a/third_party/blink/renderer/platform/fonts/font_data_for_range_set.h
++++ b/third_party/blink/renderer/platform/fonts/font_data_for_range_set.h
+@@ -37,19 +37,17 @@ namespace blink {
+ class SimpleFontData;
+
+ class PLATFORM_EXPORT FontDataForRangeSet
+- : public GarbageCollected<FontDataForRangeSet> {
++ : public RefCounted<FontDataForRangeSet> {
+ public:
+ explicit FontDataForRangeSet(
+- const SimpleFontData* font_data = nullptr,
++ scoped_refptr<SimpleFontData> font_data = nullptr,
+ scoped_refptr<UnicodeRangeSet> range_set = nullptr)
+- : font_data_(font_data), range_set_(std::move(range_set)) {}
++ : font_data_(std::move(font_data)), range_set_(std::move(range_set)) {}
+
+ FontDataForRangeSet(const FontDataForRangeSet& other);
+
+ virtual ~FontDataForRangeSet() = default;
+
+- void Trace(Visitor* visitor) const { visitor->Trace(font_data_); }
+-
+ bool Contains(UChar32 test_char) const {
+ return !range_set_ || range_set_->Contains(test_char);
+ }
+@@ -57,8 +55,8 @@ class PLATFORM_EXPORT FontDataForRangeSe
+ return !range_set_ || range_set_->IsEntireRange();
+ }
+ UnicodeRangeSet* Ranges() const { return range_set_.get(); }
+- bool HasFontData() const { return font_data_; }
+- const SimpleFontData* FontData() const { return font_data_.Get(); }
++ bool HasFontData() const { return font_data_.get(); }
++ const SimpleFontData* FontData() const { return font_data_.get(); }
+
+ // TODO(xiaochengh): |FontData::IsLoadingFallback()| returns true if the
+ // FontData is a pending custom font. We should rename it for better clarity.
+@@ -71,10 +69,20 @@ class PLATFORM_EXPORT FontDataForRangeSe
+ }
+
+ protected:
+- Member<const SimpleFontData> font_data_;
++ scoped_refptr<SimpleFontData> font_data_;
+ scoped_refptr<UnicodeRangeSet> range_set_;
+ };
+
++class PLATFORM_EXPORT FontDataForRangeSetFromCache
++ : public FontDataForRangeSet {
++ public:
++ explicit FontDataForRangeSetFromCache(
++ scoped_refptr<SimpleFontData> font_data,
++ scoped_refptr<UnicodeRangeSet> range_set = nullptr)
++ : FontDataForRangeSet(std::move(font_data), std::move(range_set)) {}
++ ~FontDataForRangeSetFromCache() override;
++};
++
+ } // namespace blink
+
+ #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_DATA_FOR_RANGE_SET_H_
+--- a/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
++++ b/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc
+@@ -60,8 +60,8 @@ void FontFallbackIterator::WillUseRange(
+ selector->WillUseRange(font_description_, family, range_set);
+ }
+
+-FontDataForRangeSet* FontFallbackIterator::UniqueOrNext(
+- FontDataForRangeSet* candidate,
++scoped_refptr<FontDataForRangeSet> FontFallbackIterator::UniqueOrNext(
++ scoped_refptr<FontDataForRangeSet> candidate,
+ const Vector<UChar32>& hint_list) {
+ if (!candidate->HasFontData())
+ return Next(hint_list);
+@@ -104,18 +104,18 @@ bool FontFallbackIterator::NeedsHintList
+ return font_data->IsSegmented();
+ }
+
+-FontDataForRangeSet* FontFallbackIterator::Next(
++scoped_refptr<FontDataForRangeSet> FontFallbackIterator::Next(
+ const Vector<UChar32>& hint_list) {
+ if (fallback_stage_ == kOutOfLuck)
+- return MakeGarbageCollected<FontDataForRangeSet>();
++ return base::AdoptRef(new FontDataForRangeSet());
+
+ if (fallback_stage_ == kFallbackPriorityFonts) {
+ // Only try one fallback priority font,
+ // then proceed to regular system fallback.
+ fallback_stage_ = kSystemFonts;
+- FontDataForRangeSet* fallback_priority_font_range =
+- MakeGarbageCollected<FontDataForRangeSet>(
+- FallbackPriorityFont(hint_list[0]));
++ scoped_refptr<FontDataForRangeSet> fallback_priority_font_range =
++ base::AdoptRef(
++ new FontDataForRangeSet(FallbackPriorityFont(hint_list[0])));
+ if (fallback_priority_font_range->HasFontData())
+ return UniqueOrNext(std::move(fallback_priority_font_range), hint_list);
+ return Next(hint_list);
+@@ -123,11 +123,11 @@ FontDataForRangeSet* FontFallbackIterato
+
+ if (fallback_stage_ == kSystemFonts) {
+ // We've reached pref + system fallback.
+- const SimpleFontData* system_font = UniqueSystemFontForHintList(hint_list);
++ scoped_refptr<SimpleFontData> system_font = UniqueSystemFontForHintList(hint_list);
+ if (system_font) {
+ // Fallback fonts are not retained in the FontDataCache.
+- return UniqueOrNext(
+- MakeGarbageCollected<FontDataForRangeSet>(system_font), hint_list);
++ return UniqueOrNext(base::AdoptRef(new FontDataForRangeSet(system_font)),
++ hint_list);
+ }
+
+ // If we don't have options from the system fallback anymore or had
+@@ -137,16 +137,18 @@ FontDataForRangeSet* FontFallbackIterato
+ // LastResort font, not just Times or Arial.
+ FontCache& font_cache = FontCache::Get();
+ fallback_stage_ = kFirstCandidateForNotdefGlyph;
+- const SimpleFontData* last_resort =
+- font_cache.GetLastResortFallbackFont(font_description_);
++ scoped_refptr<SimpleFontData> last_resort =
++ font_cache.GetLastResortFallbackFont(font_description_).get();
+
+ if (FontSelector* font_selector = font_fallback_list_->GetFontSelector()) {
+- font_selector->ReportLastResortFallbackFontLookup(font_description_,
+- last_resort);
++ font_selector->ReportLastResortFallbackFontLookup(
++ font_description_,
++ last_resort.get());
+ }
+
+- return UniqueOrNext(MakeGarbageCollected<FontDataForRangeSet>(last_resort),
+- hint_list);
++ return UniqueOrNext(
++ base::AdoptRef(new FontDataForRangeSetFromCache(last_resort)),
++ hint_list);
+ }
+
+ if (fallback_stage_ == kFirstCandidateForNotdefGlyph) {
+@@ -177,13 +179,13 @@ FontDataForRangeSet* FontFallbackIterato
+ // Skip forward to the next font family for the next call to next().
+ current_font_data_index_++;
+ if (!font_data->IsLoading()) {
+- SimpleFontData* non_segmented =
++ scoped_refptr<SimpleFontData> non_segmented =
+ const_cast<SimpleFontData*>(To<SimpleFontData>(font_data));
+ // The fontData object that we have here is tracked in m_fontList of
+ // FontFallbackList and gets released in the font cache when the
+ // FontFallbackList is destroyed.
+ return UniqueOrNext(
+- MakeGarbageCollected<FontDataForRangeSet>(non_segmented), hint_list);
++ base::AdoptRef(new FontDataForRangeSet(non_segmented)), hint_list);
+ }
+ return Next(hint_list);
+ }
+@@ -197,7 +199,7 @@ FontDataForRangeSet* FontFallbackIterato
+ }
+
+ DCHECK_LT(segmented_face_index_, segmented->NumFaces());
+- FontDataForRangeSet* current_segmented_face =
++ scoped_refptr<FontDataForRangeSet> current_segmented_face =
+ segmented->FaceAt(segmented_face_index_);
+ segmented_face_index_++;
+
+@@ -208,7 +210,7 @@ FontDataForRangeSet* FontFallbackIterato
+ current_font_data_index_++;
+ }
+
+- if (RangeSetContributesForHint(hint_list, current_segmented_face)) {
++ if (RangeSetContributesForHint(hint_list, current_segmented_face.get())) {
+ const SimpleFontData* current_segmented_face_font_data =
+ current_segmented_face->FontData();
+ if (const CustomFontData* current_segmented_face_custom_font_data =
+@@ -222,15 +224,17 @@ FontDataForRangeSet* FontFallbackIterato
+ return Next(hint_list);
+ }
+
+-const SimpleFontData* FontFallbackIterator::FallbackPriorityFont(UChar32 hint) {
+- const SimpleFontData* font_data = FontCache::Get().FallbackFontForCharacter(
+- font_description_, hint,
+- font_fallback_list_->PrimarySimpleFontData(font_description_),
+- font_fallback_priority_);
++scoped_refptr<SimpleFontData> FontFallbackIterator::FallbackPriorityFont(
++ UChar32 hint) {
++ scoped_refptr<SimpleFontData> font_data =
++ FontCache::Get().FallbackFontForCharacter(
++ font_description_, hint,
++ font_fallback_list_->PrimarySimpleFontData(font_description_),
++ font_fallback_priority_);
+
+ if (FontSelector* font_selector = font_fallback_list_->GetFontSelector()) {
+ font_selector->ReportFontLookupByFallbackCharacter(
+- hint, font_fallback_priority_, font_description_, font_data);
++ hint, font_fallback_priority_, font_description_, font_data.get());
+ }
+ return font_data;
+ }
+@@ -255,7 +259,7 @@ static inline unsigned ChooseHintIndex(c
+ return 0;
+ }
+
+-const SimpleFontData* FontFallbackIterator::UniqueSystemFontForHintList(
++scoped_refptr<SimpleFontData> FontFallbackIterator::UniqueSystemFontForHintList(
+ const Vector<UChar32>& hint_list) {
+ // When we're asked for a fallback for the same characters again, we give up
+ // because the shaper must have previously tried shaping with the font
+@@ -270,13 +274,13 @@ const SimpleFontData* FontFallbackIterat
+ return nullptr;
+ previously_asked_for_hint_.insert(hint);
+
+- const SimpleFontData* font_data = font_cache.FallbackFontForCharacter(
++ scoped_refptr<SimpleFontData> font_data = font_cache.FallbackFontForCharacter(
+ font_description_, hint,
+ font_fallback_list_->PrimarySimpleFontData(font_description_));
+
+ if (FontSelector* font_selector = font_fallback_list_->GetFontSelector()) {
+ font_selector->ReportFontLookupByFallbackCharacter(
+- hint, FontFallbackPriority::kText, font_description_, font_data);
++ hint, FontFallbackPriority::kText, font_description_, font_data.get());
+ }
+ return font_data;
+ }
+--- a/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
++++ b/third_party/blink/renderer/platform/fonts/font_fallback_iterator.h
+@@ -5,13 +5,14 @@
+ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_FALLBACK_ITERATOR_H_
+ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_FALLBACK_ITERATOR_H_
+
++#include "base/memory/scoped_refptr.h"
+ #include "third_party/blink/renderer/platform/fonts/font_data_for_range_set.h"
+ #include "third_party/blink/renderer/platform/fonts/font_fallback_priority.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
+ #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+ #include "third_party/blink/renderer/platform/wtf/hash_set.h"
+ #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
+ #include "third_party/blink/renderer/platform/wtf/text/wtf_uchar.h"
++#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+ namespace blink {
+
+@@ -48,7 +48,7 @@
+ // Some system fallback APIs (Windows, Android) require a character, or a
+ // portion of the string to be passed. On Mac and Linux, we get a list of
+ // fonts without passing in characters.
+- FontDataForRangeSet* Next(const Vector<UChar32>& hint_list);
++ scoped_refptr<FontDataForRangeSet> Next(const Vector<UChar32>& hint_list);
+
+ void Reset();
+
+@@ -50,11 +51,12 @@ class FontFallbackIterator {
+ bool AlreadyLoadingRangeForHintChar(UChar32 hint_char);
+ void WillUseRange(const AtomicString& family, const FontDataForRangeSet&);
+
+- FontDataForRangeSet* UniqueOrNext(FontDataForRangeSet* candidate,
+- const Vector<UChar32>& hint_list);
++ scoped_refptr<FontDataForRangeSet> UniqueOrNext(
++ scoped_refptr<FontDataForRangeSet> candidate,
++ const Vector<UChar32>& hint_list);
+
+- const SimpleFontData* FallbackPriorityFont(UChar32 hint);
+- const SimpleFontData* UniqueSystemFontForHintList(
++ scoped_refptr<SimpleFontData> FallbackPriorityFont(UChar32 hint);
++ scoped_refptr<SimpleFontData> UniqueSystemFontForHintList(
+ const Vector<UChar32>& hint_list);
+
+ const FontDescription& font_description_;
+@@ -82,8 +84,8 @@ class FontFallbackIterator {
+ // candidate to be used for rendering the .notdef glyph, and set HasNext() to
+ // false.
+ HashSet<uint32_t> unique_font_data_for_range_sets_returned_;
+- FontDataForRangeSet* first_candidate_ = nullptr;
+- HeapVector<Member<FontDataForRangeSet>> tracked_loading_range_sets_;
++ scoped_refptr<FontDataForRangeSet> first_candidate_;
++ Vector<scoped_refptr<FontDataForRangeSet>> tracked_loading_range_sets_;
+ FontFallbackPriority font_fallback_priority_;
+ };
+
+--- a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
++++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
+@@ -52,9 +52,17 @@ FontFallbackList::FontFallbackList(FontS
+ is_invalid_(false),
+ nullify_primary_font_data_for_test_(false) {}
+
++FontFallbackList::~FontFallbackList() {
++ unsigned num_fonts = font_list_.size();
++ for (unsigned i = 0; i < num_fonts; ++i) {
++ if (!font_list_[i]->IsCustomFont()) {
++ DCHECK(!font_list_[i]->IsSegmented());
++ FontCache::Get().ReleaseFontData(To<SimpleFontData>(font_list_[i].get()));
++ }
++ }
++}
++
+ void FontFallbackList::Trace(Visitor* visitor) const {
+- visitor->Trace(font_list_);
+- visitor->Trace(cached_primary_simple_font_data_);
+ visitor->Trace(font_selector_);
+ visitor->Trace(ng_shape_cache_);
+ visitor->Trace(shape_cache_);
+@@ -98,8 +106,8 @@ const SimpleFontData* FontFallbackList::
+ return font_data->FontDataForCharacter(kSpaceCharacter);
+
+ FontCache& font_cache = FontCache::Get();
+- const SimpleFontData* last_resort_fallback =
+- font_cache.GetLastResortFallbackFont(font_description);
++ SimpleFontData* last_resort_fallback =
++ font_cache.GetLastResortFallbackFont(font_description).get();
+ DCHECK(last_resort_fallback);
+ return last_resort_fallback;
+ }
+@@ -137,7 +145,7 @@ const SimpleFontData* FontFallbackList::
+ }
+ }
+
+-const FontData* FontFallbackList::GetFontData(
++scoped_refptr<FontData> FontFallbackList::GetFontData(
+ const FontDescription& font_description) {
+ const FontFamily* curr_family = &font_description.Family();
+ for (int i = 0; curr_family && i < family_index_; i++)
+@@ -148,7 +156,7 @@ const FontData* FontFallbackList::GetFon
+ if (!font_selector_) {
+ // Don't query system fonts for empty font family name.
+ if (!curr_family->FamilyName().empty()) {
+- if (auto* result = FontCache::Get().GetFontData(
++ if (auto result = FontCache::Get().GetFontData(
+ font_description, curr_family->FamilyName())) {
+ return result;
+ }
+@@ -156,7 +164,7 @@ const FontData* FontFallbackList::GetFon
+ continue;
+ }
+
+- const FontData* result =
++ scoped_refptr<FontData> result =
+ font_selector_->GetFontData(font_description, *curr_family);
+ // Don't query system fonts for empty font family name.
+ if (!result && !curr_family->FamilyName().empty()) {
+@@ -164,7 +172,7 @@ const FontData* FontFallbackList::GetFon
+ curr_family->FamilyName());
+ font_selector_->ReportFontLookupByUniqueOrFamilyName(
+ curr_family->FamilyName(), font_description,
+- DynamicTo<SimpleFontData>(result));
++ DynamicTo<SimpleFontData>(result.get()));
+ }
+ if (result) {
+ font_selector_->ReportSuccessfulFontFamilyMatch(
+@@ -181,18 +189,18 @@ const FontData* FontFallbackList::GetFon
+ FontFamily font_family;
+ font_family.SetFamily(font_family_names::kWebkitStandard,
+ FontFamily::Type::kGenericFamily);
+- if (const FontData* data =
++ if (scoped_refptr<FontData> data =
+ font_selector_->GetFontData(font_description, font_family)) {
+ return data;
+ }
+ }
+
+ // Still no result. Hand back our last resort fallback font.
+- auto* last_resort =
++ auto last_resort =
+ FontCache::Get().GetLastResortFallbackFont(font_description);
+ if (font_selector_) {
+ font_selector_->ReportLastResortFallbackFontLookup(font_description,
+- last_resort);
++ last_resort.get());
+ }
+ return last_resort;
+ }
+@@ -202,7 +210,7 @@ const FontData* FontFallbackList::FontDa
+ unsigned realized_font_index) {
+ // This fallback font is already in our list.
+ if (realized_font_index < font_list_.size())
+- return font_list_[realized_font_index].Get();
++ return font_list_[realized_font_index].get();
+
+ // Make sure we're not passing in some crazy value here.
+ DCHECK_EQ(realized_font_index, font_list_.size());
+@@ -216,7 +224,7 @@ const FontData* FontFallbackList::FontDa
+ // the same spot in the list twice. GetFontData will adjust our
+ // |family_index_| as it scans for the right font to make.
+ DCHECK_EQ(FontCache::Get().Generation(), generation_);
+- const FontData* result = GetFontData(font_description);
++ scoped_refptr<FontData> result = GetFontData(font_description);
+ if (result) {
+ font_list_.push_back(result);
+ if (result->IsLoadingFallback())
+@@ -224,7 +232,7 @@ const FontData* FontFallbackList::FontDa
+ if (result->IsCustomFont())
+ has_custom_font_ = true;
+ }
+- return result;
++ return result.get();
+ }
+
+ bool FontFallbackList::ComputeCanShapeWordByWord(
+--- a/third_party/blink/renderer/platform/fonts/font_fallback_list.h
++++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.h
+@@ -49,6 +49,7 @@ class PLATFORM_EXPORT FontFallbackList
+
+ FontFallbackList(const FontFallbackList&) = delete;
+ FontFallbackList& operator=(const FontFallbackList&) = delete;
++ ~FontFallbackList();
+
+ void Trace(Visitor*) const;
+
+@@ -116,7 +117,7 @@ class PLATFORM_EXPORT FontFallbackList
+ bool HasCustomFont() const { return has_custom_font_; }
+
+ private:
+- const FontData* GetFontData(const FontDescription&);
++ scoped_refptr<FontData> GetFontData(const FontDescription&);
+
+ const SimpleFontData* DeterminePrimarySimpleFontData(const FontDescription&);
+ const SimpleFontData* DeterminePrimarySimpleFontDataCore(
+@@ -124,8 +125,8 @@ class PLATFORM_EXPORT FontFallbackList
+
+ bool ComputeCanShapeWordByWord(const FontDescription&);
+
+- HeapVector<Member<const FontData>, 1> font_list_;
+- Member<const SimpleFontData> cached_primary_simple_font_data_ = nullptr;
++ Vector<scoped_refptr<FontData>, 1> font_list_;
++ const SimpleFontData* cached_primary_simple_font_data_ = nullptr;
+ const Member<FontSelector> font_selector_;
+ int family_index_ = 0;
+ const uint16_t generation_;
+--- a/third_party/blink/renderer/platform/fonts/font_platform_data.cc
++++ b/third_party/blink/renderer/platform/fonts/font_platform_data.cc
+@@ -158,10 +158,6 @@ FontPlatformData::FontPlatformData(sk_sp
+
+ FontPlatformData::~FontPlatformData() = default;
+
+-void FontPlatformData::Trace(Visitor* visitor) const {
+- visitor->Trace(harfbuzz_face_);
+-}
+-
+ #if BUILDFLAG(IS_MAC)
+ CTFontRef FontPlatformData::CtFont() const {
+ return SkTypeface_GetCTFontRef(typeface_.get());
+@@ -213,10 +209,11 @@ SkTypeface* FontPlatformData::Typeface()
+
+ HarfBuzzFace* FontPlatformData::GetHarfBuzzFace() const {
+ if (!harfbuzz_face_) {
+- harfbuzz_face_ = MakeGarbageCollected<HarfBuzzFace>(this, UniqueID());
++ harfbuzz_face_ =
++ HarfBuzzFace::Create(const_cast<FontPlatformData*>(this), UniqueID());
+ }
+
+- return harfbuzz_face_.Get();
++ return harfbuzz_face_.get();
+ }
+
+ bool FontPlatformData::HasSpaceInLigaturesOrKerning(
+@@ -246,7 +243,7 @@ unsigned FontPlatformData::GetHash() con
+ }
+
+ #if !BUILDFLAG(IS_MAC)
+-bool FontPlatformData::FontContainsCharacter(UChar32 character) const {
++bool FontPlatformData::FontContainsCharacter(UChar32 character) {
+ return CreateSkFont().unicharToGlyph(character);
+ }
+ #endif
+--- a/third_party/blink/renderer/platform/fonts/font_platform_data.h
++++ b/third_party/blink/renderer/platform/fonts/font_platform_data.h
+@@ -39,8 +39,6 @@
+ #include "third_party/blink/renderer/platform/fonts/font_orientation.h"
+ #include "third_party/blink/renderer/platform/fonts/resolved_font_features.h"
+ #include "third_party/blink/renderer/platform/fonts/small_caps_iterator.h"
+-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+-#include "third_party/blink/renderer/platform/heap/member.h"
+ #include "third_party/blink/renderer/platform/platform_export.h"
+ #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+ #include "third_party/blink/renderer/platform/wtf/forward.h"
+@@ -61,8 +59,9 @@ namespace blink {
+ class HarfBuzzFace;
+ class OpenTypeVerticalData;
+
+-class PLATFORM_EXPORT FontPlatformData
+- : public GarbageCollected<FontPlatformData> {
++class PLATFORM_EXPORT FontPlatformData {
++ USING_FAST_MALLOC(FontPlatformData);
++
+ public:
+ // Used for deleted values in the font cache's hash tables. The hash table
+ // will create us with this structure, and it will compare other values
+@@ -83,8 +82,6 @@ class PLATFORM_EXPORT FontPlatformData
+ FontOrientation = FontOrientation::kHorizontal);
+ ~FontPlatformData();
+
+- void Trace(Visitor*) const;
+-
+ #if BUILDFLAG(IS_MAC)
+ // Returns nullptr for FreeType backed SkTypefaces, compare
+ // FontCustomPlatformData, which are used for variable fonts on Mac OS
+@@ -129,7 +126,7 @@ class PLATFORM_EXPORT FontPlatformData
+
+ bool IsHashTableDeletedValue() const { return is_hash_table_deleted_value_; }
+ #if !BUILDFLAG(IS_MAC)
+- bool FontContainsCharacter(UChar32 character) const;
++ bool FontContainsCharacter(UChar32 character);
+ #endif
+
+ #if !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_MAC)
+@@ -185,7 +182,7 @@ class PLATFORM_EXPORT FontPlatformData
+ WebFontRenderStyle style_;
+ #endif
+
+- mutable Member<HarfBuzzFace> harfbuzz_face_;
++ mutable scoped_refptr<HarfBuzzFace> harfbuzz_face_;
+ bool is_hash_table_deleted_value_ = false;
+ };
+
+--- a/third_party/blink/renderer/platform/fonts/font_platform_data_cache.cc
++++ b/third_party/blink/renderer/platform/fonts/font_platform_data_cache.cc
+@@ -38,13 +38,20 @@
+
+ namespace blink {
+
++// static
++std::unique_ptr<FontPlatformDataCache> FontPlatformDataCache::Create() {
++ return std::make_unique<FontPlatformDataCache>();
++}
++
+ FontPlatformDataCache::FontPlatformDataCache()
+ : font_size_limit_(std::nextafter(
+ (static_cast<float>(std::numeric_limits<unsigned>::max()) - 2.f) /
+ static_cast<float>(blink::FontCacheKey::PrecisionMultiplier()),
+ 0.f)) {}
+
+-const FontPlatformData* FontPlatformDataCache::GetOrCreateFontPlatformData(
++FontPlatformDataCache::~FontPlatformDataCache() = default;
++
++FontPlatformData* FontPlatformDataCache::GetOrCreateFontPlatformData(
+ FontCache* font_cache,
+ const FontDescription& font_description,
+ const FontFaceCreationParams& creation_params,
+@@ -60,13 +67,15 @@ const FontPlatformData* FontPlatformData
+
+ auto it = map_.find(key);
+ if (it != map_.end()) {
+- return it->value.Get();
++ return it->value.get();
+ }
+
+- if (const FontPlatformData* result = font_cache->CreateFontPlatformData(
+- font_description, creation_params, size, alternate_font_name)) {
+- map_.insert(key, result);
+- return result;
++ if (std::unique_ptr<FontPlatformData> result =
++ font_cache->CreateFontPlatformData(font_description, creation_params,
++ size, alternate_font_name)) {
++ FontPlatformData* result_ptr = result.get();
++ map_.insert(key, std::move(result));
++ return result_ptr;
+ }
+
+ if (alternate_font_name != AlternateFontName::kAllowAlternate ||
+@@ -82,16 +91,35 @@ const FontPlatformData* FontPlatformData
+ return nullptr;
+
+ FontFaceCreationParams create_by_alternate_family(alternate_name);
+- if (const FontPlatformData* result = GetOrCreateFontPlatformData(
++ if (FontPlatformData* result = GetOrCreateFontPlatformData(
+ font_cache, font_description, create_by_alternate_family,
+ AlternateFontName::kNoAlternate)) {
+ // Cache the platform_data under the old name.
+ // "accessibility/font-changed.html" reaches here.
+- map_.insert(key, result);
++ map_.insert(key, std::make_unique<FontPlatformData>(*result));
+ return result;
+ }
+
+ return nullptr;
+ }
+
++size_t FontPlatformDataCache::ByteSize() const {
++ return map_.size() * sizeof(std::unique_ptr<FontPlatformData>);
++}
++
++void FontPlatformDataCache::Clear() {
++ map_.clear();
++}
++
++void FontPlatformDataCache::Purge(const FontDataCache& font_data_cache) {
++ Vector<FontCacheKey> keys_to_remove;
++ keys_to_remove.ReserveInitialCapacity(map_.size());
++ for (auto& entry : map_) {
++ if (entry.value && !font_data_cache.Contains(entry.value.get())) {
++ keys_to_remove.push_back(entry.key);
++ }
++ }
++ map_.RemoveAll(keys_to_remove);
++}
++
+ } // namespace blink
+--- a/third_party/blink/renderer/platform/fonts/font_platform_data_cache.h
++++ b/third_party/blink/renderer/platform/fonts/font_platform_data_cache.h
+@@ -31,13 +31,13 @@
+ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_PLATFORM_DATA_CACHE_H_
+
+ #include "third_party/blink/renderer/platform/fonts/font_cache_key.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
+-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
++#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+
+ namespace blink {
+
+ enum class AlternateFontName;
+ class FontCache;
++class FontDataCache;
+ class FontDescription;
+ class FontFaceCreationParams;
+ class FontPlatformData;
+@@ -45,23 +45,30 @@ class FontPlatformData;
+ // `FontPlatformDataCache` is the shared cache mapping from `FontDescription`
+ // to `FontPlatformData`.
+ class FontPlatformDataCache final {
+- DISALLOW_NEW();
+-
+ public:
++ static std::unique_ptr<FontPlatformDataCache> Create();
++
+ FontPlatformDataCache();
++ ~FontPlatformDataCache();
++
++ FontPlatformDataCache(const FontPlatformDataCache&) = delete;
++ FontPlatformDataCache(FontPlatformDataCache&&) = delete;
+
+- void Trace(Visitor* visitor) const { visitor->Trace(map_); }
++ FontPlatformDataCache operator=(const FontPlatformDataCache&) = delete;
++ FontPlatformDataCache operator=(FontPlatformDataCache&&) = delete;
+
+- const FontPlatformData* GetOrCreateFontPlatformData(
++ FontPlatformData* GetOrCreateFontPlatformData(
+ FontCache* font_cache,
+ const FontDescription& font_description,
+ const FontFaceCreationParams& creation_params,
+ AlternateFontName alternate_font_name);
+
+- void Clear() { map_.clear(); }
++ size_t ByteSize() const;
++ void Clear();
++ void Purge(const FontDataCache& font_data_cache);
+
+ private:
+- HeapHashMap<FontCacheKey, WeakMember<const FontPlatformData>> map_;
++ HashMap<FontCacheKey, std::unique_ptr<FontPlatformData>> map_;
+
+ // A maximum float value to which we limit incoming font sizes. This is the
+ // smallest float so that multiplying it by
+--- a/third_party/blink/renderer/platform/fonts/font_selector.h
++++ b/third_party/blink/renderer/platform/fonts/font_selector.h
+@@ -53,8 +53,8 @@ class UseCounter;
+ class PLATFORM_EXPORT FontSelector : public FontCacheClient {
+ public:
+ ~FontSelector() override = default;
+- virtual const FontData* GetFontData(const FontDescription&,
+- const FontFamily&) = 0;
++ virtual scoped_refptr<FontData> GetFontData(const FontDescription&,
++ const FontFamily&) = 0;
+
+ // TODO(crbug.com/542629): The String variant of this method should be
+ // replaced with a better approach, now that we only have complex text.
+@@ -92,7 +92,7 @@ class PLATFORM_EXPORT FontSelector : pub
+ virtual void ReportFontLookupByUniqueOrFamilyName(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) = 0;
++ scoped_refptr<SimpleFontData> resulting_font_data) = 0;
+
+ // Called whenever a page attempts to find a local font based on a name. This
+ // only includes lookups where the name is allowed to match PostScript names
+@@ -100,7 +100,7 @@ class PLATFORM_EXPORT FontSelector : pub
+ virtual void ReportFontLookupByUniqueNameOnly(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data,
++ scoped_refptr<SimpleFontData> resulting_font_data,
+ bool is_loading_fallback = false) = 0;
+
+ // Called whenever a page attempts to find a local font based on a fallback
+@@ -109,12 +109,12 @@ class PLATFORM_EXPORT FontSelector : pub
+ UChar32 fallback_character,
+ FontFallbackPriority fallback_priority,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) = 0;
++ scoped_refptr<SimpleFontData> resulting_font_data) = 0;
+
+ // Called whenever a page attempts to find a last-resort font.
+ virtual void ReportLastResortFallbackFontLookup(
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) = 0;
++ scoped_refptr<SimpleFontData> resulting_font_data) = 0;
+
+ virtual void ReportNotDefGlyph() const = 0;
+
+--- a/third_party/blink/renderer/platform/fonts/fuchsia/font_cache_fuchsia.cc
++++ b/third_party/blink/renderer/platform/fonts/fuchsia/font_cache_fuchsia.cc
+@@ -45,7 +45,7 @@ void FontCache::SetSystemFontFamily(cons
+ MutableSystemFontFamily() = family_name;
+ }
+
+-const SimpleFontData* FontCache::PlatformFallbackFontForCharacter(
++scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
+ const FontDescription& font_description,
+ UChar32 character,
+ const SimpleFontData* font_data_to_substitute,
+@@ -67,12 +67,12 @@ const SimpleFontData* FontCache::Platfor
+ !typeface->isItalic() &&
+ font_description.SyntheticItalicAllowed();
+
+- const auto* font_data = MakeGarbageCollected<FontPlatformData>(
++ auto font_data = std::make_unique<FontPlatformData>(
+ std::move(typeface), std::string(), font_description.EffectiveFontSize(),
+ synthetic_bold, synthetic_italic, font_description.TextRendering(),
+ ResolvedFontFeatures(), font_description.Orientation());
+
+- return FontDataFromFontPlatformData(font_data);
++ return FontDataFromFontPlatformData(font_data.get(), kDoNotRetain);
+ }
+
+ } // namespace blink
+--- a/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
++++ b/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
+@@ -62,7 +62,7 @@ bool FontCache::GetFontForCharacter(UCha
+ }
+ }
+
+-const SimpleFontData* FontCache::PlatformFallbackFontForCharacter(
++scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
+ const FontDescription& font_description,
+ UChar32 c,
+ const SimpleFontData*,
+@@ -77,9 +77,11 @@ const SimpleFontData* FontCache::Platfor
+ AtomicString family_name = GetFamilyNameForCharacter(
+ font_manager_.get(), c, font_description, nullptr, fallback_priority);
+ if (family_name.empty())
+- return GetLastResortFallbackFont(font_description);
+- return FontDataFromFontPlatformData(GetFontPlatformData(
+- font_description, FontFaceCreationParams(family_name)));
++ return GetLastResortFallbackFont(font_description, kDoNotRetain);
++ return FontDataFromFontPlatformData(
++ GetFontPlatformData(font_description,
++ FontFaceCreationParams(family_name)),
++ kDoNotRetain);
+ }
+
+ if (fallback_priority == FontFallbackPriority::kEmojiEmoji) {
+@@ -94,7 +96,7 @@ const SimpleFontData* FontCache::Platfor
+ if (fallback_priority != FontFallbackPriority::kEmojiEmoji &&
+ (font_description.Style() == kItalicSlopeValue ||
+ font_description.Weight() >= kBoldThreshold)) {
+- const SimpleFontData* font_data =
++ scoped_refptr<SimpleFontData> font_data =
+ FallbackOnStandardFontStyle(font_description, c);
+ if (font_data)
+ return font_data;
+@@ -137,16 +139,16 @@ const SimpleFontData* FontCache::Platfor
+ description.SetStyle(kNormalSlopeValue);
+ }
+
+- const FontPlatformData* substitute_platform_data =
++ FontPlatformData* substitute_platform_data =
+ GetFontPlatformData(description, creation_params);
+ if (!substitute_platform_data)
+ return nullptr;
+
+- FontPlatformData* platform_data =
+- MakeGarbageCollected<FontPlatformData>(*substitute_platform_data);
++ std::unique_ptr<FontPlatformData> platform_data(
++ new FontPlatformData(*substitute_platform_data));
+ platform_data->SetSyntheticBold(should_set_synthetic_bold);
+ platform_data->SetSyntheticItalic(should_set_synthetic_italic);
+- return FontDataFromFontPlatformData(platform_data);
++ return FontDataFromFontPlatformData(platform_data.get(), kDoNotRetain);
+ }
+
+ } // namespace blink
+--- a/third_party/blink/renderer/platform/fonts/segmented_font_data.h
++++ b/third_party/blink/renderer/platform/fonts/segmented_font_data.h
+@@ -28,7 +28,6 @@
+
+ #include "third_party/blink/renderer/platform/fonts/font_data.h"
+ #include "third_party/blink/renderer/platform/fonts/font_data_for_range_set.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
+ #include "third_party/blink/renderer/platform/platform_export.h"
+ #include "third_party/blink/renderer/platform/wtf/casting.h"
+
+@@ -38,21 +37,20 @@ class SimpleFontData;
+
+ class PLATFORM_EXPORT SegmentedFontData : public FontData {
+ public:
+- SegmentedFontData() = default;
+-
+- void Trace(Visitor* visitor) const override {
+- visitor->Trace(faces_);
+- FontData::Trace(visitor);
++ static scoped_refptr<SegmentedFontData> Create() {
++ return base::AdoptRef(new SegmentedFontData);
+ }
+
+- void AppendFace(FontDataForRangeSet* font_data_for_range_set) {
++ void AppendFace(scoped_refptr<FontDataForRangeSet> font_data_for_range_set) {
+ faces_.push_back(std::move(font_data_for_range_set));
+ }
+ unsigned NumFaces() const { return faces_.size(); }
+- FontDataForRangeSet* FaceAt(unsigned i) const { return faces_[i].Get(); }
++ scoped_refptr<FontDataForRangeSet> FaceAt(unsigned i) const { return faces_[i]; }
+ bool ContainsCharacter(UChar32) const;
+
+ private:
++ SegmentedFontData() = default;
++
+ const SimpleFontData* FontDataForCharacter(UChar32) const override;
+
+ bool IsCustomFont() const override;
+@@ -61,7 +59,7 @@ class PLATFORM_EXPORT SegmentedFontData
+ bool IsSegmented() const override;
+ bool ShouldSkipDrawing() const override;
+
+- HeapVector<Member<FontDataForRangeSet>, 1> faces_;
++ Vector<scoped_refptr<FontDataForRangeSet>, 1> faces_;
+ };
+
+ template <>
+--- a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc
++++ b/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc
+@@ -127,7 +127,7 @@ Vector<double> CachingWordShaper::Indivi
+ total_width);
+ }
+
+-HeapVector<ShapeResult::RunFontData> CachingWordShaper::GetRunFontData(
++Vector<ShapeResult::RunFontData> CachingWordShaper::GetRunFontData(
+ const TextRun& run) const {
+ ShapeResultBuffer buffer;
+ ShapeResultsForRun(GetShapeCache(), &font_, run, &buffer);
+--- a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h
++++ b/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h
+@@ -26,6 +26,7 @@
+ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_CACHING_WORD_SHAPER_H_
+ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_CACHING_WORD_SHAPER_H_
+
++#include "base/memory/scoped_refptr.h"
+ #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h"
+ #include "third_party/blink/renderer/platform/text/text_run.h"
+ #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+@@ -59,7 +60,7 @@ class PLATFORM_EXPORT CachingWordShaper
+ CharacterRange GetCharacterRange(const TextRun&, unsigned from, unsigned to);
+ Vector<double> IndividualCharacterAdvances(const TextRun&);
+
+- HeapVector<ShapeResult::RunFontData> GetRunFontData(const TextRun&) const;
++ Vector<ShapeResult::RunFontData> GetRunFontData(const TextRun&) const;
+
+ GlyphData EmphasisMarkGlyphData(const TextRun&) const;
+
+--- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
++++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
+@@ -62,8 +62,7 @@
+
+ namespace blink {
+
+-HarfBuzzFace::HarfBuzzFace(const FontPlatformData* platform_data,
+- uint64_t unique_id)
++HarfBuzzFace::HarfBuzzFace(FontPlatformData* platform_data, uint64_t unique_id)
+ : platform_data_(platform_data), unique_id_(unique_id) {
+ HbFontCacheEntry* const cache_entry =
+ FontGlobalContext::GetHarfBuzzFontCache().RefOrNew(unique_id_,
+@@ -76,10 +76,6 @@
+ FontGlobalContext::GetHarfBuzzFontCache().Remove(unique_id_);
+ }
+
+-void HarfBuzzFace::Trace(Visitor* visitor) const {
+- visitor->Trace(platform_data_);
+-}
+-
+ bool HarfBuzzFace::ignore_variation_selectors_ = false;
+
+ static hb_bool_t HarfBuzzGetGlyph(hb_font_t* hb_font,
+@@ -426,8 +421,7 @@ static hb_blob_t* HarfBuzzSkiaGetTable(h
+ }
+
+ // TODO(yosin): We should move |CreateFace()| to "harfbuzz_font_cache.cc".
+-static hb::unique_ptr<hb_face_t> CreateFace(
+- const FontPlatformData* platform_data) {
++static hb::unique_ptr<hb_face_t> CreateFace(FontPlatformData* platform_data) {
+ hb::unique_ptr<hb_face_t> face;
+
+ sk_sp<SkTypeface> typeface = sk_ref_sp(platform_data->Typeface());
+@@ -475,9 +469,8 @@ static scoped_refptr<HbFontCacheEntry> C
+ return cache_entry;
+ }
+
+-HbFontCacheEntry* HarfBuzzFontCache::RefOrNew(
+- uint64_t unique_id,
+- const FontPlatformData* platform_data) {
++HbFontCacheEntry* HarfBuzzFontCache::RefOrNew(uint64_t unique_id,
++ FontPlatformData* platform_data) {
+ const auto& result = font_map_.insert(unique_id, nullptr);
+ if (result.is_new_entry) {
+ hb::unique_ptr<hb_face_t> face = CreateFace(platform_data);
+--- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h
++++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h
+@@ -34,11 +34,10 @@
+ #include "third_party/blink/renderer/platform/fonts/glyph.h"
+ #include "third_party/blink/renderer/platform/fonts/typesetting_features.h"
+ #include "third_party/blink/renderer/platform/fonts/unicode_range_set.h"
+-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+-#include "third_party/blink/renderer/platform/heap/member.h"
+ #include "third_party/blink/renderer/platform/platform_export.h"
+ #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+ #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
++#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
+ #include "third_party/blink/renderer/platform/wtf/text/character_names.h"
+
+ #include <hb.h>
+@@ -53,15 +52,19 @@
+ // |HarfBuzzFace| is a thread specific data associated to |FontPlatformData|,
+ // hold by |HarfBuzzFontCache|.
+ class PLATFORM_EXPORT HarfBuzzFace final
+- : public GarbageCollected<HarfBuzzFace> {
++ : public RefCounted<HarfBuzzFace> {
++ USING_FAST_MALLOC(HarfBuzzFace);
++
+ public:
+- HarfBuzzFace(const FontPlatformData* platform_data, uint64_t);
++ static scoped_refptr<HarfBuzzFace> Create(FontPlatformData* platform_data,
++ uint64_t unique_id) {
++ return base::AdoptRef(new HarfBuzzFace(platform_data, unique_id));
++ }
++
+ HarfBuzzFace(const HarfBuzzFace&) = delete;
+ HarfBuzzFace& operator=(const HarfBuzzFace&) = delete;
+ ~HarfBuzzFace();
+
+- void Trace(Visitor*) const;
+-
+ enum VerticalLayoutCallbacks { kPrepareForVerticalLayout, kNoVerticalLayout };
+
+ // In order to support the restricting effect of unicode-range optionally a
+@@ -102,10 +105,11 @@
+ }
+
+ private:
++ HarfBuzzFace(FontPlatformData* platform_data, uint64_t);
+
+ void PrepareHarfBuzzFontData();
+
+- Member<const FontPlatformData> platform_data_;
++ FontPlatformData* const platform_data_;
+ const uint64_t unique_id_;
+ // TODO(crbug.com/1489080): When briefly given MiraclePtr protection,
+ // these members were both found dangling.
+--- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h
++++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h
+@@ -49,7 +49,7 @@ class HarfBuzzFontCache final {
+ ~HarfBuzzFontCache();
+
+ HbFontCacheEntry* RefOrNew(uint64_t unique_id,
+- const FontPlatformData* platform_data);
++ FontPlatformData* platform_data);
+ void Remove(uint64_t unique_id);
+
+ private:
+--- a/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
++++ b/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.cc
+@@ -798,7 +798,7 @@
+ fallback_chars_hint.ReserveInitialCapacity(range_data->end -
+ range_data->start);
+ }
+- FontDataForRangeSet* current_font_data_for_range_set = nullptr;
++ scoped_refptr<FontDataForRangeSet> current_font_data_for_range_set = nullptr;
+ FallbackFontStage fallback_stage = kIntermediate;
+ while (!range_data->reshape_queue.empty()) {
+ ReshapeQueueItem current_queue_item = range_data->reshape_queue.TakeFirst();
+@@ -867,7 +867,7 @@
+ if (needs_caps_handling) {
+ case_map_intend = caps_support.NeedsCaseChange(small_caps_behavior);
+ if (caps_support.NeedsSyntheticFont(small_caps_behavior)) {
+- adjusted_font = font_data->SmallCapsFontData(font_description);
++ adjusted_font = font_data->SmallCapsFontData(font_description).get();
+ }
+ }
+
+--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
++++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
+@@ -79,10 +79,9 @@ ASSERT_SIZE(ShapeResult::RunInfo, SameSi
+
+ struct SameSizeAsShapeResult {
+ float width;
+- UntracedMember<void*> deprecated_ink_bounds_;
+- Vector<int> runs_;
+- Vector<int> character_position_;
+- UntracedMember<void*> primary_font_;
++ UntracedMember<void*> member;
++ Vector<int> vectors[2];
++ void *pointer;
+ unsigned start_index_;
+ unsigned num_characters_;
+ unsigned bitfields : 32;
+@@ -396,7 +395,7 @@ void ShapeResult::RunInfo::CharacterInde
+ }
+ }
+
+-ShapeResult::ShapeResult(const SimpleFontData* font_data,
++ShapeResult::ShapeResult(scoped_refptr<const SimpleFontData> font_data,
+ unsigned start_index,
+ unsigned num_characters,
+ TextDirection direction)
+@@ -436,7 +435,6 @@ void ShapeResult::Trace(Visitor* visitor
+ visitor->Trace(deprecated_ink_bounds_);
+ visitor->Trace(runs_);
+ visitor->Trace(character_position_);
+- visitor->Trace(primary_font_);
+ }
+
+ size_t ShapeResult::ByteSize() const {
+@@ -736,10 +734,10 @@ bool ShapeResult::HasFallbackFonts(const
+ return false;
+ }
+
+-void ShapeResult::GetRunFontData(HeapVector<RunFontData>* font_data) const {
++void ShapeResult::GetRunFontData(Vector<RunFontData>* font_data) const {
+ for (const auto& run : runs_) {
+ font_data->push_back(
+- RunFontData({run->font_data_.Get(), run->glyph_data_.size()}));
++ RunFontData({run->font_data_.get(), run->glyph_data_.size()}));
+ }
+ }
+
+@@ -754,7 +752,7 @@ float ShapeResult::ForEachGlyphImpl(floa
+ for (const auto& glyph_data : run.glyph_data_) {
+ glyph_callback(context, run.start_index_ + glyph_data.character_index,
+ glyph_data.glyph, *glyph_offsets, total_advance,
+- is_horizontal, run.canvas_rotation_, run.font_data_.Get());
++ is_horizontal, run.canvas_rotation_, run.font_data_.get());
+ total_advance += glyph_data.advance;
+ ++glyph_offsets;
+ }
+@@ -789,7 +787,7 @@ float ShapeResult::ForEachGlyphImpl(floa
+ auto total_advance = initial_advance;
+ unsigned run_start = run.start_index_ + index_offset;
+ bool is_horizontal = HB_DIRECTION_IS_HORIZONTAL(run.direction_);
+- const SimpleFontData* font_data = run.font_data_.Get();
++ const SimpleFontData* font_data = run.font_data_.get();
+
+ if (run.IsLtr()) { // Left-to-right
+ for (const auto& glyph_data : run.glyph_data_) {
+@@ -1679,7 +1677,7 @@ unsigned ShapeResult::CopyRangeInternal(
+ ShapeResult* ShapeResult::SubRange(unsigned start_offset,
+ unsigned end_offset) const {
+ ShapeResult* sub_range =
+- MakeGarbageCollected<ShapeResult>(primary_font_.Get(), 0, 0, Direction());
++ MakeGarbageCollected<ShapeResult>(primary_font_.get(), 0, 0, Direction());
+ CopyRange(start_offset, end_offset, sub_range);
+ return sub_range;
+ }
+--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.h
++++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.h
+@@ -139,7 +139,7 @@ typedef void (*GraphemeClusterCallback)(
+
+ class PLATFORM_EXPORT ShapeResult : public GarbageCollected<ShapeResult> {
+ public:
+- ShapeResult(const SimpleFontData*,
++ ShapeResult(scoped_refptr<const SimpleFontData>,
+ unsigned start_index,
+ unsigned num_characters,
+ TextDirection);
+@@ -152,7 +152,7 @@ class PLATFORM_EXPORT ShapeResult : publ
+ void Trace(Visitor*) const;
+
+ static ShapeResult* CreateEmpty(const ShapeResult& other) {
+- return MakeGarbageCollected<ShapeResult>(other.primary_font_.Get(), 0, 0,
++ return MakeGarbageCollected<ShapeResult>(other.primary_font_, 0, 0,
+ other.Direction());
+ }
+ static const ShapeResult* CreateForTabulationCharacters(
+@@ -184,7 +184,7 @@ class PLATFORM_EXPORT ShapeResult : publ
+ LayoutUnit SnappedWidth() const { return LayoutUnit::FromFloatCeil(width_); }
+ unsigned NumCharacters() const { return num_characters_; }
+ unsigned NumGlyphs() const { return num_glyphs_; }
+- const SimpleFontData* PrimaryFont() const { return primary_font_.Get(); }
++ const SimpleFontData* PrimaryFont() const { return primary_font_.get(); }
+ bool HasFallbackFonts(const SimpleFontData* primary_font) const;
+
+ // TODO(eae): Remove start_x and return value once ShapeResultBuffer has been
+@@ -350,12 +350,10 @@ class PLATFORM_EXPORT ShapeResult : publ
+
+ // Computes the list of fonts along with the number of glyphs for each font.
+ struct RunFontData {
+- DISALLOW_NEW();
+- void Trace(Visitor* visitor) const { visitor->Trace(font_data_); }
+- Member<SimpleFontData> font_data_;
++ SimpleFontData* font_data_;
+ wtf_size_t glyph_count_;
+ };
+- void GetRunFontData(HeapVector<RunFontData>* font_data) const;
++ void GetRunFontData(Vector<RunFontData>* font_data) const;
+
+ // Iterates over, and calls the specified callback function, for all the
+ // glyphs. Also tracks (and returns) a seeded total advance.
+@@ -510,7 +510,7 @@
+ // index to x-position and O(log n) time, using binary search, from
+ // x-position to character index.
+ mutable HeapVector<ShapeResultCharacterData> character_position_;
+- Member<const SimpleFontData> primary_font_;
++ scoped_refptr<const SimpleFontData> primary_font_;
+
+ unsigned start_index_ = 0;
+ unsigned num_characters_ = 0;
+@@ -570,6 +568,5 @@ PLATFORM_EXPORT std::ostream& operator<<
+ } // namespace blink
+
+ WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::ShapeResult::ShapeRange)
+-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::ShapeResult::RunFontData)
+
+ #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_SHAPE_RESULT_H_
+--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc
++++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc
+@@ -249,8 +249,8 @@ int ShapeResultBuffer::OffsetForPosition
+ return total_offset;
+ }
+
+-HeapVector<ShapeResult::RunFontData> ShapeResultBuffer::GetRunFontData() const {
+- HeapVector<ShapeResult::RunFontData> font_data;
++Vector<ShapeResult::RunFontData> ShapeResultBuffer::GetRunFontData() const {
++ Vector<ShapeResult::RunFontData> font_data;
+ for (const auto& result : results_)
+ result->GetRunFontData(&font_data);
+ return font_data;
+@@ -264,9 +264,10 @@ GlyphData ShapeResultBuffer::EmphasisMar
+ if (run->glyph_data_.IsEmpty())
+ continue;
+
+- return GlyphData(run->glyph_data_[0].glyph,
+- run->font_data_->EmphasisMarkFontData(font_description),
+- run->CanvasRotation());
++ return GlyphData(
++ run->glyph_data_[0].glyph,
++ run->font_data_->EmphasisMarkFontData(font_description).get(),
++ run->CanvasRotation());
+ }
+ }
+
+--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h
++++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h
+@@ -5,6 +5,7 @@
+ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_SHAPE_RESULT_BUFFER_H_
+ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_SHAPE_RESULT_BUFFER_H_
+
++#include "base/memory/scoped_refptr.h"
+ #include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h"
+ #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
+ #include "third_party/blink/renderer/platform/platform_export.h"
+@@ -47,7 +48,7 @@ class PLATFORM_EXPORT ShapeResultBuffer
+ TextDirection,
+ float total_width) const;
+
+- HeapVector<ShapeResult::RunFontData> GetRunFontData() const;
++ Vector<ShapeResult::RunFontData> GetRunFontData() const;
+
+ GlyphData EmphasisMarkGlyphData(const FontDescription&) const;
+
+--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h
++++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h
+@@ -79,7 +79,7 @@ struct ShapeResult::RunInfo final
+ direction_(other.direction_),
+ canvas_rotation_(other.canvas_rotation_) {}
+
+- void Trace(Visitor* visitor) const { visitor->Trace(font_data_); }
++ void Trace(Visitor*) const {}
+
+ unsigned NumGlyphs() const { return glyph_data_.size(); }
+ bool IsLtr() const { return HB_DIRECTION_IS_FORWARD(direction_); }
+@@ -130,7 +130,7 @@ struct ShapeResult::RunInfo final
+ return nullptr;
+
+ auto* run = MakeGarbageCollected<RunInfo>(
+- font_data_.Get(), direction_, canvas_rotation_, script_,
++ font_data_.get(), direction_, canvas_rotation_, script_,
+ start_index_ + start, number_of_glyphs, number_of_characters);
+
+ run->glyph_data_.CopyFromRange(glyphs);
+@@ -154,7 +154,7 @@ struct ShapeResult::RunInfo final
+ return nullptr;
+ DCHECK_LT(start_index_, other.start_index_);
+ auto* run = MakeGarbageCollected<RunInfo>(
+- font_data_.Get(), direction_, canvas_rotation_, script_, start_index_,
++ font_data_.get(), direction_, canvas_rotation_, script_, start_index_,
+ glyph_data_.size() + other.glyph_data_.size(),
+ num_characters_ + other.num_characters_);
+ // Note: We populate |graphemes_| on demand, e.g. hit testing.
+@@ -374,7 +374,7 @@ struct ShapeResult::RunInfo final
+ }
+
+ GlyphDataCollection glyph_data_;
+- Member<SimpleFontData> font_data_;
++ scoped_refptr<SimpleFontData> font_data_;
+
+ // graphemes_[i] is the number of graphemes up to (and including) the ith
+ // character in the run.
+--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_test_info.cc
++++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_test_info.cc
+@@ -54,7 +54,7 @@ float ShapeResultTestInfo::AdvanceForTes
+
+ SimpleFontData* ShapeResultTestInfo::FontDataForTesting(
+ unsigned run_index) const {
+- return runs_[run_index]->font_data_.Get();
++ return runs_[run_index]->font_data_.get();
+ }
+
+ Vector<unsigned> ShapeResultTestInfo::CharacterIndexesForTesting() const {
+--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
++++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
+@@ -28,9 +28,7 @@ ShapeResultView::RunInfoPart::RunInfoPar
+ start_index_(start_index),
+ offset_(offset),
+ num_characters_(num_characters),
+- width_(width) {
+- static_assert(std::is_trivially_destructible<RunInfoPart>::value, "");
+-}
++ width_(width) {}
+
+ void ShapeResultView::RunInfoPart::Trace(Visitor* visitor) const {
+ visitor->Trace(run_);
+@@ -74,10 +72,7 @@ unsigned ShapeResultView::CharacterIndex
+ // |InitData| provides values of const member variables of |ShapeResultView|
+ // for constructor.
+ struct ShapeResultView::InitData {
+- STACK_ALLOCATED();
+-
+- public:
+- const SimpleFontData* primary_font = nullptr;
++ scoped_refptr<const SimpleFontData> primary_font;
+ unsigned start_index = 0;
+ unsigned char_index_offset = 0;
+ TextDirection direction = TextDirection::kLtr;
+@@ -188,7 +183,7 @@ ShapeResult* ShapeResultView::CreateShap
+ new_result->runs_.ReserveInitialCapacity(parts_.size());
+ for (const auto& part : RunsOrParts()) {
+ auto* new_run = MakeGarbageCollected<ShapeResult::RunInfo>(
+- part.run_->font_data_.Get(), part.run_->direction_,
++ part.run_->font_data_.get(), part.run_->direction_,
+ part.run_->canvas_rotation_, part.run_->script_, part.start_index_,
+ part.NumGlyphs(), part.num_characters_);
+ new_run->glyph_data_.CopyFromRange(part.range_);
+@@ -364,21 +359,21 @@ unsigned ShapeResultView::PreviousSafeTo
+ }
+
+ void ShapeResultView::GetRunFontData(
+- HeapVector<ShapeResult::RunFontData>* font_data) const {
++ Vector<ShapeResult::RunFontData>* font_data) const {
+ for (const auto& part : RunsOrParts()) {
+ font_data->push_back(ShapeResult::RunFontData(
+- {part.run_->font_data_.Get(),
++ {part.run_->font_data_.get(),
+ static_cast<wtf_size_t>(part.end() - part.begin())}));
+ }
+ }
+
+ void ShapeResultView::FallbackFonts(
+- HeapHashSet<Member<const SimpleFontData>>* fallback) const {
++ HashSet<const SimpleFontData*>* fallback) const {
+ DCHECK(fallback);
+ DCHECK(primary_font_);
+ for (const auto& part : RunsOrParts()) {
+ if (part.run_->font_data_ && part.run_->font_data_ != primary_font_) {
+- fallback->insert(part.run_->font_data_.Get());
++ fallback->insert(part.run_->font_data_.get());
+ }
+ }
+ }
+@@ -392,7 +387,7 @@ float ShapeResultView::ForEachGlyphImpl(
+ const auto& run = part.run_;
+ auto total_advance = initial_advance;
+ bool is_horizontal = HB_DIRECTION_IS_HORIZONTAL(run->direction_);
+- const SimpleFontData* font_data = run->font_data_.Get();
++ const SimpleFontData* font_data = run->font_data_.get();
+ const unsigned character_index_offset_for_glyph_data =
+ CharacterIndexOffsetForGlyphData(part);
+ for (const auto& glyph_data : part) {
+@@ -435,7 +430,7 @@ float ShapeResultView::ForEachGlyphImpl(
+ auto total_advance = initial_advance;
+ const auto& run = part.run_;
+ bool is_horizontal = HB_DIRECTION_IS_HORIZONTAL(run->direction_);
+- const SimpleFontData* font_data = run->font_data_.Get();
++ const SimpleFontData* font_data = run->font_data_.get();
+ const unsigned character_index_offset_for_glyph_data =
+ CharacterIndexOffsetForGlyphData(part);
+ if (run->IsLtr()) { // Left-to-right
+--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h
++++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h
+@@ -10,7 +10,6 @@
+ #include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h"
+ #include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
+ #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
+-#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
+ #include "third_party/blink/renderer/platform/platform_export.h"
+ #include "third_party/blink/renderer/platform/text/text_direction.h"
+ #include "third_party/blink/renderer/platform/wtf/forward.h"
+@@ -111,10 +110,7 @@ class PLATFORM_EXPORT ShapeResultView fi
+ ShapeResultView& operator=(const ShapeResultView&) = delete;
+ ~ShapeResultView() = default;
+
+- void Trace(Visitor* visitor) const {
+- visitor->Trace(parts_);
+- visitor->Trace(primary_font_);
+- }
++ void Trace(Visitor* visitor) const { visitor->Trace(parts_); }
+
+ ShapeResult* CreateShapeResult() const;
+
+@@ -130,7 +126,7 @@ class PLATFORM_EXPORT ShapeResultView fi
+ bool IsLtr() const { return blink::IsLtr(Direction()); }
+ bool IsRtl() const { return blink::IsRtl(Direction()); }
+ bool HasVerticalOffsets() const { return has_vertical_offsets_; }
+- void FallbackFonts(HeapHashSet<Member<const SimpleFontData>>* fallback) const;
++ void FallbackFonts(HashSet<const SimpleFontData*>* fallback) const;
+
+ unsigned PreviousSafeToBreakOffset(unsigned index) const;
+
+@@ -155,8 +151,10 @@ class PLATFORM_EXPORT ShapeResultView fi
+ // bounds.
+ gfx::RectF ComputeInkBounds() const;
+
+- const SimpleFontData* PrimaryFont() const { return primary_font_.Get(); }
+- void GetRunFontData(HeapVector<ShapeResult::RunFontData>*) const;
++ scoped_refptr<const SimpleFontData> PrimaryFont() const {
++ return primary_font_;
++ }
++ void GetRunFontData(Vector<ShapeResult::RunFontData>*) const;
+
+ void ExpandRangeToIncludePartialGlyphs(unsigned* from, unsigned* to) const;
+
+@@ -288,8 +286,7 @@ class PLATFORM_EXPORT ShapeResultView fi
+
+ unsigned StartIndexOffsetForRun() const { return char_index_offset_; }
+
+- HeapVector<RunInfoPart, 1> parts_;
+- Member<const SimpleFontData> const primary_font_;
++ scoped_refptr<const SimpleFontData> const primary_font_;
+
+ const unsigned start_index_;
+
+@@ -311,6 +308,8 @@ class PLATFORM_EXPORT ShapeResultView fi
+ // with ShapeResult::SubRange
+ const unsigned char_index_offset_;
+
++ HeapVector<RunInfoPart, 1> parts_;
++
+ private:
+ friend class ShapeResult;
+
+--- a/third_party/blink/renderer/platform/fonts/simple_font_data.cc
++++ b/third_party/blink/renderer/platform/fonts/simple_font_data.cc
+@@ -76,14 +76,14 @@ constexpr int32_t kFontObjectsMemoryCons
+ constexpr int32_t kFontObjectsMemoryConsumption = 2128;
+ #endif
+
+-SimpleFontData::SimpleFontData(const FontPlatformData* platform_data,
+- const CustomFontData* custom_data,
++SimpleFontData::SimpleFontData(const FontPlatformData& platform_data,
++ scoped_refptr<CustomFontData> custom_data,
+ bool subpixel_ascent_descent,
+ const FontMetricsOverride& metrics_override)
+ : platform_data_(platform_data),
+- font_(platform_data->size() ? platform_data->CreateSkFont()
++ font_(platform_data_.size() ? platform_data.CreateSkFont()
+ : skia::DefaultFont()),
+- custom_font_data_(custom_data) {
++ custom_font_data_(std::move(custom_data)) {
+ // Every time new SimpleFontData instance is created, Skia will ask
+ // FreeType to get the metrics for glyphs by invoking
+ // af_face_globals_get_metrics. There FT will allocate style_metrics_size
+@@ -111,7 +111,7 @@ SimpleFontData::~SimpleFontData() {
+
+ void SimpleFontData::PlatformInit(bool subpixel_ascent_descent,
+ const FontMetricsOverride& metrics_override) {
+- if (!platform_data_->size()) {
++ if (!platform_data_.size()) {
+ font_metrics_.Reset();
+ avg_char_width_ = 0;
+ max_char_width_ = 0;
+@@ -126,7 +126,7 @@ void SimpleFontData::PlatformInit(bool s
+ float descent;
+
+ FontMetrics::AscentDescentWithHacks(
+- ascent, descent, *platform_data_, font_, subpixel_ascent_descent,
++ ascent, descent, platform_data_, font_, subpixel_ascent_descent,
+ metrics_override.ascent_override, metrics_override.descent_override);
+
+ font_metrics_.SetAscent(ascent);
+@@ -164,7 +164,7 @@ void SimpleFontData::PlatformInit(bool s
+
+ float line_gap;
+ if (metrics_override.line_gap_override) {
+- line_gap = *metrics_override.line_gap_override * platform_data_->size();
++ line_gap = *metrics_override.line_gap_override * platform_data_.size();
+ } else {
+ line_gap = SkScalarToFloat(metrics.fLeading);
+ }
+@@ -261,39 +261,45 @@ bool SimpleFontData::IsSegmented() const
+ return false;
+ }
+
+-SimpleFontData* SimpleFontData::SmallCapsFontData(
++scoped_refptr<SimpleFontData> SimpleFontData::SmallCapsFontData(
+ const FontDescription& font_description) const {
+- if (!small_caps_) {
+- small_caps_ =
++ if (!derived_font_data_)
++ derived_font_data_ = std::make_unique<DerivedFontData>();
++ if (!derived_font_data_->small_caps) {
++ derived_font_data_->small_caps =
+ CreateScaledFontData(font_description, kSmallCapsFontSizeMultiplier);
+ }
+- return small_caps_;
++
++ return derived_font_data_->small_caps;
+ }
+
+-SimpleFontData* SimpleFontData::EmphasisMarkFontData(
++scoped_refptr<SimpleFontData> SimpleFontData::EmphasisMarkFontData(
+ const FontDescription& font_description) const {
+- if (!emphasis_mark_) {
+- emphasis_mark_ =
++ if (!derived_font_data_)
++ derived_font_data_ = std::make_unique<DerivedFontData>();
++ if (!derived_font_data_->emphasis_mark) {
++ derived_font_data_->emphasis_mark =
+ CreateScaledFontData(font_description, kEmphasisMarkFontSizeMultiplier);
+ }
+- return emphasis_mark_;
++
++ return derived_font_data_->emphasis_mark;
+ }
+
+-SimpleFontData* SimpleFontData::CreateScaledFontData(
++scoped_refptr<SimpleFontData> SimpleFontData::CreateScaledFontData(
+ const FontDescription& font_description,
+ float scale_factor) const {
+ const float scaled_size =
+ lroundf(font_description.ComputedSize() * scale_factor);
+- return MakeGarbageCollected<SimpleFontData>(
+- MakeGarbageCollected<FontPlatformData>(*platform_data_, scaled_size),
+- IsCustomFont() ? MakeGarbageCollected<CustomFontData>() : nullptr);
++ return SimpleFontData::Create(
++ FontPlatformData(platform_data_, scaled_size),
++ IsCustomFont() ? CustomFontData::Create() : nullptr);
+ }
+
+-SimpleFontData* SimpleFontData::MetricsOverriddenFontData(
++scoped_refptr<SimpleFontData> SimpleFontData::MetricsOverriddenFontData(
+ const FontMetricsOverride& metrics_override) const {
+- return MakeGarbageCollected<SimpleFontData>(
+- platform_data_, custom_font_data_, false /* subpixel_ascent_descent */,
+- metrics_override);
++ return base::AdoptRef(new SimpleFontData(platform_data_, custom_font_data_,
++ false /* subpixel_ascent_descent */,
++ metrics_override));
+ }
+
+ // Internal leadings can be distributed to ascent and descent.
+@@ -346,7 +352,7 @@ static std::pair<int16_t, int16_t> TypoA
+
+ void SimpleFontData::ComputeNormalizedTypoAscentAndDescent() const {
+ // Compute em height metrics from OS/2 sTypoAscender and sTypoDescender.
+- SkTypeface* typeface = platform_data_->Typeface();
++ SkTypeface* typeface = platform_data_.Typeface();
+ auto [typo_ascender, typo_descender] = TypoAscenderAndDescender(typeface);
+ if (typo_ascender > 0 &&
+ TrySetNormalizedTypoAscentAndDescent(typo_ascender, typo_descender)) {
+@@ -433,7 +439,7 @@ const std::optional<float>& SimpleFontDa
+ }
+
+ // Compute vertical advance if the orientation is `kVerticalUpright`.
+- const HarfBuzzFace* hb_face = platform_data_->GetHarfBuzzFace();
++ const HarfBuzzFace* hb_face = platform_data_.GetHarfBuzzFace();
+ const OpenTypeVerticalData& vertical_data = hb_face->VerticalData();
+ ideographic_inline_size_ = vertical_data.AdvanceHeight(cjk_water_glyph);
+ });
+@@ -461,9 +467,8 @@ const HanKerning::FontData& SimpleFontDa
+ }
+
+ gfx::RectF SimpleFontData::PlatformBoundsForGlyph(Glyph glyph) const {
+- if (!platform_data_->size()) {
++ if (!platform_data_.size())
+ return gfx::RectF();
+- }
+
+ static_assert(sizeof(glyph) == 2, "Glyph id should not be truncated.");
+
+@@ -476,18 +481,16 @@ void SimpleFontData::BoundsForGlyphs(con
+ Vector<SkRect, 256>* bounds) const {
+ DCHECK_EQ(glyphs.size(), bounds->size());
+
+- if (!platform_data_->size()) {
++ if (!platform_data_.size())
+ return;
+- }
+
+ DCHECK_EQ(bounds->size(), glyphs.size());
+ SkFontGetBoundsForGlyphs(font_, glyphs, bounds->data());
+ }
+
+ float SimpleFontData::WidthForGlyph(Glyph glyph) const {
+- if (!platform_data_->size()) {
++ if (!platform_data_.size())
+ return 0;
+- }
+
+ static_assert(sizeof(glyph) == 2, "Glyph id should not be truncated.");
+
+--- a/third_party/blink/renderer/platform/fonts/simple_font_data.h
++++ b/third_party/blink/renderer/platform/fonts/simple_font_data.h
+@@ -40,7 +40,6 @@
+ #include "third_party/blink/renderer/platform/fonts/glyph.h"
+ #include "third_party/blink/renderer/platform/fonts/shaping/han_kerning.h"
+ #include "third_party/blink/renderer/platform/fonts/typesetting_features.h"
+-#include "third_party/blink/renderer/platform/heap/member.h"
+ #include "third_party/blink/renderer/platform/platform_export.h"
+ #include "third_party/blink/renderer/platform/wtf/casting.h"
+ #include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+@@ -75,18 +74,12 @@ class FontDescription;
+ class PLATFORM_EXPORT SimpleFontData final : public FontData {
+ public:
+ // Used to create platform fonts.
+- SimpleFontData(
+- const FontPlatformData*,
+- const CustomFontData* custom_data = nullptr,
+- bool subpixel_ascent_descent = false,
+- const FontMetricsOverride& metrics_override = FontMetricsOverride());
+-
+- void Trace(Visitor* visitor) const override {
+- visitor->Trace(platform_data_);
+- visitor->Trace(small_caps_);
+- visitor->Trace(emphasis_mark_);
+- visitor->Trace(custom_font_data_);
+- FontData::Trace(visitor);
++ static scoped_refptr<SimpleFontData> Create(
++ const FontPlatformData& platform_data,
++ scoped_refptr<CustomFontData> custom_data = nullptr,
++ bool subpixel_ascent_descent = false) {
++ return base::AdoptRef(new SimpleFontData(
++ platform_data, std::move(custom_data), subpixel_ascent_descent));
+ }
+
+ SimpleFontData(const SimpleFontData&) = delete;
+@@ -95,11 +88,13 @@ class PLATFORM_EXPORT SimpleFontData fin
+ SimpleFontData& operator=(const SimpleFontData&) = delete;
+ SimpleFontData& operator=(const SimpleFontData&&) = delete;
+
+- const FontPlatformData& PlatformData() const { return *platform_data_; }
++ const FontPlatformData& PlatformData() const { return platform_data_; }
+
+- SimpleFontData* SmallCapsFontData(const FontDescription&) const;
+- SimpleFontData* EmphasisMarkFontData(const FontDescription&) const;
+- SimpleFontData* MetricsOverriddenFontData(const FontMetricsOverride&) const;
++ scoped_refptr<SimpleFontData> SmallCapsFontData(const FontDescription&) const;
++ scoped_refptr<SimpleFontData> EmphasisMarkFontData(
++ const FontDescription&) const;
++ scoped_refptr<SimpleFontData> MetricsOverriddenFontData(
++ const FontMetricsOverride&) const;
+
+ FontMetrics& GetFontMetrics() { return font_metrics_; }
+ const FontMetrics& GetFontMetrics() const { return font_metrics_; }
+@@ -154,7 +149,7 @@ class PLATFORM_EXPORT SimpleFontData fin
+
+ Glyph GlyphForCharacter(UChar32) const;
+
+- bool IsCustomFont() const override { return custom_font_data_; }
++ bool IsCustomFont() const override { return custom_font_data_.get(); }
+ bool IsLoading() const override {
+ return custom_font_data_ ? custom_font_data_->IsLoading() : false;
+ }
+@@ -169,16 +164,20 @@ class PLATFORM_EXPORT SimpleFontData fin
+ return custom_font_data_ && custom_font_data_->ShouldSkipDrawing();
+ }
+
+- const CustomFontData* GetCustomFontData() const {
+- return custom_font_data_.Get();
+- }
++ CustomFontData* GetCustomFontData() const { return custom_font_data_.get(); }
+
+ private:
++ SimpleFontData(
++ const FontPlatformData&,
++ scoped_refptr<CustomFontData> custom_data,
++ bool subpixel_ascent_descent = false,
++ const FontMetricsOverride& metrics_override = FontMetricsOverride());
++
+ void PlatformInit(bool subpixel_ascent_descent, const FontMetricsOverride&);
+ void PlatformGlyphInit();
+
+- SimpleFontData* CreateScaledFontData(const FontDescription&,
+- float scale_factor) const;
++ scoped_refptr<SimpleFontData> CreateScaledFontData(const FontDescription&,
++ float scale_factor) const;
+
+ void ComputeNormalizedTypoAscentAndDescent() const;
+ bool TrySetNormalizedTypoAscentAndDescent(float ascent, float descent) const;
+@@ -187,17 +186,30 @@ class PLATFORM_EXPORT SimpleFontData fin
+ float max_char_width_ = -1;
+ float avg_char_width_ = -1;
+
+- Member<const FontPlatformData> platform_data_;
++ const FontPlatformData platform_data_;
+ const SkFont font_;
+
+ Glyph space_glyph_ = 0;
+ float space_width_ = 0;
+ Glyph zero_glyph_ = 0;
+
+- mutable Member<SimpleFontData> small_caps_;
+- mutable Member<SimpleFontData> emphasis_mark_;
++ struct DerivedFontData final {
++ USING_FAST_MALLOC(DerivedFontData);
++
++ public:
++ DerivedFontData() = default;
++ DerivedFontData(const DerivedFontData&) = delete;
++ DerivedFontData(DerivedFontData&&) = delete;
++ DerivedFontData& operator=(const DerivedFontData&) = delete;
++ DerivedFontData& operator=(DerivedFontData&&) = delete;
++
++ scoped_refptr<SimpleFontData> small_caps;
++ scoped_refptr<SimpleFontData> emphasis_mark;
++ };
++
++ mutable std::unique_ptr<DerivedFontData> derived_font_data_;
+
+- Member<const CustomFontData> custom_font_data_;
++ const scoped_refptr<CustomFontData> custom_font_data_;
+
+ mutable std::once_flag ideographic_inline_size_once_;
+ mutable std::once_flag ideographic_advance_width_once_;
+--- a/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc
++++ b/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc
+@@ -94,7 +94,7 @@ AtomicString FontCache::GetFamilyNameFor
+
+ void FontCache::PlatformInit() {}
+
+-const SimpleFontData* FontCache::FallbackOnStandardFontStyle(
++scoped_refptr<SimpleFontData> FontCache::FallbackOnStandardFontStyle(
+ const FontDescription& font_description,
+ UChar32 character) {
+ FontDescription substitute_description(font_description);
+@@ -103,26 +103,27 @@ const SimpleFontData* FontCache::Fallbac
+
+ FontFaceCreationParams creation_params(
+ substitute_description.Family().FamilyName());
+- const FontPlatformData* substitute_platform_data =
++ FontPlatformData* substitute_platform_data =
+ GetFontPlatformData(substitute_description, creation_params);
+ if (substitute_platform_data &&
+ substitute_platform_data->FontContainsCharacter(character)) {
+- FontPlatformData* platform_data =
+- MakeGarbageCollected<FontPlatformData>(*substitute_platform_data);
+- platform_data->SetSyntheticBold(font_description.Weight() >=
+- kBoldThreshold &&
+- font_description.SyntheticBoldAllowed());
+- platform_data->SetSyntheticItalic(
+- font_description.Style() == kItalicSlopeValue &&
+- font_description.SyntheticItalicAllowed());
+- return FontDataFromFontPlatformData(platform_data);
++ FontPlatformData platform_data =
++ FontPlatformData(*substitute_platform_data);
++ platform_data.SetSyntheticBold(font_description.Weight() >=
++ kBoldThreshold &&
++ font_description.SyntheticBoldAllowed());
++ platform_data.SetSyntheticItalic(font_description.Style() ==
++ kItalicSlopeValue &&
++ font_description.SyntheticItalicAllowed());
++ return FontDataFromFontPlatformData(&platform_data, kDoNotRetain);
+ }
+
+ return nullptr;
+ }
+
+-const SimpleFontData* FontCache::GetLastResortFallbackFont(
+- const FontDescription& description) {
++scoped_refptr<SimpleFontData> FontCache::GetLastResortFallbackFont(
++ const FontDescription& description,
++ ShouldRetain should_retain) {
+ const FontFaceCreationParams fallback_creation_params(
+ GetFallbackFontFamily(description));
+ const FontPlatformData* font_platform_data = GetFontPlatformData(
+@@ -195,7 +196,7 @@ const SimpleFontData* FontCache::GetLast
+ #endif
+
+ DCHECK(font_platform_data);
+- return FontDataFromFontPlatformData(font_platform_data);
++ return FontDataFromFontPlatformData(font_platform_data, should_retain);
+ }
+
+ sk_sp<SkTypeface> FontCache::CreateTypeface(
+@@ -238,7 +239,7 @@ sk_sp<SkTypeface> FontCache::CreateTypef
+ }
+
+ #if !BUILDFLAG(IS_WIN)
+-const FontPlatformData* FontCache::CreateFontPlatformData(
++std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData(
+ const FontDescription& font_description,
+ const FontFaceCreationParams& creation_params,
+ float font_size,
+@@ -293,10 +294,11 @@ const FontPlatformData* FontCache::Creat
+ ->GetResolvedFontFeatures()
+ : ResolvedFontFeatures();
+
+- FontPlatformData* font_platform_data = MakeGarbageCollected<FontPlatformData>(
+- typeface, name, font_size, synthetic_bold, synthetic_italic,
+- font_description.TextRendering(), resolved_font_features,
+- font_description.Orientation());
++ std::unique_ptr<FontPlatformData> font_platform_data =
++ std::make_unique<FontPlatformData>(
++ typeface, name, font_size, synthetic_bold, synthetic_italic,
++ font_description.TextRendering(), resolved_font_features,
++ font_description.Orientation());
+
+ font_platform_data->SetAvoidEmbeddedBitmaps(
+ BitmapGlyphsBlockList::ShouldAvoidEmbeddedBitmapsForTypeface(*typeface));
+--- a/third_party/blink/renderer/platform/testing/font_test_helpers.cc
++++ b/third_party/blink/renderer/platform/testing/font_test_helpers.cc
+@@ -43,26 +43,23 @@ class TestFontSelector : public FontSele
+ }
+ ~TestFontSelector() override = default;
+
+- FontData* GetFontData(const FontDescription& font_description,
+- const FontFamily&) override {
++ scoped_refptr<FontData> GetFontData(const FontDescription& font_description,
++ const FontFamily&) override {
+ FontSelectionCapabilities normal_capabilities(
+ {kNormalWidthValue, kNormalWidthValue},
+ {kNormalSlopeValue, kNormalSlopeValue},
+ {kNormalWeightValue, kNormalWeightValue});
+- const FontPlatformData* platform_data =
+- custom_platform_data_->GetFontPlatformData(
+- font_description.EffectiveFontSize(),
+- font_description.AdjustedSpecifiedSize(),
+- font_description.IsSyntheticBold() &&
+- font_description.SyntheticBoldAllowed(),
+- font_description.IsSyntheticItalic() &&
+- font_description.SyntheticItalicAllowed(),
+- font_description.GetFontSelectionRequest(), normal_capabilities,
+- font_description.FontOpticalSizing(),
+- font_description.TextRendering(), {},
+- font_description.Orientation());
+- return MakeGarbageCollected<SimpleFontData>(
+- platform_data, MakeGarbageCollected<CustomFontData>());
++ FontPlatformData platform_data = custom_platform_data_->GetFontPlatformData(
++ font_description.EffectiveFontSize(),
++ font_description.AdjustedSpecifiedSize(),
++ font_description.IsSyntheticBold() &&
++ font_description.SyntheticBoldAllowed(),
++ font_description.IsSyntheticItalic() &&
++ font_description.SyntheticItalicAllowed(),
++ font_description.GetFontSelectionRequest(), normal_capabilities,
++ font_description.FontOpticalSizing(), font_description.TextRendering(),
++ {}, font_description.Orientation());
++ return SimpleFontData::Create(platform_data, CustomFontData::Create());
+ }
+
+ void WillUseFontData(const FontDescription&,
+@@ -83,20 +80,20 @@ class TestFontSelector : public FontSele
+ void ReportFontLookupByUniqueOrFamilyName(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) override {}
++ scoped_refptr<SimpleFontData> resulting_font_data) override {}
+ void ReportFontLookupByUniqueNameOnly(
+ const AtomicString& name,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data,
++ scoped_refptr<SimpleFontData> resulting_font_data,
+ bool is_loading_fallback = false) override {}
+ void ReportFontLookupByFallbackCharacter(
+ UChar32 hint,
+ FontFallbackPriority fallback_priority,
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) override {}
++ scoped_refptr<SimpleFontData> resulting_font_data) override {}
+ void ReportLastResortFallbackFontLookup(
+ const FontDescription& font_description,
+- const SimpleFontData* resulting_font_data) override {}
++ scoped_refptr<SimpleFontData> resulting_font_data) override {}
+ void ReportNotDefGlyph() const override {}
+ void ReportEmojiSegmentGlyphCoverage(unsigned, unsigned) override {}
+ ExecutionContext* GetExecutionContext() const override { return nullptr; }
+--- a/tools/privacy_budget/font_indexer/font_indexer.cc
++++ b/tools/privacy_budget/font_indexer/font_indexer.cc
+@@ -116,7 +116,7 @@ void FontIndexer::FontListHasLoaded(base
+ bool FontIndexer::DoesFontHaveDigest(WTF::AtomicString name,
+ blink::FontDescription font_description,
+ int64_t digest) {
+- const blink::SimpleFontData* font_data =
++ scoped_refptr<blink::SimpleFontData> font_data =
+ font_cache_->GetFontData(font_description, name);
+ DCHECK(font_data);
+ return blink::FontGlobalContext::Get()
+@@ -170,7 +170,7 @@ void FontIndexer::PrintAllFontsWithName(
+ // exists and for later comparison.
+ int64_t default_font_digest;
+ {
+- const blink::SimpleFontData* font_data =
++ scoped_refptr<blink::SimpleFontData> font_data =
+ font_cache_->GetFontData(blink::FontDescription(), name);
+ default_font_digest =
+ font_data ? blink::FontGlobalContext::Get()
+@@ -231,7 +231,7 @@ void FontIndexer::PrintAllFontsWithName(
+ for (auto slope_pair : slopes) {
+ font_description.SetStyle(slope_pair.first);
+
+- if (const blink::SimpleFontData* font_data =
++ if (scoped_refptr<blink::SimpleFontData> font_data =
+ font_cache_->GetFontData(font_description, name)) {
+ uint64_t typeface_digest =
+ blink::FontGlobalContext::Get()