Changeset 142305 in webkit


Ignore:
Timestamp:
Feb 8, 2013 11:30:54 AM (11 years ago)
Author:
abarth@webkit.org
Message:

Use WeakPtrs to communicate between the HTMLDocumentParser and the BackgroundHTMLParser
https://bugs.webkit.org/show_bug.cgi?id=107190

Reviewed by Eric Seidel.

Source/WebCore:

This patch replaces the parser map with WeakPtr. We now use WeakPtrs to
communicate from the main thread to the background thread. (We were
already using WeakPtrs to communicate from the background thread to the
main thread.) This change lets us remove a bunch of boilerplate code.

  • html/parser/BackgroundHTMLParser.cpp:

(WebCore::BackgroundHTMLParser::BackgroundHTMLParser):
(WebCore::BackgroundHTMLParser::stop):
(WebCore):

  • html/parser/BackgroundHTMLParser.h:

(WebCore::BackgroundHTMLParser::create):
(BackgroundHTMLParser):

  • html/parser/HTMLDocumentParser.cpp:

(WebCore::HTMLDocumentParser::didFailSpeculation):
(WebCore::HTMLDocumentParser::startBackgroundParser):
(WebCore::HTMLDocumentParser::stopBackgroundParser):
(WebCore::HTMLDocumentParser::append):
(WebCore::HTMLDocumentParser::finish):

  • html/parser/HTMLDocumentParser.h:

(WebCore):
(HTMLDocumentParser):

Source/WTF:

Add the ability to create an unbound weak reference. This facility lets
you start sending messages to a WeakPtr on another thread before the
object backing the WeakPtr has actually been created.

  • wtf/WeakPtr.h:

(WTF::WeakReference::createUnbound):
(WTF::WeakReference::bindTo):
(WeakReference):
(WTF::WeakReference::WeakReference):
(WTF::WeakPtr::WeakPtr):
(WeakPtr):
(WTF::WeakPtrFactory::WeakPtrFactory):
(WeakPtrFactory):
(WTF::WeakPtrFactory::revokeAll):

Location:
trunk/Source
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r142298 r142305  
     12013-02-08  Adam Barth  <abarth@webkit.org>
     2
     3        Use WeakPtrs to communicate between the HTMLDocumentParser and the BackgroundHTMLParser
     4        https://bugs.webkit.org/show_bug.cgi?id=107190
     5
     6        Reviewed by Eric Seidel.
     7
     8        Add the ability to create an unbound weak reference. This facility lets
     9        you start sending messages to a WeakPtr on another thread before the
     10        object backing the WeakPtr has actually been created.
     11
     12        * wtf/WeakPtr.h:
     13        (WTF::WeakReference::createUnbound):
     14        (WTF::WeakReference::bindTo):
     15        (WeakReference):
     16        (WTF::WeakReference::WeakReference):
     17        (WTF::WeakPtr::WeakPtr):
     18        (WeakPtr):
     19        (WTF::WeakPtrFactory::WeakPtrFactory):
     20        (WeakPtrFactory):
     21        (WTF::WeakPtrFactory::revokeAll):
     22
    1232013-02-08  Martin Robinson  <mrobinson@igalia.com>
    224
  • trunk/Source/WTF/wtf/WeakPtr.h

    r140589 r142305  
    3535namespace WTF {
    3636
    37 namespace Internal {
    38 
    3937template<typename T>
    4038class WeakReference : public ThreadSafeRefCounted<WeakReference<T> > {
     
    4341public:
    4442    static PassRefPtr<WeakReference<T> > create(T* ptr) { return adoptRef(new WeakReference(ptr)); }
     43    static PassRefPtr<WeakReference<T> > createUnbound() { return adoptRef(new WeakReference()); }
    4544
    4645    T* get() const
     
    5655    }
    5756
     57    void bindTo(T* ptr)
     58    {
     59        ASSERT(!m_ptr);
     60#ifndef NDEBUG
     61        m_boundThread = currentThread();
     62#endif
     63        m_ptr = ptr;
     64    }
     65
    5866private:
     67    WeakReference() : m_ptr(0) { }
     68
    5969    explicit WeakReference(T* ptr)
    6070        : m_ptr(ptr)
     
    7181};
    7282
    73 }
    74 
    7583template<typename T>
    7684class WeakPtr {
     
    7886public:
    7987    WeakPtr() { }
    80     WeakPtr(PassRefPtr<Internal::WeakReference<T> > ref) : m_ref(ref) { }
     88    WeakPtr(PassRefPtr<WeakReference<T> > ref) : m_ref(ref) { }
    8189
    8290    T* get() const { return m_ref->get(); }
    8391
    8492private:
    85     RefPtr<Internal::WeakReference<T> > m_ref;
     93    RefPtr<WeakReference<T> > m_ref;
    8694};
    8795
     
    9199    WTF_MAKE_FAST_ALLOCATED;
    92100public:
    93     explicit WeakPtrFactory(T* ptr) { m_ref = Internal::WeakReference<T>::create(ptr); }
     101    explicit WeakPtrFactory(T* ptr) : m_ref(WeakReference<T>::create(ptr)) { }
     102
     103    WeakPtrFactory(PassRefPtr<WeakReference<T> > ref, T* ptr)
     104        : m_ref(ref)
     105    {
     106        m_ref->bindTo(ptr);
     107    }
     108
    94109    ~WeakPtrFactory() { m_ref->clear(); }
    95110
     
    102117        m_ref->clear();
    103118        // We create a new WeakReference so that future calls to createWeakPtr() create nonzero WeakPtrs.
    104         m_ref = Internal::WeakReference<T>::create(ptr);
     119        m_ref = WeakReference<T>::create(ptr);
    105120    }
    106121
    107122private:
    108     RefPtr<Internal::WeakReference<T> > m_ref;
     123    RefPtr<WeakReference<T> > m_ref;
    109124};
    110125
     
    113128using WTF::WeakPtr;
    114129using WTF::WeakPtrFactory;
     130using WTF::WeakReference;
    115131
    116132#endif
  • trunk/Source/WebCore/ChangeLog

    r142303 r142305  
     12013-02-08  Adam Barth  <abarth@webkit.org>
     2
     3        Use WeakPtrs to communicate between the HTMLDocumentParser and the BackgroundHTMLParser
     4        https://bugs.webkit.org/show_bug.cgi?id=107190
     5
     6        Reviewed by Eric Seidel.
     7
     8        This patch replaces the parser map with WeakPtr. We now use WeakPtrs to
     9        communicate from the main thread to the background thread. (We were
     10        already using WeakPtrs to communicate from the background thread to the
     11        main thread.) This change lets us remove a bunch of boilerplate code.
     12
     13        * html/parser/BackgroundHTMLParser.cpp:
     14        (WebCore::BackgroundHTMLParser::BackgroundHTMLParser):
     15        (WebCore::BackgroundHTMLParser::stop):
     16        (WebCore):
     17        * html/parser/BackgroundHTMLParser.h:
     18        (WebCore::BackgroundHTMLParser::create):
     19        (BackgroundHTMLParser):
     20        * html/parser/HTMLDocumentParser.cpp:
     21        (WebCore::HTMLDocumentParser::didFailSpeculation):
     22        (WebCore::HTMLDocumentParser::startBackgroundParser):
     23        (WebCore::HTMLDocumentParser::stopBackgroundParser):
     24        (WebCore::HTMLDocumentParser::append):
     25        (WebCore::HTMLDocumentParser::finish):
     26        * html/parser/HTMLDocumentParser.h:
     27        (WebCore):
     28        (HTMLDocumentParser):
     29
    1302013-02-07  Roger Fong  <roger_fong@apple.com>
    231
  • trunk/Source/WebCore/html/parser/BackgroundHTMLParser.cpp

    r142099 r142305  
    5959static const size_t pendingTokenLimit = 4000;
    6060
    61 ParserMap& parserMap()
    62 {
    63     // This initialization assumes that this will be initialize on the main thread before
    64     // any parser thread is started.
    65     static ParserMap* sParserMap = new ParserMap;
    66     return *sParserMap;
    67 }
    68 
    69 ParserMap::BackgroundParserMap& ParserMap::backgroundParsers()
    70 {
    71     ASSERT(HTMLParserThread::shared()->threadId() == currentThread());
    72     return m_backgroundParsers;
    73 }
    74 
    75 BackgroundHTMLParser::BackgroundHTMLParser(const HTMLParserOptions& options, const WeakPtr<HTMLDocumentParser>& parser, PassOwnPtr<XSSAuditor> xssAuditor)
     61BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, const HTMLParserOptions& options, const WeakPtr<HTMLDocumentParser>& parser, PassOwnPtr<XSSAuditor> xssAuditor)
    7662    : m_inForeignContent(false)
     63    , m_weakFactory(reference, this)
    7764    , m_token(adoptPtr(new HTMLToken))
    7865    , m_tokenizer(HTMLTokenizer::create(options))
     
    10390    markEndOfFile();
    10491    pumpTokenizer();
     92}
     93
     94void BackgroundHTMLParser::stop()
     95{
     96    delete this;
    10597}
    10698
     
    195187}
    196188
    197 void BackgroundHTMLParser::createPartial(ParserIdentifier identifier, const HTMLParserOptions& options, const WeakPtr<HTMLDocumentParser>& parser, PassOwnPtr<XSSAuditor> xssAuditor)
    198 {
    199     ASSERT(!parserMap().backgroundParsers().get(identifier));
    200     parserMap().backgroundParsers().set(identifier, BackgroundHTMLParser::create(options, parser, xssAuditor));
    201 }
    202 
    203 void BackgroundHTMLParser::stopPartial(ParserIdentifier identifier)
    204 {
    205     parserMap().backgroundParsers().remove(identifier);
    206 }
    207 
    208 void BackgroundHTMLParser::appendPartial(ParserIdentifier identifier, const String& input)
    209 {
    210     ASSERT(!input.impl() || input.impl()->hasOneRef() || input.isEmpty());
    211     if (BackgroundHTMLParser* parser = parserMap().backgroundParsers().get(identifier))
    212         parser->append(input);
    213 }
    214 
    215 void BackgroundHTMLParser::resumeFromPartial(ParserIdentifier identifier, const WeakPtr<HTMLDocumentParser>& parser, PassOwnPtr<HTMLToken> token, PassOwnPtr<HTMLTokenizer> tokenizer, HTMLInputCheckpoint checkpoint)
    216 {
    217     if (BackgroundHTMLParser* backgroundParser = parserMap().backgroundParsers().get(identifier))
    218         backgroundParser->resumeFrom(parser, token, tokenizer, checkpoint);
    219 }
    220 
    221 void BackgroundHTMLParser::finishPartial(ParserIdentifier identifier)
    222 {
    223     if (BackgroundHTMLParser* parser = parserMap().backgroundParsers().get(identifier))
    224         parser->finish();
    225 }
    226 
    227189}
    228190
  • trunk/Source/WebCore/html/parser/BackgroundHTMLParser.h

    r142099 r142305  
    4848    WTF_MAKE_FAST_ALLOCATED;
    4949public:
     50    static void create(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, const HTMLParserOptions& options, const WeakPtr<HTMLDocumentParser>& parser, PassOwnPtr<XSSAuditor> xssAuditor)
     51    {
     52        new BackgroundHTMLParser(reference, options, parser, xssAuditor);
     53        // Caller must free by calling stop().
     54    }
     55
    5056    void append(const String&);
    5157    void resumeFrom(const WeakPtr<HTMLDocumentParser>&, PassOwnPtr<HTMLToken>, PassOwnPtr<HTMLTokenizer>, HTMLInputCheckpoint);
    5258    void finish();
    53 
    54     static PassOwnPtr<BackgroundHTMLParser> create(const HTMLParserOptions& options, const WeakPtr<HTMLDocumentParser>& parser, PassOwnPtr<XSSAuditor> xssAuditor)
    55     {
    56         return adoptPtr(new BackgroundHTMLParser(options, parser, xssAuditor));
    57     }
    58 
    59     static void createPartial(ParserIdentifier, const HTMLParserOptions&, const WeakPtr<HTMLDocumentParser>&, PassOwnPtr<XSSAuditor>);
    60     static void stopPartial(ParserIdentifier);
    61     static void appendPartial(ParserIdentifier, const String& input);
    62     static void resumeFromPartial(ParserIdentifier, const WeakPtr<HTMLDocumentParser>&, PassOwnPtr<HTMLToken>, PassOwnPtr<HTMLTokenizer>, HTMLInputCheckpoint);
    63     static void finishPartial(ParserIdentifier);
     59    void stop();
    6460
    6561private:
    66     BackgroundHTMLParser(const HTMLParserOptions&, const WeakPtr<HTMLDocumentParser>&, PassOwnPtr<XSSAuditor>);
     62    BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> >, const HTMLParserOptions&, const WeakPtr<HTMLDocumentParser>&, PassOwnPtr<XSSAuditor>);
    6763
    6864    void markEndOfFile();
     
    7369
    7470    bool m_inForeignContent; // FIXME: We need a stack of foreign content markers.
     71    WeakPtrFactory<BackgroundHTMLParser> m_weakFactory;
    7572    BackgroundHTMLInputStream m_input;
    7673    HTMLSourceTracker m_sourceTracker;
     
    8380};
    8481
    85 class ParserMap {
    86 public:
    87     static ParserIdentifier identifierForParser(HTMLDocumentParser* parser)
    88     {
    89         return reinterpret_cast<ParserIdentifier>(parser);
    90     }
    91 
    92     typedef HashMap<ParserIdentifier, OwnPtr<BackgroundHTMLParser> > BackgroundParserMap;
    93 
    94     BackgroundParserMap& backgroundParsers();
    95 
    96 private:
    97     BackgroundParserMap m_backgroundParsers;
    98 };
    99 
    100 ParserMap& parserMap();
    101 
    10282}
    10383
  • trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp

    r142200 r142305  
    302302    m_speculations.clear();
    303303
    304     ParserIdentifier identifier = ParserMap::identifierForParser(this);
    305     HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::resumeFromPartial,
    306         identifier, m_weakFactory.createWeakPtr(), token, tokenizer, m_currentChunk->checkpoint));
     304    HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::resumeFrom,
     305        m_backgroundParser, m_weakFactory.createWeakPtr(), token, tokenizer, m_currentChunk->checkpoint));
    307306}
    308307
     
    513512    m_haveBackgroundParser = true;
    514513
     514    RefPtr<WeakReference<BackgroundHTMLParser> > reference = WeakReference<BackgroundHTMLParser>::createUnbound();
     515    m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference);
     516
    515517    WeakPtr<HTMLDocumentParser> parser = m_weakFactory.createWeakPtr();
    516518    OwnPtr<XSSAuditor> xssAuditor = adoptPtr(new XSSAuditor);
    517519    xssAuditor->init(document());
    518520    ASSERT(xssAuditor->isSafeToSendToAnotherThread());
    519     ParserIdentifier identifier = ParserMap::identifierForParser(this);
    520     HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::createPartial, identifier, m_options, parser, xssAuditor.release()));
     521    HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::create, reference.release(), m_options, parser, xssAuditor.release()));
    521522}
    522523
     
    527528    m_haveBackgroundParser = false;
    528529
    529     ParserIdentifier identifier = ParserMap::identifierForParser(this);
    530     HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::stopPartial, identifier));
     530    HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::stop, m_backgroundParser));
    531531    m_weakFactory.revokeAll();
    532532}
     
    544544            startBackgroundParser();
    545545
    546         ParserIdentifier identifier = ParserMap::identifierForParser(this);
    547         const Closure& appendPartial = bind(&BackgroundHTMLParser::appendPartial, identifier, source.toString().isolatedCopy());
    548         HTMLParserThread::shared()->postTask(appendPartial);
     546        HTMLParserThread::shared()->postTask(bind(
     547            &BackgroundHTMLParser::append, m_backgroundParser, source.toString().isolatedCopy()));
    549548        return;
    550549    }
     
    646645    // and fall through to the non-threading case.
    647646    if (m_haveBackgroundParser) {
    648         HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::finishPartial, ParserMap::identifierForParser(this)));
     647        HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::finish, m_backgroundParser));
    649648        return;
    650649    }
  • trunk/Source/WebCore/html/parser/HTMLDocumentParser.h

    r142200 r142305  
    4747namespace WebCore {
    4848
     49class BackgroundHTMLParser;
    4950class CompactHTMLToken;
    5051class Document;
     
    183184    Deque<OwnPtr<ParsedChunk> > m_speculations;
    184185    WeakPtrFactory<HTMLDocumentParser> m_weakFactory;
     186    WeakPtr<BackgroundHTMLParser> m_backgroundParser;
    185187#endif
    186188
Note: See TracChangeset for help on using the changeset viewer.