1/* 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef HTMLParserScheduler_h 27#define HTMLParserScheduler_h 28 29#include "NestingLevelIncrementer.h" 30#include "Timer.h" 31#include <wtf/CurrentTime.h> 32#include <wtf/RefPtr.h> 33 34#if PLATFORM(IOS) 35#include "WebCoreThread.h" 36#endif 37 38namespace WebCore { 39 40class Document; 41class HTMLDocumentParser; 42 43class ActiveParserSession { 44public: 45 explicit ActiveParserSession(Document*); 46 ~ActiveParserSession(); 47 48private: 49 RefPtr<Document> m_document; 50}; 51 52class PumpSession : public NestingLevelIncrementer, public ActiveParserSession { 53public: 54 PumpSession(unsigned& nestingLevel, Document*); 55 ~PumpSession(); 56 57 int processedTokens; 58 double startTime; 59 bool needsYield; 60 bool didSeeScript; 61}; 62 63class HTMLParserScheduler { 64 WTF_MAKE_NONCOPYABLE(HTMLParserScheduler); WTF_MAKE_FAST_ALLOCATED; 65public: 66 explicit HTMLParserScheduler(HTMLDocumentParser&); 67 ~HTMLParserScheduler(); 68 69 // Inline as this is called after every token in the parser. 70 void checkForYieldBeforeToken(PumpSession& session) 71 { 72#if PLATFORM(IOS) 73 if (WebThreadShouldYield()) 74 session.needsYield = true; 75#endif 76 if (session.processedTokens > m_parserChunkSize || session.didSeeScript) { 77 // monotonicallyIncreasingTime() can be expensive. By delaying, we avoided calling 78 // monotonicallyIncreasingTime() when constructing non-yielding PumpSessions. 79 if (!session.startTime) 80 session.startTime = monotonicallyIncreasingTime(); 81 82 session.processedTokens = 0; 83 session.didSeeScript = false; 84 85 double elapsedTime = monotonicallyIncreasingTime() - session.startTime; 86 if (elapsedTime > m_parserTimeLimit) 87 session.needsYield = true; 88 } 89 ++session.processedTokens; 90 } 91 void checkForYieldBeforeScript(PumpSession&); 92 93 void scheduleForResume(); 94 bool isScheduledForResume() const { return m_isSuspendedWithActiveTimer || m_continueNextChunkTimer.isActive(); } 95 96 void suspend(); 97 void resume(); 98 99private: 100 void continueNextChunkTimerFired(Timer<HTMLParserScheduler>&); 101 102 HTMLDocumentParser& m_parser; 103 104 double m_parserTimeLimit; 105 int m_parserChunkSize; 106 Timer<HTMLParserScheduler> m_continueNextChunkTimer; 107 bool m_isSuspendedWithActiveTimer; 108#if !ASSERT_DISABLED 109 bool m_suspended; 110#endif 111}; 112 113} 114 115#endif 116