Title: [130319] trunk
Revision
130319
Author
schen...@chromium.org
Date
2012-10-03 14:00:40 -0700 (Wed, 03 Oct 2012)

Log Message

Font data is purged while fonts are still using it
https://bugs.webkit.org/show_bug.cgi?id=93640

Reviewed by Eric Seidel.

Source/WebCore: 

Move the handling of custom font pruning from Document to FontFallbackList.
The previous inplementation allowed fonts to be removed before all their
clients were done. This change moves handling of custom font purging to the
FontFallbackList class, which is the shared object that is only removed
when all clients of a font are done with it. This fixes a crash in Angry
Birds due to a seamless iframe and some failing tests in fast/frames/seamless.

The specific element that causes problems is:
<iframe id="ingame_frame0" name="ingame_frame0" frameborder="0" seamless="true"
  src=""
  _onload_="this.style.opacity = 1; parent.adLoaded();" scrolling="no"
  style="opacity: 1; -webkit-transition: opacity 1s ease-in-out 0s;
  position: absolute; border: 0px; width: 312px; height: 320px; z-index:
  300; overflow: hidden; visibility: visible;"></iframe>
The source document uses the same font as the embedding document.

Tests: fast/frames/seamless/seamless-custom-font-pruning-crash.html
       fast/frames/seamless/seamless-nested-crash.html

* css/CSSFontFaceSource.cpp:
(WebCore::CSSFontFaceSource::getFontData): Remove code to register the font with the document.
* css/CSSSegmentedFontFace.cpp:
(WebCore::CSSSegmentedFontFace::getFontData): Remove code to register the font with the document.
* dom/Document.cpp:
(WebCore::Document::~Document): Remove code that records and purges custom fonts.
(WebCore):
(WebCore::Document::reportMemoryUsage): Remove reference to non-existent objects.
* dom/Document.h:
(WebCore):
(Document): Remove method declarations for custom font handling.
* platform/graphics/FontFallbackList.h:
(FontFallbackList): Moved some code around and made non-copyable.
(WebCore::FontFallbackList::setGlyphPageZero): Moved.
(WebCore::FontFallbackList::setGlyphPages): Moved.
* platform/graphics/GlyphPageTreeNode.cpp:
(WebCore::GlyphPageTreeNode::pruneFontData): Removed unnecessary null check.
* platform/graphics/SegmentedFontData.cpp:
(WebCore::SegmentedFontData::~SegmentedFontData): Added code to prune the Glyph pages when this is deleted.
* platform/graphics/SimpleFontData.cpp:
(WebCore::SimpleFontData::~SimpleFontData): Added code to prune the Glyph pages when this is deleted.

LayoutTests: 

Tests for font purging. The seamless-custom-font-pruning-crash test
was only failing in Chromium Asan, while the seamless-nested-crash
case was only failing in Asan DumpRenderTree.

* fast/frames/seamless/seamless-custom-font-pruning-crash-expected.txt: Added.
* fast/frames/seamless/seamless-custom-font-pruning-crash.html: Added.
* fast/frames/seamless/seamless-nested-crash-expected.txt: Added.
* fast/frames/seamless/seamless-nested-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (130318 => 130319)


--- trunk/LayoutTests/ChangeLog	2012-10-03 21:00:29 UTC (rev 130318)
+++ trunk/LayoutTests/ChangeLog	2012-10-03 21:00:40 UTC (rev 130319)
@@ -1,3 +1,19 @@
+2012-10-03  Stephen Chenney  <schen...@chromium.org>
+
+        Font data is purged while fonts are still using it
+        https://bugs.webkit.org/show_bug.cgi?id=93640
+
+        Reviewed by Eric Seidel.
+
+        Tests for font purging. The seamless-custom-font-pruning-crash test
+        was only failing in Chromium Asan, while the seamless-nested-crash
+        case was only failing in Asan DumpRenderTree.
+
+        * fast/frames/seamless/seamless-custom-font-pruning-crash-expected.txt: Added.
+        * fast/frames/seamless/seamless-custom-font-pruning-crash.html: Added.
+        * fast/frames/seamless/seamless-nested-crash-expected.txt: Added.
+        * fast/frames/seamless/seamless-nested-crash.html: Added.
+
 2012-10-03  Ojan Vafai  <o...@chromium.org>
 
         Fix some style violations in perparation for changing this code.

Added: trunk/LayoutTests/fast/frames/seamless/seamless-custom-font-pruning-crash-expected.txt (0 => 130319)


--- trunk/LayoutTests/fast/frames/seamless/seamless-custom-font-pruning-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-custom-font-pruning-crash-expected.txt	2012-10-03 21:00:40 UTC (rev 130319)
@@ -0,0 +1 @@
+This test passes if it does not crash. This test passes if it does not crash.

Added: trunk/LayoutTests/fast/frames/seamless/seamless-custom-font-pruning-crash.html (0 => 130319)


--- trunk/LayoutTests/fast/frames/seamless/seamless-custom-font-pruning-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-custom-font-pruning-crash.html	2012-10-03 21:00:40 UTC (rev 130319)
@@ -0,0 +1,33 @@
+<html>
+  This test passes if it does not crash.
+  <style>@font-face {
+    font-family: "Times New Roman";
+    src: local("Arial")
+  </style>
+  <script>
+    if (window.testRunner) {
+      testRunner.dumpAsText();
+      testRunner.waitUntilDone();
+    }
+    var docElement = document.body ? document.body : document.documentElement;
+
+    function initTest() {
+      iframeElement = document.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
+      iframeElement.setAttribute("seamless", "");
+      iframeElement.setAttribute("srcdoc", "This test passes if it does not crash. <iframe seamless sandbox='allow-scripts' srcdoc='This test passes if it does not crash.'");
+      docElement.appendChild(iframeElement);
+
+      textElement = document.createTextNode("This test passes if it does not crash.");
+      docElement.appendChild(textElement);
+      setTimeout("crash()", 0);
+    }
+
+    document.addEventListener("DOMContentLoaded", initTest, false);
+
+    function crash() {
+      docElement.appendChild(iframeElement);
+      if (window.testRunner)
+        testRunner.notifyDone();
+    }
+  </script>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/frames/seamless/seamless-nested-crash-expected.txt (0 => 130319)


--- trunk/LayoutTests/fast/frames/seamless/seamless-nested-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-nested-crash-expected.txt	2012-10-03 21:00:40 UTC (rev 130319)
@@ -0,0 +1 @@
+This test passes if it does not crash.

Added: trunk/LayoutTests/fast/frames/seamless/seamless-nested-crash.html (0 => 130319)


--- trunk/LayoutTests/fast/frames/seamless/seamless-nested-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/frames/seamless/seamless-nested-crash.html	2012-10-03 21:00:40 UTC (rev 130319)
@@ -0,0 +1,30 @@
+<html>
+  <head>
+    <script>
+      if (window.testRunner) {
+          testRunner.dumpAsText();
+          testRunner.waitUntilDone();
+      }
+      if (window.eventSender)
+        for (i=0; i<10; i++)
+          setTimeout('eventSender.mouseMoveTo(' + i + ', ' + i + ');', i);
+      setTimeout(function() {
+        document.body.innerHTML = "This test passes if it does not crash.";
+        if (window.testRunner)
+          testRunner.notifyDone();
+      }, 10);
+    </script>
+    <style>
+      @font-face { font-family: "A"; src: url(); }
+      * { font-family: A; }
+    </style>
+  </head>
+  <body>
+    <!-- Multiple lines of text are needed to crash -->
+    This is a really long line. This is a really long line. This is a really long line. This is a really long line. This is a really long line. This is a really long line. This is a really long line. This is a really long line. This is a really long line. This is a really long line. This is a really long line. This is a really long line. This is a really long line. 
+    <iframe seamless src=""
+    <!-- This lonely <style> is needed to crash -->
+    <style>
+    </style>
+  </body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (130318 => 130319)


--- trunk/Source/WebCore/ChangeLog	2012-10-03 21:00:29 UTC (rev 130318)
+++ trunk/Source/WebCore/ChangeLog	2012-10-03 21:00:40 UTC (rev 130319)
@@ -1,3 +1,51 @@
+2012-10-03  Stephen Chenney  <schen...@chromium.org>
+
+        Font data is purged while fonts are still using it
+        https://bugs.webkit.org/show_bug.cgi?id=93640
+
+        Reviewed by Eric Seidel.
+
+        Move the handling of custom font pruning from Document to FontFallbackList.
+        The previous inplementation allowed fonts to be removed before all their
+        clients were done. This change moves handling of custom font purging to the
+        FontFallbackList class, which is the shared object that is only removed
+        when all clients of a font are done with it. This fixes a crash in Angry
+        Birds due to a seamless iframe and some failing tests in fast/frames/seamless.
+
+        The specific element that causes problems is:
+        <iframe id="ingame_frame0" name="ingame_frame0" frameborder="0" seamless="true"
+          src=""
+          _onload_="this.style.opacity = 1; parent.adLoaded();" scrolling="no"
+          style="opacity: 1; -webkit-transition: opacity 1s ease-in-out 0s;
+          position: absolute; border: 0px; width: 312px; height: 320px; z-index:
+          300; overflow: hidden; visibility: visible;"></iframe>
+        The source document uses the same font as the embedding document.
+
+        Tests: fast/frames/seamless/seamless-custom-font-pruning-crash.html
+               fast/frames/seamless/seamless-nested-crash.html
+
+        * css/CSSFontFaceSource.cpp:
+        (WebCore::CSSFontFaceSource::getFontData): Remove code to register the font with the document.
+        * css/CSSSegmentedFontFace.cpp:
+        (WebCore::CSSSegmentedFontFace::getFontData): Remove code to register the font with the document.
+        * dom/Document.cpp:
+        (WebCore::Document::~Document): Remove code that records and purges custom fonts.
+        (WebCore):
+        (WebCore::Document::reportMemoryUsage): Remove reference to non-existent objects.
+        * dom/Document.h:
+        (WebCore):
+        (Document): Remove method declarations for custom font handling.
+        * platform/graphics/FontFallbackList.h:
+        (FontFallbackList): Moved some code around and made non-copyable.
+        (WebCore::FontFallbackList::setGlyphPageZero): Moved.
+        (WebCore::FontFallbackList::setGlyphPages): Moved.
+        * platform/graphics/GlyphPageTreeNode.cpp:
+        (WebCore::GlyphPageTreeNode::pruneFontData): Removed unnecessary null check.
+        * platform/graphics/SegmentedFontData.cpp:
+        (WebCore::SegmentedFontData::~SegmentedFontData): Added code to prune the Glyph pages when this is deleted.
+        * platform/graphics/SimpleFontData.cpp:
+        (WebCore::SimpleFontData::~SimpleFontData): Added code to prune the Glyph pages when this is deleted.
+
 2012-10-03  Adam Barth  <aba...@webkit.org>
 
         Crash when calling document.open during unload

Modified: trunk/Source/WebCore/css/CSSFontFaceSource.cpp (130318 => 130319)


--- trunk/Source/WebCore/css/CSSFontFaceSource.cpp	2012-10-03 21:00:29 UTC (rev 130318)
+++ trunk/Source/WebCore/css/CSSFontFaceSource.cpp	2012-10-03 21:00:40 UTC (rev 130319)
@@ -184,11 +184,6 @@
         fontData = SimpleFontData::create(temporaryFont->platformData(), true, true);
     }
 
-    if (Document* document = fontSelector->document())
-        document->registerCustomFont(fontData);
-    else
-        fontData.clear();
-
     return fontData; // No release, because fontData is a reference to a RefPtr that is held in the m_fontDataTable.
 }
 

Modified: trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp (130318 => 130319)


--- trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp	2012-10-03 21:00:29 UTC (rev 130318)
+++ trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp	2012-10-03 21:00:40 UTC (rev 130319)
@@ -108,10 +108,11 @@
     unsigned hashKey = ((fontDescription.computedPixelSize() + 1) << (FontTraitsMaskWidth + 1)) | ((fontDescription.orientation() == Vertical ? 1 : 0) << FontTraitsMaskWidth) | desiredTraitsMask;
 
     RefPtr<SegmentedFontData>& fontData = m_fontDataTable.add(hashKey, 0).iterator->second;
-    if (fontData)
-        return fontData;
+    if (fontData && fontData->numRanges())
+        return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has.
 
-    fontData = SegmentedFontData::create();
+    if (!fontData)
+        fontData = SegmentedFontData::create();
 
     unsigned size = m_fontFaces.size();
     for (unsigned i = 0; i < size; i++) {
@@ -125,12 +126,8 @@
             appendFontDataWithInvalidUnicodeRangeIfLoading(fontData.get(), faceFontData.release(), m_fontFaces[i]->ranges());
         }
     }
-    if (fontData->numRanges()) {
-        if (Document* document = m_fontSelector->document()) {
-            document->registerCustomFont(fontData);
-            return fontData;
-        }
-    }
+    if (fontData->numRanges())
+        return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has.
 
     return 0;
 }

Modified: trunk/Source/WebCore/dom/Document.cpp (130318 => 130319)


--- trunk/Source/WebCore/dom/Document.cpp	2012-10-03 21:00:29 UTC (rev 130318)
+++ trunk/Source/WebCore/dom/Document.cpp	2012-10-03 21:00:40 UTC (rev 130319)
@@ -645,8 +645,6 @@
     if (m_elemSheet)
         m_elemSheet->clearOwnerNode();
 
-    deleteCustomFonts();
-
     m_weakReference->clear();
 
     if (m_mediaQueryMatcher)
@@ -1974,20 +1972,6 @@
     return style.release();
 }
 
-void Document::registerCustomFont(PassRefPtr<FontData> fontData)
-{
-    m_customFonts.append(fontData);
-}
-
-void Document::deleteCustomFonts()
-{
-    size_t size = m_customFonts.size();
-    for (size_t i = 0; i < size; ++i)
-        GlyphPageTreeNode::pruneTreeCustomFontData(m_customFonts[i].get());
-
-    m_customFonts.clear();
-}
-
 bool Document::isPageBoxVisible(int pageIndex)
 {
     RefPtr<RenderStyle> style = styleForPage(pageIndex);
@@ -5864,7 +5848,6 @@
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
     ContainerNode::reportMemoryUsage(memoryObjectInfo);
     info.addMember(m_styleResolver);
-    info.addMember(m_customFonts);
     info.addMember(m_url);
     info.addMember(m_baseURL);
     info.addMember(m_baseURLOverride);

Modified: trunk/Source/WebCore/dom/Document.h (130318 => 130319)


--- trunk/Source/WebCore/dom/Document.h	2012-10-03 21:00:29 UTC (rev 130318)
+++ trunk/Source/WebCore/dom/Document.h	2012-10-03 21:00:40 UTC (rev 130319)
@@ -90,7 +90,6 @@
 class EventListener;
 class FloatRect;
 class FloatQuad;
-class FontData;
 class FormController;
 class Frame;
 class FrameView;
@@ -540,8 +539,6 @@
     PassRefPtr<RenderStyle> styleForElementIgnoringPendingStylesheets(Element*);
     PassRefPtr<RenderStyle> styleForPage(int pageIndex);
 
-    void registerCustomFont(PassRefPtr<FontData>);
-
     // Returns true if page box (margin boxes and page borders) is visible.
     bool isPageBoxVisible(int pageIndex);
 
@@ -1210,8 +1207,6 @@
 
     void seamlessParentUpdatedStylesheets();
 
-    void deleteCustomFonts();
-
     PassRefPtr<NodeList> handleZeroPadding(const HitTestRequest&, HitTestResult&) const;
 
     void loadEventDelayTimerFired(Timer<Document>*);
@@ -1256,8 +1251,6 @@
     // do eventually load.
     PendingSheetLayout m_pendingSheetLayout;
 
-    Vector<RefPtr<FontData> > m_customFonts;
-
     Frame* m_frame;
     RefPtr<DOMWindow> m_domWindow;
 

Modified: trunk/Source/WebCore/platform/graphics/FontFallbackList.h (130318 => 130319)


--- trunk/Source/WebCore/platform/graphics/FontFallbackList.h	2012-10-03 21:00:29 UTC (rev 130318)
+++ trunk/Source/WebCore/platform/graphics/FontFallbackList.h	2012-10-03 21:00:40 UTC (rev 130319)
@@ -39,6 +39,7 @@
 const int cAllFamiliesScanned = -1;
 
 class FontFallbackList : public RefCounted<FontFallbackList> {
+    WTF_MAKE_NONCOPYABLE(FontFallbackList);
 public:
     static PassRefPtr<FontFallbackList> create() { return adoptRef(new FontFallbackList()); }
 
@@ -63,10 +64,6 @@
     const GlyphPages& glyphPages() const { return m_pages; }
 
 private:
-    friend class SVGTextRunRenderingContext;
-    void setGlyphPageZero(GlyphPageTreeNode* pageZero) { m_pageZero = pageZero; }
-    void setGlyphPages(const GlyphPages& pages) { m_pages = pages; }
-
     FontFallbackList();
 
     const SimpleFontData* primarySimpleFontData(const Font* f)
@@ -83,7 +80,9 @@
     void setPlatformFont(const FontPlatformData&);
 
     void releaseFontData();
-
+    void setGlyphPageZero(GlyphPageTreeNode* pageZero) { m_pageZero = pageZero; }
+    void setGlyphPages(const GlyphPages& pages) { m_pages = pages; }
+    
     mutable Vector<RefPtr<FontData>, 1> m_fontList;
     mutable GlyphPages m_pages;
     mutable GlyphPageTreeNode* m_pageZero;
@@ -96,6 +95,7 @@
     mutable bool m_loadingCustomFonts : 1;
 
     friend class Font;
+    friend class SVGTextRunRenderingContext;
 };
 
 }

Modified: trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp (130318 => 130319)


--- trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp	2012-10-03 21:00:29 UTC (rev 130318)
+++ trunk/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp	2012-10-03 21:00:40 UTC (rev 130319)
@@ -374,8 +374,6 @@
 void GlyphPageTreeNode::pruneFontData(const SimpleFontData* fontData, unsigned level)
 {
     ASSERT(fontData);
-    if (!fontData)
-        return;
 
     // Prune fall back child (if any) of this font.
     if (m_systemFallbackChild && m_systemFallbackChild->m_page)

Modified: trunk/Source/WebCore/platform/graphics/SegmentedFontData.cpp (130318 => 130319)


--- trunk/Source/WebCore/platform/graphics/SegmentedFontData.cpp	2012-10-03 21:00:29 UTC (rev 130318)
+++ trunk/Source/WebCore/platform/graphics/SegmentedFontData.cpp	2012-10-03 21:00:40 UTC (rev 130319)
@@ -34,6 +34,7 @@
 
 SegmentedFontData::~SegmentedFontData()
 {
+    GlyphPageTreeNode::pruneTreeCustomFontData(this);
 }
 
 const SimpleFontData* SegmentedFontData::fontDataForCharacter(UChar32 c) const

Modified: trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp (130318 => 130319)


--- trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp	2012-10-03 21:00:29 UTC (rev 130318)
+++ trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp	2012-10-03 21:00:40 UTC (rev 130319)
@@ -150,7 +150,9 @@
 #endif
         platformDestroy();
 
-    if (!isCustomFont())
+    if (isCustomFont())
+        GlyphPageTreeNode::pruneTreeCustomFontData(this);
+    else
         GlyphPageTreeNode::pruneTreeFontData(this);
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to