Use V8 completion callback API to assert that V8RecursionScope is on the stack whenev...
authorrafaelw@chromium.org <rafaelw@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Apr 2012 00:28:24 +0000 (00:28 +0000)
committerrafaelw@chromium.org <rafaelw@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Apr 2012 00:28:24 +0000 (00:28 +0000)
commit771b38acb581e34b539d460801d7187b103e5710
tree96789b67677fa3997feff0cad8f8455d2f69562f
parentc9e18ac77ba3ee61ab9efaee23fa6712faa66601
Use V8 completion callback API to assert that V8RecursionScope is on the stack whenever invoking script
https://bugs.webkit.org/show_bug.cgi?id=79131

Reviewed by Adam Barth.

Source/WebCore:

End-of-microtask work (cancelling outstanding IDB transactions,
delivering DOM mutations) depend on V8RecursionScope being on the
stack whenever a call is made into script. V8 provides a completion
callback API that could be used to hook these "end-of-microtask"
events, but it turns out that WebKit calls into script for various
reasons besides running script from the page. For example, constructing
wrapper objects from function templates counts as "running script",
yet it's not appropriate to run this callback every time a JS wrapper
is constructed.

Instead, this patch makes use of the V8 completion callback mechanism
only in debug mode, to assert that either a V8RecursionScope (when
calling author script) or a V8RecursionScope::MicrotaskSuppression
(when calling non-author script) is on the stack when V8 thinks it's
finished executing script. This requires dropping MicrotaskSuppression
objects in a bunch of places, most notably the Inspector.
Note that in release mode, this class does nothing and thus should be
optimized away.

No new tests. Existing tests have appropriate coverage.

* Target.pri:
* WebCore.gypi:
* bindings/v8/DateExtension.cpp:
(WebCore::DateExtension::setAllowSleep):
* bindings/v8/PageScriptDebugServer.cpp:
(WebCore::PageScriptDebugServer::addListener):
* bindings/v8/ScriptController.cpp:
(WebCore::ScriptController::callFunctionEvenIfScriptDisabled):
(WebCore):
(WebCore::ScriptController::collectGarbage):
* bindings/v8/ScriptController.h:
(ScriptController):
* bindings/v8/ScriptDebugServer.cpp:
(WebCore::ScriptDebugServer::callDebuggerMethod):
(WebCore):
(WebCore::ScriptDebugServer::pauseOnExceptionsState):
(WebCore::ScriptDebugServer::setPauseOnExceptionsState):
(WebCore::ScriptDebugServer::stepIntoStatement):
(WebCore::ScriptDebugServer::stepOverStatement):
(WebCore::ScriptDebugServer::stepOutOfFunction):
(WebCore::ScriptDebugServer::setScriptSource):
(WebCore::ScriptDebugServer::currentCallFrame):
(WebCore::ScriptDebugServer::handleV8DebugEvent):
(WebCore::ScriptDebugServer::ensureDebuggerScriptCompiled):
* bindings/v8/ScriptDebugServer.h:
(ScriptDebugServer):
* bindings/v8/ScriptFunctionCall.cpp:
(WebCore::ScriptFunctionCall::call):
* bindings/v8/V8Binding.cpp:
(WebCore::V8BindingPerIsolateData::V8BindingPerIsolateData):
* bindings/v8/V8Binding.h:
(V8BindingPerIsolateData):
(WebCore::V8BindingPerIsolateData::internalScriptRecursionLevel):
(WebCore::V8BindingPerIsolateData::incrementInternalScriptRecursionLevel):
(WebCore::V8BindingPerIsolateData::decrementInternalScriptRecursionLevel):
* bindings/v8/V8DOMWindowShell.cpp:
* bindings/v8/V8DOMWrapper.cpp:
* bindings/v8/V8LazyEventListener.cpp:
(WebCore::V8LazyEventListener::prepareListenerObject):
* bindings/v8/V8NPObject.cpp:
* bindings/v8/V8RecursionScope.h:
(WebCore):
(WebCore::V8RecursionScope::recursionLevel):
(V8RecursionScope):
(WebCore::V8RecursionScope::properlyUsed):
(MicrotaskSuppression):
(WebCore::V8RecursionScope::MicrotaskSuppression::MicrotaskSuppression):
(WebCore::V8RecursionScope::MicrotaskSuppression::~MicrotaskSuppression):
* bindings/v8/WorkerContextExecutionProxy.cpp:
* bindings/v8/custom/V8HTMLDocumentCustom.cpp:
(WebCore::V8HTMLDocument::WrapInShadowObject):
* bindings/v8/custom/V8InjectedScriptManager.cpp:
(WebCore::InjectedScriptManager::createInjectedScript):
* bindings/v8/custom/V8ScriptProfileCustom.cpp:
* bindings/v8/custom/V8ScriptProfileNodeCustom.cpp:

Source/WebKit/chromium:

* WebKit.gyp:
* public/WebFrame.h:
(v8):
(WebFrame):
* src/WebFrameImpl.cpp:
(WebKit):
(WebKit::WebFrameImpl::callFunctionEvenIfScriptDisabled):
* src/WebFrameImpl.h:
(WebFrameImpl):
* src/WebKit.cpp:
(WebKit):
(WebKit::assertV8RecursionScope):
(WebKit::initialize):
(WebKit::shutdown):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@113111 268f45cc-cd09-0410-ab3c-d52691b4dbfc
31 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Target.pri
Source/WebCore/WebCore.gypi
Source/WebCore/bindings/v8/DateExtension.cpp
Source/WebCore/bindings/v8/PageScriptDebugServer.cpp
Source/WebCore/bindings/v8/SafeAllocation.h [new file with mode: 0644]
Source/WebCore/bindings/v8/ScriptController.cpp
Source/WebCore/bindings/v8/ScriptController.h
Source/WebCore/bindings/v8/ScriptDebugServer.cpp
Source/WebCore/bindings/v8/ScriptDebugServer.h
Source/WebCore/bindings/v8/ScriptFunctionCall.cpp
Source/WebCore/bindings/v8/V8Binding.cpp
Source/WebCore/bindings/v8/V8Binding.h
Source/WebCore/bindings/v8/V8DOMWindowShell.cpp
Source/WebCore/bindings/v8/V8DOMWrapper.cpp
Source/WebCore/bindings/v8/V8LazyEventListener.cpp
Source/WebCore/bindings/v8/V8NPObject.cpp
Source/WebCore/bindings/v8/V8RecursionScope.h
Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
Source/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp
Source/WebCore/bindings/v8/custom/V8InjectedScriptManager.cpp
Source/WebCore/bindings/v8/custom/V8ScriptProfileCustom.cpp
Source/WebCore/bindings/v8/custom/V8ScriptProfileNodeCustom.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/WebKit.gyp
Source/WebKit/chromium/public/WebFrame.h
Source/WebKit/chromium/public/WebScopedMicrotaskSuppression.h [new file with mode: 0644]
Source/WebKit/chromium/src/WebFrameImpl.cpp
Source/WebKit/chromium/src/WebFrameImpl.h
Source/WebKit/chromium/src/WebKit.cpp
Source/WebKit/chromium/src/WebScopedMicrotaskSuppression.cpp [new file with mode: 0644]