diff --git a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl index 72edae06edaf7..e76eb3b553fa6 100644 --- a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl +++ b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl @@ -1,6 +1,35 @@ {% from 'templates/macros.tmpl' import license, print_if, source_files_for_generated_file %} {% from 'templates/fields/field.tmpl' import encode, getter_expression, setter_expression, declare_storage, fieldwise_compare, fieldwise_copy, fieldwise_diff, fieldwise_pointer_compare_inherited %} {% from 'templates/fields/group.tmpl' import declare_field_group_class %} +{% macro analyser_fields(group): -%} + HashSet {{group.type_name}}_instances{}; + {% for subgroup in group.subgroups %} + {{analyser_fields(subgroup)}} + {%- endfor %} +{%- endmacro %} +{% macro analyser_totals(group): -%} + + {{group.type_name}}_instances.size() * sizeof (ComputedStyleBase::{{group.type_name}}) + {% for subgroup in group.subgroups %} + {{analyser_totals(subgroup)}} + {%- endfor %} +{%- endmacro %} +{% macro analyser_tracks(group): -%} + void TrackFieldGroup(const ComputedStyleBase::{{group.type_name}}& x) { + {{group.type_name}}_instances.insert((uintptr_t) &x); + {% for subgroup in group.subgroups %} + if (const auto* y = x.{{subgroup.member_name}}.Get()) TrackFieldGroup(*y); + {% endfor %} + } + {% for subgroup in group.subgroups %} + {{analyser_tracks(subgroup)}} + {%- endfor %} +{%- endmacro %} +{% macro analyser_names(group): -%} +struct {{group.type_name}}TypeName { static const char* Get() { return "{{group.type_name}}"; } }; +{% for subgroup in group.subgroups %} +{{analyser_names(subgroup)}} +{%- endfor %} +{%- endmacro %} {{license()}} {{source_files_for_generated_file(template_file, input_files)}} @@ -39,6 +68,9 @@ } %} namespace blink { +{% for subgroup in computed_style.subgroups %} +{{analyser_names(subgroup)}} +{%- endfor %} // Forward declaration for diff functions. class ComputedStyle; @@ -80,6 +112,8 @@ class ComputedStyle; // 'external' field has an extra setter that takes an rvalue reference. A list // of the available templates can be found in css_properties.json5. class ComputedStyleBase { + friend struct ComputedStyleBaseMemoryAnalyser; + public: inline bool IndependentInheritedEqual(const ComputedStyleBase& o) const { return ( @@ -211,6 +245,30 @@ class ComputedStyleBase { {% endfor %} }; +struct ComputedStyleBaseMemoryAnalyser { + size_t Total() const { + return ComputedStyleBase_instances.size() * sizeof (ComputedStyleBase) + {% for subgroup in computed_style.subgroups %} + {{analyser_totals(subgroup)}} + {%- endfor -%}; + } + + void TrackComputedStyleBase(const ComputedStyleBase& x) { + ComputedStyleBase_instances.insert((uintptr_t) &x); + {% for subgroup in computed_style.subgroups %} + if (const auto* y = x.{{subgroup.member_name}}.Get()) TrackFieldGroup(*y); + {% endfor %} + } + {% for subgroup in computed_style.subgroups %} + {{analyser_tracks(subgroup)}} + {%- endfor %} + + HashSet ComputedStyleBase_instances{}; + {% for subgroup in computed_style.subgroups %} + {{analyser_fields(subgroup)}} + {%- endfor %} +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_BASE_H_ diff --git a/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl b/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl index c71baa358c13d..6d656be9b5872 100644 --- a/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl +++ b/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl @@ -7,6 +7,9 @@ {% endfor %} class {{group.type_name}} : public RefCounted<{{group.type_name}}> { public: + static const char* TypeName() { + return "{{group.type_name}}"; + } static scoped_refptr<{{group.type_name}}> Create() { return base::AdoptRef(new {{group.type_name}}); } diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc index 20d7d3f645d96..8eb4a248b73a5 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc @@ -1555,6 +1555,14 @@ void Color::ApplyInherit(StyleResolverState& state) const { } void Color::ApplyValue(StyleResolverState& state, const CSSValue& value) const { + printf( + "ApplyValue %p(%s): color = %s, parent %p(%s)\n", + &state.GetElement(), state.GetElement().ToString().Utf8().c_str(), + value.CssText().Utf8().c_str(), + state.GetElement().parentNode(), + state.GetElement().parentNode() + ? state.GetElement().parentNode()->ToString().Utf8().c_str() + : ""); // As per the spec, 'color: currentColor' is treated as 'color: inherit' auto* identifier_value = DynamicTo(value); if (identifier_value && diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index 0deb8d0fe5ee5..404f04b73d938 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc @@ -847,6 +847,10 @@ scoped_refptr StyleResolver::ResolveStyle( return nullptr; } + // printf(">>> ResolveStyle %p(%s):%d parent=%p(%s)\n", + // element, element->ToString().Utf8().c_str(), style_request.pseudo_id, element->parentNode(), + // element->parentNode() ? element->parentNode()->ToString().Utf8().c_str() : ""); + DCHECK(GetDocument().GetFrame()); DCHECK(GetDocument().GetSettings()); @@ -868,6 +872,7 @@ scoped_refptr StyleResolver::ResolveStyle( if (style_request.IsPseudoStyleRequest() && state.HadNoMatchedProperties()) { DCHECK(!cascade.InlineStyleLost()); + // printf("<<< ResolveStyle %p(%s):%d\n", element, element->ToString().Utf8().c_str(), style_request.pseudo_id); return state.TakeStyle(); } @@ -926,6 +931,8 @@ scoped_refptr StyleResolver::ResolveStyle( state.LoadPendingResources(); + // printf("<<< ResolveStyle %p(%s):%d\n", element, element->ToString().Utf8().c_str(), style_request.pseudo_id); + // Now return the style. return state.TakeStyle(); } @@ -1010,6 +1017,9 @@ void StyleResolver::InitStyleAndApplyInheritance( } state.Style()->SetInsideLink(link_state); } + + printf("ComputedStyle size + %zu after InitStyleAndApplyInheritance %p(%s):%d\n", + sizeof (ComputedStyle), &element, element.ToString().Utf8().c_str(), style_request.pseudo_id); } void StyleResolver::ApplyMathMLCustomStyleProperties( diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 7952a2392d063..885a2e3ebb21b 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc @@ -2881,6 +2881,9 @@ void StyleEngine::UpdateStyleAndLayoutTree() { SCOPED_BLINK_UMA_HISTOGRAM_TIMER_HIGHRES("Style.RebuildLayoutTreeTime"); RebuildLayoutTree(RebuildTransitionPseudoTree::kYes); } + + printf("ComputedStyle size = %zu after UpdateStyleAndLayoutTree %p(%s)\n", + GetDocument().ComputeStyleMemoryUsage(), &GetDocument(), GetDocument().ToString().Utf8().c_str()); } else { style_recalc_root_.Clear(); } diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index fb0904de20a64..f91af52fb6341 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc @@ -301,6 +301,7 @@ #include "third_party/blink/renderer/core/script/detect_javascript_frameworks.h" #include "third_party/blink/renderer/core/script/script_runner.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" +#include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/svg/svg_document_extensions.h" #include "third_party/blink/renderer/core/svg/svg_script_element.h" #include "third_party/blink/renderer/core/svg/svg_title_element.h" @@ -8370,6 +8371,17 @@ void Document::WriteIntoTrace(perfetto::TracedValue ctx) const { dict.Add("url", Url()); } +ComputedStyleMemoryAnalyser& Document::StyleMemoryAnalyser() { + return data_->analyser; +} + +size_t Document::ComputeStyleMemoryUsage() { + data_->analyser = ComputedStyleMemoryAnalyser{}; + for (const Node* node = documentElement(); node; node = FlatTreeTraversal::Next(*node)) + node->UpdateStyleMemoryUsage(); + return data_->analyser.Total(); +} + Document::PaintPreviewScope::PaintPreviewScope(Document& document, PaintPreviewState state) : document_(document) { diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 621389ab03902..5532e806cbe0d 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h @@ -240,6 +240,7 @@ class WebMouseEvent; class WorkletAnimationController; enum class CSSPropertyID; struct AnnotatedRegionValue; +struct ComputedStyleMemoryAnalyser; struct FocusParams; struct IconURL; struct PhysicalOffset; @@ -1861,6 +1862,9 @@ class CORE_EXPORT Document : public ContainerNode, void WriteIntoTrace(perfetto::TracedValue ctx) const; + ComputedStyleMemoryAnalyser& StyleMemoryAnalyser(); + size_t ComputeStyleMemoryUsage(); + protected: void ClearXMLVersion() { xml_version_ = String(); } diff --git a/third_party/blink/renderer/core/dom/document_data.h b/third_party/blink/renderer/core/dom/document_data.h index c029ba1451829..da1e07db40f59 100644 --- a/third_party/blink/renderer/core/dom/document_data.h +++ b/third_party/blink/renderer/core/dom/document_data.h @@ -8,6 +8,7 @@ #include "services/network/public/mojom/trust_tokens.mojom-blink.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_regexp.h" +#include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" @@ -69,6 +70,8 @@ class DocumentData final : public GarbageCollected { // prevents sending UKM multiple times. bool already_sent_automatic_lazy_load_frame_ukm_ = false; + ComputedStyleMemoryAnalyser analyser{}; + friend class Document; }; diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 0b2fdd8c2ba15..51c6f534855da 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc @@ -6662,8 +6662,14 @@ const ComputedStyle* Element::CachedStyleForPseudoElement( scoped_refptr result = UncachedStyleForPseudoElement( StyleRequest(pseudo_id, style, pseudo_argument)); if (result) { - return style->AddCachedPseudoElementStyle(std::move(result), pseudo_id, + auto* cached = + style->AddCachedPseudoElementStyle(std::move(result), pseudo_id, pseudo_argument); + UpdateStyleMemoryUsage(); + printf("ComputedStyle size = %zu after CachedStyleForPseudoElement %p(%s):%d\n", + GetDocument().StyleMemoryAnalyser().Total(), + this, ToString().Utf8().c_str(), pseudo_id); + return cached; } return nullptr; } diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index 908534c75dcd5..4a5ec0de5d376 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc @@ -3393,6 +3393,17 @@ void Node::Trace(Visitor* visitor) const { EventTarget::Trace(visitor); } +size_t Node::UpdateStyleMemoryUsage() const { + ComputedStyleMemoryAnalyser& analyser = this->GetDocument().StyleMemoryAnalyser(); + if (const auto* style = GetComputedStyle()) { + analyser.TrackComputedStyle(*style); + if (const auto* cache = style->GetPseudoElementStyleCache()) + for (const auto& pseudo_style : *cache) + analyser.TrackComputedStyle(*pseudo_style); + } + return analyser.Total(); +} + } // namespace blink #if DCHECK_IS_ON() diff --git a/third_party/blink/renderer/core/dom/node.h b/third_party/blink/renderer/core/dom/node.h index 6df8a84813c88..6cdd92457e2fd 100644 --- a/third_party/blink/renderer/core/dom/node.h +++ b/third_party/blink/renderer/core/dom/node.h @@ -990,6 +990,8 @@ class CORE_EXPORT Node : public EventTarget { } void Trace(Visitor*) const override; + size_t UpdateStyleMemoryUsage() const; + private: enum NodeFlags : uint32_t { kHasRareDataFlag = 1, diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index 872aea1ab66b2..286d191b6913a 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h @@ -288,6 +288,7 @@ class ComputedStyle : public ComputedStyleBase, friend class StyleResolver; // Access to UserModify(). friend class MatchedPropertiesCache; + friend class Node; protected: mutable std::unique_ptr cached_data_; @@ -3209,6 +3210,30 @@ inline void ComputedStyle::SetHasPseudoElementStyle(PseudoId pseudo) { 1 << (pseudo - kFirstPublicPseudoId)); } +struct ComputedStyleMemoryAnalyser : public ComputedStyleBaseMemoryAnalyser { + size_t Total() const { + return ComputedStyleBaseMemoryAnalyser::Total() + + ComputedStyleBase_instances.size() * sizeof (ComputedStyle) + - ComputedStyleBase_instances.size() * sizeof (ComputedStyleBase); + } + + void TrackComputedStyle(const ComputedStyle& x) { + TrackComputedStyleBase(x); + if (const auto* y = x.HighlightData().get()) TrackHighlights(*y); + } + + void TrackHighlights(const StyleHighlightData& x) { + StyleHighlightData_instances.insert((uintptr_t) &x); + if (const auto* y = x.Selection()) TrackComputedStyle(*y); + if (const auto* y = x.TargetText()) TrackComputedStyle(*y); + if (const auto* y = x.SpellingError()) TrackComputedStyle(*y); + if (const auto* y = x.GrammarError()) TrackComputedStyle(*y); + for (const auto& y : x.CustomHighlights().Values()) TrackComputedStyle(*y); + } + + HashSet StyleHighlightData_instances; +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_H_ diff --git a/third_party/blink/renderer/core/style/data_ref.h b/third_party/blink/renderer/core/style/data_ref.h index 6186788a1c6dd..42d50c181b378 100644 --- a/third_party/blink/renderer/core/style/data_ref.h +++ b/third_party/blink/renderer/core/style/data_ref.h @@ -40,8 +40,11 @@ class DataRef { const T* operator->() const { return Get(); } T* Access() { - if (!data_->HasOneRef()) + if (!data_->HasOneRef()) { data_ = data_->Copy(); + printf("ComputedStyle size + %zu after DataRef<%s> copy %p\n", + sizeof (T), T::TypeName(), data_.get()); + } return data_.get(); } diff --git a/third_party/blink/renderer/core/style/nine_piece_image.h b/third_party/blink/renderer/core/style/nine_piece_image.h index e50133b6581cc..e50c9b5182a19 100644 --- a/third_party/blink/renderer/core/style/nine_piece_image.h +++ b/third_party/blink/renderer/core/style/nine_piece_image.h @@ -47,6 +47,9 @@ enum ENinePieceImageRule { class CORE_EXPORT NinePieceImageData : public RefCountedCopyable { public: + static const char* TypeName() { + return "NinePieceImageData"; + } static scoped_refptr Create() { return base::AdoptRef(new NinePieceImageData); }