Source/WTF/ChangeLog

 12013-02-28 Eric Seidel <eric@webkit.org>
 2
 3 Threaded HTML Parser has an extra copy of every byte from the network
 4 https://bugs.webkit.org/show_bug.cgi?id=111135
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 The threaded html parser needs to accept ownership
 9 of a string buffer. The easiest way to do this seemed
 10 to be to use a PassRefPtr<StringImpl>, but there was no way
 11 to generated one from a String (easily), so I added one.
 12
 13 * wtf/text/WTFString.h:
 14 (WTF::String::releaseImpl):
 15
1162013-02-28 Oliver Hunt <oliver@apple.com>
217
318 Crash in JSC::MarkedBlock::FreeList JSC::MarkedBlock::sweepHelper

Source/WebCore/ChangeLog

 12013-02-28 Eric Seidel <eric@webkit.org>
 2
 3 Threaded HTML Parser has an extra copy of every byte from the network
 4 https://bugs.webkit.org/show_bug.cgi?id=111135
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Every LayoutTest executes this code in threaded parsing mode.
 9
 10 * dom/DecodedDataDocumentParser.cpp:
 11 (WebCore::DecodedDataDocumentParser::appendBytes):
 12 - Pass ownership of the decoded string to the parser.
 13 (WebCore::DecodedDataDocumentParser::flush):
 14 - Same.
 15 * dom/DecodedDataDocumentParser.h:
 16 (DecodedDataDocumentParser):
 17 * dom/Document.cpp:
 18 (WebCore::Document::setContent):
 19 * dom/DocumentParser.h:
 20 (DocumentParser):
 21 * dom/RawDataDocumentParser.h:
 22 (WebCore::RawDataDocumentParser::append):
 23 * html/FTPDirectoryDocument.cpp:
 24 (FTPDirectoryDocumentParser):
 25 (WebCore::FTPDirectoryDocumentParser::append):
 26 * html/parser/HTMLDocumentParser.cpp:
 27 (WebCore::HTMLDocumentParser::append):
 28 * html/parser/HTMLDocumentParser.h:
 29 (HTMLDocumentParser):
 30 * html/parser/HTMLViewSourceParser.cpp:
 31 (WebCore::HTMLViewSourceParser::append):
 32 * html/parser/HTMLViewSourceParser.h:
 33 (HTMLViewSourceParser):
 34 * html/parser/TextDocumentParser.cpp:
 35 (WebCore::TextDocumentParser::append):
 36 * html/parser/TextDocumentParser.h:
 37 (TextDocumentParser):
 38 * loader/DocumentWriter.cpp:
 39 (WebCore::DocumentWriter::replaceDocument):
 40 * xml/parser/XMLDocumentParser.cpp:
 41 (WebCore::XMLDocumentParser::append):
 42 * xml/parser/XMLDocumentParser.h:
 43 (XMLDocumentParser):
 44 * xml/parser/XMLDocumentParserLibxml2.cpp:
 45 (WebCore::XMLDocumentParser::resumeParsing):
 46
1472013-02-28 Ryosuke Niwa <rniwa@webkit.org>
248
349 Revert an erroneous change in r144336.

Source/WTF/wtf/text/WTFString.h

@@public:
167167 bool isEmpty() const { return !m_impl || !m_impl->length(); }
168168
169169 StringImpl* impl() const { return m_impl.get(); }
 170 PassRefPtr<StringImpl> releaseImpl() { return m_impl.release(); }
170171
171172 unsigned length() const
172173 {

Source/WebCore/dom/DecodedDataDocumentParser.cpp

@@void DecodedDataDocumentParser::appendBytes(DocumentWriter* writer, const char*
4747 return;
4848
4949 writer->reportDataReceived();
50  append(decoded);
 50 append(decoded.releaseImpl());
5151}
5252
5353void DecodedDataDocumentParser::flush(DocumentWriter* writer)

@@void DecodedDataDocumentParser::flush(DocumentWriter* writer)
5757 return;
5858
5959 writer->reportDataReceived();
60  append(remainingData);
 60 append(remainingData.releaseImpl());
6161}
6262
6363};

Source/WebCore/dom/DecodedDataDocumentParser.h

@@protected:
4141
4242private:
4343 // append is used by DocumentWriter::replaceDocument.
44  virtual void append(const SegmentedString&) = 0;
 44 virtual void append(PassRefPtr<StringImpl>) = 0;
4545
4646 // appendBytes and flush are used by DocumentWriter (the loader).
4747 virtual void appendBytes(DocumentWriter*, const char* bytes, size_t length);

Source/WebCore/dom/Document.cpp

@@KURL Document::baseURI() const
13581358void Document::setContent(const String& content)
13591359{
13601360 open();
1361  m_parser->append(content);
 1361 // FIXME: This should probably use insert(), but that's (intentionally)
 1362 // not implemented for the XML parser as it's normally synonymous with
 1363 // document.write(). The danger with using append() is that append()
 1364 // can yield, which would be wrong here!
 1365 m_parser->append(content.impl());
13621366 close();
13631367}
13641368

Source/WebCore/dom/DocumentParser.h

2424#ifndef DocumentParser_h
2525#define DocumentParser_h
2626
 27#include <wtf/Forward.h>
2728#include <wtf/RefCounted.h>
2829
2930namespace WebCore {

@@public:
5152
5253 virtual void pinToMainThread() { }
5354
54  // FIXME: append() should be private, but DocumentWriter::replaceDocument
55  // uses it for now.
56  virtual void append(const SegmentedString&) = 0;
 55 // FIXME: append() should be private, but DocumentWriter::replaceDocument uses it for now.
 56 virtual void append(PassRefPtr<StringImpl>) = 0;
5757
5858 virtual void finish() = 0;
5959

Source/WebCore/dom/RawDataDocumentParser.h

@@private:
5656 ASSERT_NOT_REACHED();
5757 }
5858
59  virtual void append(const SegmentedString&)
 59 virtual void append(PassRefPtr<StringImpl>)
6060 {
6161 ASSERT_NOT_REACHED();
6262 }

Source/WebCore/html/FTPDirectoryDocument.cpp

@@public:
5757 return adoptRef(new FTPDirectoryDocumentParser(document));
5858 }
5959
60  virtual void append(const SegmentedString&);
 60 virtual void append(PassRefPtr<StringImpl>);
6161 virtual void finish();
6262
6363 virtual bool isWaitingForScripts() const { return false; }

@@void FTPDirectoryDocumentParser::createBasicDocument()
346346 bodyElement->appendChild(m_tableElement, IGNORE_EXCEPTION);
347347}
348348
349 void FTPDirectoryDocumentParser::append(const SegmentedString& source)
 349void FTPDirectoryDocumentParser::append(PassRefPtr<StringImpl> inputSource)
350350{
 351 String source(inputSource);
 352
351353 // Make sure we have the table element to append to by loading the template set in the pref, or
352354 // creating a very basic document with the appropriate table
353355 if (!m_tableElement) {

Source/WebCore/html/parser/HTMLDocumentParser.cpp

@@void HTMLDocumentParser::stopBackgroundParser()
646646
647647#endif
648648
649 void HTMLDocumentParser::append(const SegmentedString& source)
 649void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource)
650650{
651651 if (isStopped())
652652 return;

@@void HTMLDocumentParser::append(const SegmentedString& source)
656656 if (!m_haveBackgroundParser)
657657 startBackgroundParser();
658658
659  HTMLParserThread::shared()->postTask(bind(
660  &BackgroundHTMLParser::append, m_backgroundParser, source.toString().isolatedCopy()));
 659 ASSERT(inputSource->hasOneRef());
 660 Closure closure = bind(&BackgroundHTMLParser::append, m_backgroundParser, String(inputSource));
 661 // NOTE: Important that the String temporary is destroyed before we post the task
 662 // otherwise the String could call deref() on a StringImpl now owned by the background parser.
 663 // We would like to ASSERT(closure.arg3()->hasOneRef()) but sadly the args are private.
 664 HTMLParserThread::shared()->postTask(closure);
661665 return;
662666 }
663667#endif

@@void HTMLDocumentParser::append(const SegmentedString& source)
665669 // pumpTokenizer can cause this parser to be detached from the Document,
666670 // but we need to ensure it isn't deleted yet.
667671 RefPtr<HTMLDocumentParser> protect(this);
 672 String source(inputSource);
668673
669674 if (m_preloadScanner) {
670675 if (m_input.current().isEmpty() && !isWaitingForScripts()) {

Source/WebCore/html/parser/HTMLDocumentParser.h

@@public:
9797
9898protected:
9999 virtual void insert(const SegmentedString&) OVERRIDE;
100  virtual void append(const SegmentedString&) OVERRIDE;
 100 virtual void append(PassRefPtr<StringImpl>) OVERRIDE;
101101 virtual void finish() OVERRIDE;
102102
103103 HTMLDocumentParser(HTMLDocument*, bool reportErrors);

Source/WebCore/html/parser/HTMLViewSourceParser.cpp

@@void HTMLViewSourceParser::pumpTokenizer()
6262 }
6363}
6464
65 void HTMLViewSourceParser::append(const SegmentedString& input)
 65void HTMLViewSourceParser::append(PassRefPtr<StringImpl> input)
6666{
67  m_input.appendToEnd(input);
 67 m_input.appendToEnd(String(input));
6868 pumpTokenizer();
6969}
7070

Source/WebCore/html/parser/HTMLViewSourceParser.h

@@protected:
5959private:
6060 // DocumentParser
6161 virtual void insert(const SegmentedString&);
62  virtual void append(const SegmentedString&);
 62 virtual void append(PassRefPtr<StringImpl>);
6363 virtual void finish();
6464
6565 HTMLViewSourceDocument* document() const { return static_cast<HTMLViewSourceDocument*>(DecodedDataDocumentParser::document()); }

Source/WebCore/html/parser/TextDocumentParser.cpp

@@TextDocumentParser::~TextDocumentParser()
4444{
4545}
4646
47 void TextDocumentParser::append(const SegmentedString& text)
 47void TextDocumentParser::append(PassRefPtr<StringImpl> text)
4848{
4949 if (!m_haveInsertedFakePreElement)
5050 insertFakePreElement();

Source/WebCore/html/parser/TextDocumentParser.h

@@public:
4141private:
4242 explicit TextDocumentParser(HTMLDocument*);
4343
44  virtual void append(const SegmentedString&);
 44 virtual void append(PassRefPtr<StringImpl>);
4545 void insertFakePreElement();
4646
4747 bool m_haveInsertedFakePreElement;

Source/WebCore/loader/DocumentWriter.cpp

@@void DocumentWriter::replaceDocument(const String& source, Document* ownerDocume
8080 // to support RawDataDocumentParsers.
8181 if (DocumentParser* parser = m_frame->document()->parser()) {
8282 parser->pinToMainThread();
83  parser->append(source);
 83 // Because we're pinned to the main thread we don't need to worry about
 84 // passing ownership of the source string.
 85 parser->append(source.impl());
8486 }
8587 }
8688

Source/WebCore/xml/parser/XMLDocumentParser.cpp

@@void XMLDocumentParser::insert(const SegmentedString&)
112112 ASSERT_NOT_REACHED();
113113}
114114
115 void XMLDocumentParser::append(const SegmentedString& source)
 115void XMLDocumentParser::append(PassRefPtr<StringImpl> inputSource)
116116{
 117 SegmentedString source(inputSource);
117118 if (m_sawXSLTransform || !m_sawFirstElement)
118119 m_originalSourceForTransform.append(source);
119120

Source/WebCore/xml/parser/XMLDocumentParser.h

@@class Text;
107107
108108 // From DocumentParser
109109 virtual void insert(const SegmentedString&);
110  virtual void append(const SegmentedString&);
 110 virtual void append(PassRefPtr<StringImpl>);
111111 virtual void finish();
112112 virtual bool isWaitingForScripts() const;
113113 virtual void stopParsing();

Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp

@@void XMLDocumentParser::resumeParsing()
14441444 // Then, write any pending data
14451445 SegmentedString rest = m_pendingSrc;
14461446 m_pendingSrc.clear();
1447  append(rest);
 1447 // There is normally only one string left, so toString() shouldn't copy.
 1448 // In any case, the XML parser runs on the main thread and it's OK if
 1449 // the passed string has more than one reference.
 1450 append(rest.toString().impl());
14481451
14491452 // Finally, if finish() has been called and write() didn't result
14501453 // in any further callbacks being queued, call end()