Changeset 61646 in webkit
- Timestamp:
- Jun 22, 2010 6:41:39 PM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r61645 r61646 1 2010-06-22 Eric Seidel <eric@webkit.org> 2 3 Unreviewed. Rolling out http://trac.webkit.org/changeset/61638 4 made a few tests crash. 5 6 Make PendingScript hold a CachedResourceClient open for its lifetime 7 https://bugs.webkit.org/show_bug.cgi?id=40968 8 9 * html/HTML5DocumentParser.cpp: 10 (WebCore::HTML5DocumentParser::watchForLoad): 11 (WebCore::HTML5DocumentParser::notifyFinished): 12 * html/HTML5ScriptRunner.cpp: 13 (WebCore::HTML5ScriptRunner::~HTML5ScriptRunner): 14 (WebCore::HTML5ScriptRunner::sourceFromPendingScript): 15 (WebCore::HTML5ScriptRunner::isPendingScriptReady): 16 (WebCore::HTML5ScriptRunner::executePendingScript): 17 (WebCore::HTML5ScriptRunner::hasScriptsWaitingForLoad): 18 (WebCore::HTML5ScriptRunner::watchForLoad): 19 (WebCore::HTML5ScriptRunner::stopWatchingForLoad): 20 (WebCore::HTML5ScriptRunner::executeScriptsWaitingForLoad): 21 (WebCore::HTML5ScriptRunner::executeScriptsWaitingForStylesheets): 22 (WebCore::HTML5ScriptRunner::requestScript): 23 * html/HTML5ScriptRunner.h: 24 (WebCore::HTML5ScriptRunner::PendingScript::): 25 (WebCore::HTML5ScriptRunner::PendingScript::PendingScript): 26 (WebCore::HTML5ScriptRunner::PendingScript::watchingForLoad): 27 * html/HTML5ScriptRunnerHost.h: 28 1 29 2010-06-22 Adele Peterson <adele@apple.com> 2 30 -
trunk/WebCore/html/HTML5DocumentParser.cpp
r61640 r61646 407 407 void HTML5DocumentParser::watchForLoad(CachedResource* cachedScript) 408 408 { 409 ASSERT(!cachedScript->isLoaded());410 // addClient would call notifyFinished if the load were complete.411 // Callers do not expect to be re-entered from this call, so they should412 // not an already-loaded CachedResource.413 409 cachedScript->addClient(this); 414 410 } … … 429 425 { 430 426 ASSERT(m_scriptRunner); 427 // Ignore calls unless we have a script blocking the parser waiting 428 // for its own load. Otherwise this may be a load callback from 429 // CachedResource::addClient because the script was already in the cache. 430 // HTML5ScriptRunner may not be ready to handle running that script yet. 431 if (!m_scriptRunner->hasScriptsWaitingForLoad()) { 432 ASSERT(m_scriptRunner->inScriptExecution()); 433 return; 434 } 431 435 ASSERT(!inScriptExecution()); 432 436 ASSERT(m_treeConstructor->isPaused()); -
trunk/WebCore/html/HTML5ScriptRunner.cpp
r61638 r61646 75 75 { 76 76 // FIXME: Should we be passed a "done loading/parsing" callback sooner than destruction? 77 if (m_parsingBlockingScript.cachedScript ()&& m_parsingBlockingScript.watchingForLoad())77 if (m_parsingBlockingScript.cachedScript && m_parsingBlockingScript.watchingForLoad()) 78 78 stopWatchingForLoad(m_parsingBlockingScript); 79 79 } … … 100 100 ScriptSourceCode HTML5ScriptRunner::sourceFromPendingScript(const PendingScript& script, bool& errorOccurred) 101 101 { 102 if (script.cachedScript ()) {103 errorOccurred = script.cachedScript ()->errorOccurred();104 ASSERT(script.cachedScript ()->isLoaded());105 return ScriptSourceCode(script.cachedScript ());102 if (script.cachedScript) { 103 errorOccurred = script.cachedScript->errorOccurred(); 104 ASSERT(script.cachedScript->isLoaded()); 105 return ScriptSourceCode(script.cachedScript.get()); 106 106 } 107 107 errorOccurred = false; … … 114 114 if (m_hasScriptsWaitingForStylesheets) 115 115 return false; 116 if (script.cachedScript () && !script.cachedScript()->isLoaded())116 if (script.cachedScript && !script.cachedScript->isLoaded()) 117 117 return false; 118 118 return true; … … 128 128 129 129 // Stop watching loads before executeScript to prevent recursion if the script reloads itself. 130 if (m_parsingBlockingScript.cachedScript ()&& m_parsingBlockingScript.watchingForLoad())130 if (m_parsingBlockingScript.cachedScript && m_parsingBlockingScript.watchingForLoad()) 131 131 stopWatchingForLoad(m_parsingBlockingScript); 132 132 … … 162 162 } 163 163 164 bool HTML5ScriptRunner::hasScriptsWaitingForLoad() const 165 { 166 // We're only actually waiting for a load. This allows us to ignore load 167 // callbacks when CachedResource::addClient calls notifyFinished because 168 // of a cache hit (not because of a load we were set up to wait for). 169 return m_parsingBlockingScript.watchingForLoadState == PendingScript::WatchingForLoad; 170 } 171 164 172 void HTML5ScriptRunner::watchForLoad(PendingScript& pendingScript) 165 173 { 166 174 ASSERT(!pendingScript.watchingForLoad()); 167 m_host->watchForLoad(pendingScript.cachedScript()); 168 pendingScript.setWatchingForLoad(true); 175 // CachedResource::addClient will call notifyFinished if the load is already 176 // complete. We set watchingForLoadState to RegisteringForWatch so that we 177 // know to ignore any notifyFinished call during addClient. 178 pendingScript.watchingForLoadState = PendingScript::RegisteringForWatch; 179 m_host->watchForLoad(pendingScript.cachedScript.get()); 180 pendingScript.watchingForLoadState = PendingScript::WatchingForLoad; 169 181 } 170 182 … … 172 184 { 173 185 ASSERT(pendingScript.watchingForLoad()); 174 m_host->stopWatchingForLoad(pendingScript.cachedScript ());175 pendingScript. setWatchingForLoad(false);186 m_host->stopWatchingForLoad(pendingScript.cachedScript.get()); 187 pendingScript.watchingForLoadState = PendingScript::NotWatchingForLoad; 176 188 } 177 189 … … 213 225 bool HTML5ScriptRunner::executeScriptsWaitingForLoad(CachedResource* cachedScript) 214 226 { 227 // Callers should check hasScriptsWaitingForLoad() before calling 228 // to prevent parser or script re-entry during due to 229 // CachedResource::addClient calling notifyFinished on cache-hits. 230 ASSERT(hasScriptsWaitingForLoad()); 215 231 ASSERT(!m_scriptNestingLevel); 216 232 ASSERT(haveParsingBlockingScript()); 217 ASSERT_UNUSED(cachedScript, m_parsingBlockingScript.cachedScript ()== cachedScript);218 ASSERT(m_parsingBlockingScript.cachedScript ()->isLoaded());233 ASSERT_UNUSED(cachedScript, m_parsingBlockingScript.cachedScript == cachedScript); 234 ASSERT(m_parsingBlockingScript.cachedScript->isLoaded()); 219 235 return executeParsingBlockingScripts(); 220 236 } … … 224 240 // Callers should check hasScriptsWaitingForStylesheets() before calling 225 241 // to prevent parser or script re-entry during </style> parsing. 226 ASSERT( m_hasScriptsWaitingForStylesheets);242 ASSERT(hasScriptsWaitingForStylesheets()); 227 243 ASSERT(!m_scriptNestingLevel); 228 244 ASSERT(m_document->haveStylesheetsLoaded()); … … 247 263 return; 248 264 } 249 m_parsingBlockingScript.setCachedScript(cachedScript); 250 251 // We only care about a load callback if cachedScript is not already 252 // in the cache. Callers will attempt to run the m_parsingBlockingScript 253 // if possible before returning control to the parser. 254 if (!m_parsingBlockingScript.cachedScript()->isLoaded()) 255 watchForLoad(m_parsingBlockingScript); 265 m_parsingBlockingScript.cachedScript = cachedScript; 266 267 // Always call watchForLoad, even if the script is already loaded. 268 // CachedResource may purge its data if it has no clients, which would cause 269 // later script execution to fail. watchForLoad sets m_parsingBlockingScript 270 // to the RegisteringForWatch state so we know to ignore any 271 // executeScriptsWaitingForLoad callbacks during the watchForLoad call. 272 watchForLoad(m_parsingBlockingScript); 273 // Callers will attempt to run the m_parsingBlockingScript if possible 274 // before returning control to the parser. 256 275 } 257 276 … … 279 298 } 280 299 281 HTML5ScriptRunner::PendingScript::~PendingScript() 282 { 283 if (m_cachedScript) 284 m_cachedScript->removeClient(this); 285 } 286 287 void HTML5ScriptRunner::PendingScript::setCachedScript(CachedScript* cachedScript) 288 { 289 if (m_cachedScript) 290 m_cachedScript->removeClient(this); 291 m_cachedScript = cachedScript; 292 if (m_cachedScript) 293 m_cachedScript->addClient(this); 294 } 295 296 CachedScript* HTML5ScriptRunner::PendingScript::cachedScript() const 297 { 298 return m_cachedScript.get(); 299 } 300 301 } 300 } -
trunk/WebCore/html/HTML5ScriptRunner.h
r61640 r61646 49 49 // Processes the passed in script and any pending scripts if possible. 50 50 bool execute(PassRefPtr<Element> scriptToProcess, int scriptStartLine); 51 // Processes any pending scripts. 51 52 bool hasScriptsWaitingForLoad() const; 52 53 bool executeScriptsWaitingForLoad(CachedResource*); 54 53 55 bool hasScriptsWaitingForStylesheets() const { return m_hasScriptsWaitingForStylesheets; } 54 56 bool executeScriptsWaitingForStylesheets(); … … 57 59 58 60 private: 59 // A container for an external script which may be loaded and executed. 60 // 61 // A CachedResourceHandle alone does not prevent the underlying CachedResource 62 // from purging its data buffer. This class holds a dummy client open for its 63 // lifetime in order to guarantee that the data buffer will not be purged. 64 class PendingScript : public CachedResourceClient { 65 public: 61 struct PendingScript { 62 // This state controls whether we need to do anything with this script 63 // when we get a executeScriptsWaitingForLoad callback. 64 // We ignore callbacks during RegisteringForWatch. 65 enum WatchingForLoadState { 66 NotWatchingForLoad, 67 RegisteringForWatch, 68 WatchingForLoad, 69 }; 70 66 71 PendingScript() 67 : startingLineNumber(0)68 , m_watchingForLoad(false)72 : watchingForLoadState(NotWatchingForLoad) 73 , startingLineNumber(0) 69 74 { 70 75 } 71 76 72 ~PendingScript(); 73 74 bool watchingForLoad() const { return m_watchingForLoad; } 75 void setWatchingForLoad(bool b) { m_watchingForLoad = b; } 76 77 CachedScript* cachedScript() const; 78 void setCachedScript(CachedScript* cachedScript); 79 80 virtual void notifyFinished(CachedResource*) 77 bool watchingForLoad() 81 78 { 79 return watchingForLoadState != NotWatchingForLoad; 82 80 } 83 81 84 82 RefPtr<Element> element; 83 CachedResourceHandle<CachedScript> cachedScript; 84 WatchingForLoadState watchingForLoadState; 85 85 int startingLineNumber; // Only used for inline script tags. 86 86 // HTML5 has an isReady parameter, however isReady ends up equivalent to 87 87 // m_document->haveStylesheetsLoaded() && cachedScript->isLoaded() 88 89 private:90 bool m_watchingForLoad; // Did we pass the cachedScript to the HTML5ScriptRunnerHost.91 CachedResourceHandle<CachedScript> m_cachedScript;92 88 }; 93 89 -
trunk/WebCore/html/HTML5ScriptRunnerHost.h
r61638 r61646 39 39 virtual ~HTML5ScriptRunnerHost() { } 40 40 41 // Implementors should call cachedResource->addClient() here or soon after.41 // Implementors must call cachedResource->addClient() immediately. 42 42 virtual void watchForLoad(CachedResource*) = 0; 43 43 // Implementors must call cachedResource->removeClient() immediately.
Note: See TracChangeset
for help on using the changeset viewer.