diff options
Diffstat (limited to 'chromium-125-debian-bad-font-gc2.patch')
-rw-r--r-- | chromium-125-debian-bad-font-gc2.patch | 3727 |
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() |