Changeset 254634 in webkit


Ignore:
Timestamp:
Jan 15, 2020 1:49:37 PM (4 years ago)
Author:
Antti Koivisto
Message:

[LFC] Cache display box for the first LayoutState to Layout::Box
https://bugs.webkit.org/show_bug.cgi?id=206288

Reviewed by Zalan Bujtas.

Add a single item cache for the common case to avoid using the hash.

  • layout/FormattingState.cpp:

(WebCore::Layout::FormattingState::displayBox):

  • layout/LayoutState.cpp:

(WebCore::Layout::LayoutState::displayBoxForRootLayoutBox):
(WebCore::Layout::LayoutState::ensureDisplayBoxForLayoutBoxSlow):
(WebCore::Layout::LayoutState::displayBoxForLayoutBox): Deleted.
(WebCore::Layout::LayoutState::displayBoxForLayoutBox const): Deleted.

  • layout/LayoutState.h:

(WebCore::Layout::Box::cachedDisplayBoxForLayoutState const):
(WebCore::Layout::LayoutState::hasDisplayBox const):
(WebCore::Layout::LayoutState::ensureDisplayBoxForLayoutBox):
(WebCore::Layout::LayoutState::displayBoxForLayoutBox const):

  • layout/layouttree/LayoutBox.cpp:

(WebCore::Layout::Box::setCachedDisplayBoxForLayoutState const):

  • layout/layouttree/LayoutBox.h:

(WebCore::Layout::Box::hasCachedDisplayBox const):

  • layout/layouttree/LayoutTreeBuilder.h:
Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r254631 r254634  
     12020-01-15  Antti Koivisto  <antti@apple.com>
     2
     3        [LFC] Cache display box for the first LayoutState to Layout::Box
     4        https://bugs.webkit.org/show_bug.cgi?id=206288
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        Add a single item cache for the common case to avoid using the hash.
     9
     10        * layout/FormattingState.cpp:
     11        (WebCore::Layout::FormattingState::displayBox):
     12        * layout/LayoutState.cpp:
     13        (WebCore::Layout::LayoutState::displayBoxForRootLayoutBox):
     14        (WebCore::Layout::LayoutState::ensureDisplayBoxForLayoutBoxSlow):
     15        (WebCore::Layout::LayoutState::displayBoxForLayoutBox): Deleted.
     16        (WebCore::Layout::LayoutState::displayBoxForLayoutBox const): Deleted.
     17        * layout/LayoutState.h:
     18        (WebCore::Layout::Box::cachedDisplayBoxForLayoutState const):
     19        (WebCore::Layout::LayoutState::hasDisplayBox const):
     20        (WebCore::Layout::LayoutState::ensureDisplayBoxForLayoutBox):
     21        (WebCore::Layout::LayoutState::displayBoxForLayoutBox const):
     22        * layout/layouttree/LayoutBox.cpp:
     23        (WebCore::Layout::Box::setCachedDisplayBoxForLayoutState const):
     24        * layout/layouttree/LayoutBox.h:
     25        (WebCore::Layout::Box::hasCachedDisplayBox const):
     26        * layout/layouttree/LayoutTreeBuilder.h:
     27
    1282020-01-15  Simon Fraser  <simon.fraser@apple.com>
    229
  • trunk/Source/WebCore/layout/FormattingState.cpp

    r250064 r254634  
    5252    // Should never need to mutate a display box outside of the formatting context.
    5353    ASSERT(&layoutState().establishedFormattingState(layoutBox.formattingContextRoot()) == this);
    54     return layoutState().displayBoxForLayoutBox(layoutBox);
     54    return layoutState().ensureDisplayBoxForLayoutBox(layoutBox);
    5555}
    5656
  • trunk/Source/WebCore/layout/LayoutState.cpp

    r253985 r254634  
    6161Display::Box& LayoutState::displayBoxForRootLayoutBox()
    6262{
    63     return displayBoxForLayoutBox(m_layoutTreeContent->rootLayoutBox());
     63    return ensureDisplayBoxForLayoutBox(m_layoutTreeContent->rootLayoutBox());
    6464}
    6565
    66 Display::Box& LayoutState::displayBoxForLayoutBox(const Box& layoutBox)
     66Display::Box& LayoutState::ensureDisplayBoxForLayoutBoxSlow(const Box& layoutBox)
    6767{
     68    if (layoutBox.canCacheForLayoutState(*this)) {
     69        ASSERT(!layoutBox.cachedDisplayBoxForLayoutState(*this));
     70        auto newBox = makeUnique<Display::Box>();
     71        auto& newBoxPtr = *newBox;
     72        layoutBox.setCachedDisplayBoxForLayoutState(*this, WTFMove(newBox));
     73        return newBoxPtr;
     74    }
     75
    6876    return *m_layoutToDisplayBox.ensure(&layoutBox, [] {
    6977        return makeUnique<Display::Box>();
    7078    }).iterator->value;
    71 }
    72 
    73 const Display::Box& LayoutState::displayBoxForLayoutBox(const Box& layoutBox) const
    74 {
    75     ASSERT(hasDisplayBox(layoutBox));
    76     return *m_layoutToDisplayBox.get(&layoutBox);
    7779}
    7880
  • trunk/Source/WebCore/layout/LayoutState.h

    r253985 r254634  
    4343namespace Layout {
    4444
    45 class Box;
    4645class FormattingContext;
    4746class FormattingState;
    4847
    49 class LayoutState {
     48class LayoutState : public CanMakeWeakPtr<LayoutState> {
    5049    WTF_MAKE_ISO_ALLOCATED(LayoutState);
    5150public:
     
    6463
    6564    Display::Box& displayBoxForRootLayoutBox();
    66     Display::Box& displayBoxForLayoutBox(const Box& layoutBox);
    67     const Display::Box& displayBoxForLayoutBox(const Box& layoutBox) const;
    68     bool hasDisplayBox(const Box& layoutBox) const { return m_layoutToDisplayBox.contains(&layoutBox); }
     65    Display::Box& ensureDisplayBoxForLayoutBox(const Box&);
     66    const Display::Box& displayBoxForLayoutBox(const Box&) const;
     67
     68    bool hasDisplayBox(const Box&) const;
    6969
    7070    enum class QuirksMode { No, Limited, Yes };
     
    8585private:
    8686    void setQuirksMode(QuirksMode quirksMode) { m_quirksMode = quirksMode; }
     87    Display::Box& ensureDisplayBoxForLayoutBoxSlow(const Box&);
    8788
    8889    HashMap<const Container*, std::unique_ptr<FormattingState>> m_formattingStates;
     
    9899};
    99100
     101inline bool LayoutState::hasDisplayBox(const Box& layoutBox) const
     102{
     103    if (layoutBox.cachedDisplayBoxForLayoutState(*this))
     104        return true;
     105    return m_layoutToDisplayBox.contains(&layoutBox);
     106}
     107
     108inline Display::Box& LayoutState::ensureDisplayBoxForLayoutBox(const Box& layoutBox)
     109{
     110    if (auto* displayBox = layoutBox.cachedDisplayBoxForLayoutState(*this))
     111        return *displayBox;
     112    return ensureDisplayBoxForLayoutBoxSlow(layoutBox);
     113}
     114
     115inline const Display::Box& LayoutState::displayBoxForLayoutBox(const Box& layoutBox) const
     116{
     117    if (auto* displayBox = layoutBox.cachedDisplayBoxForLayoutState(*this))
     118        return *displayBox;
     119    ASSERT(m_layoutToDisplayBox.contains(&layoutBox));
     120    return *m_layoutToDisplayBox.get(&layoutBox);
     121}
     122
    100123#ifndef NDEBUG
    101124inline void LayoutState::registerFormattingContext(const FormattingContext& formattingContext)
     
    107130#endif
    108131
     132// These Layout::Box function are here to allow inlining.
     133inline bool Box::canCacheForLayoutState(const LayoutState& layoutState) const
     134{
     135    return !m_cachedLayoutState || m_cachedLayoutState.get() == &layoutState;
     136}
     137
     138inline Display::Box* Box::cachedDisplayBoxForLayoutState(const LayoutState& layoutState) const
     139{
     140    if (m_cachedLayoutState.get() != &layoutState)
     141        return nullptr;
     142    return m_cachedDisplayBoxForLayoutState.get();
     143}
     144
    109145}
    110146}
  • trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp

    r254410 r254634  
    3131#include "LayoutContainer.h"
    3232#include "LayoutPhase.h"
     33#include "LayoutState.h"
    3334#include "RenderStyle.h"
    3435#include <wtf/IsoMallocInlines.h>
     
    445446}
    446447
     448void Box::setCachedDisplayBoxForLayoutState(LayoutState& layoutState, std::unique_ptr<Display::Box> box) const
     449{
     450    ASSERT(!m_cachedLayoutState);
     451    m_cachedLayoutState = makeWeakPtr(layoutState);
     452    m_cachedDisplayBoxForLayoutState = WTFMove(box);
     453}
     454
    447455Box::RareDataMap& Box::rareDataMap()
    448456{
  • trunk/Source/WebCore/layout/layouttree/LayoutBox.h

    r254410 r254634  
    3535
    3636namespace WebCore {
     37
     38namespace Display {
     39class Box;
     40}
     41
    3742namespace Layout {
    3843
    3944class Container;
     45class LayoutState;
    4046class TreeBuilder;
    4147
     
    168174    void setIsAnonymous() { m_isAnonymous = true; }
    169175
     176    bool canCacheForLayoutState(const LayoutState&) const;
     177    Display::Box* cachedDisplayBoxForLayoutState(const LayoutState&) const;
     178    void setCachedDisplayBoxForLayoutState(LayoutState&, std::unique_ptr<Display::Box>) const;
     179
    170180protected:
    171181    Box(Optional<ElementAttributes>, Optional<TextContext>, RenderStyle&&, BaseTypeFlags);
     
    202212    const Optional<TextContext> m_textContext;
    203213
     214    // First LayoutState gets a direct cache.
     215    mutable WeakPtr<LayoutState> m_cachedLayoutState;
     216    mutable std::unique_ptr<Display::Box> m_cachedDisplayBoxForLayoutState;
     217
    204218    unsigned m_baseTypeFlags : 6;
    205219    bool m_hasRareData : 1;
  • trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h

    r253921 r254634  
    2828#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
    2929
    30 #include "LayoutBox.h"
    3130#include <wtf/IsoMalloc.h>
    3231#include <wtf/WeakPtr.h>
Note: See TracChangeset for help on using the changeset viewer.