Skip to content

Commit

Permalink
Reduce size of RenderText from 128 to 120 bytes on 64-bit
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=262655

Reviewed by Simon Fraser.

Reduce size of RenderText from 128 to 120 bytes on 64-bit by leveraging Markable.

* Source/WTF/wtf/Markable.h:
(WTF::FloatMarkableTraits::isEmptyValue):
(WTF::FloatMarkableTraits::emptyValue):
(WTF::Markable::value_or const):
* Source/WebCore/platform/graphics/FontSizeAdjust.h:
(WebCore::FloatMarkableTraits::isEmptyValue): Deleted.
(WebCore::FloatMarkableTraits::emptyValue): Deleted.
* Source/WebCore/rendering/RenderText.cpp:
(WebCore::RenderText::RenderText):
* Source/WebCore/rendering/RenderText.h:

Canonical link: https://commits.webkit.org/268887@main
  • Loading branch information
cdumez committed Oct 5, 2023
1 parent e483494 commit 728c278
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 36 deletions.
19 changes: 19 additions & 0 deletions Source/WTF/wtf/Markable.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ struct IntegralMarkableTraits {
}
};

struct FloatMarkableTraits {
constexpr static bool isEmptyValue(float value)
{
return value != value;
}

constexpr static float emptyValue()
{
return std::numeric_limits<float>::quiet_NaN();
}
};

// The goal of Markable is offering Optional without sacrificing storage efficiency.
// Markable takes Traits, which should have isEmptyValue and emptyValue functions. By using
// one value of T as an empty value, we can remove bool flag in Optional. This strategy is
Expand Down Expand Up @@ -129,6 +141,13 @@ class Markable {
constexpr const T& operator*() const& { return m_value; }
constexpr T& operator*() & { return m_value; }

template <class U> constexpr T value_or(U&& fallback) const
{
if (bool(*this))
return m_value;
return static_cast<T>(std::forward<U>(fallback));
}

operator std::optional<T>() &&
{
if (bool(*this))
Expand Down
14 changes: 1 addition & 13 deletions Source/WebCore/platform/graphics/FontSizeAdjust.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,6 @@

namespace WebCore {

struct FloatMarkableTraits {
constexpr static bool isEmptyValue(float value)
{
return value != value;
}

constexpr static float emptyValue()
{
return std::numeric_limits<float>::quiet_NaN();
}
};

struct FontSizeAdjust {
friend bool operator==(const FontSizeAdjust&, const FontSizeAdjust&) = default;

Expand All @@ -55,7 +43,7 @@ struct FontSizeAdjust {
};
Metric metric { Metric::ExHeight };
bool isFromFont { false };
Markable<float, FloatMarkableTraits> value { };
Markable<float, WTF::FloatMarkableTraits> value { };
};

inline void add(Hasher& hasher, const FontSizeAdjust& fontSizeAdjust)
Expand Down
12 changes: 5 additions & 7 deletions Source/WebCore/rendering/RenderText.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,14 @@ using namespace WTF::Unicode;
WTF_MAKE_ISO_ALLOCATED_IMPL(RenderText);

struct SameSizeAsRenderText : public RenderObject {
void* pointers[2];
uint32_t bitfields : 16;
#if ENABLE(TEXT_AUTOSIZING)
float candidateTextSize;
#endif
float widths[2];
std::optional<float> minWidth;
std::optional<float> maxWidth;
std::optional<bool> canUseSimplifiedTextMeasuring;
float widths[4];
void* pointers[2];
String text;
std::optional<bool> canUseSimplifiedTextMeasuring;
uint32_t bitfields : 16;
};

static_assert(sizeof(RenderText) == sizeof(SameSizeAsRenderText), "RenderText should stay small");
Expand Down Expand Up @@ -247,8 +245,8 @@ static unsigned offsetForPositionInRun(const InlineIterator::TextBox& textBox, f

inline RenderText::RenderText(Type type, Node& node, const String& text)
: RenderObject(type, node)
, m_containsOnlyASCII(text.impl()->containsOnlyASCII())
, m_text(text)
, m_containsOnlyASCII(text.impl()->containsOnlyASCII())
{
ASSERT(!m_text.isNull());
setIsText();
Expand Down
32 changes: 16 additions & 16 deletions Source/WebCore/rendering/RenderText.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "RenderTextLineBoxes.h"
#include "Text.h"
#include <wtf/Forward.h>
#include <wtf/Markable.h>
#include <wtf/text/TextBreakIterator.h>

namespace WebCore {
Expand Down Expand Up @@ -229,35 +230,34 @@ class RenderText : public RenderObject {
float maxWordFragmentWidth(const RenderStyle&, const FontCascade&, StringView word, unsigned minimumPrefixLength, unsigned minimumSuffixLength, bool currentCharacterIsSpace, unsigned characterIndex, float xPos, float entireWordWidth, WordTrailingSpace&, WeakHashSet<const Font>& fallbackFonts, GlyphOverflow&);
float widthFromCacheConsideringPossibleTrailingSpace(const RenderStyle&, const FontCascade&, unsigned startIndex, unsigned wordLen, float xPos, bool currentCharacterIsSpace, WordTrailingSpace&, WeakHashSet<const Font>& fallbackFonts, GlyphOverflow&) const;

// We put the bitfield first to minimize padding on 64-bit.
#if ENABLE(TEXT_AUTOSIZING)
// FIXME: This should probably be part of the text sizing structures in Document instead. That would save some memory.
float m_candidateComputedTextSize { 0 };
#endif
Markable<float, WTF::FloatMarkableTraits> m_minWidth;
Markable<float, WTF::FloatMarkableTraits> m_maxWidth;
float m_beginMinWidth { 0 };
float m_endMinWidth { 0 };

String m_text;

std::optional<bool> m_canUseSimplifiedTextMeasuring;
unsigned m_hasBreakableChar : 1 { false }; // Whether or not we can be broken into multiple lines.
unsigned m_hasBreak : 1 { false }; // Whether or not we have a hard break (e.g., <pre> with '\n').
unsigned m_hasTab : 1 { false }; // Whether or not we have a variable width tab character (e.g., <pre> with '\t').
unsigned m_hasBeginWS : 1 { false }; // Whether or not we begin with WS (only true if we aren't pre)
unsigned m_hasEndWS : 1 { false }; // Whether or not we end with WS (only true if we aren't pre)
unsigned m_linesDirty : 1 { false }; // This bit indicates that the text run has already dirtied specific
// line boxes, and this hint will enable layoutInlineChildren to avoid
// just dirtying everything when character data is modified (e.g., appended/inserted
// or removed).
// line boxes, and this hint will enable layoutInlineChildren to avoid
// just dirtying everything when character data is modified (e.g., appended/inserted
// or removed).
unsigned m_needsVisualReordering : 1 { false };
unsigned m_containsOnlyASCII : 1 { false };
unsigned m_canUseSimpleFontCodePath : 1 { false };
mutable unsigned m_knownToHaveNoOverflowAndNoFallbackFonts : 1 { false };
unsigned m_useBackslashAsYenSymbol : 1 { false };
unsigned m_originalTextDiffersFromRendered : 1 { false };
unsigned m_hasInlineWrapperForDisplayContents : 1 { false };

#if ENABLE(TEXT_AUTOSIZING)
// FIXME: This should probably be part of the text sizing structures in Document instead. That would save some memory.
float m_candidateComputedTextSize { 0 };
#endif
std::optional<float> m_minWidth;
std::optional<float> m_maxWidth;
std::optional<bool> m_canUseSimplifiedTextMeasuring { };
float m_beginMinWidth { 0 };
float m_endMinWidth { 0 };

String m_text;
};

String applyTextTransform(const RenderStyle&, const String&, UChar previousCharacter);
Expand Down

0 comments on commit 728c278

Please sign in to comment.