- Revision
- 254634
- Author
- an...@apple.com
- Date
- 2020-01-15 13:49:37 -0800 (Wed, 15 Jan 2020)
Log 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:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (254633 => 254634)
--- trunk/Source/WebCore/ChangeLog 2020-01-15 21:41:50 UTC (rev 254633)
+++ trunk/Source/WebCore/ChangeLog 2020-01-15 21:49:37 UTC (rev 254634)
@@ -1,3 +1,30 @@
+2020-01-15 Antti Koivisto <an...@apple.com>
+
+ [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:
+
2020-01-15 Simon Fraser <simon.fra...@apple.com>
Add more mousewheel-scrolling logging and improve the latching code
Modified: trunk/Source/WebCore/layout/FormattingState.cpp (254633 => 254634)
--- trunk/Source/WebCore/layout/FormattingState.cpp 2020-01-15 21:41:50 UTC (rev 254633)
+++ trunk/Source/WebCore/layout/FormattingState.cpp 2020-01-15 21:49:37 UTC (rev 254634)
@@ -51,7 +51,7 @@
{
// Should never need to mutate a display box outside of the formatting context.
ASSERT(&layoutState().establishedFormattingState(layoutBox.formattingContextRoot()) == this);
- return layoutState().displayBoxForLayoutBox(layoutBox);
+ return layoutState().ensureDisplayBoxForLayoutBox(layoutBox);
}
}
Modified: trunk/Source/WebCore/layout/LayoutState.cpp (254633 => 254634)
--- trunk/Source/WebCore/layout/LayoutState.cpp 2020-01-15 21:41:50 UTC (rev 254633)
+++ trunk/Source/WebCore/layout/LayoutState.cpp 2020-01-15 21:49:37 UTC (rev 254634)
@@ -60,22 +60,24 @@
Display::Box& LayoutState::displayBoxForRootLayoutBox()
{
- return displayBoxForLayoutBox(m_layoutTreeContent->rootLayoutBox());
+ return ensureDisplayBoxForLayoutBox(m_layoutTreeContent->rootLayoutBox());
}
-Display::Box& LayoutState::displayBoxForLayoutBox(const Box& layoutBox)
+Display::Box& LayoutState::ensureDisplayBoxForLayoutBoxSlow(const Box& layoutBox)
{
+ if (layoutBox.canCacheForLayoutState(*this)) {
+ ASSERT(!layoutBox.cachedDisplayBoxForLayoutState(*this));
+ auto newBox = makeUnique<Display::Box>();
+ auto& newBoxPtr = *newBox;
+ layoutBox.setCachedDisplayBoxForLayoutState(*this, WTFMove(newBox));
+ return newBoxPtr;
+ }
+
return *m_layoutToDisplayBox.ensure(&layoutBox, [] {
return makeUnique<Display::Box>();
}).iterator->value;
}
-const Display::Box& LayoutState::displayBoxForLayoutBox(const Box& layoutBox) const
-{
- ASSERT(hasDisplayBox(layoutBox));
- return *m_layoutToDisplayBox.get(&layoutBox);
-}
-
FormattingState& LayoutState::formattingStateForBox(const Box& layoutBox) const
{
auto& root = layoutBox.formattingContextRoot();
Modified: trunk/Source/WebCore/layout/LayoutState.h (254633 => 254634)
--- trunk/Source/WebCore/layout/LayoutState.h 2020-01-15 21:41:50 UTC (rev 254633)
+++ trunk/Source/WebCore/layout/LayoutState.h 2020-01-15 21:49:37 UTC (rev 254634)
@@ -42,11 +42,10 @@
namespace Layout {
-class Box;
class FormattingContext;
class FormattingState;
-class LayoutState {
+class LayoutState : public CanMakeWeakPtr<LayoutState> {
WTF_MAKE_ISO_ALLOCATED(LayoutState);
public:
LayoutState(const LayoutTreeContent&);
@@ -63,10 +62,11 @@
#endif
Display::Box& displayBoxForRootLayoutBox();
- Display::Box& displayBoxForLayoutBox(const Box& layoutBox);
- const Display::Box& displayBoxForLayoutBox(const Box& layoutBox) const;
- bool hasDisplayBox(const Box& layoutBox) const { return m_layoutToDisplayBox.contains(&layoutBox); }
+ Display::Box& ensureDisplayBoxForLayoutBox(const Box&);
+ const Display::Box& displayBoxForLayoutBox(const Box&) const;
+ bool hasDisplayBox(const Box&) const;
+
enum class QuirksMode { No, Limited, Yes };
bool inQuirksMode() const { return m_quirksMode == QuirksMode::Yes; }
bool inLimitedQuirksMode() const { return m_quirksMode == QuirksMode::Limited; }
@@ -84,6 +84,7 @@
private:
void setQuirksMode(QuirksMode quirksMode) { m_quirksMode = quirksMode; }
+ Display::Box& ensureDisplayBoxForLayoutBoxSlow(const Box&);
HashMap<const Container*, std::unique_ptr<FormattingState>> m_formattingStates;
#ifndef NDEBUG
@@ -97,6 +98,28 @@
LayoutSize m_viewportSize;
};
+inline bool LayoutState::hasDisplayBox(const Box& layoutBox) const
+{
+ if (layoutBox.cachedDisplayBoxForLayoutState(*this))
+ return true;
+ return m_layoutToDisplayBox.contains(&layoutBox);
+}
+
+inline Display::Box& LayoutState::ensureDisplayBoxForLayoutBox(const Box& layoutBox)
+{
+ if (auto* displayBox = layoutBox.cachedDisplayBoxForLayoutState(*this))
+ return *displayBox;
+ return ensureDisplayBoxForLayoutBoxSlow(layoutBox);
+}
+
+inline const Display::Box& LayoutState::displayBoxForLayoutBox(const Box& layoutBox) const
+{
+ if (auto* displayBox = layoutBox.cachedDisplayBoxForLayoutState(*this))
+ return *displayBox;
+ ASSERT(m_layoutToDisplayBox.contains(&layoutBox));
+ return *m_layoutToDisplayBox.get(&layoutBox);
+}
+
#ifndef NDEBUG
inline void LayoutState::registerFormattingContext(const FormattingContext& formattingContext)
{
@@ -106,6 +129,19 @@
}
#endif
+// These Layout::Box function are here to allow inlining.
+inline bool Box::canCacheForLayoutState(const LayoutState& layoutState) const
+{
+ return !m_cachedLayoutState || m_cachedLayoutState.get() == &layoutState;
}
+
+inline Display::Box* Box::cachedDisplayBoxForLayoutState(const LayoutState& layoutState) const
+{
+ if (m_cachedLayoutState.get() != &layoutState)
+ return nullptr;
+ return m_cachedDisplayBoxForLayoutState.get();
}
+
+}
+}
#endif
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp (254633 => 254634)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2020-01-15 21:41:50 UTC (rev 254633)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp 2020-01-15 21:49:37 UTC (rev 254634)
@@ -30,6 +30,7 @@
#include "LayoutContainer.h"
#include "LayoutPhase.h"
+#include "LayoutState.h"
#include "RenderStyle.h"
#include <wtf/IsoMallocInlines.h>
@@ -444,6 +445,13 @@
return rareData().columnWidth;
}
+void Box::setCachedDisplayBoxForLayoutState(LayoutState& layoutState, std::unique_ptr<Display::Box> box) const
+{
+ ASSERT(!m_cachedLayoutState);
+ m_cachedLayoutState = makeWeakPtr(layoutState);
+ m_cachedDisplayBoxForLayoutState = WTFMove(box);
+}
+
Box::RareDataMap& Box::rareDataMap()
{
static NeverDestroyed<RareDataMap> map;
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.h (254633 => 254634)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2020-01-15 21:41:50 UTC (rev 254633)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2020-01-15 21:49:37 UTC (rev 254634)
@@ -34,9 +34,15 @@
#include <wtf/WeakPtr.h>
namespace WebCore {
+
+namespace Display {
+class Box;
+}
+
namespace Layout {
class Container;
+class LayoutState;
class TreeBuilder;
class Box : public CanMakeWeakPtr<Box> {
@@ -167,6 +173,10 @@
void setIsAnonymous() { m_isAnonymous = true; }
+ bool canCacheForLayoutState(const LayoutState&) const;
+ Display::Box* cachedDisplayBoxForLayoutState(const LayoutState&) const;
+ void setCachedDisplayBoxForLayoutState(LayoutState&, std::unique_ptr<Display::Box>) const;
+
protected:
Box(Optional<ElementAttributes>, Optional<TextContext>, RenderStyle&&, BaseTypeFlags);
@@ -201,6 +211,10 @@
const Optional<TextContext> m_textContext;
+ // First LayoutState gets a direct cache.
+ mutable WeakPtr<LayoutState> m_cachedLayoutState;
+ mutable std::unique_ptr<Display::Box> m_cachedDisplayBoxForLayoutState;
+
unsigned m_baseTypeFlags : 6;
bool m_hasRareData : 1;
bool m_isAnonymous : 1;
Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h (254633 => 254634)
--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h 2020-01-15 21:41:50 UTC (rev 254633)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h 2020-01-15 21:49:37 UTC (rev 254634)
@@ -27,7 +27,6 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
-#include "LayoutBox.h"
#include <wtf/IsoMalloc.h>
#include <wtf/WeakPtr.h>