JSLock should be per-JSGlobalData
authormhahnenberg@apple.com <mhahnenberg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Jun 2012 23:08:26 +0000 (23:08 +0000)
committermhahnenberg@apple.com <mhahnenberg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Jun 2012 23:08:26 +0000 (23:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=89123

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

* API/APIShims.h:
(APIEntryShimWithoutLock):
(JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): Added an extra parameter to the constructor to
determine whether we should ref the JSGlobalData or not. We want to ref all the time except for in the
HeapTimer class because timerDidFire could run after somebody has started to tear down that particular
JSGlobalData, so we wouldn't want to resurrect the ref count of that JSGlobalData from 0 back to 1 after
its destruction has begun.
(JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
(JSC::APIEntryShim::APIEntryShim):
(APIEntryShim):
(JSC::APIEntryShim::~APIEntryShim):
(JSC::APIEntryShim::init): Factored out common initialization code for the various APIEntryShim constructors.
Also moved the timeoutChecker stop and start here because we need to start after we've grabbed the API lock
and before we've released it, which can only done in APIEntryShim.
(JSC::APICallbackShim::~APICallbackShim): We no longer need to synchronize here.
* API/JSContextRef.cpp:
(JSGlobalContextCreate):
(JSGlobalContextCreateInGroup):
(JSGlobalContextRelease):
(JSContextCreateBacktrace):
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* heap/CopiedSpace.cpp:
(JSC::CopiedSpace::tryAllocateSlowCase):
* heap/Heap.cpp:
(JSC::Heap::protect):
(JSC::Heap::unprotect):
(JSC::Heap::collect):
(JSC::Heap::setActivityCallback):
(JSC::Heap::activityCallback):
(JSC::Heap::sweeper):
* heap/Heap.h: Changed m_activityCallback and m_sweeper to be raw pointers rather than OwnPtrs because they
are now responsible for their own lifetime. Also changed the order of declaration of the GCActivityCallback
and the IncrementalSweeper to make sure they're the last things that get initialized during construction to
prevent any issues with uninitialized memory in the JSGlobalData/Heap they might care about.
(Heap):
* heap/HeapTimer.cpp: Refactored to allow for thread-safe operation and shutdown.
(JSC::HeapTimer::~HeapTimer):
(JSC::HeapTimer::invalidate):
(JSC):
(JSC::HeapTimer::didStartVMShutdown): Called at the beginning of ~JSGlobalData. If we're on the same thread
that the HeapTimer is running on, we kill the HeapTimer ourselves. If not, then we set some state in the
HeapTimer and schedule it to fire immediately so that it can notice and kill itself.
(JSC::HeapTimer::timerDidFire): We grab our mutex and check our JSGlobalData pointer. If it has been zero-ed
out, then we know the VM has started to shutdown and we should kill ourselves. Otherwise, grab the APIEntryShim,
but without ref-ing the JSGlobalData (we don't want to bring the JSGlobalData's ref-count from 0 to 1) in case
we were interrupted between releasing our mutex and trying to grab the APILock.
* heap/HeapTimer.h:
(HeapTimer):
* heap/IncrementalSweeper.cpp:
(JSC::IncrementalSweeper::doWork): We no longer need the API shim here since HeapTimer::timerDidFire handles
all of that for us.
(JSC::IncrementalSweeper::create):
* heap/IncrementalSweeper.h:
(IncrementalSweeper):
* heap/MarkedAllocator.cpp:
(JSC::MarkedAllocator::allocateSlowCase):
* heap/WeakBlock.cpp:
(JSC::WeakBlock::reap):
* jsc.cpp:
(functionGC):
(functionReleaseExecutableMemory):
(jscmain):
* runtime/Completion.cpp:
(JSC::checkSyntax):
(JSC::evaluate):
* runtime/GCActivityCallback.h:
(DefaultGCActivityCallback):
(JSC::DefaultGCActivityCallback::create):
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::~JSGlobalData): Signals to the two HeapTimers (GCActivityCallback and IncrementalSweeper)
that the VM has started shutting down. It then waits until the HeapTimer is done with whatever activity
it needs to do before continuing with any further destruction. Also asserts that we do not currently hold the
APILock because this could potentially cause deadlock when we try to signal to the HeapTimers using their mutexes.
(JSC::JSGlobalData::sharedInstance): Protect the initialization for the shared instance with the GlobalJSLock.
(JSC::JSGlobalData::sharedInstanceInternal):
* runtime/JSGlobalData.h: Change to be ThreadSafeRefCounted so that we don't have to worry about refing and
de-refing JSGlobalDatas on separate threads since we don't do it that often anyways.
(JSGlobalData):
(JSC::JSGlobalData::apiLock):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::~JSGlobalObject):
(JSC::JSGlobalObject::init):
* runtime/JSLock.cpp:
(JSC):
(JSC::GlobalJSLock::GlobalJSLock): For accessing the shared instance.
(JSC::GlobalJSLock::~GlobalJSLock):
(JSC::JSLockHolder::JSLockHolder): MutexLocker for JSLock. Also refs the JSGlobalData to keep it alive so that
it can successfully unlock it later without it disappearing from underneath it.
(JSC::JSLockHolder::~JSLockHolder):
(JSC::JSLock::JSLock):
(JSC::JSLock::~JSLock):
(JSC::JSLock::lock): Uses the spin lock for guarding the lock count and owner thread fields. Uses the mutex for
actually waiting for long periods.
(JSC::JSLock::unlock):
(JSC::JSLock::currentThreadIsHoldingLock):
(JSC::JSLock::dropAllLocks):
(JSC::JSLock::dropAllLocksUnconditionally):
(JSC::JSLock::grabAllLocks):
(JSC::JSLock::DropAllLocks::DropAllLocks):
(JSC::JSLock::DropAllLocks::~DropAllLocks):
* runtime/JSLock.h:
(JSC):
(GlobalJSLock):
(JSLockHolder):
(JSLock):
(DropAllLocks):
* runtime/WeakGCMap.h:
(JSC::WeakGCMap::set):
* testRegExp.cpp:
(realMain):

Source/WebCore:

No new tests. Current regression tests are sufficient.

Changed all sites that used JSLock to instead use the new JSLockHolder
and pass in the correct JS context that the code is about to interact with that
needs protection. Also added a couple JSLocks to places that didn't already
have it that needed it.

* bindings/js/GCController.cpp:
(WebCore::collect):
(WebCore::GCController::garbageCollectSoon):
(WebCore::GCController::garbageCollectNow):
(WebCore::GCController::discardAllCompiledCode):
* bindings/js/JSCustomSQLStatementErrorCallback.cpp:
(WebCore::JSSQLStatementErrorCallback::handleEvent):
* bindings/js/JSCustomVoidCallback.cpp:
(WebCore::JSCustomVoidCallback::handleEvent):
* bindings/js/JSCustomXPathNSResolver.cpp:
(WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
* bindings/js/JSErrorHandler.cpp:
(WebCore::JSErrorHandler::handleEvent):
* bindings/js/JSEventCustom.cpp:
(WebCore::toJS):
* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
* bindings/js/JSInjectedScriptHostCustom.cpp:
(WebCore::InjectedScriptHost::nodeAsScriptValue):
(WebCore::JSInjectedScriptHost::inspectedObject):
* bindings/js/JSInjectedScriptManager.cpp:
(WebCore::InjectedScriptManager::createInjectedScript):
(WebCore::InjectedScriptManager::canAccessInspectedWindow):
* bindings/js/JSLazyEventListener.cpp:
(WebCore::JSLazyEventListener::initializeJSFunction):
* bindings/js/JSMainThreadExecState.h:
(WebCore::JSMainThreadExecState::evaluate):
* bindings/js/JSMutationCallbackCustom.cpp:
(WebCore::JSMutationCallback::handleEvent):
* bindings/js/JSNodeFilterCondition.cpp:
(WebCore::JSNodeFilterCondition::acceptNode):
* bindings/js/JSRequestAnimationFrameCallbackCustom.cpp:
(WebCore::JSRequestAnimationFrameCallback::handleEvent):
* bindings/js/JavaScriptCallFrame.cpp:
(WebCore::JavaScriptCallFrame::evaluate):
* bindings/js/PageScriptDebugServer.cpp:
(WebCore::PageScriptDebugServer::recompileAllJSFunctions):
* bindings/js/ScheduledAction.cpp:
(WebCore::ScheduledAction::executeFunctionInContext):
* bindings/js/ScriptCachedFrameData.cpp:
(WebCore::ScriptCachedFrameData::ScriptCachedFrameData):
(WebCore::ScriptCachedFrameData::restore):
(WebCore::ScriptCachedFrameData::clear):
* bindings/js/ScriptController.cpp:
(WebCore::ScriptController::evaluateInWorld):
(WebCore::ScriptController::clearWindowShell):
(WebCore::ScriptController::initScript):
(WebCore::ScriptController::updateDocument):
(WebCore::ScriptController::cacheableBindingRootObject):
(WebCore::ScriptController::bindingRootObject):
(WebCore::ScriptController::windowScriptNPObject):
(WebCore::ScriptController::jsObjectForPluginElement):
(WebCore::ScriptController::clearScriptObjects):
* bindings/js/ScriptControllerMac.mm:
(WebCore::ScriptController::windowScriptObject):
* bindings/js/ScriptDebugServer.cpp:
(WebCore::ScriptDebugServer::dispatchDidPause):
* bindings/js/ScriptEventListener.cpp:
(WebCore::eventListenerHandlerBody):
(WebCore::eventListenerHandlerLocation):
* bindings/js/ScriptFunctionCall.cpp:
(WebCore::ScriptCallArgumentHandler::appendArgument):
(WebCore::ScriptFunctionCall::call):
(WebCore::ScriptFunctionCall::construct):
(WebCore::ScriptCallback::call):
* bindings/js/ScriptObject.cpp:
(WebCore::ScriptGlobalObject::set):
(WebCore::ScriptGlobalObject::get):
(WebCore::ScriptGlobalObject::remove):
* bindings/js/ScriptValue.cpp:
(WebCore::ScriptValue::getString):
(WebCore::ScriptValue::toInspectorValue):
* bindings/js/WorkerScriptController.cpp:
(WebCore::WorkerScriptController::~WorkerScriptController):
(WebCore::WorkerScriptController::initScript):
(WebCore::WorkerScriptController::evaluate):
(WebCore::WorkerScriptController::disableEval):
* bindings/objc/WebScriptObject.mm:
(_didExecute):
(-[WebScriptObject callWebScriptMethod:withArguments:]):
(-[WebScriptObject evaluateWebScript:]):
(-[WebScriptObject setValue:forKey:]):
(-[WebScriptObject valueForKey:]):
(-[WebScriptObject removeWebScriptKey:]):
(-[WebScriptObject hasWebScriptKey:]):
(-[WebScriptObject stringRepresentation]):
(-[WebScriptObject webScriptValueAtIndex:]):
(-[WebScriptObject setWebScriptValueAtIndex:value:]):
(+[WebScriptObject _convertValueToObjcValue:originRootObject:rootObject:]):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateCallbackImplementation):
* bindings/scripts/test/JS/JSTestCallback.cpp:
(WebCore::JSTestCallback::callbackWithNoParam):
(WebCore::JSTestCallback::callbackWithClass1Param):
(WebCore::JSTestCallback::callbackWithClass2Param):
(WebCore::JSTestCallback::callbackWithStringList):
(WebCore::JSTestCallback::callbackWithBoolean):
(WebCore::JSTestCallback::callbackRequiresThisToPass):
* bridge/NP_jsobject.cpp:
(_NPN_InvokeDefault):
(_NPN_Invoke):
(_NPN_Evaluate):
(_NPN_GetProperty):
(_NPN_SetProperty):
(_NPN_RemoveProperty):
(_NPN_HasProperty):
(_NPN_HasMethod):
(_NPN_Enumerate):
(_NPN_Construct):
* bridge/c/c_class.cpp:
(JSC::Bindings::CClass::~CClass):
(JSC::Bindings::CClass::methodsNamed):
(JSC::Bindings::CClass::fieldNamed):
* bridge/c/c_instance.cpp:
(JSC::Bindings::CInstance::moveGlobalExceptionToExecState):
(JSC::Bindings::CInstance::invokeMethod):
(JSC::Bindings::CInstance::invokeDefaultMethod):
(JSC::Bindings::CInstance::invokeConstruct):
(JSC::Bindings::CInstance::getPropertyNames):
* bridge/c/c_runtime.cpp:
(JSC::Bindings::CField::valueFromInstance):
(JSC::Bindings::CField::setValueToInstance):
* bridge/c/c_utility.cpp:
(JSC::Bindings::convertValueToNPVariant):
(JSC::Bindings::convertNPVariantToValue):
* bridge/jni/jni_jsobject.mm:
(JavaJSObject::call):
(JavaJSObject::eval):
(JavaJSObject::getMember):
(JavaJSObject::setMember):
(JavaJSObject::removeMember):
(JavaJSObject::getSlot):
(JavaJSObject::setSlot):
(JavaJSObject::toString):
(JavaJSObject::convertValueToJObject):
(JavaJSObject::convertJObjectToValue):
* bridge/jni/jni_objc.mm:
(JSC::Bindings::dispatchJNICall):
* bridge/jni/jsc/JNIUtilityPrivate.cpp:
(JSC::Bindings::convertValueToJValue):
* bridge/jni/jsc/JavaClassJSC.cpp:
(JavaClass::JavaClass):
(JavaClass::~JavaClass):
* bridge/jni/jsc/JavaInstanceJSC.cpp:
(JavaInstance::stringValue):
* bridge/jni/jsc/JavaMethodJSC.cpp:
(appendClassName):
(JavaMethod::signature):
* bridge/jni/jsc/JavaStringJSC.h:
(JSC::Bindings::JavaString::JavaString):
(JSC::Bindings::JavaString::~JavaString):
(JSC::Bindings::JavaString::utf8):
(JSC::Bindings::JavaString::init):
* bridge/jsc/BridgeJSC.cpp:
(JSC::Bindings::Instance::createRuntimeObject):
(JSC::Bindings::Instance::newRuntimeObject):
* bridge/objc/objc_instance.mm:
(ObjcInstance::moveGlobalExceptionToExecState):
(ObjcInstance::invokeObjcMethod):
(ObjcInstance::invokeDefaultMethod):
(ObjcInstance::setValueOfUndefinedField):
(ObjcInstance::getValueOfUndefinedField):
* bridge/objc/objc_runtime.mm:
(JSC::Bindings::ObjcField::valueFromInstance):
(JSC::Bindings::ObjcField::setValueToInstance):
* bridge/objc/objc_utility.mm:
(JSC::Bindings::convertValueToObjcValue):
(JSC::Bindings::convertNSStringToString):
(JSC::Bindings::convertObjcValueToValue):
* bridge/qt/qt_instance.cpp:
(JSC::Bindings::QtInstance::~QtInstance):
(JSC::Bindings::QtInstance::getQtInstance):
(JSC::Bindings::QtInstance::newRuntimeObject):
* bridge/qt/qt_pixmapruntime.cpp:
(JSC::Bindings::QtPixmapInstance::createPixmapRuntimeObject):
* bridge/qt/qt_runtime.cpp:
(JSC::Bindings::convertValueToQVariant):
(JSC::Bindings::convertQVariantToValue):
(JSC::Bindings::QtRuntimeMetaMethod::call):
(JSC::Bindings::QtRuntimeConnectionMethod::call):
* bridge/qt/qt_runtime_qt4.cpp:
(JSC::Bindings::convertValueToQVariant):
(JSC::Bindings::convertQVariantToValue):
(JSC::Bindings::QtRuntimeMetaMethod::call):
(JSC::Bindings::QtRuntimeConnectionMethod::call):
* bridge/runtime_root.cpp:
(JSC::Bindings::RootObject::gcProtect):
(JSC::Bindings::RootObject::gcUnprotect):
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::createImageBuffer):
* html/HTMLImageLoader.cpp:
(WebCore::HTMLImageLoader::notifyFinished):
* plugins/PluginView.cpp:
(WebCore::PluginView::start):
(WebCore::PluginView::stop):
(WebCore::PluginView::performRequest):
(WebCore::PluginView::npObject):
(WebCore::PluginView::privateBrowsingStateChanged):
* plugins/blackberry/PluginViewBlackBerry.cpp:
(WebCore::PluginView::dispatchNPEvent):
(WebCore::PluginView::setNPWindowIfNeeded):
(WebCore::PluginView::platformStart):
(WebCore::PluginView::getWindowInfo):
* plugins/efl/PluginViewEfl.cpp:
(WebCore::PluginView::dispatchNPEvent):
* plugins/gtk/PluginViewGtk.cpp:
(WebCore::PluginView::dispatchNPEvent):
(WebCore::PluginView::handleKeyboardEvent):
(WebCore::PluginView::handleMouseEvent):
(WebCore::PluginView::setNPWindowIfNeeded):
(WebCore::PluginView::platformStart):
* plugins/mac/PluginViewMac.mm:
(WebCore::PluginView::setNPWindowIfNeeded):
(WebCore::PluginView::dispatchNPEvent):
* plugins/qt/PluginViewQt.cpp:
(WebCore::PluginView::dispatchNPEvent):
(WebCore::PluginView::setNPWindowIfNeeded):
(WebCore::PluginView::platformStart):
* plugins/win/PluginViewWin.cpp:
(WebCore::PluginView::dispatchNPEvent):
(WebCore::PluginView::handleKeyboardEvent):
(WebCore::PluginView::handleMouseEvent):
(WebCore::PluginView::setNPWindowRect):
* testing/js/WebCoreTestSupport.cpp:
(WebCoreTestSupport::injectInternalsObject):
(WebCoreTestSupport::resetInternalsObject):
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::dropProtection):

Source/WebKit/blackberry:

Changed all sites that used JSLock to instead use the new JSLockHolder
and pass in the correct JS context that the code is about to interact with that
needs protection. Also added a couple JSLocks to places that didn't already
have it that needed it.

* Api/BlackBerryGlobal.cpp:
(BlackBerry::WebKit::clearMemoryCaches):
* WebCoreSupport/ClientExtension.cpp:
* WebCoreSupport/PagePopupBlackBerry.cpp:
(WebCore::PagePopupBlackBerry::installDomFunction):
* WebKitSupport/DumpRenderTreeSupport.cpp:
(DumpRenderTreeSupport::computedStyleIncludingVisitedInfo):

Source/WebKit/efl:

Changed all sites that used JSLock to instead use the new JSLockHolder
and pass in the correct JS context that the code is about to interact with that
needs protection. Also added a couple JSLocks to places that didn't already
have it that needed it.

* ewk/ewk_frame.cpp:
(ewk_frame_script_execute):
* ewk/ewk_view.cpp:
(ewk_view_js_object_add):

Source/WebKit/gtk:

Changed all sites that used JSLock to instead use the new JSLockHolder
and pass in the correct JS context that the code is about to interact with that
needs protection. Also added a couple JSLocks to places that didn't already
have it that needed it.

* WebCoreSupport/DumpRenderTreeSupportGtk.cpp:
(DumpRenderTreeSupportGtk::gcCountJavascriptObjects):

Source/WebKit/mac:

Changed all sites that used JSLock to instead use the new JSLockHolder
and pass in the correct JS context that the code is about to interact with that
needs protection. Also added a couple JSLocks to places that didn't already
have it that needed it.

* DOM/WebDOMOperations.mm:
(JSC):
* Misc/WebCoreStatistics.mm:
(+[WebCoreStatistics javaScriptObjectsCount]):
(+[WebCoreStatistics javaScriptGlobalObjectsCount]):
(+[WebCoreStatistics javaScriptProtectedObjectsCount]):
(+[WebCoreStatistics javaScriptProtectedGlobalObjectsCount]):
(+[WebCoreStatistics javaScriptProtectedObjectTypeCounts]):
(+[WebCoreStatistics javaScriptObjectTypeCounts]):
(+[WebCoreStatistics shouldPrintExceptions]):
(+[WebCoreStatistics setShouldPrintExceptions:]):
(+[WebCoreStatistics memoryStatistics]):
(+[WebCoreStatistics javaScriptReferencedObjectsCount]):
* Plugins/Hosted/NetscapePluginInstanceProxy.mm:
(WebKit::NetscapePluginInstanceProxy::evaluate):
(WebKit::NetscapePluginInstanceProxy::invoke):
(WebKit::NetscapePluginInstanceProxy::invokeDefault):
(WebKit::NetscapePluginInstanceProxy::construct):
(WebKit::NetscapePluginInstanceProxy::getProperty):
(WebKit::NetscapePluginInstanceProxy::setProperty):
(WebKit::NetscapePluginInstanceProxy::removeProperty):
(WebKit::NetscapePluginInstanceProxy::hasMethod):
(WebKit::NetscapePluginInstanceProxy::enumerate):
(WebKit::NetscapePluginInstanceProxy::addValueToArray):
(WebKit::NetscapePluginInstanceProxy::moveGlobalExceptionToExecState):
* Plugins/WebNetscapePluginStream.mm:
(WebNetscapePluginStream::wantsAllStreams):
* Plugins/WebNetscapePluginView.mm:
(-[WebNetscapePluginView sendEvent:isDrawRect:]):
(-[WebNetscapePluginView privateBrowsingModeDidChange]):
(-[WebNetscapePluginView setWindowIfNecessary]):
(-[WebNetscapePluginView createPluginScriptableObject]):
(-[WebNetscapePluginView getFormValue:]):
(-[WebNetscapePluginView evaluateJavaScriptPluginRequest:]):
(-[WebNetscapePluginView webFrame:didFinishLoadWithReason:]):
(-[WebNetscapePluginView loadPluginRequest:]):
(-[WebNetscapePluginView _printedPluginBitmap]):
* Plugins/WebPluginController.mm:
(+[WebPluginController plugInViewWithArguments:fromPluginPackage:]):
(-[WebPluginController stopOnePlugin:]):
(-[WebPluginController destroyOnePlugin:]):
(-[WebPluginController startAllPlugins]):
(-[WebPluginController addPlugin:]):
* WebView/WebFrame.mm:
(-[WebFrame _stringByEvaluatingJavaScriptFromString:forceUserGesture:]):
(-[WebFrame _stringByEvaluatingJavaScriptFromString:withGlobalObject:inScriptWorld:]):
* WebView/WebScriptDebugDelegate.mm:
(-[WebScriptCallFrame scopeChain]):
(-[WebScriptCallFrame evaluateWebScript:]):
* WebView/WebView.mm:
(+[WebView _reportException:inContext:]):
(-[WebView aeDescByEvaluatingJavaScriptFromString:]):
(-[WebView _computedStyleIncludingVisitedInfo:forElement:]):

Source/WebKit/qt:

Changed all sites that used JSLock to instead use the new JSLockHolder
and pass in the correct JS context that the code is about to interact with that
needs protection. Also added a couple JSLocks to places that didn't already
have it that needed it.

* Api/qwebframe.cpp:
(QWebFramePrivate::addQtSenderToGlobalObject):
(QWebFrame::addToJavaScriptWindowObject):
* WebCoreSupport/DumpRenderTreeSupportQt.cpp:
(DumpRenderTreeSupportQt::injectInternalsObject):
(DumpRenderTreeSupportQt::resetInternalsObject):

Source/WebKit/win:

Changed all sites that used JSLock to instead use the new JSLockHolder
and pass in the correct JS context that the code is about to interact with that
needs protection. Also added a couple JSLocks to places that didn't already
have it that needed it.

* WebCoreStatistics.cpp:
(WebCoreStatistics::javaScriptObjectsCount):
(WebCoreStatistics::javaScriptGlobalObjectsCount):
(WebCoreStatistics::javaScriptProtectedObjectsCount):
(WebCoreStatistics::javaScriptProtectedGlobalObjectsCount):
(WebCoreStatistics::javaScriptProtectedObjectTypeCounts):
* WebFrame.cpp:
(WebFrame::stringByEvaluatingJavaScriptInScriptWorld):
* WebJavaScriptCollector.cpp:
(WebJavaScriptCollector::objectCount):
* WebView.cpp:
(WebView::stringByEvaluatingJavaScriptFromString):
(WebView::reportException):
(WebView::elementFromJS):

Source/WebKit2:

Changed all sites that used JSLock to instead use the new JSLockHolder
and pass in the correct JS context that the code is about to interact with that
needs protection. Also added a couple JSLocks to places that didn't already
have it that needed it.

* Shared/mac/WebMemorySampler.mac.mm:
(WebKit::WebMemorySampler::sampleWebKit):
* WebProcess/InjectedBundle/InjectedBundle.cpp:
(WebKit::InjectedBundle::javaScriptObjectsCount):
(WebKit::InjectedBundle::reportException):
* WebProcess/Plugins/Netscape/JSNPObject.cpp:
(WebKit::JSNPObject::callMethod):
(WebKit::JSNPObject::callObject):
(WebKit::JSNPObject::callConstructor):
(WebKit::JSNPObject::put):
(WebKit::JSNPObject::deleteProperty):
(WebKit::JSNPObject::getOwnPropertyNames):
(WebKit::JSNPObject::propertyGetter):
* WebProcess/Plugins/Netscape/NPJSObject.cpp:
(WebKit::NPJSObject::hasMethod):
(WebKit::NPJSObject::invoke):
(WebKit::NPJSObject::invokeDefault):
(WebKit::NPJSObject::hasProperty):
(WebKit::NPJSObject::getProperty):
(WebKit::NPJSObject::setProperty):
(WebKit::NPJSObject::removeProperty):
(WebKit::NPJSObject::enumerate):
(WebKit::NPJSObject::construct):
* WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp:
(WebKit::NPRuntimeObjectMap::convertJSValueToNPVariant):
(WebKit::NPRuntimeObjectMap::evaluate):
(WebKit::NPRuntimeObjectMap::moveGlobalExceptionToExecState):
* WebProcess/WebPage/WebFrame.cpp:
(WebKit::WebFrame::jsWrapperForWorld):
(WebKit::WebFrame::computedStyleIncludingVisitedInfo):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::runJavaScriptInMainFrame):
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::getWebCoreStatistics):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@121381 268f45cc-cd09-0410-ab3c-d52691b4dbfc

122 files changed:
Source/JavaScriptCore/API/APIShims.h
Source/JavaScriptCore/API/JSContextRef.cpp
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
Source/JavaScriptCore/heap/CopiedSpace.cpp
Source/JavaScriptCore/heap/Heap.cpp
Source/JavaScriptCore/heap/Heap.h
Source/JavaScriptCore/heap/HeapTimer.cpp
Source/JavaScriptCore/heap/HeapTimer.h
Source/JavaScriptCore/heap/IncrementalSweeper.cpp
Source/JavaScriptCore/heap/IncrementalSweeper.h
Source/JavaScriptCore/heap/MarkedAllocator.cpp
Source/JavaScriptCore/heap/WeakBlock.cpp
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/runtime/Completion.cpp
Source/JavaScriptCore/runtime/GCActivityCallback.h
Source/JavaScriptCore/runtime/JSGlobalData.cpp
Source/JavaScriptCore/runtime/JSGlobalData.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSLock.cpp
Source/JavaScriptCore/runtime/JSLock.h
Source/JavaScriptCore/runtime/WeakGCMap.h
Source/JavaScriptCore/testRegExp.cpp
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/GCController.cpp
Source/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
Source/WebCore/bindings/js/JSCustomVoidCallback.cpp
Source/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
Source/WebCore/bindings/js/JSErrorHandler.cpp
Source/WebCore/bindings/js/JSEventCustom.cpp
Source/WebCore/bindings/js/JSEventListener.cpp
Source/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp
Source/WebCore/bindings/js/JSInjectedScriptManager.cpp
Source/WebCore/bindings/js/JSLazyEventListener.cpp
Source/WebCore/bindings/js/JSMainThreadExecState.h
Source/WebCore/bindings/js/JSMutationCallbackCustom.cpp
Source/WebCore/bindings/js/JSNodeFilterCondition.cpp
Source/WebCore/bindings/js/JSRequestAnimationFrameCallbackCustom.cpp
Source/WebCore/bindings/js/JavaScriptCallFrame.cpp
Source/WebCore/bindings/js/PageScriptDebugServer.cpp
Source/WebCore/bindings/js/ScheduledAction.cpp
Source/WebCore/bindings/js/ScriptCachedFrameData.cpp
Source/WebCore/bindings/js/ScriptController.cpp
Source/WebCore/bindings/js/ScriptControllerMac.mm
Source/WebCore/bindings/js/ScriptDebugServer.cpp
Source/WebCore/bindings/js/ScriptEventListener.cpp
Source/WebCore/bindings/js/ScriptFunctionCall.cpp
Source/WebCore/bindings/js/ScriptObject.cpp
Source/WebCore/bindings/js/ScriptValue.cpp
Source/WebCore/bindings/js/WorkerScriptController.cpp
Source/WebCore/bindings/objc/WebScriptObject.mm
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestCallback.cpp
Source/WebCore/bridge/NP_jsobject.cpp
Source/WebCore/bridge/c/c_class.cpp
Source/WebCore/bridge/c/c_instance.cpp
Source/WebCore/bridge/c/c_runtime.cpp
Source/WebCore/bridge/c/c_utility.cpp
Source/WebCore/bridge/jni/jni_jsobject.mm
Source/WebCore/bridge/jni/jni_objc.mm
Source/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp
Source/WebCore/bridge/jni/jsc/JavaClassJSC.cpp
Source/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp
Source/WebCore/bridge/jni/jsc/JavaMethodJSC.cpp
Source/WebCore/bridge/jni/jsc/JavaStringJSC.h
Source/WebCore/bridge/jsc/BridgeJSC.cpp
Source/WebCore/bridge/objc/objc_instance.mm
Source/WebCore/bridge/objc/objc_runtime.mm
Source/WebCore/bridge/objc/objc_utility.mm
Source/WebCore/bridge/qt/qt_instance.cpp
Source/WebCore/bridge/qt/qt_pixmapruntime.cpp
Source/WebCore/bridge/qt/qt_runtime.cpp
Source/WebCore/bridge/qt/qt_runtime_qt4.cpp
Source/WebCore/bridge/runtime_root.cpp
Source/WebCore/html/HTMLCanvasElement.cpp
Source/WebCore/html/HTMLImageLoader.cpp
Source/WebCore/plugins/PluginView.cpp
Source/WebCore/plugins/blackberry/PluginViewBlackBerry.cpp
Source/WebCore/plugins/efl/PluginViewEfl.cpp
Source/WebCore/plugins/gtk/PluginViewGtk.cpp
Source/WebCore/plugins/mac/PluginViewMac.mm
Source/WebCore/plugins/qt/PluginViewQt.cpp
Source/WebCore/plugins/win/PluginViewWin.cpp
Source/WebCore/testing/js/WebCoreTestSupport.cpp
Source/WebCore/xml/XMLHttpRequest.cpp
Source/WebKit/blackberry/Api/BlackBerryGlobal.cpp
Source/WebKit/blackberry/ChangeLog
Source/WebKit/blackberry/WebCoreSupport/ClientExtension.cpp
Source/WebKit/blackberry/WebCoreSupport/PagePopupBlackBerry.cpp
Source/WebKit/blackberry/WebKitSupport/DumpRenderTreeSupport.cpp
Source/WebKit/efl/ChangeLog
Source/WebKit/efl/ewk/ewk_frame.cpp
Source/WebKit/efl/ewk/ewk_view.cpp
Source/WebKit/gtk/ChangeLog
Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/DOM/WebDOMOperations.mm
Source/WebKit/mac/Misc/WebCoreStatistics.mm
Source/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
Source/WebKit/mac/Plugins/WebNetscapePluginStream.mm
Source/WebKit/mac/Plugins/WebNetscapePluginView.mm
Source/WebKit/mac/Plugins/WebPluginController.mm
Source/WebKit/mac/WebView/WebFrame.mm
Source/WebKit/mac/WebView/WebScriptDebugDelegate.mm
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit/qt/Api/qwebframe.cpp
Source/WebKit/qt/ChangeLog
Source/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp
Source/WebKit/win/ChangeLog
Source/WebKit/win/WebCoreStatistics.cpp
Source/WebKit/win/WebFrame.cpp
Source/WebKit/win/WebJavaScriptCollector.cpp
Source/WebKit/win/WebView.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/mac/WebMemorySampler.mac.mm
Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp
Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp
Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp
Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp
Source/WebKit2/WebProcess/WebPage/WebFrame.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebProcess.cpp

index 0249511..ef5f104 100644 (file)
 
 #include "CallFrame.h"
 #include "GCActivityCallback.h"
+#include "IncrementalSweeper.h"
 #include "JSLock.h"
 #include <wtf/WTFThreadData.h>
 
 namespace JSC {
 
 class APIEntryShimWithoutLock {
+public:
+    enum RefGlobalDataTag { DontRefGlobalData = 0, RefGlobalData };
+
 protected:
-    APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread)
-        : m_globalData(globalData)
+    APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread, RefGlobalDataTag shouldRefGlobalData)
+        : m_shouldRefGlobalData(shouldRefGlobalData)
+        , m_globalData(globalData)
         , m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(globalData->identifierTable))
     {
+        if (shouldRefGlobalData)
+            m_globalData->ref();
         UNUSED_PARAM(registerThread);
         if (registerThread)
             globalData->heap.machineThreads().addCurrentThread();
         m_globalData->heap.activityCallback()->synchronize();
-        m_globalData->timeoutChecker.start();
+        m_globalData->heap.sweeper()->synchronize();
     }
 
     ~APIEntryShimWithoutLock()
     {
-        m_globalData->timeoutChecker.stop();
         wtfThreadData().setCurrentIdentifierTable(m_entryIdentifierTable);
+        if (m_shouldRefGlobalData)
+            m_globalData->deref();
     }
 
-private:
+protected:
+    RefGlobalDataTag m_shouldRefGlobalData;
     JSGlobalData* m_globalData;
     IdentifierTable* m_entryIdentifierTable;
 };
@@ -61,20 +70,38 @@ class APIEntryShim : public APIEntryShimWithoutLock {
 public:
     // Normal API entry
     APIEntryShim(ExecState* exec, bool registerThread = true)
-        : APIEntryShimWithoutLock(&exec->globalData(), registerThread)
-        , m_lock(exec)
+        : APIEntryShimWithoutLock(&exec->globalData(), registerThread, RefGlobalData)
+    {
+        init();
+    }
+
+    // This constructor is necessary for HeapTimer to prevent it from accidentally resurrecting 
+    // the ref count of a "dead" JSGlobalData.
+    APIEntryShim(JSGlobalData* globalData, RefGlobalDataTag refGlobalData, bool registerThread = true)
+        : APIEntryShimWithoutLock(globalData, registerThread, refGlobalData)
     {
+        init();
     }
 
     // JSPropertyNameAccumulator only has a globalData.
     APIEntryShim(JSGlobalData* globalData, bool registerThread = true)
-        : APIEntryShimWithoutLock(globalData, registerThread)
-        , m_lock(globalData->isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
+        : APIEntryShimWithoutLock(globalData, registerThread, RefGlobalData)
     {
+        init();
+    }
+
+    ~APIEntryShim()
+    {
+        m_globalData->timeoutChecker.stop();
+        m_globalData->apiLock().unlock();
     }
 
 private:
-    JSLock m_lock;
+    void init()
+    {
+        m_globalData->apiLock().lock();
+        m_globalData->timeoutChecker.start();
+    }
 };
 
 class APICallbackShim {
@@ -88,7 +115,6 @@ public:
 
     ~APICallbackShim()
     {
-        m_globalData->heap.activityCallback()->synchronize();
         wtfThreadData().setCurrentIdentifierTable(m_globalData->identifierTable);
     }
 
index 92e03a6..7a57287 100644 (file)
@@ -78,7 +78,6 @@ JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
     // If the application was linked before JSGlobalContextCreate was changed to use a unique JSGlobalData,
     // we use a shared one for backwards compatibility.
     if (NSVersionOfLinkTimeLibrary("JavaScriptCore") <= webkitFirstVersionWithConcurrentGlobalContexts) {
-        JSLock lock(LockForReal);
         return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass);
     }
 #endif // OS(DARWIN)
@@ -90,11 +89,9 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
 {
     initializeThreading();
 
-    JSLock lock(LockForReal);
     RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createContextGroup(ThreadStackTypeSmall);
 
     APIEntryShim entryShim(globalData.get(), false);
-
     globalData->makeUsableFromMultipleThreads();
 
     if (!globalObjectClass) {
@@ -124,18 +121,19 @@ JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
 
 void JSGlobalContextRelease(JSGlobalContextRef ctx)
 {
+    IdentifierTable* savedIdentifierTable;
     ExecState* exec = toJS(ctx);
-    JSLock lock(exec);
+    {
+        JSLockHolder lock(exec);
 
-    JSGlobalData& globalData = exec->globalData();
-    IdentifierTable* savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable);
+        JSGlobalData& globalData = exec->globalData();
+        savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable);
 
-    bool protectCountIsZero = Heap::heap(exec->dynamicGlobalObject())->unprotect(exec->dynamicGlobalObject());
-    if (protectCountIsZero) {
-        globalData.heap.activityCallback()->synchronize();
-        globalData.heap.reportAbandonedObjectGraph();
+        bool protectCountIsZero = Heap::heap(exec->dynamicGlobalObject())->unprotect(exec->dynamicGlobalObject());
+        if (protectCountIsZero)
+            globalData.heap.reportAbandonedObjectGraph();
+        globalData.deref();
     }
-    globalData.deref();
 
     wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable);
 }
@@ -166,7 +164,7 @@ JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx)
 JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize)
 {
     ExecState* exec = toJS(ctx);
-    JSLock lock(exec);
+    JSLockHolder lock(exec);
 
     unsigned count = 0;
     UStringBuilder builder;
index 88dc4d0..bb32a89 100644 (file)
@@ -1,3 +1,122 @@
+2012-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSLock should be per-JSGlobalData
+        https://bugs.webkit.org/show_bug.cgi?id=89123
+
+        Reviewed by Geoffrey Garen.
+
+        * API/APIShims.h:
+        (APIEntryShimWithoutLock):
+        (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): Added an extra parameter to the constructor to 
+        determine whether we should ref the JSGlobalData or not. We want to ref all the time except for in the 
+        HeapTimer class because timerDidFire could run after somebody has started to tear down that particular 
+        JSGlobalData, so we wouldn't want to resurrect the ref count of that JSGlobalData from 0 back to 1 after 
+        its destruction has begun. 
+        (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
+        (JSC::APIEntryShim::APIEntryShim):
+        (APIEntryShim):
+        (JSC::APIEntryShim::~APIEntryShim):
+        (JSC::APIEntryShim::init): Factored out common initialization code for the various APIEntryShim constructors.
+        Also moved the timeoutChecker stop and start here because we need to start after we've grabbed the API lock
+        and before we've released it, which can only done in APIEntryShim.
+        (JSC::APICallbackShim::~APICallbackShim): We no longer need to synchronize here.
+        * API/JSContextRef.cpp:
+        (JSGlobalContextCreate):
+        (JSGlobalContextCreateInGroup):
+        (JSGlobalContextRelease):
+        (JSContextCreateBacktrace):
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+        * heap/CopiedSpace.cpp:
+        (JSC::CopiedSpace::tryAllocateSlowCase):
+        * heap/Heap.cpp:
+        (JSC::Heap::protect):
+        (JSC::Heap::unprotect):
+        (JSC::Heap::collect):
+        (JSC::Heap::setActivityCallback):
+        (JSC::Heap::activityCallback):
+        (JSC::Heap::sweeper):
+        * heap/Heap.h: Changed m_activityCallback and m_sweeper to be raw pointers rather than OwnPtrs because they 
+        are now responsible for their own lifetime. Also changed the order of declaration of the GCActivityCallback
+        and the IncrementalSweeper to make sure they're the last things that get initialized during construction to 
+        prevent any issues with uninitialized memory in the JSGlobalData/Heap they might care about.
+        (Heap):
+        * heap/HeapTimer.cpp: Refactored to allow for thread-safe operation and shutdown.
+        (JSC::HeapTimer::~HeapTimer):
+        (JSC::HeapTimer::invalidate):
+        (JSC):
+        (JSC::HeapTimer::didStartVMShutdown): Called at the beginning of ~JSGlobalData. If we're on the same thread 
+        that the HeapTimer is running on, we kill the HeapTimer ourselves. If not, then we set some state in the 
+        HeapTimer and schedule it to fire immediately so that it can notice and kill itself.
+        (JSC::HeapTimer::timerDidFire): We grab our mutex and check our JSGlobalData pointer. If it has been zero-ed
+        out, then we know the VM has started to shutdown and we should kill ourselves. Otherwise, grab the APIEntryShim,
+        but without ref-ing the JSGlobalData (we don't want to bring the JSGlobalData's ref-count from 0 to 1) in case 
+        we were interrupted between releasing our mutex and trying to grab the APILock.
+        * heap/HeapTimer.h:
+        (HeapTimer):
+        * heap/IncrementalSweeper.cpp:
+        (JSC::IncrementalSweeper::doWork): We no longer need the API shim here since HeapTimer::timerDidFire handles 
+        all of that for us. 
+        (JSC::IncrementalSweeper::create):
+        * heap/IncrementalSweeper.h:
+        (IncrementalSweeper):
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::allocateSlowCase):
+        * heap/WeakBlock.cpp:
+        (JSC::WeakBlock::reap):
+        * jsc.cpp:
+        (functionGC):
+        (functionReleaseExecutableMemory):
+        (jscmain):
+        * runtime/Completion.cpp:
+        (JSC::checkSyntax):
+        (JSC::evaluate):
+        * runtime/GCActivityCallback.h:
+        (DefaultGCActivityCallback):
+        (JSC::DefaultGCActivityCallback::create):
+        * runtime/JSGlobalData.cpp:
+        (JSC::JSGlobalData::JSGlobalData):
+        (JSC::JSGlobalData::~JSGlobalData): Signals to the two HeapTimers (GCActivityCallback and IncrementalSweeper)
+        that the VM has started shutting down. It then waits until the HeapTimer is done with whatever activity 
+        it needs to do before continuing with any further destruction. Also asserts that we do not currently hold the 
+        APILock because this could potentially cause deadlock when we try to signal to the HeapTimers using their mutexes.
+        (JSC::JSGlobalData::sharedInstance): Protect the initialization for the shared instance with the GlobalJSLock.
+        (JSC::JSGlobalData::sharedInstanceInternal):
+        * runtime/JSGlobalData.h: Change to be ThreadSafeRefCounted so that we don't have to worry about refing and 
+        de-refing JSGlobalDatas on separate threads since we don't do it that often anyways.
+        (JSGlobalData):
+        (JSC::JSGlobalData::apiLock):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::~JSGlobalObject):
+        (JSC::JSGlobalObject::init):
+        * runtime/JSLock.cpp:
+        (JSC):
+        (JSC::GlobalJSLock::GlobalJSLock): For accessing the shared instance.
+        (JSC::GlobalJSLock::~GlobalJSLock):
+        (JSC::JSLockHolder::JSLockHolder): MutexLocker for JSLock. Also refs the JSGlobalData to keep it alive so that 
+        it can successfully unlock it later without it disappearing from underneath it.
+        (JSC::JSLockHolder::~JSLockHolder):
+        (JSC::JSLock::JSLock):
+        (JSC::JSLock::~JSLock):
+        (JSC::JSLock::lock): Uses the spin lock for guarding the lock count and owner thread fields. Uses the mutex for 
+        actually waiting for long periods. 
+        (JSC::JSLock::unlock):
+        (JSC::JSLock::currentThreadIsHoldingLock):
+        (JSC::JSLock::dropAllLocks):
+        (JSC::JSLock::dropAllLocksUnconditionally):
+        (JSC::JSLock::grabAllLocks):
+        (JSC::JSLock::DropAllLocks::DropAllLocks):
+        (JSC::JSLock::DropAllLocks::~DropAllLocks):
+        * runtime/JSLock.h:
+        (JSC):
+        (GlobalJSLock):
+        (JSLockHolder):
+        (JSLock):
+        (DropAllLocks):
+        * runtime/WeakGCMap.h:
+        (JSC::WeakGCMap::set):
+        * testRegExp.cpp:
+        (realMain):
+
 2012-06-27  Filip Pizlo  <fpizlo@apple.com>
 
         x86 disassembler confuses immediates with addresses
index 6a8a893..b6fcce9 100755 (executable)
@@ -6,11 +6,14 @@ EXPORTS
     ??0Collator@WTF@@QAE@PBD@Z
     ??0DateInstance@JSC@@IAE@PAVExecState@1@PAVStructure@1@@Z
     ??0DefaultGCActivityCallback@JSC@@QAE@PAVHeap@1@@Z
-    ??0DropAllLocks@JSLock@JSC@@QAE@W4JSLockBehavior@2@@Z
+    ??0DropAllLocks@JSLock@JSC@@QAE@PAVExecState@2@@Z
+    ??0DropAllLocks@JSLock@JSC@@QAE@PAVJSGlobalData@2@@Z
     ??0DynamicGlobalObjectScope@JSC@@QAE@AAVJSGlobalData@1@PAVJSGlobalObject@1@@Z 
     ??0InternalFunction@JSC@@IAE@PAVJSGlobalObject@1@PAVStructure@1@@Z
     ??0JSGlobalObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@PBUGlobalObjectMethodTable@1@@Z
-    ??0JSLock@JSC@@QAE@PAVExecState@1@@Z
+    ??0JSLockHolder@JSC@@QAE@AAVJSGlobalData@1@@Z
+    ??0JSLockHolder@JSC@@QAE@PAVExecState@1@@Z
+    ??0JSLockHolder@JSC@@QAE@PAVJSGlobalData@1@@Z
     ??0MD5@WTF@@QAE@XZ
     ??0Mutex@WTF@@QAE@XZ
     ??0ParallelEnvironment@WTF@@QAE@P6AXPAX@ZIH@Z
@@ -33,6 +36,7 @@ EXPORTS
     ??1DropAllLocks@JSLock@JSC@@QAE@XZ
     ??1JSGlobalData@JSC@@QAE@XZ
     ??1JSGlobalObject@JSC@@QAE@XZ
+    ??1JSLockHolder@JSC@@QAE@XZ
     ??1Mutex@WTF@@QAE@XZ
     ??1RefCountedLeakCounter@WTF@@QAE@XZ
     ??1SourceProviderCache@JSC@@QAE@XZ
@@ -124,7 +128,6 @@ EXPORTS
     ?cryptographicallyRandomNumber@WTF@@YAIXZ
     ?cryptographicallyRandomValues@WTF@@YAXPAXI@Z
     ?currentThread@WTF@@YAIXZ
-    ?currentThreadIsHoldingLock@JSLock@JSC@@SA_NXZ
     ?currentTime@WTF@@YANXZ
     ?data@CString@WTF@@QBEPBDXZ
     ?dataLog@WTF@@YAXPBDZZ
@@ -236,10 +239,9 @@ EXPORTS
     ?jsOwnedString@JSC@@YAPAVJSString@1@PAVJSGlobalData@1@ABVUString@1@@Z
     ?jsString@JSC@@YAPAVJSString@1@PAVJSGlobalData@1@ABVUString@1@@Z
     ?length@CString@WTF@@QBEIXZ
-    ?lock@JSLock@JSC@@SAXW4JSLockBehavior@2@@Z
+    ?lock@JSLock@JSC@@QAEXXZ
     ?lock@Mutex@WTF@@QAEXXZ
     ?lockAtomicallyInitializedStaticMutex@WTF@@YAXXZ
-    ?lockCount@JSLock@JSC@@SAHXZ
     ?match@RegExp@JSC@@QAEHAAVJSGlobalData@2@ABVUString@2@IAAV?$Vector@H$0CA@@WTF@@@Z
     ?materializePropertyMap@Structure@JSC@@AAEXAAVJSGlobalData@2@@Z
     ?monotonicallyIncreasingTime@WTF@@YANXZ
@@ -324,6 +326,7 @@ EXPORTS
     ?stopSampling@JSGlobalData@JSC@@QAEXXZ
     ?substringSharingImpl@UString@JSC@@QBE?AV12@II@Z
     ?suggestedNewPropertyStorageSize@Structure@JSC@@QAEIXZ
+    ?sweeper@Heap@JSC@@QAEPAVIncrementalSweeper@2@XZ
     ?synthesizePrototype@JSValue@JSC@@QBEPAVJSObject@2@PAVExecState@2@@Z
     ?thisObject@DebuggerCallFrame@JSC@@QBEPAVJSObject@2@XZ
     ?throwError@JSC@@YA?AVJSValue@1@PAVExecState@1@V21@@Z
@@ -353,7 +356,7 @@ EXPORTS
     ?tryFinishCreationUninitialized@JSArray@JSC@@IAEPAV12@AAVJSGlobalData@2@I@Z
     ?tryLock@Mutex@WTF@@QAE_NXZ
     ?type@DebuggerCallFrame@JSC@@QBE?AW4Type@12@XZ
-    ?unlock@JSLock@JSC@@SAXW4JSLockBehavior@2@@Z
+    ?unlock@JSLock@JSC@@QAEXXZ
     ?unlock@Mutex@WTF@@QAEXXZ
     ?unlockAtomicallyInitializedStaticMutex@WTF@@YAXXZ
     ?unprotect@Heap@JSC@@QAE_NVJSValue@2@@Z
index 631e829..9eb70a5 100644 (file)
@@ -66,6 +66,7 @@ CheckedBoolean CopiedSpace::tryAllocateSlowCase(size_t bytes, void** outPtr)
     if (isOversize(bytes))
         return tryAllocateOversize(bytes, outPtr);
     
+    ASSERT(m_heap->globalData()->apiLock().currentThreadIsHoldingLock());
     m_heap->didAllocate(m_allocator.currentCapacity());
 
     allocateBlock();
index ef062c9..33c6dc1 100644 (file)
@@ -160,15 +160,9 @@ static inline size_t proportionalHeapSize(size_t heapSize, size_t ramSize)
     return 1.25 * heapSize;
 }
 
-static inline bool isValidSharedInstanceThreadState()
+static inline bool isValidSharedInstanceThreadState(JSGlobalData* globalData)
 {
-    if (!JSLock::lockCount())
-        return false;
-
-    if (!JSLock::currentThreadIsHoldingLock())
-        return false;
-
-    return true;
+    return globalData->apiLock().currentThreadIsHoldingLock();
 }
 
 static inline bool isValidThreadState(JSGlobalData* globalData)
@@ -176,7 +170,7 @@ static inline bool isValidThreadState(JSGlobalData* globalData)
     if (globalData->identifierTable != wtfThreadData().currentIdentifierTable())
         return false;
 
-    if (globalData->isSharedInstance() && !isValidSharedInstanceThreadState())
+    if (globalData->isSharedInstance() && !isValidSharedInstanceThreadState(globalData))
         return false;
 
     return true;
@@ -327,7 +321,7 @@ void Heap::didAbandon(size_t bytes)
 void Heap::protect(JSValue k)
 {
     ASSERT(k);
-    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance());
+    ASSERT(m_globalData->apiLock().currentThreadIsHoldingLock());
 
     if (!k.isCell())
         return;
@@ -338,7 +332,7 @@ void Heap::protect(JSValue k)
 bool Heap::unprotect(JSValue k)
 {
     ASSERT(k);
-    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance());
+    ASSERT(m_globalData->apiLock().currentThreadIsHoldingLock());
 
     if (!k.isCell())
         return false;
@@ -692,6 +686,7 @@ void Heap::collect(SweepToggle sweepToggle)
     SamplingRegion samplingRegion("Garbage Collection");
     
     GCPHASE(Collect);
+    ASSERT(globalData()->apiLock().currentThreadIsHoldingLock());
     ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
     ASSERT(m_isSafeToCollect);
     JAVASCRIPTCORE_GC_BEGIN();
@@ -777,19 +772,19 @@ void Heap::collect(SweepToggle sweepToggle)
     JAVASCRIPTCORE_GC_END();
 }
 
-void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)
+void Heap::setActivityCallback(GCActivityCallback* activityCallback)
 {
     m_activityCallback = activityCallback;
 }
 
 GCActivityCallback* Heap::activityCallback()
 {
-    return m_activityCallback.get();
+    return m_activityCallback;
 }
 
 IncrementalSweeper* Heap::sweeper()
 {
-    return m_sweeper.get();
+    return m_sweeper;
 }
 
 void Heap::setGarbageCollectionTimerEnabled(bool enable)
index 91c3aa5..a559f92 100644 (file)
@@ -99,10 +99,10 @@ namespace JSC {
         MachineThreads& machineThreads() { return m_machineThreads; }
 
         JS_EXPORT_PRIVATE GCActivityCallback* activityCallback();
-        JS_EXPORT_PRIVATE void setActivityCallback(PassOwnPtr<GCActivityCallback>);
+        JS_EXPORT_PRIVATE void setActivityCallback(GCActivityCallback*);
         JS_EXPORT_PRIVATE void setGarbageCollectionTimerEnabled(bool);
 
-        IncrementalSweeper* sweeper();
+        JS_EXPORT_PRIVATE IncrementalSweeper* sweeper();
 
         // true if an allocation or collection is in progress
         inline bool isBusy();
@@ -237,10 +237,10 @@ namespace JSC {
         double m_lastGCLength;
         double m_lastCodeDiscardTime;
 
-        OwnPtr<GCActivityCallback> m_activityCallback;
-        OwnPtr<IncrementalSweeper> m_sweeper;
-        
         DoublyLinkedList<ExecutableBase> m_compiledCode;
+        
+        GCActivityCallback* m_activityCallback;
+        IncrementalSweeper* m_sweeper;
     };
 
     inline bool Heap::shouldCollect()
index b4d928a..ae66f9e 100644 (file)
 #include "config.h"
 #include "HeapTimer.h"
 
+#include "APIShims.h"
+#include "JSObject.h"
+#include "JSString.h"
+#include "ScopeChain.h"
 #include <wtf/Threading.h>
 
 namespace JSC {
@@ -46,7 +50,8 @@ HeapTimer::HeapTimer(JSGlobalData* globalData, CFRunLoopRef runLoop)
 
 HeapTimer::~HeapTimer()
 {
-    invalidate();
+    CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
+    CFRunLoopTimerInvalidate(m_timer.get());
 }
 
 void HeapTimer::synchronize()
@@ -60,14 +65,37 @@ void HeapTimer::synchronize()
 
 void HeapTimer::invalidate()
 {
-    CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
-    CFRunLoopTimerInvalidate(m_timer.get());
+    m_globalData = 0;
+    CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() - s_decade);
+}
+
+void HeapTimer::didStartVMShutdown()
+{
+    if (CFRunLoopGetCurrent() == m_runLoop.get()) {
+        invalidate();
+        delete this;
+        return;
+    }
+    ASSERT(!m_globalData->apiLock().currentThreadIsHoldingLock());
+    MutexLocker locker(m_shutdownMutex);
+    invalidate();
 }
 
 void HeapTimer::timerDidFire(CFRunLoopTimerRef, void* info)
 {
     HeapTimer* agent = static_cast<HeapTimer*>(info);
-    agent->doWork();
+    agent->m_shutdownMutex.lock();
+    if (!agent->m_globalData) {
+        agent->m_shutdownMutex.unlock();
+        delete agent;
+        return;
+    }
+    {
+        // We don't ref here to prevent us from resurrecting the ref count of a "dead" JSGlobalData.
+        APIEntryShim shim(agent->m_globalData, APIEntryShimWithoutLock::DontRefGlobalData);
+        agent->doWork();
+    }
+    agent->m_shutdownMutex.unlock();
 }
 
 #else
@@ -81,6 +109,11 @@ HeapTimer::~HeapTimer()
 {
 }
 
+void HeapTimer::didStartVMShutdown()
+{
+    delete this;
+}
+
 void HeapTimer::synchronize()
 {
 }
@@ -89,7 +122,6 @@ void HeapTimer::invalidate()
 {
 }
 
-
 #endif
     
 
index fea0139..9255e06 100644 (file)
@@ -27,6 +27,7 @@
 #define HeapTimer_h
 
 #include <wtf/RetainPtr.h>
+#include <wtf/Threading.h>
 
 #if USE(CF)
 #include <CoreFoundation/CoreFoundation.h>
@@ -46,7 +47,8 @@ public:
 #endif
     
     virtual ~HeapTimer();
-    
+
+    void didStartVMShutdown();
     virtual void synchronize();
     virtual void doWork() = 0;
     
@@ -59,6 +61,8 @@ protected:
     RetainPtr<CFRunLoopTimerRef> m_timer;
     RetainPtr<CFRunLoopRef> m_runLoop;
     CFRunLoopTimerContext m_context;
+
+    Mutex m_shutdownMutex;
 #endif
     
 private:
index 8483773..49222c5 100644 (file)
@@ -45,7 +45,6 @@ static const CFTimeInterval sweepTimeMultiplier = 1.0 / sweepTimeTotal;
 
 void IncrementalSweeper::doWork()
 {
-    APIEntryShim shim(m_globalData);
     doSweep(WTF::monotonicallyIncreasingTime());
 }
     
@@ -55,9 +54,9 @@ IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop)
 {
 }
 
-PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap)
+IncrementalSweeper* IncrementalSweeper::create(Heap* heap)
 {
-    return adoptPtr(new IncrementalSweeper(heap, CFRunLoopGetCurrent()));
+    return new IncrementalSweeper(heap, CFRunLoopGetCurrent());
 }
 
 void IncrementalSweeper::scheduleTimer()
@@ -110,9 +109,9 @@ void IncrementalSweeper::doWork()
 {
 }
 
-PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap)
+IncrementalSweeper* IncrementalSweeper::create(Heap* heap)
 {
-    return adoptPtr(new IncrementalSweeper(heap->globalData()));
+    return new IncrementalSweeper(heap->globalData());
 }
 
 void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>&)
index 20f4e3c..eedfa7f 100644 (file)
@@ -39,7 +39,7 @@ class Heap;
     
 class IncrementalSweeper : public HeapTimer {
 public:
-    static PassOwnPtr<IncrementalSweeper> create(Heap*);
+    static IncrementalSweeper* create(Heap*);
     void startSweeping(const HashSet<MarkedBlock*>& blockSnapshot);
     virtual void doWork();
 
index 9cac906..9727286 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "GCActivityCallback.h"
 #include "Heap.h"
+#include "JSGlobalData.h"
 #include <wtf/CurrentTime.h>
 
 namespace JSC {
@@ -56,6 +57,7 @@ inline void* MarkedAllocator::tryAllocate()
     
 void* MarkedAllocator::allocateSlowCase()
 {
+    ASSERT(m_heap->globalData()->apiLock().currentThreadIsHoldingLock());
 #if COLLECT_ON_EVERY_ALLOCATION
     m_heap->collectAllGarbage();
     ASSERT(m_heap->m_operationInProgress == NoOperation);
index 8900e73..05a44ea 100644 (file)
@@ -127,8 +127,10 @@ void WeakBlock::reap()
         if (weakImpl->state() > WeakImpl::Dead)
             continue;
 
-        if (Heap::isMarked(weakImpl->jsValue().asCell()))
+        if (Heap::isMarked(weakImpl->jsValue().asCell())) {
+            ASSERT(weakImpl->state() == WeakImpl::Live);
             continue;
+        }
 
         weakImpl->setState(WeakImpl::Dead);
     }
index f796333..35ea01f 100644 (file)
@@ -299,7 +299,7 @@ EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState* exec)
 
 EncodedJSValue JSC_HOST_CALL functionGC(ExecState* exec)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     exec->heap()->collectAllGarbage();
     return JSValue::encode(jsUndefined());
 }
@@ -307,7 +307,7 @@ EncodedJSValue JSC_HOST_CALL functionGC(ExecState* exec)
 #ifndef NDEBUG
 EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState* exec)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     exec->globalData().releaseExecutableMemory();
     return JSValue::encode(jsUndefined());
 }
@@ -667,9 +667,9 @@ static void parseArguments(int argc, char** argv, CommandLine& options)
 
 int jscmain(int argc, char** argv)
 {
-    JSLock lock(SilenceAssertionsOnly);
-
+    
     RefPtr<JSGlobalData> globalData = JSGlobalData::create(ThreadStackTypeLarge, LargeHeap);
+    JSLockHolder lock(globalData.get());
 
     CommandLine options;
     parseArguments(argc, argv, options);
index 311d660..1c35b96 100644 (file)
@@ -37,7 +37,7 @@ namespace JSC {
 
 bool checkSyntax(ExecState* exec, const SourceCode& source, JSValue* returnedException)
 {
-    JSLock lock(exec);
+    JSLockHolder lock(exec);
     ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
 
     ProgramExecutable* program = ProgramExecutable::create(exec, source);
@@ -53,7 +53,7 @@ bool checkSyntax(ExecState* exec, const SourceCode& source, JSValue* returnedExc
 
 JSValue evaluate(ExecState* exec, ScopeChainNode* scopeChain, const SourceCode& source, JSValue thisValue, JSValue* returnedException)
 {
-    JSLock lock(exec);
+    JSLockHolder lock(exec);
     ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
     if (exec->globalData().isCollectorBusy())
         CRASH();
index 18bbd31..67ee174 100644 (file)
@@ -69,7 +69,7 @@ protected:
 
 class DefaultGCActivityCallback : public GCActivityCallback {
 public:
-    static PassOwnPtr<DefaultGCActivityCallback> create(Heap*);
+    static DefaultGCActivityCallback* create(Heap*);
 
     DefaultGCActivityCallback(Heap*);
 
@@ -91,9 +91,9 @@ private:
 #endif
 };
 
-inline PassOwnPtr<DefaultGCActivityCallback> DefaultGCActivityCallback::create(Heap* heap)
+inline DefaultGCActivityCallback* DefaultGCActivityCallback::create(Heap* heap)
 {
-    return adoptPtr(new DefaultGCActivityCallback(heap));
+    return new DefaultGCActivityCallback(heap);
 }
 
 }
index 1fb90df..4476bd6 100644 (file)
 #include "CommonIdentifiers.h"
 #include "DebuggerActivation.h"
 #include "FunctionConstructor.h"
+#include "GCActivityCallback.h"
 #include "GetterSetter.h"
 #include "HostCallReturnValue.h"
+#include "IncrementalSweeper.h"
 #include "Interpreter.h"
 #include "JSActivation.h"
 #include "JSAPIValueWrapper.h"
@@ -178,12 +180,9 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
 {
     interpreter = new Interpreter;
 
-    if (isSharedInstance())
-        turnOffVerifier();
-
     // Need to be careful to keep everything consistent here
+    JSLockHolder lock(this);
     IdentifierTable* existingEntryIdentifierTable = wtfThreadData().setCurrentIdentifierTable(identifierTable);
-    JSLock lock(SilenceAssertionsOnly);
     structureStructure.set(*this, Structure::createStructure(*this));
     debuggerActivationStructure.set(*this, DebuggerActivation::createStructure(*this, 0, jsNull()));
     activationStructure.set(*this, JSActivation::createStructure(*this, 0, jsNull()));
@@ -222,6 +221,9 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
 
 JSGlobalData::~JSGlobalData()
 {
+    ASSERT(!m_apiLock.currentThreadIsHoldingLock());
+    heap.activityCallback()->didStartVMShutdown();
+    heap.sweeper()->didStartVMShutdown();
     heap.lastChanceToFinalize();
 
     delete interpreter;
@@ -311,6 +313,7 @@ bool JSGlobalData::sharedInstanceExists()
 
 JSGlobalData& JSGlobalData::sharedInstance()
 {
+    GlobalJSLock globalLock;
     JSGlobalData*& instance = sharedInstanceInternal();
     if (!instance) {
         instance = adoptRef(new JSGlobalData(APIShared, ThreadStackTypeSmall, SmallHeap)).leakRef();
@@ -321,7 +324,6 @@ JSGlobalData& JSGlobalData::sharedInstance()
 
 JSGlobalData*& JSGlobalData::sharedInstanceInternal()
 {
-    ASSERT(JSLock::currentThreadIsHoldingLock());
     static JSGlobalData* sharedInstance;
     return sharedInstance;
 }
index f883310..fcbee15 100644 (file)
@@ -35,6 +35,7 @@
 #include "Heap.h"
 #include "Intrinsic.h"
 #include "JITStubs.h"
+#include "JSLock.h"
 #include "JSValue.h"
 #include "LLIntData.h"
 #include "NumericStrings.h"
@@ -46,8 +47,8 @@
 #include <wtf/BumpPointerAllocator.h>
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
-#include <wtf/RefCounted.h>
 #include <wtf/SimpleStats.h>
+#include <wtf/ThreadSafeRefCounted.h>
 #include <wtf/ThreadSpecific.h>
 #include <wtf/WTFThreadData.h>
 #if ENABLE(REGEXP_TRACING)
@@ -152,7 +153,7 @@ namespace JSC {
     };
 #endif
 
-    class JSGlobalData : public RefCounted<JSGlobalData> {
+    class JSGlobalData : public ThreadSafeRefCounted<JSGlobalData> {
     public:
         // WebCore has a one-to-one mapping of threads to JSGlobalDatas;
         // either create() or createLeaked() should only be called once
@@ -180,6 +181,10 @@ namespace JSC {
 
         void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
 
+    private:
+        JSLock m_apiLock;
+
+    public:
         Heap heap; // The heap is our first data member to ensure that it's destructed after all the objects that reference it.
 
         GlobalDataType globalDataType;
@@ -409,6 +414,8 @@ namespace JSC {
         registerTypedArrayFunction(float64, Float64);
 #undef registerTypedArrayFunction
 
+        JSLock& apiLock() { return m_apiLock; }
+
     private:
         friend class LLIntOffsetsExtractor;
         
index d19db4f..c1a4dc8 100644 (file)
@@ -123,8 +123,6 @@ JSGlobalObject::JSGlobalObject(JSGlobalData& globalData, Structure* structure, c
 
 JSGlobalObject::~JSGlobalObject()
 {
-    ASSERT(JSLock::currentThreadIsHoldingLock());
-
     if (m_debugger)
         m_debugger->detach(this);
 
@@ -139,7 +137,7 @@ void JSGlobalObject::destroy(JSCell* cell)
 
 void JSGlobalObject::init(JSObject* thisValue)
 {
-    ASSERT(JSLock::currentThreadIsHoldingLock());
+    ASSERT(globalData().apiLock().currentThreadIsHoldingLock());
     
     m_globalScopeChain.set(globalData(), this, ScopeChainNode::create(0, this, &globalData(), this, thisValue));
 
index 90e2f5d..be30c0c 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "Heap.h"
 #include "CallFrame.h"
+#include "JSGlobalObject.h"
 #include "JSObject.h"
 #include "ScopeChain.h"
 
@@ -37,95 +38,96 @@ namespace JSC {
 // So it's safe to disable it on non-mac platforms where we don't have native pthreads.
 #if (OS(DARWIN) || USE(PTHREADS))
 
-// Acquire this mutex before accessing lock-related data.
-static pthread_mutex_t JSMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t sharedInstanceLock = PTHREAD_MUTEX_INITIALIZER;
 
-// Thread-specific key that tells whether a thread holds the JSMutex, and how many times it was taken recursively.
-pthread_key_t JSLockCount;
+GlobalJSLock::GlobalJSLock()
+{
+    pthread_mutex_lock(&sharedInstanceLock);
+}
 
-static void createJSLockCount()
+GlobalJSLock::~GlobalJSLock()
 {
-    pthread_key_create(&JSLockCount, 0);
+    pthread_mutex_unlock(&sharedInstanceLock);
 }
 
-pthread_once_t createJSLockCountOnce = PTHREAD_ONCE_INIT;
+JSLockHolder::JSLockHolder(ExecState* exec)
+    : m_globalData(&exec->globalData())
+{
+    m_globalData->apiLock().lock();
+}
 
-// Lock nesting count.
-intptr_t JSLock::lockCount()
+JSLockHolder::JSLockHolder(JSGlobalData* globalData)
+    : m_globalData(globalData)
 {
-    pthread_once(&createJSLockCountOnce, createJSLockCount);
+    m_globalData->apiLock().lock();
+}
 
-    return reinterpret_cast<intptr_t>(pthread_getspecific(JSLockCount));
+JSLockHolder::JSLockHolder(JSGlobalData& globalData)
+    : m_globalData(&globalData)
+{
+    m_globalData->apiLock().lock();
 }
 
-static void setLockCount(intptr_t count)
+JSLockHolder::~JSLockHolder()
 {
-    ASSERT(count >= 0);
-    pthread_setspecific(JSLockCount, reinterpret_cast<void*>(count));
+    m_globalData->apiLock().unlock();
 }
 
-JSLock::JSLock(ExecState* exec)
-    : m_lockBehavior(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
+JSLock::JSLock()
+    : m_lockCount(0)
 {
-    lock(m_lockBehavior);
+    m_spinLock.Init();
 }
 
-JSLock::JSLock(JSGlobalData* globalData)
-    : m_lockBehavior(globalData->isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
+JSLock::~JSLock()
 {
-    lock(m_lockBehavior);
 }
 
-void JSLock::lock(JSLockBehavior lockBehavior)
+void JSLock::lock()
 {
-#ifdef NDEBUG
-    // Locking "not for real" is a debug-only feature.
-    if (lockBehavior == SilenceAssertionsOnly)
-        return;
-#endif
+    ThreadIdentifier currentThread = WTF::currentThread();
+    {
+        SpinLockHolder holder(&m_spinLock);
+        if (m_ownerThread == currentThread && m_lockCount) {
+            m_lockCount++;
+            return;
+        }
+    }
 
-    pthread_once(&createJSLockCountOnce, createJSLockCount);
+    m_lock.lock();
 
-    intptr_t currentLockCount = lockCount();
-    if (!currentLockCount && lockBehavior == LockForReal) {
-        int result = pthread_mutex_lock(&JSMutex);
-        ASSERT_UNUSED(result, !result);
+    {
+        SpinLockHolder holder(&m_spinLock);
+        m_ownerThread = currentThread;
+        ASSERT(!m_lockCount);
+        m_lockCount = 1;
     }
-    setLockCount(currentLockCount + 1);
 }
 
-void JSLock::unlock(JSLockBehavior lockBehavior)
+void JSLock::unlock()
 {
-    ASSERT(lockCount());
+    ASSERT(currentThreadIsHoldingLock());
 
-#ifdef NDEBUG
-    // Locking "not for real" is a debug-only feature.
-    if (lockBehavior == SilenceAssertionsOnly)
-        return;
-#endif
+    SpinLockHolder holder(&m_spinLock);
+    m_lockCount--;
 
-    intptr_t newLockCount = lockCount() - 1;
-    setLockCount(newLockCount);
-    if (!newLockCount && lockBehavior == LockForReal) {
-        int result = pthread_mutex_unlock(&JSMutex);
-        ASSERT_UNUSED(result, !result);
-    }
+    if (!m_lockCount)
+        m_lock.unlock();
 }
 
 void JSLock::lock(ExecState* exec)
 {
-    lock(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly);
+    exec->globalData().apiLock().lock();
 }
 
 void JSLock::unlock(ExecState* exec)
 {
-    unlock(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly);
+    exec->globalData().apiLock().unlock();
 }
 
 bool JSLock::currentThreadIsHoldingLock()
 {
-    pthread_once(&createJSLockCountOnce, createJSLockCount);
-    return !!pthread_getspecific(JSLockCount);
+    return m_lockCount && m_ownerThread == WTF::currentThread();
 }
 
 // This is fairly nasty.  We allow multiple threads to run on the same
@@ -149,7 +151,7 @@ bool JSLock::currentThreadIsHoldingLock()
 // this to happen, and were its stack to grow further, then it may potentially
 // write over the second thread's call frames.
 //
-// In avoid JS stack corruption we enforce a policy of only ever allowing two
+// To avoid JS stack corruption we enforce a policy of only ever allowing two
 // threads to use a JS context concurrently, and only allowing the second of
 // these threads to execute until it has completed and fully returned from its
 // outermost call into JSC.  We enforce this policy using 'lockDropDepth'.  The
@@ -158,7 +160,7 @@ bool JSLock::currentThreadIsHoldingLock()
 // same thread again, enter JSC (through evaluate script or call function), and exit
 // again through a callback, then the locks will not be dropped when DropAllLocks
 // is called (since lockDropDepth is non-zero).  Since this thread is still holding
-// the locks, only it will re able to re-enter JSC (either be returning from the
+// the locks, only it will be able to re-enter JSC (either be returning from the
 // callback, or by re-entering through another call to evaulate script or call
 // function).
 //
@@ -168,61 +170,84 @@ bool JSLock::currentThreadIsHoldingLock()
 // order in which they were made - though implementing the less restrictive policy
 // would likely increase complexity and overhead.
 //
-static unsigned lockDropDepth = 0;
 
-JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
-    : m_lockBehavior(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
+// This function returns the number of locks that were dropped.
+unsigned JSLock::dropAllLocks()
 {
-    pthread_once(&createJSLockCountOnce, createJSLockCount);
+    if (m_lockDropDepth++)
+        return 0;
 
-    if (lockDropDepth++) {
-        m_lockCount = 0;
-        return;
-    }
+    return dropAllLocksUnconditionally();
+}
+
+unsigned JSLock::dropAllLocksUnconditionally()
+{
+    unsigned lockCount = m_lockCount;
+    for (unsigned i = 0; i < lockCount; i++)
+        unlock();
 
-    m_lockCount = JSLock::lockCount();
-    for (intptr_t i = 0; i < m_lockCount; i++)
-        JSLock::unlock(m_lockBehavior);
+    return lockCount;
 }
 
-JSLock::DropAllLocks::DropAllLocks(JSLockBehavior JSLockBehavior)
-    : m_lockBehavior(JSLockBehavior)
+void JSLock::grabAllLocks(unsigned lockCount)
 {
-    pthread_once(&createJSLockCountOnce, createJSLockCount);
+    for (unsigned i = 0; i < lockCount; i++)
+        lock();
 
-    if (lockDropDepth++) {
-        m_lockCount = 0;
-        return;
-    }
+    m_lockDropDepth--;
+}
 
-    // It is necessary to drop even "unreal" locks, because having a non-zero lock count
-    // will prevent a real lock from being taken.
+JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
+    : m_lockCount(0)
+    , m_globalData(&exec->globalData())
+{
+    m_lockCount = m_globalData->apiLock().dropAllLocks();
+}
 
-    m_lockCount = JSLock::lockCount();
-    for (intptr_t i = 0; i < m_lockCount; i++)
-        JSLock::unlock(m_lockBehavior);
+JSLock::DropAllLocks::DropAllLocks(JSGlobalData* globalData)
+    : m_lockCount(0)
+    , m_globalData(globalData)
+{
+    m_lockCount = m_globalData->apiLock().dropAllLocks();
 }
 
 JSLock::DropAllLocks::~DropAllLocks()
 {
-    for (intptr_t i = 0; i < m_lockCount; i++)
-        JSLock::lock(m_lockBehavior);
-
-    --lockDropDepth;
+    m_globalData->apiLock().grabAllLocks(m_lockCount);
 }
 
 #else // (OS(DARWIN) || USE(PTHREADS))
 
-JSLock::JSLock(ExecState*)
-    : m_lockBehavior(SilenceAssertionsOnly)
+GlobalJSLock::GlobalJSLock()
+{
+}
+
+GlobalJSLock::~GlobalJSLock()
+{
+}
+
+JSLockHolder::JSLockHolder(JSGlobalData*)
 {
 }
 
-// If threading support is off, set the lock count to a constant value of 1 so ssertions
-// that the lock is held don't fail
-intptr_t JSLock::lockCount()
+JSLockHolder::JSLockHolder(JSGlobalData&)
+{
+}
+
+JSLockHolder::JSLockHolder(ExecState*)
+{
+}
+
+JSLockHolder::~JSLockHolder()
+{
+}
+
+JSLock::JSLock()
+{
+}
+
+JSLock::~JSLock()
 {
-    return 1;
 }
 
 bool JSLock::currentThreadIsHoldingLock()
@@ -230,11 +255,11 @@ bool JSLock::currentThreadIsHoldingLock()
     return true;
 }
 
-void JSLock::lock(JSLockBehavior)
+void JSLock::lock()
 {
 }
 
-void JSLock::unlock(JSLockBehavior)
+void JSLock::unlock()
 {
 }
 
@@ -246,11 +271,33 @@ void JSLock::unlock(ExecState*)
 {
 }
 
+void JSLock::lock(JSGlobalData&)
+{
+}
+
+void JSLock::unlock(JSGlobalData&)
+{
+}
+
+unsigned JSLock::dropAllLocks()
+{
+    return 0;
+}
+
+unsigned JSLock::dropAllLocksUnconditionally()
+{
+    return 0;
+}
+
+void JSLock::grabAllLocks(unsigned)
+{
+}
+
 JSLock::DropAllLocks::DropAllLocks(ExecState*)
 {
 }
 
-JSLock::DropAllLocks::DropAllLocks(JSLockBehavior)
+JSLock::DropAllLocks::DropAllLocks(JSGlobalData*)
 {
 }
 
index a0eb969..94108d0 100644 (file)
@@ -23,6 +23,9 @@
 
 #include <wtf/Assertions.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/RefPtr.h>
+#include <wtf/TCSpinLock.h>
+#include <wtf/Threading.h>
 
 namespace JSC {
 
@@ -30,8 +33,9 @@ namespace JSC {
     // important to lock before doing anything that allocates a
     // JavaScript data structure or that interacts with shared state
     // such as the protect count hash table. The simplest way to lock
-    // is to create a local JSLock object in the scope where the lock 
-    // must be held. The lock is recursive so nesting is ok. The JSLock 
+    // is to create a local JSLockHolder object in the scope where the lock 
+    // must be held and pass it the context that requires protection. 
+    // The lock is recursive so nesting is ok. The JSLock 
     // object also acts as a convenience short-hand for running important
     // initialization routines.
 
@@ -44,62 +48,65 @@ namespace JSC {
     // DropAllLocks object takes care to release the JSLock only if your
     // thread acquired it to begin with.
 
-    // For contexts other than the single shared one, implicit locking is not done,
-    // but we still need to perform all the counting in order to keep debug
-    // assertions working, so that clients that use the shared context don't break.
-
     class ExecState;
     class JSGlobalData;
 
-    enum JSLockBehavior { SilenceAssertionsOnly, LockForReal };
+    // This class is used to protect the initialization of the legacy single 
+    // shared JSGlobalData.
+    class GlobalJSLock {
+        WTF_MAKE_NONCOPYABLE(GlobalJSLock);
+    public:
+        JS_EXPORT_PRIVATE GlobalJSLock();
+        JS_EXPORT_PRIVATE ~GlobalJSLock();
+    };
+
+    class JSLockHolder {
+    public:
+        JS_EXPORT_PRIVATE JSLockHolder(JSGlobalData*);
+        JS_EXPORT_PRIVATE JSLockHolder(JSGlobalData&);
+        JS_EXPORT_PRIVATE JSLockHolder(ExecState*);
+
+        JS_EXPORT_PRIVATE ~JSLockHolder();
+    private:
+        RefPtr<JSGlobalData> m_globalData;
+    };
 
     class JSLock {
         WTF_MAKE_NONCOPYABLE(JSLock);
     public:
-        JS_EXPORT_PRIVATE JSLock(ExecState*);
-        JSLock(JSGlobalData*);
-
-        JSLock(JSLockBehavior lockBehavior)
-            : m_lockBehavior(lockBehavior)
-        {
-#ifdef NDEBUG
-            // Locking "not for real" is a debug-only feature.
-            if (lockBehavior == SilenceAssertionsOnly)
-                return;
-#endif
-            lock(lockBehavior);
-        }
-
-        ~JSLock()
-        { 
-#ifdef NDEBUG
-            // Locking "not for real" is a debug-only feature.
-            if (m_lockBehavior == SilenceAssertionsOnly)
-                return;
-#endif
-            unlock(m_lockBehavior); 
-        }
-        
-        JS_EXPORT_PRIVATE static void lock(JSLockBehavior);
-        JS_EXPORT_PRIVATE static void unlock(JSLockBehavior);
+        JSLock();
+        JS_EXPORT_PRIVATE ~JSLock();
+
+        JS_EXPORT_PRIVATE void lock();
+        JS_EXPORT_PRIVATE void unlock();
+
         static void lock(ExecState*);
         static void unlock(ExecState*);
+        static void lock(JSGlobalData&);
+        static void unlock(JSGlobalData&);
+
+        JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
 
-        JS_EXPORT_PRIVATE static intptr_t lockCount();
-        JS_EXPORT_PRIVATE static bool currentThreadIsHoldingLock();
+        unsigned dropAllLocks();
+        unsigned dropAllLocksUnconditionally();
+        void grabAllLocks(unsigned lockCount);
 
-        JSLockBehavior m_lockBehavior;
+        SpinLock m_spinLock;
+        Mutex m_lock;
+        ThreadIdentifier m_ownerThread;
+        intptr_t m_lockCount;
+        unsigned m_lockDropDepth;
 
         class DropAllLocks {
             WTF_MAKE_NONCOPYABLE(DropAllLocks);
         public:
             JS_EXPORT_PRIVATE DropAllLocks(ExecState* exec);
-            JS_EXPORT_PRIVATE DropAllLocks(JSLockBehavior);
+            JS_EXPORT_PRIVATE DropAllLocks(JSGlobalData*);
             JS_EXPORT_PRIVATE ~DropAllLocks();
             
         private:
             intptr_t m_lockCount;
-            JSLockBehavior m_lockBehavior;
+            RefPtr<JSGlobalData> m_globalData;
         };
     };
 
index 9e8db4d..6926165 100644 (file)
@@ -75,8 +75,9 @@ public:
         return HandleTypes<MappedType>::getFromSlot(const_cast<JSValue*>(&impl->jsValue()));
     }
 
-    void set(JSGlobalData&, const KeyType& key, ExternalType value)
+    void set(JSGlobalData& globalData, const KeyType& key, ExternalType value)
     {
+        ASSERT_UNUSED(globalData, globalData.apiLock().currentThreadIsHoldingLock());
         typename MapType::AddResult result = m_map.add(key, 0);
         if (!result.isNewEntry)
             WeakSet::deallocate(result.iterator->second);
index 6899ac2..61c21c3 100644 (file)
@@ -495,9 +495,8 @@ static void parseArguments(int argc, char** argv, CommandLine& options)
 
 int realMain(int argc, char** argv)
 {
-    JSLock lock(SilenceAssertionsOnly);
-
     RefPtr<JSGlobalData> globalData = JSGlobalData::create(ThreadStackTypeLarge, LargeHeap);
+    JSLockHolder lock(globalData.get());
 
     CommandLine options;
     parseArguments(argc, argv, options);
index 6dc0996..6cf4d2e 100755 (executable)
@@ -1,3 +1,246 @@
+2012-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSLock should be per-JSGlobalData
+        https://bugs.webkit.org/show_bug.cgi?id=89123
+
+        Reviewed by Geoffrey Garen.
+
+        No new tests. Current regression tests are sufficient.
+
+        Changed all sites that used JSLock to instead use the new JSLockHolder
+        and pass in the correct JS context that the code is about to interact with that 
+        needs protection. Also added a couple JSLocks to places that didn't already 
+        have it that needed it.
+
+        * bindings/js/GCController.cpp:
+        (WebCore::collect):
+        (WebCore::GCController::garbageCollectSoon):
+        (WebCore::GCController::garbageCollectNow):
+        (WebCore::GCController::discardAllCompiledCode):
+        * bindings/js/JSCustomSQLStatementErrorCallback.cpp:
+        (WebCore::JSSQLStatementErrorCallback::handleEvent):
+        * bindings/js/JSCustomVoidCallback.cpp:
+        (WebCore::JSCustomVoidCallback::handleEvent):
+        * bindings/js/JSCustomXPathNSResolver.cpp:
+        (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
+        * bindings/js/JSErrorHandler.cpp:
+        (WebCore::JSErrorHandler::handleEvent):
+        * bindings/js/JSEventCustom.cpp:
+        (WebCore::toJS):
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::JSEventListener::handleEvent):
+        * bindings/js/JSInjectedScriptHostCustom.cpp:
+        (WebCore::InjectedScriptHost::nodeAsScriptValue):
+        (WebCore::JSInjectedScriptHost::inspectedObject):
+        * bindings/js/JSInjectedScriptManager.cpp:
+        (WebCore::InjectedScriptManager::createInjectedScript):
+        (WebCore::InjectedScriptManager::canAccessInspectedWindow):
+        * bindings/js/JSLazyEventListener.cpp:
+        (WebCore::JSLazyEventListener::initializeJSFunction):
+        * bindings/js/JSMainThreadExecState.h:
+        (WebCore::JSMainThreadExecState::evaluate):
+        * bindings/js/JSMutationCallbackCustom.cpp:
+        (WebCore::JSMutationCallback::handleEvent):
+        * bindings/js/JSNodeFilterCondition.cpp:
+        (WebCore::JSNodeFilterCondition::acceptNode):
+        * bindings/js/JSRequestAnimationFrameCallbackCustom.cpp:
+        (WebCore::JSRequestAnimationFrameCallback::handleEvent):
+        * bindings/js/JavaScriptCallFrame.cpp:
+        (WebCore::JavaScriptCallFrame::evaluate):
+        * bindings/js/PageScriptDebugServer.cpp:
+        (WebCore::PageScriptDebugServer::recompileAllJSFunctions):
+        * bindings/js/ScheduledAction.cpp:
+        (WebCore::ScheduledAction::executeFunctionInContext):
+        * bindings/js/ScriptCachedFrameData.cpp:
+        (WebCore::ScriptCachedFrameData::ScriptCachedFrameData):
+        (WebCore::ScriptCachedFrameData::restore):
+        (WebCore::ScriptCachedFrameData::clear):
+        * bindings/js/ScriptController.cpp:
+        (WebCore::ScriptController::evaluateInWorld):
+        (WebCore::ScriptController::clearWindowShell):
+        (WebCore::ScriptController::initScript):
+        (WebCore::ScriptController::updateDocument):
+        (WebCore::ScriptController::cacheableBindingRootObject):
+        (WebCore::ScriptController::bindingRootObject):
+        (WebCore::ScriptController::windowScriptNPObject):
+        (WebCore::ScriptController::jsObjectForPluginElement):
+        (WebCore::ScriptController::clearScriptObjects):
+        * bindings/js/ScriptControllerMac.mm:
+        (WebCore::ScriptController::windowScriptObject):
+        * bindings/js/ScriptDebugServer.cpp:
+        (WebCore::ScriptDebugServer::dispatchDidPause):
+        * bindings/js/ScriptEventListener.cpp:
+        (WebCore::eventListenerHandlerBody):
+        (WebCore::eventListenerHandlerLocation):
+        * bindings/js/ScriptFunctionCall.cpp:
+        (WebCore::ScriptCallArgumentHandler::appendArgument):
+        (WebCore::ScriptFunctionCall::call):
+        (WebCore::ScriptFunctionCall::construct):
+        (WebCore::ScriptCallback::call):
+        * bindings/js/ScriptObject.cpp:
+        (WebCore::ScriptGlobalObject::set):
+        (WebCore::ScriptGlobalObject::get):
+        (WebCore::ScriptGlobalObject::remove):
+        * bindings/js/ScriptValue.cpp:
+        (WebCore::ScriptValue::getString):
+        (WebCore::ScriptValue::toInspectorValue):
+        * bindings/js/WorkerScriptController.cpp:
+        (WebCore::WorkerScriptController::~WorkerScriptController):
+        (WebCore::WorkerScriptController::initScript):
+        (WebCore::WorkerScriptController::evaluate):
+        (WebCore::WorkerScriptController::disableEval):
+        * bindings/objc/WebScriptObject.mm:
+        (_didExecute):
+        (-[WebScriptObject callWebScriptMethod:withArguments:]):
+        (-[WebScriptObject evaluateWebScript:]):
+        (-[WebScriptObject setValue:forKey:]):
+        (-[WebScriptObject valueForKey:]):
+        (-[WebScriptObject removeWebScriptKey:]):
+        (-[WebScriptObject hasWebScriptKey:]):
+        (-[WebScriptObject stringRepresentation]):
+        (-[WebScriptObject webScriptValueAtIndex:]):
+        (-[WebScriptObject setWebScriptValueAtIndex:value:]):
+        (+[WebScriptObject _convertValueToObjcValue:originRootObject:rootObject:]):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateCallbackImplementation):
+        * bindings/scripts/test/JS/JSTestCallback.cpp:
+        (WebCore::JSTestCallback::callbackWithNoParam):
+        (WebCore::JSTestCallback::callbackWithClass1Param):
+        (WebCore::JSTestCallback::callbackWithClass2Param):
+        (WebCore::JSTestCallback::callbackWithStringList):
+        (WebCore::JSTestCallback::callbackWithBoolean):
+        (WebCore::JSTestCallback::callbackRequiresThisToPass):
+        * bridge/NP_jsobject.cpp:
+        (_NPN_InvokeDefault):
+        (_NPN_Invoke):
+        (_NPN_Evaluate):
+        (_NPN_GetProperty):
+        (_NPN_SetProperty):
+        (_NPN_RemoveProperty):
+        (_NPN_HasProperty):
+        (_NPN_HasMethod):
+        (_NPN_Enumerate):
+        (_NPN_Construct):
+        * bridge/c/c_class.cpp:
+        (JSC::Bindings::CClass::~CClass):
+        (JSC::Bindings::CClass::methodsNamed):
+        (JSC::Bindings::CClass::fieldNamed):
+        * bridge/c/c_instance.cpp:
+        (JSC::Bindings::CInstance::moveGlobalExceptionToExecState):
+        (JSC::Bindings::CInstance::invokeMethod):
+        (JSC::Bindings::CInstance::invokeDefaultMethod):
+        (JSC::Bindings::CInstance::invokeConstruct):
+        (JSC::Bindings::CInstance::getPropertyNames):
+        * bridge/c/c_runtime.cpp:
+        (JSC::Bindings::CField::valueFromInstance):
+        (JSC::Bindings::CField::setValueToInstance):
+        * bridge/c/c_utility.cpp:
+        (JSC::Bindings::convertValueToNPVariant):
+        (JSC::Bindings::convertNPVariantToValue):
+        * bridge/jni/jni_jsobject.mm:
+        (JavaJSObject::call):
+        (JavaJSObject::eval):
+        (JavaJSObject::getMember):
+        (JavaJSObject::setMember):
+        (JavaJSObject::removeMember):
+        (JavaJSObject::getSlot):
+        (JavaJSObject::setSlot):
+        (JavaJSObject::toString):
+        (JavaJSObject::convertValueToJObject):
+        (JavaJSObject::convertJObjectToValue):
+        * bridge/jni/jni_objc.mm:
+        (JSC::Bindings::dispatchJNICall):
+        * bridge/jni/jsc/JNIUtilityPrivate.cpp:
+        (JSC::Bindings::convertValueToJValue):
+        * bridge/jni/jsc/JavaClassJSC.cpp:
+        (JavaClass::JavaClass):
+        (JavaClass::~JavaClass):
+        * bridge/jni/jsc/JavaInstanceJSC.cpp:
+        (JavaInstance::stringValue):
+        * bridge/jni/jsc/JavaMethodJSC.cpp:
+        (appendClassName):
+        (JavaMethod::signature):
+        * bridge/jni/jsc/JavaStringJSC.h:
+        (JSC::Bindings::JavaString::JavaString):
+        (JSC::Bindings::JavaString::~JavaString):
+        (JSC::Bindings::JavaString::utf8):
+        (JSC::Bindings::JavaString::init):
+        * bridge/jsc/BridgeJSC.cpp:
+        (JSC::Bindings::Instance::createRuntimeObject):
+        (JSC::Bindings::Instance::newRuntimeObject):
+        * bridge/objc/objc_instance.mm:
+        (ObjcInstance::moveGlobalExceptionToExecState):
+        (ObjcInstance::invokeObjcMethod):
+        (ObjcInstance::invokeDefaultMethod):
+        (ObjcInstance::setValueOfUndefinedField):
+        (ObjcInstance::getValueOfUndefinedField):
+        * bridge/objc/objc_runtime.mm:
+        (JSC::Bindings::ObjcField::valueFromInstance):
+        (JSC::Bindings::ObjcField::setValueToInstance):
+        * bridge/objc/objc_utility.mm:
+        (JSC::Bindings::convertValueToObjcValue):
+        (JSC::Bindings::convertNSStringToString):
+        (JSC::Bindings::convertObjcValueToValue):
+        * bridge/qt/qt_instance.cpp:
+        (JSC::Bindings::QtInstance::~QtInstance):
+        (JSC::Bindings::QtInstance::getQtInstance):
+        (JSC::Bindings::QtInstance::newRuntimeObject):
+        * bridge/qt/qt_pixmapruntime.cpp:
+        (JSC::Bindings::QtPixmapInstance::createPixmapRuntimeObject):
+        * bridge/qt/qt_runtime.cpp:
+        (JSC::Bindings::convertValueToQVariant):
+        (JSC::Bindings::convertQVariantToValue):
+        (JSC::Bindings::QtRuntimeMetaMethod::call):
+        (JSC::Bindings::QtRuntimeConnectionMethod::call):
+        * bridge/qt/qt_runtime_qt4.cpp:
+        (JSC::Bindings::convertValueToQVariant):
+        (JSC::Bindings::convertQVariantToValue):
+        (JSC::Bindings::QtRuntimeMetaMethod::call):
+        (JSC::Bindings::QtRuntimeConnectionMethod::call):
+        * bridge/runtime_root.cpp:
+        (JSC::Bindings::RootObject::gcProtect):
+        (JSC::Bindings::RootObject::gcUnprotect):
+        * html/HTMLCanvasElement.cpp:
+        (WebCore::HTMLCanvasElement::createImageBuffer):
+        * html/HTMLImageLoader.cpp:
+        (WebCore::HTMLImageLoader::notifyFinished):
+        * plugins/PluginView.cpp:
+        (WebCore::PluginView::start):
+        (WebCore::PluginView::stop):
+        (WebCore::PluginView::performRequest):
+        (WebCore::PluginView::npObject):
+        (WebCore::PluginView::privateBrowsingStateChanged):
+        * plugins/blackberry/PluginViewBlackBerry.cpp:
+        (WebCore::PluginView::dispatchNPEvent):
+        (WebCore::PluginView::setNPWindowIfNeeded):
+        (WebCore::PluginView::platformStart):
+        (WebCore::PluginView::getWindowInfo):
+        * plugins/efl/PluginViewEfl.cpp:
+        (WebCore::PluginView::dispatchNPEvent):
+        * plugins/gtk/PluginViewGtk.cpp:
+        (WebCore::PluginView::dispatchNPEvent):
+        (WebCore::PluginView::handleKeyboardEvent):
+        (WebCore::PluginView::handleMouseEvent):
+        (WebCore::PluginView::setNPWindowIfNeeded):
+        (WebCore::PluginView::platformStart):
+        * plugins/mac/PluginViewMac.mm:
+        (WebCore::PluginView::setNPWindowIfNeeded):
+        (WebCore::PluginView::dispatchNPEvent):
+        * plugins/qt/PluginViewQt.cpp:
+        (WebCore::PluginView::dispatchNPEvent):
+        (WebCore::PluginView::setNPWindowIfNeeded):
+        (WebCore::PluginView::platformStart):
+        * plugins/win/PluginViewWin.cpp:
+        (WebCore::PluginView::dispatchNPEvent):
+        (WebCore::PluginView::handleKeyboardEvent):
+        (WebCore::PluginView::handleMouseEvent):
+        (WebCore::PluginView::setNPWindowRect):
+        * testing/js/WebCoreTestSupport.cpp:
+        (WebCoreTestSupport::injectInternalsObject):
+        (WebCoreTestSupport::resetInternalsObject):
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::dropProtection):
+
 2012-06-27  Tony Chang  <tony@chromium.org>
 
         Split flex into flex-grow/flex-shrink/flex-basis
index 96dadf3..7950968 100644 (file)
@@ -38,7 +38,7 @@ namespace WebCore {
 
 static void collect(void*)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     JSDOMWindow::commonJSGlobalData()->heap.collectAllGarbage();
 }
 
@@ -63,7 +63,7 @@ void GCController::garbageCollectSoon()
     // down into WTF so that more platforms can take advantage of it, we will be 
     // able to use reportAbandonedObjectGraph on more platforms.
 #if USE(CF)
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     JSDOMWindow::commonJSGlobalData()->heap.reportAbandonedObjectGraph();
 #else
     if (!m_GCTimer.isActive())
@@ -80,7 +80,7 @@ void GCController::gcTimerFired(Timer<GCController>*)
 
 void GCController::garbageCollectNow()
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     if (!JSDOMWindow::commonJSGlobalData()->heap.isBusy())
         JSDOMWindow::commonJSGlobalData()->heap.collectAllGarbage();
 }
@@ -104,7 +104,7 @@ void GCController::setJavaScriptGarbageCollectorTimerEnabled(bool enable)
 
 void GCController::discardAllCompiledCode()
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     JSDOMWindow::commonJSGlobalData()->heap.deleteAllCompiledCode();
 }
 
index 17bd910..34c28e9 100644 (file)
@@ -48,7 +48,7 @@ bool JSSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLEr
 
     RefPtr<JSSQLStatementErrorCallback> protect(this);
 
-    JSC::JSLock lock(SilenceAssertionsOnly);
+    JSC::JSLockHolder lock(m_data->globalObject()->globalData());
 
     ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
index f830f5c..5d421ba 100644 (file)
@@ -63,7 +63,7 @@ void JSCustomVoidCallback::handleEvent()
 
     RefPtr<JSCustomVoidCallback> protect(this);
         
-    JSC::JSLock lock(SilenceAssertionsOnly);
+    JSC::JSLockHolder lock(m_data->globalObject()->globalData());
     MarkedArgumentBuffer args;
     m_data->invokeCallback(args);
 }
index bdaf0d5..a897b6f 100644 (file)
@@ -67,7 +67,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
 {
     ASSERT(m_customResolver);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
 
     ExecState* exec = m_globalObject->globalExec();
         
index e292d29..5b4b59f 100644 (file)
@@ -63,7 +63,7 @@ void JSErrorHandler::handleEvent(ScriptExecutionContext* scriptExecutionContext,
 
     ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(scriptExecutionContext->globalData());
 
     JSObject* jsFunction = this->jsFunction(scriptExecutionContext);
     if (!jsFunction)
index b891f89..fdc75c7 100644 (file)
@@ -54,7 +54,7 @@ JSValue JSEvent::clipboardData(ExecState* exec) const
 
 JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     if (!event)
         return jsNull();
index ab28ca8..0a557f7 100644 (file)
@@ -75,7 +75,7 @@ void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext
     if (!scriptExecutionContext || scriptExecutionContext->isJSExecutionForbidden())
         return;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(scriptExecutionContext->globalData());
 
     JSObject* jsFunction = this->jsFunction(scriptExecutionContext);
     if (!jsFunction)
index a1d286a..3f09352 100644 (file)
@@ -82,7 +82,7 @@ Node* InjectedScriptHost::scriptValueAsNode(ScriptValue value)
 
 ScriptValue InjectedScriptHost::nodeAsScriptValue(ScriptState* state, Node* node)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(state);
     return ScriptValue(state->globalData(), toJS(state, deprecatedGlobalObjectForPrototype(state), node));
 }
 
@@ -95,7 +95,7 @@ JSValue JSInjectedScriptHost::inspectedObject(ExecState* exec)
     if (!object)
         return jsUndefined();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     ScriptValue scriptValue = object->get(exec);
     if (scriptValue.hasNoValue())
         return jsUndefined();
index 138193b..b237744 100644 (file)
@@ -51,7 +51,7 @@ namespace WebCore {
 
 ScriptObject InjectedScriptManager::createInjectedScript(const String& source, ScriptState* scriptState, int id)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(scriptState);
 
     SourceCode sourceCode = makeSource(stringToUString(source));
     JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject());
@@ -81,7 +81,7 @@ ScriptObject InjectedScriptManager::createInjectedScript(const String& source, S
 
 bool InjectedScriptManager::canAccessInspectedWindow(ScriptState* scriptState)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(scriptState);
     JSDOMWindow* inspectedWindow = toJSDOMWindow(scriptState->lexicalGlobalObject());
     if (!inspectedWindow)
         return false;
index 64f9cb9..8879727 100644 (file)
@@ -108,7 +108,7 @@ JSObject* JSLazyEventListener::initializeJSFunction(ScriptExecutionContext* exec
     if (m_originalNode) {
         if (!wrapper()) {
             // Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating.
-            JSLock lock(SilenceAssertionsOnly);
+            JSLockHolder lock(exec);
             // FIXME: Should pass the global object associated with the node
             setWrapper(exec->globalData(), asObject(toJS(exec, globalObject, m_originalNode)));
         }
index b9af066..838e3ed 100644 (file)
@@ -73,6 +73,7 @@ public:
     static JSC::JSValue evaluate(JSC::ExecState* exec, JSC::ScopeChainNode* chain, const JSC::SourceCode& source, JSC::JSValue thisValue, JSC::JSValue* exception)
     {
         JSMainThreadExecState currentState(exec);
+        JSC::JSLockHolder lock(exec);
         return JSC::evaluate(exec, chain, source, thisValue, exception);
     };
 
index 4375ce4..d4a5701 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "JSMutationCallback.h"
 
+#include "JSDOMWindowBase.h"
 #include "JSMutationRecord.h"
 #include "JSWebKitMutationObserver.h"
 #include "ScriptExecutionContext.h"
@@ -50,7 +51,7 @@ bool JSMutationCallback::handleEvent(MutationRecordArray* mutations, WebKitMutat
 
     RefPtr<JSMutationCallback> protect(this);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
 
     ExecState* exec = m_data->globalObject()->globalExec();
 
index 120f638..7d01b9f 100644 (file)
@@ -40,7 +40,7 @@ JSNodeFilterCondition::JSNodeFilterCondition(JSGlobalData&, NodeFilter* owner, J
 
 short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) const
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     if (!m_filter)
         return NodeFilter::FILTER_ACCEPT;
index c6be647..eb2ab3c 100644 (file)
@@ -40,7 +40,7 @@ bool JSRequestAnimationFrameCallback::handleEvent(DOMTimeStamp time)
 
     RefPtr<JSRequestAnimationFrameCallback> protect(this);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_data->globalObject()->globalData());
 
     MarkedArgumentBuffer args;
     args.append(jsNumber(time));
index 29b7399..3aefad1 100644 (file)
@@ -30,6 +30,7 @@
 #include "JavaScriptCallFrame.h"
 
 #include "JSDOMBinding.h"
+#include "JSDOMWindowBase.h"
 #include "PlatformString.h"
 #include <debugger/DebuggerCallFrame.h>
 #include <runtime/Completion.h>
@@ -106,7 +107,7 @@ JSValue JavaScriptCallFrame::evaluate(const UString& script, JSValue& exception)
     if (!m_isValid)
         return jsNull();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
     return m_debuggerCallFrame.evaluate(script, exception);
 }
 
index 10bb8c8..ff0aeef 100755 (executable)
@@ -110,7 +110,7 @@ void PageScriptDebugServer::removeListener(ScriptDebugListener* listener, Page*
 
 void PageScriptDebugServer::recompileAllJSFunctions(Timer<ScriptDebugServer>*)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     // If JavaScript stack is not empty postpone recompilation.
     if (JSDOMWindow::commonJSGlobalData()->dynamicGlobalObject)
         recompileAllJSFunctionsSoon();
index 1906905..c469bf8 100644 (file)
@@ -94,7 +94,7 @@ void ScheduledAction::execute(ScriptExecutionContext* context)
 void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSValue thisValue, ScriptExecutionContext* context)
 {
     ASSERT(m_function);
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(context->globalData());
 
     CallData callData;
     CallType callType = getCallData(m_function.get(), callData);
index 2100c6b..9cf4e99 100644 (file)
@@ -46,7 +46,7 @@ namespace WebCore {
 
 ScriptCachedFrameData::ScriptCachedFrameData(Frame* frame)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
 
     ScriptController* scriptController = frame->script();
     ScriptController::ShellMap& windowShells = scriptController->m_windowShells;
@@ -67,7 +67,7 @@ ScriptCachedFrameData::~ScriptCachedFrameData()
 
 void ScriptCachedFrameData::restore(Frame* frame)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
 
     ScriptController* scriptController = frame->script();
     ScriptController::ShellMap& windowShells = scriptController->m_windowShells;
@@ -95,7 +95,7 @@ void ScriptCachedFrameData::clear()
     if (m_windows.isEmpty())
         return;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
     m_windows.clear();
     gcController().garbageCollectSoon();
 }
index 7999502..50a8ac5 100644 (file)
@@ -133,7 +133,7 @@ ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode
     const String* savedSourceURL = m_sourceURL;
     m_sourceURL = &sourceURL;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     RefPtr<Frame> protect = m_frame;
 
@@ -177,7 +177,7 @@ void ScriptController::clearWindowShell(bool goingIntoPageCache)
     if (m_windowShells.isEmpty())
         return;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
 
     for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) {
         JSDOMWindowShell* windowShell = iter->second.get();
@@ -209,7 +209,7 @@ JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world)
 {
     ASSERT(!m_windowShells.contains(world));
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(world->globalData());
 
     JSDOMWindowShell* windowShell = createWindowShell(world);
 
@@ -284,9 +284,10 @@ void ScriptController::updateDocument()
     if (!m_frame->document())
         return;
 
-    JSLock lock(SilenceAssertionsOnly);
-    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
+    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) {
+        JSLockHolder lock(iter->first->globalData());
         iter->second->window()->updateDocument();
+    }
 }
 
 void ScriptController::updateSecurityOrigin()
@@ -300,7 +301,7 @@ Bindings::RootObject* ScriptController::cacheableBindingRootObject()
         return 0;
 
     if (!m_cacheableBindingRootObject) {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
         m_cacheableBindingRootObject = Bindings::RootObject::create(0, globalObject(pluginWorld()));
     }
     return m_cacheableBindingRootObject.get();
@@ -312,7 +313,7 @@ Bindings::RootObject* ScriptController::bindingRootObject()
         return 0;
 
     if (!m_bindingRootObject) {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
         m_bindingRootObject = Bindings::RootObject::create(0, globalObject(pluginWorld()));
     }
     return m_bindingRootObject.get();
@@ -349,9 +350,9 @@ NPObject* ScriptController::windowScriptNPObject()
         if (canExecuteScripts(NotAboutToExecuteScript)) {
             // JavaScript is enabled, so there is a JavaScript window object.
             // Return an NPObject bound to the window object.
-            JSC::JSLock lock(SilenceAssertionsOnly);
-            JSObject* win = windowShell(pluginWorld())->window();
+            JSDOMWindow* win = windowShell(pluginWorld())->window();
             ASSERT(win);
+            JSC::JSLockHolder lock(win->globalExec());
             Bindings::RootObject* root = bindingRootObject();
             m_windowScriptNPObject = _NPN_CreateScriptObject(0, win, root);
         } else {
@@ -383,8 +384,8 @@ JSObject* ScriptController::jsObjectForPluginElement(HTMLPlugInElement* plugin)
         return 0;
 
     // Create a JSObject bound to this element
-    JSLock lock(SilenceAssertionsOnly);
     JSDOMWindow* globalObj = globalObject(pluginWorld());
+    JSLockHolder lock(globalObj->globalExec());
     // FIXME: is normal okay? - used for NP plugins?
     JSValue jsElementValue = toJS(globalObj->globalExec(), globalObj, plugin);
     if (!jsElementValue || !jsElementValue.isObject())
@@ -418,7 +419,7 @@ void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle)
 
 void ScriptController::clearScriptObjects()
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
 
     RootObjectMap::const_iterator end = m_rootObjects.end();
     for (RootObjectMap::const_iterator it = m_rootObjects.begin(); it != end; ++it)
index 50a5a7e..66210c7 100644 (file)
@@ -111,7 +111,7 @@ WebScriptObject* ScriptController::windowScriptObject()
         return 0;
 
     if (!m_windowScriptObject) {
-        JSC::JSLock lock(JSC::SilenceAssertionsOnly);
+        JSC::JSLockHolder lock(JSDOMWindowBase::commonJSGlobalData());
         JSC::Bindings::RootObject* root = bindingRootObject();
         m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(windowShell(pluginWorld())) originRootObject:root rootObject:root];
     }
index f2227c7..9ace82d 100644 (file)
@@ -222,7 +222,7 @@ void ScriptDebugServer::dispatchDidPause(ScriptDebugListener* listener)
     {
         if (m_currentCallFrame->isValid() && globalObject->inherits(&JSDOMGlobalObject::s_info)) {
             JSDOMGlobalObject* domGlobalObject = jsCast<JSDOMGlobalObject*>(globalObject);
-            JSLock lock(SilenceAssertionsOnly);
+            JSLockHolder lock(state);
             jsCallFrame = toJS(state, domGlobalObject, m_currentCallFrame.get());
         } else
             jsCallFrame = jsUndefined();
index 390fde1..7216b6f 100644 (file)
@@ -98,7 +98,7 @@ String eventListenerHandlerBody(Document* document, EventListener* eventListener
     ASSERT(jsListener);
     if (!jsListener)
         return "";
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(jsListener->isolatedWorld()->globalData());
     JSC::JSObject* jsFunction = jsListener->jsFunction(document);
     if (!jsFunction)
         return "";
@@ -112,7 +112,7 @@ bool eventListenerHandlerLocation(Document* document, EventListener* eventListen
     ASSERT(jsListener);
     if (!jsListener)
         return false;
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(jsListener->isolatedWorld()->globalData());
     JSC::JSObject* jsObject = jsListener->jsFunction(document);
     if (!jsObject)
         return false;
index 83b0e45..5477825 100644 (file)
@@ -58,19 +58,19 @@ void ScriptCallArgumentHandler::appendArgument(const ScriptValue& argument)
 
 void ScriptCallArgumentHandler::appendArgument(const String& argument)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
     m_arguments.append(jsString(m_exec, argument));
 }
 
 void ScriptCallArgumentHandler::appendArgument(const JSC::UString& argument)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
     m_arguments.append(jsString(m_exec, argument));
 }
 
 void ScriptCallArgumentHandler::appendArgument(const char* argument)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
     m_arguments.append(jsString(m_exec, UString(argument)));
 }
 
@@ -81,31 +81,31 @@ void ScriptCallArgumentHandler::appendArgument(JSC::JSValue argument)
 
 void ScriptCallArgumentHandler::appendArgument(long argument)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
     m_arguments.append(jsNumber(argument));
 }
 
 void ScriptCallArgumentHandler::appendArgument(long long argument)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
     m_arguments.append(jsNumber(argument));
 }
 
 void ScriptCallArgumentHandler::appendArgument(unsigned int argument)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
     m_arguments.append(jsNumber(argument));
 }
 
 void ScriptCallArgumentHandler::appendArgument(unsigned long argument)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
     m_arguments.append(jsNumber(argument));
 }
 
 void ScriptCallArgumentHandler::appendArgument(int argument)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
     m_arguments.append(jsNumber(argument));
 }
 
@@ -125,7 +125,7 @@ ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions)
 {
     JSObject* thisObject = m_thisObject.jsObject();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
 
     JSValue function = thisObject->get(m_exec, Identifier(m_exec, stringToUString(m_name)));
     if (m_exec->hadException()) {
@@ -163,7 +163,7 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExcept
 {
     JSObject* thisObject = m_thisObject.jsObject();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
 
     JSObject* constructor = asObject(thisObject->get(m_exec, Identifier(m_exec, stringToUString(m_name))));
     if (m_exec->hadException()) {
@@ -205,7 +205,7 @@ ScriptValue ScriptCallback::call()
 
 ScriptValue ScriptCallback::call(bool& hadException)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_exec);
 
     CallData callData;
     CallType callType = getCallData(m_function.jsValue(), callData);
index 0cfb82b..bf9140d 100644 (file)
@@ -67,7 +67,7 @@ static bool handleException(ScriptState* scriptState)
 
 bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(scriptState);
     scriptState->lexicalGlobalObject()->putDirect(scriptState->globalData(), Identifier(scriptState, name), value.jsObject());
     return handleException(scriptState);
 }
@@ -75,7 +75,7 @@ bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, const S
 #if ENABLE(INSPECTOR)
 bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorFrontendHost* value)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(scriptState);
     JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject());
     globalObject->putDirect(scriptState->globalData(), Identifier(scriptState, name), toJS(scriptState, globalObject, value));
     return handleException(scriptState);
@@ -83,7 +83,7 @@ bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, Inspect
 
 bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InjectedScriptHost* value)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(scriptState);
     JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject());
     globalObject->putDirect(scriptState->globalData(), Identifier(scriptState, name), toJS(scriptState, globalObject, value));
     return handleException(scriptState);
@@ -92,7 +92,7 @@ bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, Injecte
 
 bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptObject& value)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(scriptState);
     JSValue jsValue = scriptState->lexicalGlobalObject()->get(scriptState, Identifier(scriptState, name));
     if (!jsValue)
         return false;
@@ -106,7 +106,7 @@ bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptO
 
 bool ScriptGlobalObject::remove(ScriptState* scriptState, const char* name)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(scriptState);
     scriptState->lexicalGlobalObject()->methodTable()->deleteProperty(scriptState->lexicalGlobalObject(), scriptState, Identifier(scriptState, name));
     return handleException(scriptState);
 }
index fd32872..83dfd5f 100644 (file)
@@ -49,7 +49,7 @@ bool ScriptValue::getString(ScriptState* scriptState, String& result) const
 {
     if (!m_value)
         return false;
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(scriptState);
     UString ustring;
     if (!m_value.get().getString(scriptState, ustring))
         return false;
@@ -175,6 +175,7 @@ static PassRefPtr<InspectorValue> jsToInspectorValue(ScriptState* scriptState, J
 
 PassRefPtr<InspectorValue> ScriptValue::toInspectorValue(ScriptState* scriptState) const
 {
+    JSC::JSLockHolder holder(scriptState);
     return jsToInspectorValue(scriptState, m_value.get(), InspectorValue::maxDepth);
 }
 #endif // ENABLE(INSPECTOR)
index e2e607d..9bfde8f 100644 (file)
@@ -64,7 +64,7 @@ WorkerScriptController::WorkerScriptController(WorkerContext* workerContext)
 
 WorkerScriptController::~WorkerScriptController()
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(globalData());
     m_workerContextWrapper.clear();
     m_globalData.clear();
 }
@@ -73,7 +73,7 @@ void WorkerScriptController::initScript()
 {
     ASSERT(!m_workerContextWrapper);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_globalData.get());
 
     // Explicitly protect the global object's prototype so it isn't collected
     // when we allocate the global object. (Once the global object is fully
@@ -117,7 +117,7 @@ void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
     ScriptValue exception;
     evaluate(sourceCode, &exception);
     if (exception.jsValue()) {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(globalData());
         reportException(m_workerContextWrapper->globalExec(), exception.jsValue());
     }
 }
@@ -128,9 +128,9 @@ void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, Script
         return;
 
     initScriptIfNeeded();
-    JSLock lock(SilenceAssertionsOnly);
 
     ExecState* exec = m_workerContextWrapper->globalExec();
+    JSLockHolder lock(exec);
 
     m_workerContextWrapper->globalData().timeoutChecker.start();
 
@@ -191,7 +191,7 @@ bool WorkerScriptController::isExecutionForbidden() const
 void WorkerScriptController::disableEval()
 {
     initScriptIfNeeded();
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(globalData());
 
     m_workerContextWrapper->setEvalEnabled(false);
 }
index aeef941..cef0c5f 100644 (file)
@@ -122,13 +122,12 @@ static void addExceptionToConsole(ExecState* exec)
 
 static void _didExecute(WebScriptObject *obj)
 {
-    ASSERT(JSLock::lockCount() > 0);
-    
     RootObject* root = [obj _rootObject];
     if (!root)
         return;
 
     ExecState* exec = root->globalObject()->globalExec();
+    ASSERT(exec->globalData().apiLock().currentThreadIsHoldingLock());
     KJSDidExecuteFunctionPtr func = Instance::didExecuteFunction();
     if (func)
         func(exec, root->globalObject());
@@ -281,10 +280,9 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     if (![self _isSafeScript])
         return nil;
 
-    JSLock lock(SilenceAssertionsOnly);
-    
     // Look up the function object.
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
+    JSLockHolder lock(exec);
     ASSERT(!exec->hadException());
 
     JSValue function = [self _imp]->get(exec, Identifier(exec, stringToUString(String(name))));
@@ -325,7 +323,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     ASSERT(!exec->hadException());
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     
     [self _rootObject]->globalObject()->globalData().timeoutChecker.start();
     JSValue returnValue = JSMainThreadExecState::evaluate(exec, [self _rootObject]->globalObject()->globalScopeChain(), makeSource(String(script)), JSC::JSValue(), 0);
@@ -346,7 +344,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     ASSERT(!exec->hadException());
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     PutPropertySlot slot;
     [self _imp]->methodTable()->put([self _imp], exec, Identifier(exec, stringToUString(String(key))), convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]), slot);
@@ -372,7 +370,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
         // Need to scope this lock to ensure that we release the lock before calling
         // [super valueForKey:key] which might throw an exception and bypass the JSLock destructor,
         // leaving the lock permanently held
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         
         JSValue result = [self _imp]->get(exec, Identifier(exec, stringToUString(String(key))));
         
@@ -388,7 +386,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     if ([resultObj isKindOfClass:[WebUndefined class]])
         resultObj = [super valueForKey:key];    // defaults to throwing an exception
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     _didExecute(self);
     
     return resultObj;
@@ -402,7 +400,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     ASSERT(!exec->hadException());
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     [self _imp]->methodTable()->deleteProperty([self _imp], exec, Identifier(exec, stringToUString(String(key))));
 
     if (exec->hadException()) {
@@ -421,7 +419,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     ASSERT(!exec->hadException());
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     BOOL result = [self _imp]->hasProperty(exec, Identifier(exec, stringToUString(String(key))));
 
     if (exec->hadException()) {
@@ -441,8 +439,8 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
         return @"Undefined";
     }
 
-    JSLock lock(SilenceAssertionsOnly);
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
+    JSLockHolder lock(exec);
     
     id result = convertValueToObjcValue(exec, [self _imp], ObjcObjectType).objectValue;
 
@@ -461,7 +459,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     ASSERT(!exec->hadException());
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     JSValue result = [self _imp]->get(exec, index);
 
     if (exec->hadException()) {
@@ -485,7 +483,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     ASSERT(!exec->hadException());
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     [self _imp]->methodTable()->putByIndex([self _imp], exec, index, convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]), false);
 
     if (exec->hadException()) {
@@ -515,7 +513,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
 {
     if (value.isObject()) {
         JSObject* object = asObject(value);
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(rootObject->globalObject()->globalData());
 
         if (object->inherits(&JSHTMLElement::s_info)) {
             // Plugin elements cache the instance internally.
index e45e762..bcf567e 100644 (file)
@@ -2745,7 +2745,7 @@ END
             push(@implContent, "    if (!canInvokeCallback())\n");
             push(@implContent, "        return true;\n\n");
             push(@implContent, "    RefPtr<$className> protect(this);\n\n");
-            push(@implContent, "    JSLock lock(SilenceAssertionsOnly);\n\n");
+            push(@implContent, "    JSLockHolder lock(m_data->globalObject()->globalData());\n\n");
             push(@implContent, "    ExecState* exec = m_data->globalObject()->globalExec();\n");
             push(@implContent, "    MarkedArgumentBuffer args;\n");
 
index abae044..e7ba4c0 100644 (file)
@@ -65,7 +65,7 @@ bool JSTestCallback::callbackWithNoParam()
 
     RefPtr<JSTestCallback> protect(this);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_data->globalObject()->globalData());
 
     ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
@@ -82,7 +82,7 @@ bool JSTestCallback::callbackWithClass1Param(Class1* class1Param)
 
     RefPtr<JSTestCallback> protect(this);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_data->globalObject()->globalData());
 
     ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
@@ -100,7 +100,7 @@ bool JSTestCallback::callbackWithClass2Param(Class2* class2Param, const String&
 
     RefPtr<JSTestCallback> protect(this);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_data->globalObject()->globalData());
 
     ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
@@ -119,7 +119,7 @@ bool JSTestCallback::callbackWithStringList(PassRefPtr<DOMStringList> listParam)
 
     RefPtr<JSTestCallback> protect(this);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_data->globalObject()->globalData());
 
     ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
@@ -137,7 +137,7 @@ bool JSTestCallback::callbackWithBoolean(bool boolParam)
 
     RefPtr<JSTestCallback> protect(this);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_data->globalObject()->globalData());
 
     ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
@@ -157,7 +157,7 @@ bool JSTestCallback::callbackRequiresThisToPass(Class8* class8Param, ThisClass*
 
     RefPtr<JSTestCallback> protect(this);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(m_data->globalObject()->globalData());
 
     ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
index aef97f0..61e3679 100644 (file)
@@ -177,7 +177,7 @@ bool _NPN_InvokeDefault(NPP, NPObject* o, const NPVariant* args, uint32_t argCou
             return false;
         
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         
         // Call the function object.
         JSValue function = obj->imp;
@@ -225,7 +225,7 @@ bool _NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVariant*
         if (!rootObject || !rootObject->isValid())
             return false;
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         JSValue function = obj->imp->get(exec, identifierFromNPIdentifier(exec, i->string()));
         CallData callData;
         CallType callType = getCallData(function, callData);
@@ -264,7 +264,7 @@ bool _NPN_Evaluate(NPP instance, NPObject* o, NPString* s, NPVariant* variant)
         PluginView::keepAlive(instance);
 
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         String scriptString = convertNPStringToUTF16(s);
         
         JSValue returnValue = JSC::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), makeSource(scriptString), JSC::JSValue());
@@ -290,7 +290,7 @@ bool _NPN_GetProperty(NPP, NPObject* o, NPIdentifier propertyName, NPVariant* va
         ExecState* exec = rootObject->globalObject()->globalExec();
         IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
         
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         JSValue result;
         if (i->isString())
             result = obj->imp->get(exec, identifierFromNPIdentifier(exec, i->string()));
@@ -322,7 +322,7 @@ bool _NPN_SetProperty(NPP, NPObject* o, NPIdentifier propertyName, const NPVaria
             return false;
 
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
 
         if (i->isString()) {
@@ -363,7 +363,7 @@ bool _NPN_RemoveProperty(NPP, NPObject* o, NPIdentifier propertyName)
             }
         }
 
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         if (i->isString())
             obj->imp->methodTable()->deleteProperty(obj->imp, exec, identifierFromNPIdentifier(exec, i->string()));
         else
@@ -386,7 +386,7 @@ bool _NPN_HasProperty(NPP, NPObject* o, NPIdentifier propertyName)
 
         ExecState* exec = rootObject->globalObject()->globalExec();
         IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         if (i->isString()) {
             bool result = obj->imp->hasProperty(exec, identifierFromNPIdentifier(exec, i->string()));
             exec->clearException();
@@ -418,7 +418,7 @@ bool _NPN_HasMethod(NPP, NPObject* o, NPIdentifier methodName)
             return false;
 
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         JSValue func = obj->imp->get(exec, identifierFromNPIdentifier(exec, i->string()));
         exec->clearException();
         return !func.isUndefined();
@@ -447,7 +447,7 @@ bool _NPN_Enumerate(NPP, NPObject* o, NPIdentifier** identifier, uint32_t* count
             return false;
         
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         PropertyNameArray propertyNames(exec);
 
         obj->imp->methodTable()->getPropertyNames(obj->imp, exec, propertyNames, ExcludeDontEnumProperties);
@@ -484,7 +484,7 @@ bool _NPN_Construct(NPP, NPObject* o, const NPVariant* args, uint32_t argCount,
             return false;
         
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         
         // Call the constructor object.
         JSValue constructor = obj->imp;
index efd7f4e..cfc026b 100644 (file)
@@ -34,7 +34,7 @@
 #include "npruntime_impl.h"
 #include <runtime/ScopeChain.h>
 #include <runtime/Identifier.h>
-#include <runtime/JSLock.h>
+#include <runtime/JSGlobalObject.h>
 #include <runtime/JSObject.h>
 #include <wtf/text/StringHash.h>
 
@@ -47,8 +47,6 @@ CClass::CClass(NPClass* aClass)
 
 CClass::~CClass()
 {
-    JSLock lock(SilenceAssertionsOnly);
-
     deleteAllValues(_methods);
     _methods.clear();
 
@@ -90,10 +88,7 @@ MethodList CClass::methodsNamed(PropertyName propertyName, Instance* instance) c
     NPObject* obj = inst->getObject();
     if (_isa->hasMethod && _isa->hasMethod(obj, ident)){
         Method* aMethod = new CMethod(ident); // deleted in the CClass destructor
-        {
-            JSLock lock(SilenceAssertionsOnly);
-            _methods.set(name.impl(), aMethod);
-        }
+        _methods.set(name.impl(), aMethod);
         methodList.append(aMethod);
     }
     
@@ -113,10 +108,7 @@ Field* CClass::fieldNamed(PropertyName propertyName, Instance* instance) const
     NPObject* obj = inst->getObject();
     if (_isa->hasProperty && _isa->hasProperty(obj, ident)){
         aField = new CField(ident); // deleted in the CClass destructor
-        {
-            JSLock lock(SilenceAssertionsOnly);
-            _fields.set(name.impl(), aField);
-        }
+        _fields.set(name.impl(), aField);
     }
     return aField;
 }
index fad386c..5b98f6e 100644 (file)
@@ -73,7 +73,7 @@ void CInstance::moveGlobalExceptionToExecState(ExecState* exec)
         return;
 
     {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         throwError(exec, createError(exec, globalExceptionString()));
     }
 
@@ -182,7 +182,7 @@ JSValue CInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod)
     VOID_TO_NPVARIANT(resultVariant);
 
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(exec);
         ASSERT(globalExceptionString().isNull());
         retval = _object->_class->invoke(_object, ident, cArgs.data(), count, &resultVariant);
         moveGlobalExceptionToExecState(exec);
@@ -217,7 +217,7 @@ JSValue CInstance::invokeDefaultMethod(ExecState* exec)
     NPVariant resultVariant;
     VOID_TO_NPVARIANT(resultVariant);
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(exec);
         ASSERT(globalExceptionString().isNull());
         retval = _object->_class->invokeDefault(_object, cArgs.data(), count, &resultVariant);
         moveGlobalExceptionToExecState(exec);
@@ -256,7 +256,7 @@ JSValue CInstance::invokeConstruct(ExecState* exec, const ArgList& args)
     NPVariant resultVariant;
     VOID_TO_NPVARIANT(resultVariant);
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(exec);
         ASSERT(globalExceptionString().isNull());
         retval = _object->_class->construct(_object, cArgs.data(), count, &resultVariant);
         moveGlobalExceptionToExecState(exec);
@@ -315,7 +315,7 @@ void CInstance::getPropertyNames(ExecState* exec, PropertyNameArray& nameArray)
     NPIdentifier* identifiers;
 
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(exec);
         ASSERT(globalExceptionString().isNull());
         bool ok = _object->_class->enumerate(_object, &identifiers, &count);
         moveGlobalExceptionToExecState(exec);
index a84acbb..a92cfe5 100644 (file)
@@ -49,7 +49,7 @@ JSValue CField::valueFromInstance(ExecState* exec, const Instance* inst) const
 
         bool result;
         {
-            JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+            JSLock::DropAllLocks dropAllLocks(exec);
             result = obj->_class->getProperty(obj, _fieldIdentifier, &property);
             CInstance::moveGlobalExceptionToExecState(exec);
         }
@@ -71,7 +71,7 @@ void CField::setValueToInstance(ExecState *exec, const Instance *inst, JSValue a
         convertValueToNPVariant(exec, aValue, &variant);
 
         {
-            JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+            JSLock::DropAllLocks dropAllLocks(exec);
             obj->_class->setProperty(obj, _fieldIdentifier, &variant);
             CInstance::moveGlobalExceptionToExecState(exec);
         }
index 8a70b27..dc3755f 100644 (file)
@@ -68,7 +68,7 @@ static String convertUTF8ToUTF16WithLatin1Fallback(const NPUTF8* UTF8Chars, int
 // Variant value must be released with NPReleaseVariantValue()
 void convertValueToNPVariant(ExecState* exec, JSValue value, NPVariant* result)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     VOID_TO_NPVARIANT(*result);
 
@@ -107,7 +107,7 @@ void convertValueToNPVariant(ExecState* exec, JSValue value, NPVariant* result)
 
 JSValue convertNPVariantToValue(ExecState* exec, const NPVariant* variant, RootObject* rootObject)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     
     NPVariantType type = variant->type;
 
index 9d45134..98f3aeb 100644 (file)
@@ -284,7 +284,7 @@ jobject JavaJSObject::call(jstring methodName, jobjectArray args) const
     
     // Lookup the function object.
     ExecState* exec = rootObject->globalObject()->globalExec();
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     
     Identifier identifier(exec, JavaString(methodName).impl());
     JSValue function = _imp->get(exec, identifier);
@@ -307,12 +307,12 @@ jobject JavaJSObject::eval(jstring script) const
 {
     LOG(LiveConnect, "JavaJSObject::eval script = %s", JavaString(script).utf8());
 
-    JSLock lock(SilenceAssertionsOnly);
-    
     RootObject* rootObject = this->rootObject();
     if (!rootObject)
         return 0;
 
+    JSLockHolder lock(rootObject->globalObject()->globalData());
+    
     rootObject->globalObject()->globalData().timeoutChecker.start();
     JSValue result = JSC::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), makeSource(JavaString(script).impl()));
     rootObject->globalObject()->globalData().timeoutChecker.stop();
@@ -330,7 +330,7 @@ jobject JavaJSObject::getMember(jstring memberName) const
 
     ExecState* exec = rootObject->globalObject()->globalExec();
     
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     JSValue result = _imp->get(exec, Identifier(exec, JavaString(memberName).impl()));
 
     return convertValueToJObject(result);
@@ -346,7 +346,7 @@ void JavaJSObject::setMember(jstring memberName, jobject value) const
 
     ExecState* exec = rootObject->globalObject()->globalExec();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     PutPropertySlot slot;
     _imp->methodTable()->put(_imp, exec, Identifier(exec, JavaString(memberName).impl()), convertJObjectToValue(exec, value), slot);
 }
@@ -361,7 +361,7 @@ void JavaJSObject::removeMember(jstring memberName) const
         return;
 
     ExecState* exec = rootObject->globalObject()->globalExec();
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     _imp->methodTable()->deleteProperty(_imp, exec, Identifier(exec, JavaString(memberName).impl()));
 }
 
@@ -376,7 +376,7 @@ jobject JavaJSObject::getSlot(jint index) const
 
     ExecState* exec = rootObject->globalObject()->globalExec();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     JSValue result = _imp->get(exec, index);
 
     return convertValueToJObject(result);
@@ -392,7 +392,7 @@ void JavaJSObject::setSlot(jint index, jobject value) const
         return;
 
     ExecState* exec = rootObject->globalObject()->globalExec();
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     _imp->methodTable()->putByIndex(_imp, exec, (unsigned)index, convertJObjectToValue(exec, value), false);
 }
 
@@ -405,9 +405,9 @@ jstring JavaJSObject::toString() const
     if (!rootObject)
         return 0;
 
-    JSLock lock(SilenceAssertionsOnly);
     JSObject *thisObj = const_cast<JSObject*>(_imp);
     ExecState* exec = rootObject->globalObject()->globalExec();
+    JSLockHolder lock(exec);
     
     return static_cast<jstring>(convertValueToJValue(exec, rootObject, thisObj, JavaTypeObject, "java.lang.String").l);
 }
@@ -463,13 +463,13 @@ jlong JavaJSObject::createNative(jlong nativeHandle)
 
 jobject JavaJSObject::convertValueToJObject(JSValue value) const
 {
-    JSLock lock(SilenceAssertionsOnly);
-    
     RootObject* rootObject = this->rootObject();
     if (!rootObject)
         return 0;
 
+    
     ExecState* exec = rootObject->globalObject()->globalExec();
+    JSLockHolder lock(exec);
     JNIEnv *env = getJNIEnv();
     jobject result = 0;
     
@@ -554,7 +554,7 @@ JSValue JavaJSObject::convertJObjectToValue(ExecState* exec, jobject theObject)
     // figure 22-4.
     jobject classOfInstance = callJNIMethod<jobject>(theObject, "getClass", "()Ljava/lang/Class;");
     if (!classOfInstance) {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         return JavaInstance::create(theObject, _rootObject)->createRuntimeObject(exec);
     }
 
@@ -563,7 +563,7 @@ JSValue JavaJSObject::convertJObjectToValue(ExecState* exec, jobject theObject)
     // pointer and stores it in this object, so that it can be retrieved below.
     jstring className = (jstring)callJNIMethod<jobject>(classOfInstance, "getName", "()Ljava/lang/String;");
     if (!className || (strcmp(JavaString(className).utf8(), "sun.plugin.javascript.webkit.JSObject") != 0)) {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         return JavaInstance::create(theObject, _rootObject)->createRuntimeObject(exec);
     }
 
index 9c943e8..6ae1ae5 100644 (file)
@@ -62,7 +62,7 @@ bool JSC::Bindings::dispatchJNICall(ExecState* exec, const void* targetAppletVie
         // implemented in WebCore will guarantee that only appropriate JavaScript
         // can reference the applet.
         {
-           JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+           JSLock::DropAllLocks dropAllLocks(exec);
             result = [view webPlugInCallJava:obj isStatic:isStatic returnType:returnType method:methodID arguments:args callingURL:nil exceptionDescription:&_exceptionDescription];
         }
 
@@ -72,7 +72,7 @@ bool JSC::Bindings::dispatchJNICall(ExecState* exec, const void* targetAppletVie
         return true;
     }
     else if ([view respondsToSelector:@selector(webPlugInCallJava:method:returnType:arguments:)]) {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(exec);
         result = [view webPlugInCallJava:obj method:methodID returnType:returnType arguments:args];
         return true;
     }
index 9872da8..a3b2c2e 100644 (file)
@@ -174,7 +174,7 @@ static jobject convertArrayInstanceToJavaArray(ExecState* exec, JSArray* jsArray
 
 jvalue convertValueToJValue(ExecState* exec, RootObject* rootObject, JSValue value, JavaType javaType, const char* javaClassName)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     jvalue result;
     memset(&result, 0, sizeof(jvalue));
index 08ec6e6..aeb4020 100644 (file)
@@ -63,7 +63,7 @@ JavaClass::JavaClass(jobject anInstance)
             jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
             JavaField* aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
             {
-                JSLock lock(SilenceAssertionsOnly);
+                // FIXME: Should we acquire a JSLock here?
                 m_fields.set(aField->name().impl(), aField);
             }
             env->DeleteLocalRef(aJField);
@@ -79,7 +79,7 @@ JavaClass::JavaClass(jobject anInstance)
             JavaMethod* aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor
             MethodList* methodList;
             {
-                JSLock lock(SilenceAssertionsOnly);
+                // FIXME: Should we acquire a JSLock here?
 
                 methodList = m_methods.get(aMethod->name().impl());
                 if (!methodList) {
@@ -100,7 +100,7 @@ JavaClass::~JavaClass()
 {
     fastFree(const_cast<char*>(m_name));
 
-    JSLock lock(SilenceAssertionsOnly);
+    // FIXME: Should we acquire a JSLock here?
 
     deleteAllValues(m_fields);
     m_fields.clear();
index 7d2b02f..15dffa5 100644 (file)
@@ -87,7 +87,7 @@ Class* JavaInstance::getClass() const
 
 JSValue JavaInstance::stringValue(ExecState* exec) const
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     jstring stringValue = (jstring)callJNIMethod<jobject>(m_instance->instance(), "toString", "()Ljava/lang/String;");
 
index 5e18ea8..0d2b6e5 100644 (file)
@@ -92,7 +92,7 @@ JavaMethod::~JavaMethod()
 // we get '.' between components from the reflection API.
 static void appendClassName(StringBuilder& builder, const char* className)
 {
-    ASSERT(JSLock::lockCount() > 0);
+    ASSERT(JSC::JSGlobalData::sharedInstance().apiLock().currentThreadIsHoldingLock());
 
     char* c = fastStrDup(className);
 
@@ -111,7 +111,7 @@ static void appendClassName(StringBuilder& builder, const char* className)
 const char* JavaMethod::signature() const
 {
     if (!m_signature) {
-        JSLock lock(SilenceAssertionsOnly);
+        // FIXME: Should we acquire a JSLock here?
 
         StringBuilder signatureBuilder;
         signatureBuilder.append('(');
index 0f8b779..1e1803a 100644 (file)
@@ -28,6 +28,7 @@
 #define JavaStringJSC_h
 
 #include "JNIUtility.h"
+#include "JSDOMWindowBase.h"
 #include "JavaInstanceJSC.h"
 
 #include <runtime/JSLock.h>
@@ -52,20 +53,20 @@ public:
 
     JavaString()
     {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(WebCore::JSDOMWindowBase::commonJSGlobalData());
         m_impl = UString().impl();
     }
 
     ~JavaString()
     {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(WebCore::JSDOMWindowBase::commonJSGlobalData());
         m_impl = 0;
     }
 
     const char* utf8() const
     {
         if (!m_utf8String.data()) {
-            JSLock lock(SilenceAssertionsOnly);
+            JSLockHolder lock(WebCore::JSDOMWindowBase::commonJSGlobalData());
             m_utf8String = UString(m_impl).utf8();
         }
         return m_utf8String.data();
@@ -79,7 +80,7 @@ private:
         int size = e->GetStringLength(s);
         const jchar* uc = getUCharactersFromJStringInEnv(e, s);
         {
-            JSLock lock(SilenceAssertionsOnly);
+            JSLockHolder lock(WebCore::JSDOMWindowBase::commonJSGlobalData());
             m_impl = UString(reinterpret_cast<const UChar*>(uc), size).impl();
         }
         releaseUCharactersForJStringInEnv(e, s, uc);
index 6b81a9b..4cc8003 100644 (file)
@@ -92,7 +92,7 @@ JSObject* Instance::createRuntimeObject(ExecState* exec)
     if (RuntimeObject* existingObject = m_runtimeObject.get())
         return existingObject;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     RuntimeObject* newObject = newRuntimeObject(exec);
     m_runtimeObject = PassWeak<RuntimeObject>(newObject);
     m_rootObject->addRuntimeObject(exec->globalData(), newObject);
@@ -101,7 +101,7 @@ JSObject* Instance::createRuntimeObject(ExecState* exec)
 
 RuntimeObject* Instance::newRuntimeObject(ExecState* exec)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     // FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object
     // We need to pass in the right global object for "i".
index 88c359e..8a97b7d 100644 (file)
@@ -92,7 +92,7 @@ void ObjcInstance::moveGlobalExceptionToExecState(ExecState* exec)
     }
 
     if (!s_exceptionEnvironment || s_exceptionEnvironment == exec->dynamicGlobalObject()) {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         throwError(exec, s_exception);
     }
 
@@ -239,7 +239,7 @@ JSValue ObjcInstance::invokeObjcMethod(ExecState* exec, ObjcMethod* method)
 {
     JSValue result = jsUndefined();
     
-    JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(exec); // Can't put this inside the @try scope because it unwinds incorrectly.
 
     setGlobalException(nil);
     
@@ -354,7 +354,7 @@ JSValue ObjcInstance::invokeDefaultMethod(ExecState* exec)
 {
     JSValue result = jsUndefined();
 
-    JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(exec); // Can't put this inside the @try scope because it unwinds incorrectly.
     setGlobalException(nil);
     
 @try {
@@ -411,7 +411,7 @@ bool ObjcInstance::setValueOfUndefinedField(ExecState* exec, PropertyName proper
     if (![targetObject respondsToSelector:@selector(setValue:forUndefinedKey:)])
         return false;
 
-    JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(exec); // Can't put this inside the @try scope because it unwinds incorrectly.
 
     // This check is not really necessary because NSObject implements
     // setValue:forUndefinedKey:, and unfortunately the default implementation
@@ -443,7 +443,7 @@ JSValue ObjcInstance::getValueOfUndefinedField(ExecState* exec, PropertyName pro
     
     id targetObject = getObject();
 
-    JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(exec); // Can't put this inside the @try scope because it unwinds incorrectly.
 
     // This check is not really necessary because NSObject implements
     // valueForUndefinedKey:, and unfortunately the default implementation
index 3fa7994..335668e 100644 (file)
@@ -92,19 +92,18 @@ JSValue ObjcField::valueFromInstance(ExecState* exec, const Instance* instance)
     
     id targetObject = (static_cast<const ObjcInstance*>(instance))->getObject();
 
-    JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(exec); // Can't put this inside the @try scope because it unwinds incorrectly.
 
     @try {
         if (id objcValue = [targetObject valueForKey:(NSString *)_name.get()])
             result = convertObjcValueToValue(exec, &objcValue, ObjcObjectType, instance->rootObject());
         {
-            JSLock lock(SilenceAssertionsOnly);
+            JSLockHolder lock(exec);
             ObjcInstance::moveGlobalExceptionToExecState(exec);
         }
     } @catch(NSException* localException) {
-        JSLock::lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         throwError(exec, [localException reason]);
-        JSLock::unlock(SilenceAssertionsOnly);
     }
 
     // Work around problem in some versions of GCC where result gets marked volatile and
@@ -125,18 +124,17 @@ void ObjcField::setValueToInstance(ExecState* exec, const Instance* instance, JS
     id targetObject = (static_cast<const ObjcInstance*>(instance))->getObject();
     id value = convertValueToObjcObject(exec, aValue);
 
-    JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(exec); // Can't put this inside the @try scope because it unwinds incorrectly.
 
     @try {
         [targetObject setValue:value forKey:(NSString *)_name.get()];
         {
-            JSLock lock(SilenceAssertionsOnly);
+            JSLockHolder lock(exec);
             ObjcInstance::moveGlobalExceptionToExecState(exec);
         }
     } @catch(NSException* localException) {
-        JSLock::lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         throwError(exec, [localException reason]);
-        JSLock::unlock(SilenceAssertionsOnly);
     }
 }
 
index 999f732..b62e3df 100644 (file)
@@ -86,7 +86,7 @@ ObjcValue convertValueToObjcValue(ExecState* exec, JSValue value, ObjcValueType
 
     switch (type) {
         case ObjcObjectType: {
-            JSLock lock(SilenceAssertionsOnly);
+            JSLockHolder lock(exec);
             
             JSGlobalObject *originGlobalObject = exec->dynamicGlobalObject();
             RootObject* originRootObject = findRootObject(originGlobalObject);
@@ -146,7 +146,7 @@ ObjcValue convertValueToObjcValue(ExecState* exec, JSValue value, ObjcValueType
 
 JSValue convertNSStringToString(ExecState* exec, NSString *nsstring)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     
     unichar *chars;
     unsigned int length = [nsstring length];
@@ -178,7 +178,7 @@ JSValue convertNSStringToString(ExecState* exec, NSString *nsstring)
 */
 JSValue convertObjcValueToValue(ExecState* exec, void* buffer, ObjcValueType type, RootObject* rootObject)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     
     switch (type) {
         case ObjcObjectType: {
index e1fedc8..6b5e6a7 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "Error.h"
 #include "JSDOMBinding.h"
+#include "JSDOMWindowBase.h"
 #include "JSGlobalObject.h"
 #include "JSLock.h"
 #include "ObjectPrototype.h"
@@ -92,7 +93,7 @@ QtInstance::QtInstance(QObject* o, PassRefPtr<RootObject> rootObject, ValueOwner
 
 QtInstance::~QtInstance()
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(WebCore::JSDOMWindowBase::commonJSGlobalData());
 
     cachedInstances.remove(m_hashkey);
 
@@ -119,7 +120,7 @@ QtInstance::~QtInstance()
 
 PassRefPtr<QtInstance> QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObject> rootObject, ValueOwnership ownership)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(WebCore::JSDOMWindowBase::commonJSGlobalData());
 
     foreach (QtInstance* instance, cachedInstances.values(o))
         if (instance->rootObject() == rootObject) {
@@ -180,7 +181,7 @@ Class* QtInstance::getClass() const
 
 RuntimeObject* QtInstance::newRuntimeObject(ExecState* exec)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     m_methods.clear();
     return QtRuntimeObject::create(exec, exec->lexicalGlobalObject(), this);
 }
index c00fb49..b0e5f62 100644 (file)
@@ -420,7 +420,7 @@ RuntimeObject* QtPixmapInstance::newRuntimeObject(ExecState* exec)
 
 JSObject* QtPixmapInstance::createPixmapRuntimeObject(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& data)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     RefPtr<QtPixmapInstance> instance = adoptRef(new QtPixmapInstance(root, data));
     return instance->createRuntimeObject(exec);
 }
index 11e2e9c..040d51f 100644 (file)
@@ -230,7 +230,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
         return QVariant();
     }
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     JSRealType type = valueRealType(exec, value);
     if (hint == QMetaType::Void) {
         switch(type) {
@@ -824,7 +824,7 @@ JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, con
         return jsNull();
     }
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     if (type == QMetaType::Bool)
         return jsBoolean(variant.toBool());
@@ -1420,7 +1420,7 @@ EncodedJSValue QtRuntimeMetaMethod::call(ExecState* exec)
         return JSValue::encode(jsUndefined());
 
     // We have to pick a method that matches..
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     QObject *obj = d->m_instance->getObject();
     if (obj) {
@@ -1561,7 +1561,7 @@ EncodedJSValue QtRuntimeConnectionMethod::call(ExecState* exec)
 {
     QtRuntimeConnectionMethodData* d = static_cast<QtRuntimeConnectionMethod *>(exec->callee())->d_func();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     QObject* sender = d->m_instance->getObject();
 
index 73595f0..9682f14 100644 (file)
@@ -230,7 +230,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
         return QVariant();
     }
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     JSRealType type = valueRealType(exec, value);
     if (hint == QMetaType::Void) {
         switch(type) {
@@ -824,7 +824,7 @@ JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, con
         return jsNull();
     }
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     if (type == QMetaType::Bool)
         return jsBoolean(variant.toBool());
@@ -1429,7 +1429,7 @@ EncodedJSValue QtRuntimeMetaMethod::call(ExecState* exec)
         return JSValue::encode(jsUndefined());
 
     // We have to pick a method that matches..
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     QObject *obj = d->m_instance->getObject();
     if (obj) {
@@ -1570,7 +1570,7 @@ EncodedJSValue QtRuntimeConnectionMethod::call(ExecState* exec)
 {
     QtRuntimeConnectionMethodData* d = static_cast<QtRuntimeConnectionMethod *>(exec->callee())->d_func();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     QObject* sender = d->m_instance->getObject();
 
index 58b0788..9b6224a 100644 (file)
@@ -139,8 +139,10 @@ void RootObject::gcProtect(JSObject* jsObject)
 {
     ASSERT(m_isValid);
     
-    if (!m_protectCountSet.contains(jsObject))
+    if (!m_protectCountSet.contains(jsObject)) {
+        JSC::JSLockHolder holder(&globalObject()->globalData());
         JSC::gcProtect(jsObject);
+    }
     m_protectCountSet.add(jsObject);
 }
 
@@ -151,8 +153,10 @@ void RootObject::gcUnprotect(JSObject* jsObject)
     if (!jsObject)
         return;
 
-    if (m_protectCountSet.count(jsObject) == 1)
+    if (m_protectCountSet.count(jsObject) == 1) {
+        JSC::JSLockHolder holder(&globalObject()->globalData());
         JSC::gcUnprotect(jsObject);
+    }
     m_protectCountSet.remove(jsObject);
 }
 
index 062316a..073afa2 100644 (file)
@@ -551,7 +551,7 @@ void HTMLCanvasElement::createImageBuffer() const
     m_contextStateSaver = adoptPtr(new GraphicsContextStateSaver(*m_imageBuffer->context()));
 
 #if USE(JSC)
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
+    JSC::JSLockHolder lock(scriptExecutionContext()->globalData());
     size_t numBytes = 4 * m_imageBuffer->internalSize().width() * m_imageBuffer->internalSize().height();
     scriptExecutionContext()->globalData()->heap.reportExtraMemoryCost(numBytes);
 #endif
index 77ee1e7..9bf013d 100644 (file)
@@ -81,8 +81,8 @@ void HTMLImageLoader::notifyFinished(CachedResource*)
 #if USE(JSC)
     if (!loadError) {
         if (!elem->inDocument()) {
-            JSC::JSLock lock(JSC::SilenceAssertionsOnly);
             JSC::JSGlobalData* globalData = JSDOMWindowBase::commonJSGlobalData();
+            JSC::JSLockHolder lock(globalData);
             globalData->heap.reportExtraMemoryCost(cachedImage->encodedSize());
         }
     }
index d37573e..0d6857f 100644 (file)
@@ -240,7 +240,7 @@ bool PluginView::start()
     {
         PluginView::setCurrentPluginView(this);
 #if USE(JSC)
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 #endif
         setCallingPlugin(true);
         npErr = m_plugin->pluginFuncs()->newp((NPMIMEType)m_mimeType.utf8().data(), m_instance, m_mode, m_paramCount, m_paramNames, m_paramValues, NULL);
@@ -330,7 +330,7 @@ void PluginView::stop()
     m_isStarted = false;
 
 #if USE(JSC)
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 #endif
 
 #if ENABLE(NETSCAPE_PLUGIN_API)
@@ -446,7 +446,7 @@ void PluginView::performRequest(PluginRequest* request)
             if (request->sendNotification()) {
                 PluginView::setCurrentPluginView(this);
 #if USE(JSC)
-                JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+                JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 #endif
                 setCallingPlugin(true);
                 m_plugin->pluginFuncs()->urlnotify(m_instance, requestURL.string().utf8().data(), NPRES_DONE, request->notifyData());
@@ -736,7 +736,7 @@ NPObject* PluginView::npObject()
     {
         PluginView::setCurrentPluginView(this);
 #if USE(JSC)
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 #endif
         setCallingPlugin(true);
         npErr = m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginScriptableNPObject, &object);
@@ -1492,7 +1492,7 @@ void PluginView::privateBrowsingStateChanged(bool privateBrowsingEnabled)
 
     PluginView::setCurrentPluginView(this);
 #if USE(JSC)
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 #endif
     setCallingPlugin(true);
     NPBool value = privateBrowsingEnabled;
index b62933d..2cc96d5 100644 (file)
@@ -403,7 +403,7 @@ bool PluginView::dispatchNPEvent(NPEvent& event)
         return false;
 
     PluginView::setCurrentPluginView(this);
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     setCallingPlugin(true);
 
     bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event);
@@ -970,7 +970,7 @@ void PluginView::setNPWindowIfNeeded()
         ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->windowGroup = window->windowGroup();
 
     PluginView::setCurrentPluginView(this);
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     setCallingPlugin(true);
 
     // FIXME: Passing zoomFactor to setwindow make windowed plugin scale incorrectly.
@@ -1220,7 +1220,7 @@ bool PluginView::platformStart()
 
     if (m_plugin->pluginFuncs()->getvalue) {
         PluginView::setCurrentPluginView(this);
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         setCallingPlugin(true);
         m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginNeedsXEmbed, &m_needsXEmbed);
         setCallingPlugin(false);
@@ -1301,7 +1301,7 @@ void PluginView::getWindowInfo(Vector<PluginWindowInfo>& windowList)
     void* valPtr = 0;
 
     PluginView::setCurrentPluginView(this);
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     setCallingPlugin(true);
     m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginScreenWindow, &valPtr);
     setCallingPlugin(false);
index 86ea200..4ab2ff6 100644 (file)
@@ -56,7 +56,7 @@ bool PluginView::dispatchNPEvent(NPEvent& event)
         return false;
 
     PluginView::setCurrentPluginView(this);
-    JSC::JSLock::DropAllLocks dropAllLocks(false);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     setCallingPlugin(true);
 
     bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event);
index 93bd3db..26253a0 100644 (file)
@@ -106,7 +106,7 @@ bool PluginView::dispatchNPEvent(NPEvent& event)
         return false;
 
     PluginView::setCurrentPluginView(this);
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     setCallingPlugin(true);
 
     bool accepted = !m_plugin->pluginFuncs()->event(m_instance, &event);
@@ -276,7 +276,7 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
 
 void PluginView::handleKeyboardEvent(KeyboardEvent* event)
 {
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 
     if (!m_isStarted || m_status != PluginStatusLoadedSuccessfully)
         return;
@@ -406,7 +406,7 @@ static void setXCrossingEventSpecificFields(XEvent* xEvent, MouseEvent* event, c
 
 void PluginView::handleMouseEvent(MouseEvent* event)
 {
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 
     if (!m_isStarted || m_status != PluginStatusLoadedSuccessfully)
         return;
@@ -535,7 +535,7 @@ void PluginView::setNPWindowIfNeeded()
     }
 
     PluginView::setCurrentPluginView(this);
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     setCallingPlugin(true);
     m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
     setCallingPlugin(false);
@@ -842,7 +842,7 @@ bool PluginView::platformStart()
 #if defined(XP_UNIX)
     if (m_plugin->pluginFuncs()->getvalue) {
         PluginView::setCurrentPluginView(this);
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         setCallingPlugin(true);
         m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginNeedsXEmbed, &m_needsXEmbed);
         setCallingPlugin(false);
index 2d9d686..785a74d 100644 (file)
@@ -426,7 +426,7 @@ void PluginView::setNPWindowIfNeeded()
             m_npWindow.clipRect.right - m_npWindow.clipRect.left, m_npWindow.clipRect.bottom - m_npWindow.clipRect.top);
 
     PluginView::setCurrentPluginView(this);
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     setCallingPlugin(true);
     m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
     setCallingPlugin(false);
@@ -772,7 +772,7 @@ Point PluginView::mousePosForPlugin(MouseEvent* event) const
 bool PluginView::dispatchNPEvent(NPEvent& event)
 {
     PluginView::setCurrentPluginView(this);
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     setCallingPlugin(true);
 
     bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event);
index eda0504..bee7f62 100644 (file)
@@ -373,7 +373,7 @@ bool PluginView::dispatchNPEvent(NPEvent& event)
 
     PluginView::setCurrentPluginView(this);
 #if USE(JSC)
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 #endif
     setCallingPlugin(true);
     bool accepted = !m_plugin->pluginFuncs()->event(m_instance, &event);
@@ -687,7 +687,7 @@ void PluginView::setNPWindowIfNeeded()
 
     PluginView::setCurrentPluginView(this);
 #if USE(JSC)
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 #endif
     setCallingPlugin(true);
     m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
@@ -949,7 +949,7 @@ bool PluginView::platformStart()
     if (m_plugin->pluginFuncs()->getvalue) {
         PluginView::setCurrentPluginView(this);
 #if USE(JSC)
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 #endif
         setCallingPlugin(true);
         m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginNeedsXEmbed, &m_needsXEmbed);
index d4dc9b9..05cc102 100644 (file)
@@ -537,7 +537,7 @@ bool PluginView::dispatchNPEvent(NPEvent& npEvent)
         shouldPop = true;
     }
 
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     setCallingPlugin(true);
     bool accepted = !m_plugin->pluginFuncs()->event(m_instance, &npEvent);
     setCallingPlugin(false);
@@ -688,7 +688,7 @@ void PluginView::handleKeyboardEvent(KeyboardEvent* event)
     } else
         return;
 
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     if (dispatchNPEvent(npEvent))
         event->setDefaultHandled();
 }
@@ -758,7 +758,7 @@ void PluginView::handleMouseEvent(MouseEvent* event)
     } else
         return;
 
-    JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
     // FIXME: Consider back porting the http://webkit.org/b/58108 fix here.
     if (dispatchNPEvent(npEvent))
         event->setDefaultHandled();
@@ -846,7 +846,7 @@ void PluginView::setNPWindowRect(const IntRect& rect)
     m_npWindow.clipRect.top = 0;
 
     if (m_plugin->pluginFuncs()->setwindow) {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         setCallingPlugin(true);
         m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
         setCallingPlugin(false);
index 7e50bc2..f36e4a0 100644 (file)
@@ -39,8 +39,8 @@ namespace WebCoreTestSupport {
 
 void injectInternalsObject(JSContextRef context)
 {
-    JSLock lock(SilenceAssertionsOnly);
     ExecState* exec = toJS(context);
+    JSLockHolder lock(exec);
     JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
     ScriptExecutionContext* scriptContext = globalObject->scriptExecutionContext();
     Document* document = scriptContext->isDocument() ? static_cast<Document*>(scriptContext) : 0;
@@ -49,8 +49,8 @@ void injectInternalsObject(JSContextRef context)
 
 void resetInternalsObject(JSContextRef context)
 {
-    JSLock lock(SilenceAssertionsOnly);
     ExecState* exec = toJS(context);
+    JSLockHolder lock(exec);
     JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
     Internals * internals = toInternals(globalObject->getDirect(exec->globalData(), Identifier(exec, Internals::internalsId)));
     if (internals) {
index b079d0c..ebe8d2f 100644 (file)
@@ -851,8 +851,8 @@ void XMLHttpRequest::dropProtection()
     // out. But it is protected from GC while loading, so this
     // can't be recouped until the load is done, so only
     // report the extra cost at that point.
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
     JSC::JSGlobalData* globalData = scriptExecutionContext()->globalData();
+    JSC::JSLockHolder lock(globalData);
     globalData->heap.reportExtraMemoryCost(m_responseBuilder.length() * 2);
 #endif
 
index 3a6033a..a4c48a5 100644 (file)
@@ -105,7 +105,10 @@ void clearMemoryCaches()
     BlackBerry::Platform::userInterfaceThreadMessageClient()->dispatchMessage(BlackBerry::Platform::createFunctionCallMessage(clearMemoryCachesInCompositingThread));
 #endif
 
-    collectJavascriptGarbageNow();
+    {
+        JSC::JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
+        collectJavascriptGarbageNow();
+    }
 
     // Clean caches after JS garbage collection because JS GC can
     // generate more dead resources.
index 9d9db92..ae37ba0 100644 (file)
@@ -1,3 +1,23 @@
+2012-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSLock should be per-JSGlobalData
+        https://bugs.webkit.org/show_bug.cgi?id=89123
+
+        Reviewed by Geoffrey Garen.
+
+        Changed all sites that used JSLock to instead use the new JSLockHolder
+        and pass in the correct JS context that the code is about to interact with that 
+        needs protection. Also added a couple JSLocks to places that didn't already 
+        have it that needed it.
+
+        * Api/BlackBerryGlobal.cpp:
+        (BlackBerry::WebKit::clearMemoryCaches):
+        * WebCoreSupport/ClientExtension.cpp:
+        * WebCoreSupport/PagePopupBlackBerry.cpp:
+        (WebCore::PagePopupBlackBerry::installDomFunction):
+        * WebKitSupport/DumpRenderTreeSupport.cpp:
+        (DumpRenderTreeSupport::computedStyleIncludingVisitedInfo):
+
 2012-06-27  Jacky Jiang  <zhajiang@rim.com>
 
         [BlackBerry] Wrong scale after leaving fullscreen <video>
index d3d7b62..c6d0a6e 100644 (file)
@@ -84,11 +84,11 @@ static JSStaticValue clientExtensionStaticValues[] = {
 // FIXME: Revisit the creation of this class and make sure this is the best way to approach it.
 void attachExtensionObjectToFrame(Frame* frame, WebPageClient* client)
 {
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
-
     JSDOMWindow* window = frame->script()->windowShell(mainThreadNormalWorld())->window();
 
     JSC::ExecState* exec = window->globalExec();
+    JSC::JSLockHolder lock(exec);
+
     JSContextRef scriptCtx = toRef(exec);
 
     JSClassDefinition definition = kJSClassDefinitionEmpty;
index a751fb7..354f128 100644 (file)
@@ -122,13 +122,12 @@ static JSStaticValue popUpExtensionStaticValues[] =
 
 void PagePopupBlackBerry::installDomFunction(Frame* frame)
 {
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
-
     JSDOMWindow* window = toJSDOMWindow(frame, mainThreadNormalWorld());
     ASSERT(window);
 
     JSC::ExecState* exec = window->globalExec();
     ASSERT(exec);
+    JSC::JSLockHolder lock(exec);
 
     JSContextRef context = ::toRef(exec);
     JSObjectRef globalObject = JSContextGetGlobalObject(context);
index cd1cb4c..f60c162 100644 (file)
@@ -141,8 +141,8 @@ void DumpRenderTreeSupport::scalePageBy(WebPage* webPage, float scaleFactor, flo
 
 JSValueRef DumpRenderTreeSupport::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value)
 {
-    JSLock lock(SilenceAssertionsOnly);
     ExecState* exec = toJS(context);
+    JSLockHolder lock(exec);
     if (!value)
         return JSValueMakeUndefined(context);
     JSValue jsValue = toJS(exec, value);
index 2a67575..6c6ff93 100644 (file)
@@ -1,3 +1,20 @@
+2012-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSLock should be per-JSGlobalData
+        https://bugs.webkit.org/show_bug.cgi?id=89123
+
+        Reviewed by Geoffrey Garen.
+
+        Changed all sites that used JSLock to instead use the new JSLockHolder
+        and pass in the correct JS context that the code is about to interact with that 
+        needs protection. Also added a couple JSLocks to places that didn't already 
+        have it that needed it.
+
+        * ewk/ewk_frame.cpp:
+        (ewk_frame_script_execute):
+        * ewk/ewk_view.cpp:
+        (ewk_view_js_object_add):
+
 2012-06-26  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
 
         Change return type in bandwidth attribute of network information API
index 6ba941d..67a9bc8 100644 (file)
@@ -455,8 +455,8 @@ char* ewk_frame_script_execute(Evas_Object* ewkFrame, const char* script)
     if (!result || (!result.isBoolean() && !result.isString() && !result.isNumber()))
         return 0;
 
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
     JSC::ExecState* exec = smartData->frame->script()->globalObject(WebCore::mainThreadNormalWorld())->globalExec();
+    JSC::JSLockHolder lock(exec);
     resultString = WebCore::ustringToString(result.toString(exec)->value(exec));
     return strdup(resultString.utf8().data());
 #else
index c45569c..7c8b3db 100644 (file)
@@ -4045,8 +4045,8 @@ Eina_Bool ewk_view_js_object_add(Evas_Object* ewkView, Ewk_JS_Object* object, co
     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
 
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
     WebCore::JSDOMWindow* window = toJSDOMWindow(priv->mainFrame, WebCore::mainThreadNormalWorld());
+    JSC::JSLockHolder lock(window->globalExec());
     JSC::Bindings::RootObject* root;
     root = priv->mainFrame->script()->bindingRootObject();
 
index 5e2a63d..7504dd4 100644 (file)
@@ -1,3 +1,18 @@
+2012-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSLock should be per-JSGlobalData
+        https://bugs.webkit.org/show_bug.cgi?id=89123
+
+        Reviewed by Geoffrey Garen.
+
+        Changed all sites that used JSLock to instead use the new JSLockHolder
+        and pass in the correct JS context that the code is about to interact with that 
+        needs protection. Also added a couple JSLocks to places that didn't already 
+        have it that needed it.
+
+        * WebCoreSupport/DumpRenderTreeSupportGtk.cpp:
+        (DumpRenderTreeSupportGtk::gcCountJavascriptObjects):
+
 2012-06-27  Martin Robinson  <mrobinson@igalia.com>
 
         [gtk] Spell checker doesn't recognize contractions (apostrophes)
index a9de875..9eb8671 100644 (file)
@@ -600,7 +600,7 @@ void DumpRenderTreeSupportGtk::gcCollectJavascriptObjectsOnAlternateThread(bool
 
 unsigned long DumpRenderTreeSupportGtk::gcCountJavascriptObjects()
 {
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
+    JSC::JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     return JSDOMWindow::commonJSGlobalData()->heap.objectCount();
 }
 
index 606bceb..341f45f 100644 (file)
@@ -1,3 +1,69 @@
+2012-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSLock should be per-JSGlobalData
+        https://bugs.webkit.org/show_bug.cgi?id=89123
+
+        Reviewed by Geoffrey Garen.
+
+        Changed all sites that used JSLock to instead use the new JSLockHolder
+        and pass in the correct JS context that the code is about to interact with that 
+        needs protection. Also added a couple JSLocks to places that didn't already 
+        have it that needed it.
+
+        * DOM/WebDOMOperations.mm:
+        (JSC):
+        * Misc/WebCoreStatistics.mm:
+        (+[WebCoreStatistics javaScriptObjectsCount]):
+        (+[WebCoreStatistics javaScriptGlobalObjectsCount]):
+        (+[WebCoreStatistics javaScriptProtectedObjectsCount]):
+        (+[WebCoreStatistics javaScriptProtectedGlobalObjectsCount]):
+        (+[WebCoreStatistics javaScriptProtectedObjectTypeCounts]):
+        (+[WebCoreStatistics javaScriptObjectTypeCounts]):
+        (+[WebCoreStatistics shouldPrintExceptions]):
+        (+[WebCoreStatistics setShouldPrintExceptions:]):
+        (+[WebCoreStatistics memoryStatistics]):
+        (+[WebCoreStatistics javaScriptReferencedObjectsCount]):
+        * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
+        (WebKit::NetscapePluginInstanceProxy::evaluate):
+        (WebKit::NetscapePluginInstanceProxy::invoke):
+        (WebKit::NetscapePluginInstanceProxy::invokeDefault):
+        (WebKit::NetscapePluginInstanceProxy::construct):
+        (WebKit::NetscapePluginInstanceProxy::getProperty):
+        (WebKit::NetscapePluginInstanceProxy::setProperty):
+        (WebKit::NetscapePluginInstanceProxy::removeProperty):
+        (WebKit::NetscapePluginInstanceProxy::hasMethod):
+        (WebKit::NetscapePluginInstanceProxy::enumerate):
+        (WebKit::NetscapePluginInstanceProxy::addValueToArray):
+        (WebKit::NetscapePluginInstanceProxy::moveGlobalExceptionToExecState):
+        * Plugins/WebNetscapePluginStream.mm:
+        (WebNetscapePluginStream::wantsAllStreams):
+        * Plugins/WebNetscapePluginView.mm:
+        (-[WebNetscapePluginView sendEvent:isDrawRect:]):
+        (-[WebNetscapePluginView privateBrowsingModeDidChange]):
+        (-[WebNetscapePluginView setWindowIfNecessary]):
+        (-[WebNetscapePluginView createPluginScriptableObject]):
+        (-[WebNetscapePluginView getFormValue:]):
+        (-[WebNetscapePluginView evaluateJavaScriptPluginRequest:]):
+        (-[WebNetscapePluginView webFrame:didFinishLoadWithReason:]):
+        (-[WebNetscapePluginView loadPluginRequest:]):
+        (-[WebNetscapePluginView _printedPluginBitmap]):
+        * Plugins/WebPluginController.mm:
+        (+[WebPluginController plugInViewWithArguments:fromPluginPackage:]):
+        (-[WebPluginController stopOnePlugin:]):
+        (-[WebPluginController destroyOnePlugin:]):
+        (-[WebPluginController startAllPlugins]):
+        (-[WebPluginController addPlugin:]):
+        * WebView/WebFrame.mm:
+        (-[WebFrame _stringByEvaluatingJavaScriptFromString:forceUserGesture:]):
+        (-[WebFrame _stringByEvaluatingJavaScriptFromString:withGlobalObject:inScriptWorld:]):
+        * WebView/WebScriptDebugDelegate.mm:
+        (-[WebScriptCallFrame scopeChain]):
+        (-[WebScriptCallFrame evaluateWebScript:]):
+        * WebView/WebView.mm:
+        (+[WebView _reportException:inContext:]):
+        (-[WebView aeDescByEvaluatingJavaScriptFromString:]):
+        (-[WebView _computedStyleIncludingVisitedInfo:forElement:]):
+
 2012-06-23  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r121058.
index e6e6d3a..aaa7a70 100644 (file)
@@ -67,8 +67,9 @@ using namespace JSC;
     if (!value)
         return 0;
 
-    JSLock lock(SilenceAssertionsOnly);
-    return kit(toElement(toJS(toJS(context), value)));
+    ExecState* exec = toJS(context);
+    JSLockHolder lock(exec);
+    return kit(toElement(toJS(exec, value)));
 }
 
 - (NSString *)_markerTextForListItem
index 1840451..296dd6b 100644 (file)
@@ -58,31 +58,31 @@ using namespace WebCore;
 
 + (size_t)javaScriptObjectsCount
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     return JSDOMWindow::commonJSGlobalData()->heap.objectCount();
 }
 
 + (size_t)javaScriptGlobalObjectsCount
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     return JSDOMWindow::commonJSGlobalData()->heap.globalObjectCount();
 }
 
 + (size_t)javaScriptProtectedObjectsCount
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     return JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount();
 }
 
 + (size_t)javaScriptProtectedGlobalObjectsCount
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     return JSDOMWindow::commonJSGlobalData()->heap.protectedGlobalObjectCount();
 }
 
 + (NSCountedSet *)javaScriptProtectedObjectTypeCounts
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     
     NSCountedSet *result = [NSCountedSet set];
 
@@ -97,7 +97,7 @@ using namespace WebCore;
 
 + (NSCountedSet *)javaScriptObjectTypeCounts
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     
     NSCountedSet *result = [NSCountedSet set];
 
@@ -167,13 +167,13 @@ using namespace WebCore;
 
 + (BOOL)shouldPrintExceptions
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     return Console::shouldPrintExceptions();
 }
 
 + (void)setShouldPrintExceptions:(BOOL)print
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     Console::setShouldPrintExceptions(print);
 }
 
@@ -201,7 +201,7 @@ using namespace WebCore;
 {
     WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics();
     
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     size_t heapSize = JSDOMWindow::commonJSGlobalData()->heap.size();
     size_t heapFree = JSDOMWindow::commonJSGlobalData()->heap.capacity() - heapSize;
     GlobalMemoryStatistics globalMemoryStats = globalMemoryStatistics();
@@ -245,7 +245,7 @@ using namespace WebCore;
 
 + (size_t)javaScriptReferencedObjectsCount
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     return JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount();
 }
 
index fa82096..4a7d3d2 100644 (file)
@@ -867,8 +867,7 @@ bool NetscapePluginInstanceProxy::evaluate(uint32_t objectID, const String& scri
     if (!frame)
         return false;
 
-    JSLock lock(SilenceAssertionsOnly);
-    
+    JSLockHolder lock(pluginWorld()->globalData());
     Strong<JSGlobalObject> globalObject(*pluginWorld()->globalData(), frame->script()->globalObject(pluginWorld()));
     ExecState* exec = globalObject->globalExec();
 
@@ -904,7 +903,7 @@ bool NetscapePluginInstanceProxy::invoke(uint32_t objectID, const Identifier& me
         return false;
     
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     JSValue function = object->get(exec, methodName);
     CallData callData;
     CallType callType = getCallData(function, callData);
@@ -937,7 +936,7 @@ bool NetscapePluginInstanceProxy::invokeDefault(uint32_t objectID, data_t argume
         return false;
     
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
-    JSLock lock(SilenceAssertionsOnly);    
+    JSLockHolder lock(exec);    
     CallData callData;
     CallType callType = object->methodTable()->getCallData(object, callData);
     if (callType == CallTypeNone)
@@ -969,7 +968,7 @@ bool NetscapePluginInstanceProxy::construct(uint32_t objectID, data_t argumentsD
         return false;
     
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     ConstructData constructData;
     ConstructType constructType = object->methodTable()->getConstructData(object, constructData);
@@ -1002,7 +1001,7 @@ bool NetscapePluginInstanceProxy::getProperty(uint32_t objectID, const Identifie
         return false;
     
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
-    JSLock lock(SilenceAssertionsOnly);    
+    JSLockHolder lock(exec);    
     JSValue value = object->get(exec, propertyName);
     
     marshalValue(exec, value, resultData, resultLength);
@@ -1023,7 +1022,7 @@ bool NetscapePluginInstanceProxy::getProperty(uint32_t objectID, unsigned proper
         return false;
     
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
-    JSLock lock(SilenceAssertionsOnly);    
+    JSLockHolder lock(exec);    
     JSValue value = object->get(exec, propertyName);
     
     marshalValue(exec, value, resultData, resultLength);
@@ -1047,7 +1046,7 @@ bool NetscapePluginInstanceProxy::setProperty(uint32_t objectID, const Identifie
         return false;
     
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
-    JSLock lock(SilenceAssertionsOnly);    
+    JSLockHolder lock(exec);    
 
     JSValue value = demarshalValue(exec, valueData, valueLength);
     PutPropertySlot slot;
@@ -1073,7 +1072,7 @@ bool NetscapePluginInstanceProxy::setProperty(uint32_t objectID, unsigned proper
         return false;
     
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
-    JSLock lock(SilenceAssertionsOnly);    
+    JSLockHolder lock(exec);    
     
     JSValue value = demarshalValue(exec, valueData, valueLength);
     object->methodTable()->putByIndex(object, exec, propertyName, value, false);
@@ -1098,12 +1097,12 @@ bool NetscapePluginInstanceProxy::removeProperty(uint32_t objectID, const Identi
         return false;
 
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
+    JSLockHolder lock(exec);
     if (!object->hasProperty(exec, propertyName)) {
         exec->clearException();
         return false;
     }
     
-    JSLock lock(SilenceAssertionsOnly);
     object->methodTable()->deleteProperty(object, exec, propertyName);
     exec->clearException();    
     return true;
@@ -1125,12 +1124,12 @@ bool NetscapePluginInstanceProxy::removeProperty(uint32_t objectID, unsigned pro
         return false;
     
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
+    JSLockHolder lock(exec);
     if (!object->hasProperty(exec, propertyName)) {
         exec->clearException();
         return false;
     }
     
-    JSLock lock(SilenceAssertionsOnly);
     object->methodTable()->deletePropertyByIndex(object, exec, propertyName);
     exec->clearException();    
     return true;
@@ -1196,7 +1195,7 @@ bool NetscapePluginInstanceProxy::hasMethod(uint32_t objectID, const Identifier&
         return false;
     
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     JSValue func = object->get(exec, methodName);
     exec->clearException();
     return !func.isUndefined();
@@ -1218,7 +1217,7 @@ bool NetscapePluginInstanceProxy::enumerate(uint32_t objectID, data_t& resultDat
         return false;
     
     ExecState* exec = frame->script()->globalObject(pluginWorld())->globalExec();
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
  
     PropertyNameArray propertyNames(exec);
     object->methodTable()->getPropertyNames(object, exec, propertyNames, ExcludeDontEnumProperties);
@@ -1262,7 +1261,7 @@ static bool getObjectID(NetscapePluginInstanceProxy* pluginInstanceProxy, JSObje
     
 void NetscapePluginInstanceProxy::addValueToArray(NSMutableArray *array, ExecState* exec, JSValue value)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     if (value.isString()) {
         [array addObject:[NSNumber numberWithInt:StringValueType]];
@@ -1672,7 +1671,7 @@ void NetscapePluginInstanceProxy::moveGlobalExceptionToExecState(ExecState* exec
         return;
 
     {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         throwError(exec, createError(exec, stringToUString(globalExceptionString())));
     }
 
index bb7f4d5..a7daaae 100644 (file)
@@ -368,7 +368,7 @@ bool WebNetscapePluginStream::wantsAllStreams() const
     NPError error;
     {
         PluginStopDeferrer deferrer(m_pluginView.get());
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         error = m_pluginFuncs->getvalue(m_plugin, NPPVpluginWantsAllNetworkStreams, &value);
     }
     if (error != NPERR_NO_ERROR)
index 5f1f556..426405f 100644 (file)
@@ -669,7 +669,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     // Set the pluginAllowPopup flag.
     ASSERT(_eventHandler);
     {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         UserGestureIndicator gestureIndicator(_eventHandler->currentEventIsUserGesture() ? DefinitelyProcessingUserGesture : PossiblyProcessingUserGesture);
         acceptedEvent = [_pluginPackage.get() pluginFuncs]->event(plugin, event);
     }
@@ -850,7 +850,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
 
     [self willCallPlugInFunction];
     {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         if ([_pluginPackage.get() pluginFuncs]->setvalue)
             [_pluginPackage.get() pluginFuncs]->setvalue(plugin, NPNVprivateModeBool, &value);
     }
@@ -991,7 +991,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
         inSetWindow = YES;        
         [self willCallPlugInFunction];
         {
-            JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+            JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
             npErr = [_pluginPackage.get() pluginFuncs]->setwindow(plugin, &window);
         }
         [self didCallPlugInFunction];
@@ -1444,7 +1444,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     NPError error;
     [self willCallPlugInFunction];
     {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         error = [_pluginPackage.get() pluginFuncs]->getvalue(plugin, NPPVpluginScriptableNPObject, &value);
     }
     [self didCallPlugInFunction];
@@ -1463,7 +1463,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     NPError error;
     [self willCallPlugInFunction];
     {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         error = [_pluginPackage.get() pluginFuncs]->getvalue(plugin, NPPVformValue, &buffer);
     }
     [self didCallPlugInFunction];
@@ -1595,7 +1595,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
         if ([JSPluginRequest sendNotification]) {
             [self willCallPlugInFunction];
             {
-                JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+                JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
                 [_pluginPackage.get() pluginFuncs]->urlnotify(plugin, [URL _web_URLCString], NPRES_DONE, [JSPluginRequest notifyData]);
             }
             [self didCallPlugInFunction];
@@ -1627,7 +1627,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
         
     [self willCallPlugInFunction];
     {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         [_pluginPackage.get() pluginFuncs]->urlnotify(plugin, [[[pluginRequest request] URL] _web_URLCString], reason, [pluginRequest notifyData]);
     }
     [self didCallPlugInFunction];
@@ -1671,7 +1671,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
                 if ([pluginRequest sendNotification]) {
                     [self willCallPlugInFunction];
                     {
-                        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+                        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
                         [_pluginPackage.get() pluginFuncs]->urlnotify(plugin, [[[pluginRequest request] URL] _web_URLCString], NPERR_GENERIC_ERROR, [pluginRequest notifyData]);
                     }
                     [self didCallPlugInFunction];
@@ -2471,7 +2471,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     // Tell the plugin to print into the GWorld
     [self willCallPlugInFunction];
     {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         [_pluginPackage.get() pluginFuncs]->print(plugin, &npPrint);
     }
     [self didCallPlugInFunction];
index 65a05ae..dd599d6 100644 (file)
@@ -96,10 +96,10 @@ static NSMutableSet *pluginViews = nil;
     NSView *view = nil;
 
     if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         view = [viewFactory plugInViewWithArguments:arguments];
     } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         view = [viewFactory pluginViewWithArguments:arguments];
     }
     
@@ -149,10 +149,10 @@ static NSMutableSet *pluginViews = nil;
 - (void)stopOnePlugin:(NSView *)view
 {
     if ([view respondsToSelector:@selector(webPlugInStop)]) {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         [view webPlugInStop];
     } else if ([view respondsToSelector:@selector(pluginStop)]) {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         [view pluginStop];
     }
 }
@@ -160,10 +160,10 @@ static NSMutableSet *pluginViews = nil;
 - (void)destroyOnePlugin:(NSView *)view
 {
     if ([view respondsToSelector:@selector(webPlugInDestroy)]) {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         [view webPlugInDestroy];
     } else if ([view respondsToSelector:@selector(pluginDestroy)]) {
-        JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         [view pluginDestroy];
     }
 }
@@ -180,10 +180,10 @@ static NSMutableSet *pluginViews = nil;
     for (int i = 0; i < count; i++) {
         id aView = [_views objectAtIndex:i];
         if ([aView respondsToSelector:@selector(webPlugInStart)]) {
-            JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+            JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
             [aView webPlugInStart];
         } else if ([aView respondsToSelector:@selector(pluginStart)]) {
-            JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+            JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
             [aView pluginStart];
         }
     }
@@ -252,10 +252,10 @@ static NSMutableSet *pluginViews = nil;
 
         LOG(Plugins, "initializing plug-in %@", view);
         if ([view respondsToSelector:@selector(webPlugInInitialize)]) {
-            JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+            JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
             [view webPlugInInitialize];
         } else if ([view respondsToSelector:@selector(pluginInitialize)]) {
-            JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+            JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
             [view pluginInitialize];
         }
 
@@ -265,15 +265,15 @@ static NSMutableSet *pluginViews = nil;
         if (_started) {
             LOG(Plugins, "starting plug-in %@", view);
             if ([view respondsToSelector:@selector(webPlugInStart)]) {
-                JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+                JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
                 [view webPlugInStart];
             } else if ([view respondsToSelector:@selector(pluginStart)]) {
-                JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+                JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
                 [view pluginStart];
             }
             
             if ([view respondsToSelector:@selector(setContainingWindow:)]) {
-                JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
+                JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
                 [view setContainingWindow:[_documentView window]];
             }
         }
index 3c497f6..0ad0eca 100644 (file)
@@ -104,7 +104,6 @@ using namespace HTMLNames;
 using JSC::JSGlobalObject;
 using JSC::JSLock;
 using JSC::JSValue;
-using JSC::SilenceAssertionsOnly;
 
 /*
 Here is the current behavior matrix for four types of navigations:
@@ -597,8 +596,8 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
     if (!result || (!result.isBoolean() && !result.isString() && !result.isNumber()))
         return @"";
 
-    JSLock lock(SilenceAssertionsOnly);
     JSC::ExecState* exec = _private->coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec();
+    JSC::JSLockHolder lock(exec);
     return ustringToString(result.toString(exec)->value(exec));
 }
 
@@ -1123,8 +1122,8 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
     if (!result || (!result.isBoolean() && !result.isString() && !result.isNumber()))
         return @"";
 
-    JSLock lock(SilenceAssertionsOnly);
     JSC::ExecState* exec = anyWorldGlobalObject->globalExec();
+    JSC::JSLockHolder lock(exec);
     return ustringToString(result.toString(exec)->value(exec));
 }
 
index 25a596c..50b84be 100644 (file)
@@ -174,9 +174,9 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber";
     if (!_private->debuggerCallFrame)
         return [NSArray array];
 
-    JSLock lock(SilenceAssertionsOnly);
 
     ScopeChainNode* scopeChain = _private->debuggerCallFrame->scopeChain();
+    JSLockHolder lock(scopeChain->globalData);
     if (!scopeChain->next)  // global frame
         return [NSArray arrayWithObject:_private->globalObject];
 
@@ -229,13 +229,13 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber";
     if (!_private->debuggerCallFrame)
         return nil;
 
-    JSLock lock(SilenceAssertionsOnly);
-
     // If this is the global call frame and there is no dynamic global object,
     // Dashcode is attempting to execute JS in the evaluator using a stale
     // WebScriptCallFrame. Instead, we need to set the dynamic global object
     // and evaluate the JS in the global object's global call frame.
     JSGlobalObject* globalObject = _private->debugger->globalObject();
+    JSLockHolder lock(globalObject->globalData());
+
     if (self == _private->debugger->globalCallFrame() && !globalObject->globalData().dynamicGlobalObject) {
         JSGlobalObject* globalObject = _private->debugger->globalObject();
 
index f7a681b..45a4cf5 100644 (file)
@@ -581,8 +581,8 @@ static NSString *createUserVisibleWebKitVersionString()
     if (!exception || !context)
         return;
 
-    JSLock lock(SilenceAssertionsOnly);
     JSC::ExecState* execState = toJS(context);
+    JSLockHolder lock(execState);
 
     // Make sure the context has a DOMWindow global object, otherwise this context didn't originate from a WebView.
     if (!toJSDOMWindow(execState->lexicalGlobalObject()))
@@ -4851,7 +4851,7 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue jsValu
     JSValue result = coreFrame->script()->executeScript(script, true).jsValue();
     if (!result) // FIXME: pass errors
         return 0;
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
     return aeDescFromJSValue(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec(), result);
 }
 
@@ -6560,8 +6560,8 @@ static void glibContextIterationCallback(CFRunLoopObserverRef, CFRunLoopActivity
 
 - (JSValueRef)_computedStyleIncludingVisitedInfo:(JSContextRef)context forElement:(JSValueRef)value
 {
-    JSLock lock(SilenceAssertionsOnly);
     ExecState* exec = toJS(context);
+    JSLockHolder lock(exec);
     if (!value)
         return JSValueMakeUndefined(context);
     JSValue jsValue = toJS(exec, value);
index b72d4e4..0360638 100644 (file)
@@ -506,13 +506,12 @@ static JSValueRef qtSenderCallback(JSContextRef context, JSObjectRef, JSObjectRe
 
 void QWebFramePrivate::addQtSenderToGlobalObject()
 {
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
-
     JSDOMWindow* window = toJSDOMWindow(frame, mainThreadNormalWorld());
     Q_ASSERT(window);
 
     JSC::ExecState* exec = window->globalExec();
     Q_ASSERT(exec);
+    JSC::JSLockHolder lock(exec);
 
     JSContextRef context = ::toRef(exec);
     JSRetainPtr<JSStringRef> propertyName(Adopt, JSStringCreateWithUTF8CString("__qt_sender__"));
@@ -657,7 +656,6 @@ void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object
         return;
 #if USE(JSC)
     JSC::Bindings::QtInstance::ValueOwnership valueOwnership = static_cast<JSC::Bindings::QtInstance::ValueOwnership>(ownership);
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
     JSDOMWindow* window = toJSDOMWindow(d->frame, mainThreadNormalWorld());
     JSC::Bindings::RootObject* root;
     if (valueOwnership == JSC::Bindings::QtInstance::QtOwnership)
@@ -675,6 +673,7 @@ void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object
     }
 
     JSC::ExecState* exec = window->globalExec();
+    JSC::JSLockHolder lock(exec);
 
     JSC::JSObject* runtimeObject =
             JSC::Bindings::QtInstance::getQtInstance(object, root, valueOwnership)->createRuntimeObject(exec);
index 8789ec9..5e674d0 100644 (file)
@@ -1,3 +1,22 @@
+2012-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSLock should be per-JSGlobalData
+        https://bugs.webkit.org/show_bug.cgi?id=89123
+
+        Reviewed by Geoffrey Garen.
+
+        Changed all sites that used JSLock to instead use the new JSLockHolder
+        and pass in the correct JS context that the code is about to interact with that 
+        needs protection. Also added a couple JSLocks to places that didn't already 
+        have it that needed it.
+
+        * Api/qwebframe.cpp:
+        (QWebFramePrivate::addQtSenderToGlobalObject):
+        (QWebFrame::addToJavaScriptWindowObject):
+        * WebCoreSupport/DumpRenderTreeSupportQt.cpp:
+        (DumpRenderTreeSupportQt::injectInternalsObject):
+        (DumpRenderTreeSupportQt::resetInternalsObject):
+
 2012-06-27  Simon Hausmann  <simon.hausmann@nokia.com>
 
         [Qt] Fix compilation of example platform plugin with Qt 5
index 3814d35..acc6635 100644 (file)
@@ -1086,13 +1086,12 @@ void DumpRenderTreeSupportQt::injectInternalsObject(QWebFrame* frame)
 {
     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
 #if USE(JSC)
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
-
     JSDOMWindow* window = toJSDOMWindow(coreFrame, mainThreadNormalWorld());
     Q_ASSERT(window);
 
     JSC::ExecState* exec = window->globalExec();
     Q_ASSERT(exec);
+    JSC::JSLockHolder lock(exec);
 
     JSContextRef context = toRef(exec);
     WebCoreTestSupport::injectInternalsObject(context);
@@ -1113,13 +1112,12 @@ void DumpRenderTreeSupportQt::resetInternalsObject(QWebFrame* frame)
 {
     WebCore::Frame* coreFrame = QWebFramePrivate::core(frame);
 #if USE(JSC)
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
-
     JSDOMWindow* window = toJSDOMWindow(coreFrame, mainThreadNormalWorld());
     Q_ASSERT(window);
 
     JSC::ExecState* exec = window->globalExec();
     Q_ASSERT(exec);
+    JSC::JSLockHolder lock(exec);
 
     JSContextRef context = toRef(exec);
     WebCoreTestSupport::resetInternalsObject(context);
index 39d4d07..9f2755c 100644 (file)
@@ -1,3 +1,30 @@
+2012-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSLock should be per-JSGlobalData
+        https://bugs.webkit.org/show_bug.cgi?id=89123
+
+        Reviewed by Geoffrey Garen.
+
+        Changed all sites that used JSLock to instead use the new JSLockHolder
+        and pass in the correct JS context that the code is about to interact with that 
+        needs protection. Also added a couple JSLocks to places that didn't already 
+        have it that needed it.
+
+        * WebCoreStatistics.cpp:
+        (WebCoreStatistics::javaScriptObjectsCount):
+        (WebCoreStatistics::javaScriptGlobalObjectsCount):
+        (WebCoreStatistics::javaScriptProtectedObjectsCount):
+        (WebCoreStatistics::javaScriptProtectedGlobalObjectsCount):
+        (WebCoreStatistics::javaScriptProtectedObjectTypeCounts):
+        * WebFrame.cpp:
+        (WebFrame::stringByEvaluatingJavaScriptInScriptWorld):
+        * WebJavaScriptCollector.cpp:
+        (WebJavaScriptCollector::objectCount):
+        * WebView.cpp:
+        (WebView::stringByEvaluatingJavaScriptFromString):
+        (WebView::reportException):
+        (WebView::elementFromJS):
+
 2012-06-23  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r121058.
index 0e30576..c1ca9f2 100644 (file)
@@ -98,7 +98,7 @@ HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptObjectsCount(
     if (!count)
         return E_POINTER;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     *count = (UINT)JSDOMWindow::commonJSGlobalData()->heap.objectCount();
     return S_OK;
 }
@@ -109,7 +109,7 @@ HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptGlobalObjectsCount(
     if (!count)
         return E_POINTER;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     *count = (UINT)JSDOMWindow::commonJSGlobalData()->heap.globalObjectCount();
     return S_OK;
 }
@@ -120,7 +120,7 @@ HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptProtectedObjectsCount(
     if (!count)
         return E_POINTER;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     *count = (UINT)JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount();
     return S_OK;
 }
@@ -131,7 +131,7 @@ HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptProtectedGlobalObjectsCou
     if (!count)
         return E_POINTER;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     *count = (UINT)JSDOMWindow::commonJSGlobalData()->heap.protectedGlobalObjectCount();
     return S_OK;
 }
@@ -139,7 +139,7 @@ HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptProtectedGlobalObjectsCou
 HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptProtectedObjectTypeCounts( 
     /* [retval][out] */ IPropertyBag2** typeNamesAndCounts)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     OwnPtr<TypeCountSet> jsObjectTypeNames(JSDOMWindow::commonJSGlobalData()->heap.protectedObjectTypeCounts());
     typedef TypeCountSet::const_iterator Iterator;
     Iterator end = jsObjectTypeNames->end();
index 27d24f2..9ce1c78 100644 (file)
@@ -126,7 +126,6 @@ using namespace std;
 using JSC::JSGlobalObject;
 using JSC::JSLock;
 using JSC::JSValue;
-using JSC::SilenceAssertionsOnly;
 
 #define FLASH_REDRAW 0
 
@@ -2528,8 +2527,8 @@ HRESULT WebFrame::stringByEvaluatingJavaScriptInScriptWorld(IWebScriptWorld* iWo
     if (!result || !result.isBoolean() && !result.isString() && !result.isNumber())
         return S_OK;
 
-    JSLock lock(SilenceAssertionsOnly);
     JSC::ExecState* exec = anyWorldGlobalObject->globalExec();
+    JSC::JSLockHolder lock(exec);
     String resultString = ustringToString(result.toString(exec)->value(exec));
     *evaluationResult = BString(resultString).release();
 
index cb56b27..7b2f67f 100644 (file)
@@ -111,7 +111,7 @@ HRESULT STDMETHODCALLTYPE WebJavaScriptCollector::objectCount(
         return E_POINTER;
     }
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     *count = (UINT)JSDOMWindow::commonJSGlobalData()->heap.objectCount();
     return S_OK;
 }
index 880bc1b..b32c8b4 100644 (file)
@@ -3194,8 +3194,8 @@ HRESULT STDMETHODCALLTYPE WebView::stringByEvaluatingJavaScriptFromString(
     if (!scriptExecutionResult)
         return E_FAIL;
     else if (scriptExecutionResult.isString()) {
-        JSLock lock(JSC::SilenceAssertionsOnly);
         JSC::ExecState* exec = coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec();
+        JSC::JSLockHolder lock(exec);
         *result = BString(ustringToString(scriptExecutionResult.getString(exec)));
     }
 
@@ -5851,8 +5851,8 @@ HRESULT STDMETHODCALLTYPE WebView::reportException(
     if (!context || !exception)
         return E_FAIL;
 
-    JSLock lock(JSC::SilenceAssertionsOnly);
     JSC::ExecState* execState = toJS(context);
+    JSC::JSLockHolder lock(execState);
 
     // Make sure the context has a DOMWindow global object, otherwise this context didn't originate from a WebView.
     if (!toJSDOMWindow(execState->lexicalGlobalObject()))
@@ -5878,8 +5878,9 @@ HRESULT STDMETHODCALLTYPE WebView::elementFromJS(
     if (!nodeObject)
         return E_FAIL;
 
-    JSLock lock(JSC::SilenceAssertionsOnly);
-    Element* elt = toElement(toJS(toJS(context), nodeObject));
+    JSC::ExecState* exec = toJS(context);
+    JSC::JSLockHolder lock(exec);
+    Element* elt = toElement(toJS(exec, nodeObject));
     if (!elt)
         return E_FAIL;
 
index 88556d1..208d591 100644 (file)
@@ -1,3 +1,50 @@
+2012-06-25  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        JSLock should be per-JSGlobalData
+        https://bugs.webkit.org/show_bug.cgi?id=89123
+
+        Reviewed by Geoffrey Garen.
+
+        Changed all sites that used JSLock to instead use the new JSLockHolder
+        and pass in the correct JS context that the code is about to interact with that 
+        needs protection. Also added a couple JSLocks to places that didn't already 
+        have it that needed it.
+
+        * Shared/mac/WebMemorySampler.mac.mm:
+        (WebKit::WebMemorySampler::sampleWebKit):
+        * WebProcess/InjectedBundle/InjectedBundle.cpp:
+        (WebKit::InjectedBundle::javaScriptObjectsCount):
+        (WebKit::InjectedBundle::reportException):
+        * WebProcess/Plugins/Netscape/JSNPObject.cpp:
+        (WebKit::JSNPObject::callMethod):
+        (WebKit::JSNPObject::callObject):
+        (WebKit::JSNPObject::callConstructor):
+        (WebKit::JSNPObject::put):
+        (WebKit::JSNPObject::deleteProperty):
+        (WebKit::JSNPObject::getOwnPropertyNames):
+        (WebKit::JSNPObject::propertyGetter):
+        * WebProcess/Plugins/Netscape/NPJSObject.cpp:
+        (WebKit::NPJSObject::hasMethod):
+        (WebKit::NPJSObject::invoke):
+        (WebKit::NPJSObject::invokeDefault):
+        (WebKit::NPJSObject::hasProperty):
+        (WebKit::NPJSObject::getProperty):
+        (WebKit::NPJSObject::setProperty):
+        (WebKit::NPJSObject::removeProperty):
+        (WebKit::NPJSObject::enumerate):
+        (WebKit::NPJSObject::construct):
+        * WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp:
+        (WebKit::NPRuntimeObjectMap::convertJSValueToNPVariant):
+        (WebKit::NPRuntimeObjectMap::evaluate):
+        (WebKit::NPRuntimeObjectMap::moveGlobalExceptionToExecState):
+        * WebProcess/WebPage/WebFrame.cpp:
+        (WebKit::WebFrame::jsWrapperForWorld):
+        (WebKit::WebFrame::computedStyleIncludingVisitedInfo):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::runJavaScriptInMainFrame):
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::getWebCoreStatistics):
+
 2012-06-27  Thiago Marcos P. Santos  <thiago.santos@intel.com>
 
         REGRESSION(r121135): It made qmltests::WebViewColorChooser::test_accept() fail
index 6a947ae..29cdddc 100644 (file)
@@ -116,7 +116,7 @@ WebMemoryStatistics WebMemorySampler::sampleWebKit() const
     totalBytesInUse += fastMallocBytesInUse;
     totalBytesCommitted += fastMallocBytesCommitted;
     
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     size_t jscHeapBytesInUse = JSDOMWindow::commonJSGlobalData()->heap.size();
     size_t jscHeapBytesCommitted = JSDOMWindow::commonJSGlobalData()->heap.capacity();
     totalBytesInUse += jscHeapBytesInUse;
index c6e9a60..50facbb 100644 (file)
@@ -409,7 +409,7 @@ void InjectedBundle::garbageCollectJavaScriptObjectsOnAlternateThreadForDebuggin
 
 size_t InjectedBundle::javaScriptObjectsCount()
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     return JSDOMWindow::commonJSGlobalData()->heap.objectCount();
 }
 
@@ -418,8 +418,8 @@ void InjectedBundle::reportException(JSContextRef context, JSValueRef exception)
     if (!context || !exception)
         return;
 
-    JSLock lock(JSC::SilenceAssertionsOnly);
     JSC::ExecState* execState = toJS(context);
+    JSLockHolder lock(execState);
 
     // Make sure the context has a DOMWindow global object, otherwise this context didn't originate from a Page.
     if (!toJSDOMWindow(execState->lexicalGlobalObject()))
index dc597c6..54fec0c 100644 (file)
@@ -37,6 +37,7 @@
 #include <JavaScriptCore/JSLock.h>
 #include <JavaScriptCore/ObjectPrototype.h>
 #include <WebCore/IdentifierRep.h>
+#include <WebCore/JSDOMWindowBase.h>
 #include <wtf/Assertions.h>
 #include <wtf/text/WTFString.h>
 
@@ -125,7 +126,7 @@ JSValue JSNPObject::callMethod(ExecState* exec, NPIdentifier methodName)
     VOID_TO_NPVARIANT(result);
     
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         returnValue = m_npObject->_class->invoke(m_npObject, methodName, arguments.data(), argumentCount, &result);
         NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec);
     }
@@ -165,7 +166,7 @@ JSC::JSValue JSNPObject::callObject(JSC::ExecState* exec)
     VOID_TO_NPVARIANT(result);
 
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         returnValue = m_npObject->_class->invokeDefault(m_npObject, arguments.data(), argumentCount, &result);
         NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec);
     }
@@ -205,7 +206,7 @@ JSValue JSNPObject::callConstructor(ExecState* exec)
     VOID_TO_NPVARIANT(result);
     
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         returnValue = m_npObject->_class->construct(m_npObject, arguments.data(), argumentCount, &result);
         NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec);
     }
@@ -340,7 +341,7 @@ void JSNPObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, J
     NPRuntimeObjectMap::PluginProtector protector(thisObject->m_objectMap);
 
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         thisObject->m_npObject->_class->setProperty(thisObject->m_npObject, npIdentifier, &variant);
 
         NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec);
@@ -380,7 +381,7 @@ bool JSNPObject::deleteProperty(ExecState* exec, NPIdentifier propertyName)
     NPRuntimeObjectMap::PluginProtector protector(m_objectMap);
 
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 
         // FIXME: Should we throw an exception if removeProperty returns false?
         if (!m_npObject->_class->removeProperty(m_npObject, propertyName))
@@ -413,7 +414,7 @@ void JSNPObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Property
     NPRuntimeObjectMap::PluginProtector protector(thisObject->m_objectMap);
     
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
 
         // FIXME: Should we throw an exception if enumerate returns false?
         if (!thisObject->m_npObject->_class->enumerate(thisObject->m_npObject, &identifiers, &identifierCount))
@@ -461,7 +462,7 @@ JSValue JSNPObject::propertyGetter(ExecState* exec, JSValue slotBase, PropertyNa
     
     bool returnValue;
     {
-        JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly);
+        JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
         NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName);
         returnValue = thisObj->m_npObject->_class->getProperty(thisObj->m_npObject, npIdentifier, &result);
         
index 4cea7e5..1fadc17 100644 (file)
@@ -99,7 +99,7 @@ bool NPJSObject::hasMethod(NPIdentifier methodName)
     if (!exec)
         return false;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     JSValue value = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep));    
     exec->clearException();
@@ -119,7 +119,7 @@ bool NPJSObject::invoke(NPIdentifier methodName, const NPVariant* arguments, uin
     if (!exec)
         return false;
     
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     JSValue function = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep));
     return invoke(exec, m_objectMap->globalObject(), function, arguments, argumentCount, result);
@@ -131,7 +131,7 @@ bool NPJSObject::invokeDefault(const NPVariant* arguments, uint32_t argumentCoun
     if (!exec)
         return false;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     JSValue function = m_jsObject.get();
     return invoke(exec, m_objectMap->globalObject(), function, arguments, argumentCount, result);
@@ -145,7 +145,7 @@ bool NPJSObject::hasProperty(NPIdentifier identifier)
     if (!exec)
         return false;
     
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     bool result;
     if (identifierRep->isString())
@@ -165,7 +165,7 @@ bool NPJSObject::getProperty(NPIdentifier propertyName, NPVariant* result)
     if (!exec)
         return false;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     JSValue jsResult;
     if (identifierRep->isString())
         jsResult = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep));
@@ -185,7 +185,7 @@ bool NPJSObject::setProperty(NPIdentifier propertyName, const NPVariant* value)
     if (!exec)
         return false;
     
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     JSValue jsValue = m_objectMap->convertNPVariantToJSValue(exec, m_objectMap->globalObject(), *value);
     if (identifierRep->isString()) {
@@ -206,7 +206,7 @@ bool NPJSObject::removeProperty(NPIdentifier propertyName)
     if (!exec)
         return false;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     if (identifierRep->isString()) {
         Identifier identifier = identifierFromIdentifierRep(exec, identifierRep);
         
@@ -235,7 +235,7 @@ bool NPJSObject::enumerate(NPIdentifier** identifiers, uint32_t* identifierCount
     if (!exec)
         return false;
     
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     PropertyNameArray propertyNames(exec);
     m_jsObject->methodTable()->getPropertyNames(m_jsObject.get(), exec, propertyNames, ExcludeDontEnumProperties);
@@ -257,7 +257,7 @@ bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, N
     if (!exec)
         return false;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     ConstructData constructData;
     ConstructType constructType = getConstructData(m_jsObject.get(), constructData);
index 8f037ae..2b115f1 100644 (file)
@@ -139,7 +139,7 @@ JSValue NPRuntimeObjectMap::convertNPVariantToJSValue(JSC::ExecState* exec, JSC:
 
 void NPRuntimeObjectMap::convertJSValueToNPVariant(ExecState* exec, JSValue value, NPVariant& variant)
 {
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
 
     VOID_TO_NPVARIANT(variant);
     
@@ -186,7 +186,7 @@ bool NPRuntimeObjectMap::evaluate(NPObject* npObject, const String&scriptString,
 
     ExecState* exec = globalObject->globalExec();
     
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     JSValue thisValue = getOrCreateJSObject(globalObject.get(), npObject);
 
     globalObject->globalData().timeoutChecker.start();
@@ -266,7 +266,7 @@ void NPRuntimeObjectMap::moveGlobalExceptionToExecState(ExecState* exec)
         return;
 
     {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(exec);
         throwError(exec, createError(exec, stringToUString(globalExceptionString())));
     }
     
index db2ed41..f36fc02 100644 (file)
@@ -642,7 +642,7 @@ JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, Inj
     JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld());
     ExecState* exec = globalObject->globalExec();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     return toRef(exec, toJS(exec, globalObject, nodeHandle->coreNode()));
 }
 
@@ -654,7 +654,7 @@ JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleRangeHandle* rangeHandle, I
     JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld());
     ExecState* exec = globalObject->globalExec();
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     return toRef(exec, toJS(exec, globalObject, rangeHandle->coreRange()));
 }
 
@@ -671,7 +671,7 @@ JSValueRef WebFrame::computedStyleIncludingVisitedInfo(JSObjectRef element)
 
     RefPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(static_cast<JSElement*>(toJS(element))->impl(), true);
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(exec);
     return toRef(exec, toJS(exec, globalObject, style.get()));
 }
 
index b4e19bf..bc2dca3 100644 (file)
@@ -1813,7 +1813,7 @@ void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID
     RefPtr<SerializedScriptValue> serializedResultValue;
     CoreIPC::DataReference dataReference;
 
-    JSLock lock(SilenceAssertionsOnly);
+    JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
     if (JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue()) {
         if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(), toRef(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0)))
             dataReference = serializedResultValue->data();
index 2b0382d..1424a1a 100644 (file)
@@ -920,7 +920,7 @@ void WebProcess::getWebCoreStatistics(uint64_t callbackID)
     
     // Gather JavaScript statistics.
     {
-        JSLock lock(SilenceAssertionsOnly);
+        JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
         data.statisticsNumbers.set("JavaScriptObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.objectCount());
         data.statisticsNumbers.set("JavaScriptGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.globalObjectCount());
         data.statisticsNumbers.set("JavaScriptProtectedObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount());