Changeset 143601 in webkit


Ignore:
Timestamp:
Feb 21, 2013 7:44:02 AM (11 years ago)
Author:
akling@apple.com
Message:

GlyphPage: Bake per-glyph font data array into same allocation as GlyphPage.

A hopeful fix for REGRESSION(r143125): ~5% performance hit on Chromium's intl2 page cycler
<http://webkit.org/b/108835>

Reviewed by Antti Koivisto.

Rewire GlyphPage so that we have to decide at creation time whether there will be a per-glyph
array of SimpleFontData* or not. This removes one allocation and one step of indirection for
pages with glyphs from mixed fonts.

  • platform/graphics/GlyphPage.h:

(WebCore::GlyphPage::createForMixedFontData):
(WebCore::GlyphPage::createForSingleFontData):
(WebCore::GlyphPage::createCopiedSystemFallbackPage):
(WebCore::GlyphPage::~GlyphPage):
(WebCore::GlyphPage::glyphDataForIndex):
(WebCore::GlyphPage::fontDataForCharacter):
(WebCore::GlyphPage::setGlyphDataForIndex):
(WebCore::GlyphPage::removeFontDataFromSystemFallbackPage):
(WebCore::GlyphPage::GlyphPage):
(WebCore::GlyphPage::hasPerGlyphFontData):
(GlyphPage):

  • platform/graphics/GlyphPageTreeNode.cpp:

(WebCore::GlyphPageTreeNode::initializePage):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r143600 r143601  
     12013-02-21  Andreas Kling  <akling@apple.com>
     2
     3        GlyphPage: Bake per-glyph font data array into same allocation as GlyphPage.
     4
     5        A hopeful fix for REGRESSION(r143125): ~5% performance hit on Chromium's intl2 page cycler
     6        <http://webkit.org/b/108835>
     7
     8        Reviewed by Antti Koivisto.
     9
     10        Rewire GlyphPage so that we have to decide at creation time whether there will be a per-glyph
     11        array of SimpleFontData* or not. This removes one allocation and one step of indirection for
     12        pages with glyphs from mixed fonts.
     13
     14        * platform/graphics/GlyphPage.h:
     15        (WebCore::GlyphPage::createForMixedFontData):
     16        (WebCore::GlyphPage::createForSingleFontData):
     17        (WebCore::GlyphPage::createCopiedSystemFallbackPage):
     18        (WebCore::GlyphPage::~GlyphPage):
     19        (WebCore::GlyphPage::glyphDataForIndex):
     20        (WebCore::GlyphPage::fontDataForCharacter):
     21        (WebCore::GlyphPage::setGlyphDataForIndex):
     22        (WebCore::GlyphPage::removeFontDataFromSystemFallbackPage):
     23        (WebCore::GlyphPage::GlyphPage):
     24        (WebCore::GlyphPage::hasPerGlyphFontData):
     25        (GlyphPage):
     26        * platform/graphics/GlyphPageTreeNode.cpp:
     27        (WebCore::GlyphPageTreeNode::initializePage):
     28
    1292013-02-21  Xan Lopez  <xlopez@rim.com>
    230
  • trunk/Source/WebCore/platform/graphics/GlyphPage.h

    r143137 r143601  
    5454};
    5555
     56#if COMPILER(MSVC)
     57#pragma warning(push)
     58#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
     59#endif
     60
    5661// A GlyphPage contains a fixed-size set of GlyphData mappings for a contiguous
    5762// range of characters in the Unicode code space. GlyphPages are indexed
     
    6469class GlyphPage : public RefCounted<GlyphPage> {
    6570public:
    66     static PassRefPtr<GlyphPage> createUninitialized(GlyphPageTreeNode* owner)
     71    static PassRefPtr<GlyphPage> createForMixedFontData(GlyphPageTreeNode* owner)
    6772    {
    68         return adoptRef(new GlyphPage(owner, false));
     73        void* slot = fastMalloc(sizeof(GlyphPage) + sizeof(SimpleFontData*) * GlyphPage::size);
     74        return adoptRef(new (slot) GlyphPage(owner));
    6975    }
    7076
    71     static PassRefPtr<GlyphPage> createZeroedSystemFallbackPage(GlyphPageTreeNode* owner)
     77    static PassRefPtr<GlyphPage> createForSingleFontData(GlyphPageTreeNode* owner, const SimpleFontData* fontData)
    7278    {
    73         return adoptRef(new GlyphPage(owner, true));
     79        ASSERT(fontData);
     80        return adoptRef(new GlyphPage(owner, fontData));
    7481    }
    7582
    7683    PassRefPtr<GlyphPage> createCopiedSystemFallbackPage(GlyphPageTreeNode* owner) const
    7784    {
    78         RefPtr<GlyphPage> page = GlyphPage::createUninitialized(owner);
     85        RefPtr<GlyphPage> page = GlyphPage::createForMixedFontData(owner);
    7986        memcpy(page->m_glyphs, m_glyphs, sizeof(m_glyphs));
    80         page->m_fontDataForAllGlyphs = m_fontDataForAllGlyphs;
    81         if (m_perGlyphFontData) {
    82             page->m_perGlyphFontData = static_cast<const SimpleFontData**>(fastMalloc(size * sizeof(SimpleFontData*)));
    83             memcpy(page->m_perGlyphFontData, m_perGlyphFontData, size * sizeof(SimpleFontData*));
     87        if (hasPerGlyphFontData())
     88            memcpy(page->m_perGlyphFontData, m_perGlyphFontData, sizeof(SimpleFontData*) * GlyphPage::size);
     89        else {
     90            for (size_t i = 0; i < GlyphPage::size; ++i) {
     91                page->m_perGlyphFontData[i] = m_glyphs[i] ? m_fontDataForAllGlyphs : 0;
     92            }
    8493        }
    8594        return page.release();
    8695    }
    8796
    88     ~GlyphPage()
    89     {
    90         if (m_perGlyphFontData)
    91             fastFree(m_perGlyphFontData);
    92     }
     97    ~GlyphPage() { }
    9398
    9499    static const size_t size = 256; // Covers Latin-1 in a single page.
     
    104109        ASSERT_WITH_SECURITY_IMPLICATION(index < size);
    105110        Glyph glyph = m_glyphs[index];
    106         if (m_perGlyphFontData)
     111        if (hasPerGlyphFontData())
    107112            return GlyphData(glyph, m_perGlyphFontData[index]);
    108         if (!glyph)
    109             return GlyphData(0, 0);
    110         return GlyphData(glyph, m_fontDataForAllGlyphs);
     113        return GlyphData(glyph, glyph ? m_fontDataForAllGlyphs : 0);
    111114    }
    112115
     
    120123    {
    121124        unsigned index = indexForCharacter(c);
    122         if (m_perGlyphFontData)
     125        if (hasPerGlyphFontData())
    123126            return m_perGlyphFontData[index];
    124         Glyph glyph = m_glyphs[index];
    125         if (!glyph)
    126             return 0;
    127         return m_fontDataForAllGlyphs;
     127        return m_glyphs[index] ? m_fontDataForAllGlyphs : 0;
    128128    }
    129129
     
    139139
    140140        // GlyphPage getters will always return a null SimpleFontData* for glyph #0 if there's no per-glyph font array.
    141         if (m_perGlyphFontData) {
     141        if (hasPerGlyphFontData()) {
    142142            m_perGlyphFontData[index] = glyph ? fontData : 0;
    143143            return;
    144144        }
    145145
    146         if (!glyph)
    147             return;
    148 
    149         // A glyph index without a font data pointer makes no sense.
    150         ASSERT(fontData);
    151 
    152         if (!m_fontDataForAllGlyphs)
    153             m_fontDataForAllGlyphs = fontData;
    154 
    155         if (m_fontDataForAllGlyphs == fontData)
    156             return;
    157 
    158         // This GlyphPage houses glyphs from multiple fonts, transition to an array of SimpleFontData pointers.
    159         const SimpleFontData* oldFontData = m_fontDataForAllGlyphs;
    160         m_perGlyphFontData = static_cast<const SimpleFontData**>(fastMalloc(size * sizeof(SimpleFontData*)));
    161         for (unsigned i = 0; i < size; ++i)
    162             m_perGlyphFontData[i] = m_glyphs[i] ? oldFontData : 0;
    163         m_perGlyphFontData[index] = fontData;
     146        // A single-font GlyphPage already assigned m_fontDataForAllGlyphs in the constructor.
     147        ASSERT(!glyph || fontData == m_fontDataForAllGlyphs);
    164148    }
    165149
     
    169153    }
    170154
    171     void clearForFontData(const SimpleFontData* fontData)
     155    void removeFontDataFromSystemFallbackPage(const SimpleFontData* fontData)
    172156    {
    173         if (!m_perGlyphFontData) {
    174             if (m_fontDataForAllGlyphs == fontData) {
    175                 memset(m_glyphs, 0, sizeof(m_glyphs));
    176                 m_fontDataForAllGlyphs = 0;
    177             }
    178             return;
    179         }
     157        // This method should only be called on the system fallback page, which is never single-font.
     158        ASSERT(hasPerGlyphFontData());
    180159        for (size_t i = 0; i < size; ++i) {
    181160            if (m_perGlyphFontData[i] == fontData) {
     
    192171
    193172private:
    194     GlyphPage(GlyphPageTreeNode* owner, bool clearGlyphs)
    195         : m_fontDataForAllGlyphs(0)
    196         , m_perGlyphFontData(0)
     173    explicit GlyphPage(GlyphPageTreeNode* owner, const SimpleFontData* fontDataForAllGlyphs = 0)
     174        : m_fontDataForAllGlyphs(fontDataForAllGlyphs)
    197175        , m_owner(owner)
    198176    {
    199         if (clearGlyphs)
    200             memset(m_glyphs, 0, sizeof(m_glyphs));
     177        memset(m_glyphs, 0, sizeof(m_glyphs));
     178        if (hasPerGlyphFontData())
     179            memset(m_perGlyphFontData, 0, sizeof(SimpleFontData*) * GlyphPage::size);
    201180    }
    202181
     182    bool hasPerGlyphFontData() const { return !m_fontDataForAllGlyphs; }
     183
    203184    const SimpleFontData* m_fontDataForAllGlyphs;
    204     const SimpleFontData** m_perGlyphFontData;
    205 
    206185    GlyphPageTreeNode* m_owner;
    207186    Glyph m_glyphs[size];
     187
     188    // NOTE: This array has (GlyphPage::size) elements if m_fontDataForAllGlyphs is null.
     189    const SimpleFontData* m_perGlyphFontData[0];
    208190};
     191
     192#if COMPILER(MSVC)
     193#pragma warning(pop)
     194#endif
    209195
    210196} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp

    r143125 r143601  
    202202            }
    203203
    204             m_page = GlyphPage::createUninitialized(this);
    205 
    206204            // Now that we have a buffer full of characters, we want to get back an array
    207205            // of glyph indices.  This part involves calling into the platform-specific
     
    210208            // for only 128 out of 256 characters.
    211209            bool haveGlyphs;
    212             if (fontData->isSegmented()) {
     210            if (!fontData->isSegmented()) {
     211                m_page = GlyphPage::createForSingleFontData(this, static_cast<const SimpleFontData*>(fontData));
     212                haveGlyphs = fill(m_page.get(), 0, GlyphPage::size, buffer, bufferLength, static_cast<const SimpleFontData*>(fontData));
     213            } else {
     214                m_page = GlyphPage::createForMixedFontData(this);
    213215                haveGlyphs = false;
    214216
     
    226228                    if (from < static_cast<int>(GlyphPage::size) && to > 0) {
    227229                        if (haveGlyphs && !scratchPage) {
    228                             scratchPage = GlyphPage::createUninitialized(this);
     230                            scratchPage = GlyphPage::createForMixedFontData(this);
    229231                            pageToFill = scratchPage.get();
    230232                        }
     
    247249                    }
    248250                }
    249             } else
    250                 haveGlyphs = fill(m_page.get(), 0, GlyphPage::size, buffer, bufferLength, static_cast<const SimpleFontData*>(fontData));
     251            }
    251252
    252253            if (!haveGlyphs)
     
    280281            } else {
    281282                // Combine the parent's glyphs and ours to form a new more complete page.
    282                 m_page = GlyphPage::createUninitialized(this);
     283                m_page = GlyphPage::createForMixedFontData(this);
    283284
    284285                // Overlay the parent page on the fallback page. Check if the fallback font
     
    308309            m_page = parentPage->createCopiedSystemFallbackPage(this);
    309310        else
    310             m_page = GlyphPage::createZeroedSystemFallbackPage(this);
     311            m_page = GlyphPage::createForMixedFontData(this);
    311312    }
    312313}
     
    370371    // Prune fall back child (if any) of this font.
    371372    if (m_systemFallbackChild && m_systemFallbackChild->m_page)
    372         m_systemFallbackChild->m_page->clearForFontData(fontData);
     373        m_systemFallbackChild->m_page->removeFontDataFromSystemFallbackPage(fontData);
    373374
    374375    // Prune any branch that contains this FontData.
Note: See TracChangeset for help on using the changeset viewer.