Reviewed by Darin.
authorap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Jul 2008 07:00:53 +0000 (07:00 +0000)
committerap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Jul 2008 07:00:53 +0000 (07:00 +0000)
        Disable JSLock for per-thread contexts.

        No change on SunSpider.

        * kjs/JSGlobalData.h:
        * kjs/JSGlobalData.cpp:
        (KJS::JSGlobalData::JSGlobalData):
        (KJS::JSGlobalData::sharedInstance):
        Added isSharedInstance as a better way to tell whether the instance is shared (legacy).

        * kjs/JSLock.cpp:
        (KJS::createJSLockCount):
        (KJS::JSLock::lockCount):
        (KJS::setLockCount):
        (KJS::JSLock::JSLock):
        (KJS::JSLock::lock):
        (KJS::JSLock::unlock):
        (KJS::JSLock::currentThreadIsHoldingLock):
        (KJS::JSLock::DropAllLocks::DropAllLocks):
        (KJS::JSLock::DropAllLocks::~DropAllLocks):
        * kjs/JSLock.h:
        (KJS::JSLock::JSLock):
        (KJS::JSLock::~JSLock):
        Made JSLock and JSLock::DropAllLocks constructors take a parameter to decide whether to
        actually lock a mutex, or only to increment recursion count. We cannot turn it into no-op
        if we want to keep existing assertions working.
        Made recursion count per-thread, now that locks may not lock.

        * API/JSBase.cpp:
        (JSEvaluateScript): Take JSLock after casting JSContextRef to ExecState* (which doesn't need
        locking in any case), so that a decision whether to actually lock can be made.
        (JSCheckScriptSyntax): Ditto.
        (JSGarbageCollect): Only lock while collecting the shared heap, not the per-thread one.

        * API/JSObjectRef.cpp:
        (JSClassCreate): Don't lock, as there is no reason to.
        (JSClassRetain): Ditto.
        (JSClassRelease): Ditto.
        (JSPropertyNameArrayRetain): Ditto.
        (JSPropertyNameArrayRelease): Only lock while deleting the array, as that may touch
        identifier table.
        (JSPropertyNameAccumulatorAddName): Adding a string also involves an identifier table
        lookup, and possibly modification.

        * API/JSStringRef.cpp:
        (JSStringCreateWithCharacters):
        (JSStringCreateWithUTF8CString):
        (JSStringRetain):
        (JSStringRelease):
        (JSStringGetUTF8CString):
        (JSStringIsEqual):
        * API/JSStringRefCF.cpp:
        (JSStringCreateWithCFString):
        JSStringRef operations other than releasing do not need locking.

        * VM/Machine.cpp: Don't include unused JSLock.h.

        * kjs/CollectorHeapIntrospector.cpp: (KJS::CollectorHeapIntrospector::statistics):
        Don't take the lock for real, as heap introspection pauses the process anyway. It seems that
        the existing code could cause deadlocks.

        * kjs/Shell.cpp:
        (functionGC):
        (main):
        (jscmain):
        The test tool uses a per-thread context, so no real locking is required.

        * kjs/collector.h:
        (KJS::Heap::setGCProtectNeedsLocking): Optionally protect m_protectedValues access with a
        per-heap mutex. This is only needed for WebCore Database code, which violates the "no data
        migration between threads" by using ProtectedPtr on a background thread.
        (KJS::Heap::isShared): Keep a shared flag here, as well.

        * kjs/protect.h:
        (KJS::::ProtectedPtr):
        (KJS::::~ProtectedPtr):
        (KJS::::operator):
        (KJS::operator==):
        (KJS::operator!=):
        ProtectedPtr is ony used from WebCore, so it doesn't need to take JSLock. An assertion in
        Heap::protect/unprotect guards agains possible future unlocked uses of ProtectedPtr in JSC.

        * kjs/collector.cpp:
        (KJS::Heap::Heap): Initialize m_isShared.
        (KJS::Heap::~Heap): No need to lock for real during destruction, but must keep assertions
        in sweep() working.
        (KJS::destroyRegisteredThread): Registered thread list is only accessed for shared heap,
        so locking is always needed here.
        (KJS::Heap::registerThread): Ditto.
        (KJS::Heap::markStackObjectsConservatively): Use m_isShared instead of comparing to a shared
        instance for a small speedup.
        (KJS::Heap::setGCProtectNeedsLocking): Create m_protectedValuesMutex. There is currently no
        way to undo this - and ideally, Database code will be fixed to lo longer require this quirk.
        (KJS::Heap::protect): Take m_protectedValuesMutex (if it exists) while accessing
        m_protectedValues.
        (KJS::Heap::unprotect): Ditto.
        (KJS::Heap::markProtectedObjects): Ditto.
        (KJS::Heap::protectedGlobalObjectCount): Ditto.
        (KJS::Heap::protectedObjectCount): Ditto.
        (KJS::Heap::protectedObjectTypeCounts): Ditto.

        * kjs/ustring.cpp:
        * kjs/ustring.h:
        Don't include JSLock.h, which is no longer used here. As a result, an explicit include had
        to be added to many files in JavaScriptGlue, WebCore and WebKit.

        * kjs/JSGlobalObject.cpp:
        (KJS::JSGlobalObject::init):
        * API/JSCallbackConstructor.cpp:
        (KJS::constructJSCallback):
        * API/JSCallbackFunction.cpp:
        (KJS::JSCallbackFunction::call):
        * API/JSCallbackObjectFunctions.h:
        (KJS::::init):
        (KJS::::getOwnPropertySlot):
        (KJS::::put):
        (KJS::::deleteProperty):
        (KJS::::construct):
        (KJS::::hasInstance):
        (KJS::::call):
        (KJS::::getPropertyNames):
        (KJS::::toNumber):
        (KJS::::toString):
        (KJS::::staticValueGetter):
        (KJS::::callbackGetter):
        * API/JSContextRef.cpp:
        (JSGlobalContextCreate):
        (JSGlobalContextRetain):
        (JSGlobalContextRelease):
        * API/JSValueRef.cpp:
        (JSValueIsEqual):
        (JSValueIsStrictEqual):
        (JSValueIsInstanceOfConstructor):
        (JSValueMakeNumber):
        (JSValueMakeString):
        (JSValueToNumber):
        (JSValueToStringCopy):
        (JSValueToObject):
        (JSValueProtect):
        (JSValueUnprotect):
        * JavaScriptCore.exp:
        * kjs/PropertyNameArray.h:
        (KJS::PropertyNameArray::globalData):
        * kjs/interpreter.cpp:
        (KJS::Interpreter::checkSyntax):
        (KJS::Interpreter::evaluate):
        Pass a parameter to JSLock/JSLock::DropAllLocks to decide whether the lock needs to be taken.

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

93 files changed:
JavaScriptCore/API/JSBase.cpp
JavaScriptCore/API/JSCallbackConstructor.cpp
JavaScriptCore/API/JSCallbackFunction.cpp
JavaScriptCore/API/JSCallbackObjectFunctions.h
JavaScriptCore/API/JSContextRef.cpp
JavaScriptCore/API/JSObjectRef.cpp
JavaScriptCore/API/JSStringRef.cpp
JavaScriptCore/API/JSStringRefCF.cpp
JavaScriptCore/API/JSValueRef.cpp
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/VM/Machine.cpp
JavaScriptCore/kjs/CollectorHeapIntrospector.cpp
JavaScriptCore/kjs/JSGlobalData.cpp
JavaScriptCore/kjs/JSGlobalData.h
JavaScriptCore/kjs/JSGlobalObject.cpp
JavaScriptCore/kjs/JSLock.cpp
JavaScriptCore/kjs/JSLock.h
JavaScriptCore/kjs/PropertyNameArray.h
JavaScriptCore/kjs/Shell.cpp
JavaScriptCore/kjs/collector.cpp
JavaScriptCore/kjs/collector.h
JavaScriptCore/kjs/interpreter.cpp
JavaScriptCore/kjs/protect.h
JavaScriptCore/kjs/ustring.cpp
JavaScriptCore/kjs/ustring.h
JavaScriptGlue/ChangeLog
JavaScriptGlue/ForwardingHeaders/wtf/Locker.h [new file with mode: 0644]
JavaScriptGlue/ForwardingHeaders/wtf/Threading.h [new file with mode: 0644]
JavaScriptGlue/JSBase.cpp
JavaScriptGlue/JSUtils.cpp
JavaScriptGlue/JSUtils.h
JavaScriptGlue/JSValueWrapper.cpp
JavaScriptGlue/JavaScriptGlue.cpp
JavaScriptGlue/UserObjectImp.cpp
WebCore/ChangeLog
WebCore/bindings/js/GCController.cpp
WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
WebCore/bindings/js/JSCustomVoidCallback.cpp
WebCore/bindings/js/JSCustomXPathNSResolver.cpp
WebCore/bindings/js/JSDOMWindowBase.cpp
WebCore/bindings/js/JSEventCustom.cpp
WebCore/bindings/js/JSEventListener.cpp
WebCore/bindings/js/JSNodeFilterCondition.cpp
WebCore/bindings/js/ScheduledAction.cpp
WebCore/bindings/js/ScriptController.cpp
WebCore/bindings/objc/WebScriptObject.mm
WebCore/bridge/NP_jsobject.cpp
WebCore/bridge/c/c_class.cpp
WebCore/bridge/c/c_instance.cpp
WebCore/bridge/c/c_runtime.cpp
WebCore/bridge/c/c_utility.cpp
WebCore/bridge/jni/jni_class.cpp
WebCore/bridge/jni/jni_instance.cpp
WebCore/bridge/jni/jni_jsobject.mm
WebCore/bridge/jni/jni_objc.mm
WebCore/bridge/jni/jni_runtime.cpp
WebCore/bridge/jni/jni_runtime.h
WebCore/bridge/jni/jni_utility.cpp
WebCore/bridge/npruntime.cpp
WebCore/bridge/objc/objc_instance.mm
WebCore/bridge/objc/objc_runtime.mm
WebCore/bridge/objc/objc_utility.mm
WebCore/bridge/runtime.cpp
WebCore/bridge/runtime_root.cpp
WebCore/dom/Document.cpp
WebCore/dom/Node.cpp
WebCore/history/CachedPage.cpp
WebCore/html/HTMLPlugInElement.cpp
WebCore/loader/FrameLoader.cpp
WebCore/page/Frame.cpp
WebCore/page/InspectorController.cpp
WebCore/page/JavaScriptCallFrame.cpp
WebCore/page/JavaScriptProfileNode.cpp
WebCore/page/mac/FrameMac.mm
WebCore/storage/Database.cpp
WebCore/xml/XMLHttpRequest.cpp
WebKit/mac/ChangeLog
WebKit/mac/Misc/WebCoreStatistics.mm
WebKit/mac/Plugins/WebBaseNetscapePluginView.mm
WebKit/mac/Plugins/WebPluginController.mm
WebKit/mac/WebView/WebFrame.mm
WebKit/mac/WebView/WebScriptDebugDelegate.mm
WebKit/mac/WebView/WebView.mm
WebKit/qt/Api/qwebframe.cpp
WebKit/qt/ChangeLog
WebKit/win/ChangeLog
WebKit/win/WebCoreStatistics.cpp
WebKit/win/WebScriptCallFrame.cpp
WebKit/win/WebView.cpp

index e9921a9..6ce27f7 100644 (file)
@@ -40,8 +40,8 @@ using namespace KJS;
 
 JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     JSObject* jsThisObject = toJS(thisObject);
     UString::Rep* scriptRep = toJS(script);
     UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
@@ -65,9 +65,8 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
 
 bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
 {
-    JSLock lock;
-
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     UString::Rep* scriptRep = toJS(script);
     UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
     Completion completion = Interpreter::checkSyntax(exec->dynamicGlobalObject()->globalExec(), UString(sourceURLRep), startingLineNumber, UString(scriptRep));
@@ -89,13 +88,13 @@ void JSGarbageCollect(JSContextRef ctx)
     // It might seem that we have a context passed to this function, and can use toJS(ctx)->heap(), but the parameter is likely to be NULL,
     // and it may actually be garbage for some clients (most likely, because of JSGarbageCollect being called after releasing the context).
 
-    JSLock lock;
-
     // FIXME: It would be good to avoid creating a JSGlobalData instance if it didn't exist for this thread yet.
     Heap* heap = JSGlobalData::threadInstance().heap;
     if (!heap->isBusy())
         heap->collect();
 
+    JSLock lock(true);
+
     // FIXME: Similarly, we shouldn't create a shared instance here.
     heap = JSGlobalData::sharedInstance().heap;
     if (!heap->isBusy())
index 0f1ae01..cf9166d 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "APICast.h"
 #include <kjs/JSGlobalObject.h>
+#include <kjs/JSLock.h>
 #include <kjs/ObjectPrototype.h>
 #include <wtf/Vector.h>
 
@@ -68,7 +69,7 @@ static JSObject* constructJSCallback(ExecState* exec, JSObject* constructor, con
         for (int i = 0; i < argumentCount; i++)
             arguments[i] = toRef(args[i]);
             
-        JSLock::DropAllLocks dropAllLocks;
+        JSLock::DropAllLocks dropAllLocks(exec);
         return toJS(callback(ctx, constructorRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
     }
     
index ced7d9d..0f5a558 100644 (file)
@@ -32,6 +32,7 @@
 #include "JSFunction.h"
 #include "FunctionPrototype.h"
 #include <kjs/JSGlobalObject.h>
+#include <kjs/JSLock.h>
 #include <wtf/Vector.h>
 
 namespace KJS {
@@ -62,7 +63,7 @@ JSValue* JSCallbackFunction::call(ExecState* exec, JSObject* functionObject, JSV
     for (int i = 0; i < argumentCount; i++)
         arguments[i] = toRef(args[i]);
 
-    JSLock::DropAllLocks dropAllLocks;
+    JSLock::DropAllLocks dropAllLocks(exec);
     return toJS(static_cast<JSCallbackFunction*>(functionObject)->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
 }
 
index 5cf7fae..b9f34e0 100644 (file)
@@ -29,6 +29,7 @@
 #include "JSCallbackFunction.h"
 #include "JSClassRef.h"
 #include "JSGlobalObject.h"
+#include "JSLock.h"
 #include "JSObjectRef.h"
 #include "JSString.h"
 #include "JSStringRef.h"
@@ -71,7 +72,7 @@ void JSCallbackObject<Base>::init(ExecState* exec)
     
     // initialize from base to derived
     for (int i = static_cast<int>(initRoutines.size()) - 1; i >= 0; i--) {
-        JSLock::DropAllLocks dropAllLocks;
+        JSLock::DropAllLocks dropAllLocks(exec);
         JSObjectInitializeCallback initialize = initRoutines[i];
         initialize(toRef(exec), toRef(this));
     }
@@ -109,13 +110,13 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie
     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
         // optional optimization to bypass getProperty in cases when we only need to know if the property exists
         if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
-            JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(exec);
             if (hasProperty(ctx, thisRef, propertyNameRef)) {
                 slot.setCustom(this, callbackGetter);
                 return true;
             }
         } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
-            JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(exec);
             if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef, toRef(exec->exceptionSlot()))) {
                 // cache the value so we don't have to compute it again
                 // FIXME: This violates the PropertySlot design a little bit.
@@ -159,7 +160,7 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
     
     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
         if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
-            JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(exec);
             if (setProperty(ctx, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot())))
                 return;
         }
@@ -169,7 +170,7 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
                 if (entry->attributes & kJSPropertyAttributeReadOnly)
                     return;
                 if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
-                    JSLock::DropAllLocks dropAllLocks;
+                    JSLock::DropAllLocks dropAllLocks(exec);
                     if (setProperty(ctx, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot())))
                         return;
                 } else
@@ -205,7 +206,7 @@ bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& p
     
     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
         if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
-            JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(exec);
             if (deleteProperty(ctx, thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
                 return true;
         }
@@ -260,7 +261,7 @@ JSObject* JSCallbackObject<Base>::construct(ExecState* exec, JSObject* construct
             Vector<JSValueRef, 16> arguments(argumentCount);
             for (int i = 0; i < argumentCount; i++)
                 arguments[i] = toRef(args[i]);
-            JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(exec);
             return toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
         }
     }
@@ -287,7 +288,7 @@ bool JSCallbackObject<Base>::hasInstance(ExecState *exec, JSValue *value)
     
     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
         if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) {
-            JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(exec);
             return hasInstance(execRef, thisRef, toRef(value), toRef(exec->exceptionSlot()));
         }
             
@@ -320,7 +321,7 @@ JSValue* JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject,
             Vector<JSValueRef, 16> arguments(argumentCount);
             for (int i = 0; i < argumentCount; i++)
                 arguments[i] = toRef(args[i]);
-            JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(exec);
             return toJS(callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
         }
     }
@@ -337,7 +338,7 @@ void JSCallbackObject<Base>::getPropertyNames(ExecState* exec, PropertyNameArray
     
     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
         if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) {
-            JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(exec);
             getPropertyNames(execRef, thisRef, toRef(&propertyNames));
         }
         
@@ -380,7 +381,7 @@ double JSCallbackObject<Base>::toNumber(ExecState* exec) const
     
     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
         if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
-            JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(exec);
             if (JSValueRef value = convertToType(ctx, thisRef, kJSTypeNumber, toRef(exec->exceptionSlot())))
                 return toJS(value)->getNumber();
         }
@@ -398,7 +399,7 @@ UString JSCallbackObject<Base>::toString(ExecState* exec) const
         if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
             JSValueRef value;
             {
-                JSLock::DropAllLocks dropAllLocks;
+                JSLock::DropAllLocks dropAllLocks(exec);
                 value = convertToType(ctx, thisRef, kJSTypeString, toRef(exec->exceptionSlot()));
             }
             if (value)
@@ -451,7 +452,7 @@ JSValue* JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identi
         if (OpaqueJSClass::StaticValuesTable* staticValues = jsClass->staticValues)
             if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep()))
                 if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
-                    JSLock::DropAllLocks dropAllLocks;
+                    JSLock::DropAllLocks dropAllLocks(exec);
                     if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
                         return toJS(value);
                 }
@@ -496,7 +497,7 @@ JSValue* JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifie
     
     for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
         if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
-            JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(exec);
             if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
                 return toJS(value);
         }
index 322370c..bf37741 100644 (file)
@@ -41,7 +41,7 @@ JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
 {
     initializeThreading();
 
-    JSLock lock;
+    JSLock lock(true);
 
     if (!globalObjectClass) {
         JSGlobalObject* globalObject = new (JSGlobalObject::Shared) JSGlobalObject;
@@ -59,16 +59,16 @@ JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
 
 JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     gcProtect(exec->dynamicGlobalObject());
     return ctx;
 }
 
 void JSGlobalContextRelease(JSGlobalContextRef ctx)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     gcUnprotect(exec->dynamicGlobalObject());
 }
 
index 2d92069..a8a4044 100644 (file)
@@ -47,7 +47,6 @@ using namespace KJS;
 
 JSClassRef JSClassCreate(const JSClassDefinition* definition)
 {
-    JSLock lock;
     RefPtr<OpaqueJSClass> jsClass = (definition->attributes & kJSClassAttributeNoAutomaticPrototype)
         ? OpaqueJSClass::createNoAutomaticPrototype(definition)
         : OpaqueJSClass::create(definition);
@@ -57,21 +56,19 @@ JSClassRef JSClassCreate(const JSClassDefinition* definition)
 
 JSClassRef JSClassRetain(JSClassRef jsClass)
 {
-    JSLock lock;
     jsClass->ref();
     return jsClass;
 }
 
 void JSClassRelease(JSClassRef jsClass)
 {
-    JSLock lock;
     jsClass->deref();
 }
 
 JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
 
     if (!jsClass)
         return toRef(new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype())); // slightly more efficient
@@ -85,8 +82,8 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
 
 JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     Identifier nameID = name ? Identifier(exec, toJS(name)) : Identifier(exec, "anonymous");
     
     return toRef(new (exec) JSCallbackFunction(exec, callAsFunction, nameID));
@@ -94,8 +91,8 @@ JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name,
 
 JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     
     JSValue* jsPrototype = jsClass 
         ? jsClass->prototype(ctx)
@@ -108,9 +105,9 @@ JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObje
 
 JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
 {
-    JSLock lock;
-    
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
+
     UString::Rep* bodyRep = toJS(body);
     UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
     
@@ -147,8 +144,8 @@ void JSObjectSetPrototype(JSContextRef, JSObjectRef object, JSValueRef value)
 
 bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     JSObject* jsObject = toJS(object);
     UString::Rep* nameRep = toJS(propertyName);
     
@@ -157,8 +154,8 @@ bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
 
 JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     JSObject* jsObject = toJS(object);
     UString::Rep* nameRep = toJS(propertyName);
 
@@ -173,8 +170,8 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
 
 void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     JSObject* jsObject = toJS(object);
     Identifier name(exec, toJS(propertyName));
     JSValue* jsValue = toJS(value);
@@ -193,8 +190,8 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
 
 JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     JSObject* jsObject = toJS(object);
 
     JSValue* jsValue = jsObject->get(exec, propertyIndex);
@@ -209,8 +206,8 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsi
 
 void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     JSObject* jsObject = toJS(object);
     JSValue* jsValue = toJS(value);
     
@@ -224,8 +221,8 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
 
 bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     JSObject* jsObject = toJS(object);
     UString::Rep* nameRep = toJS(propertyName);
 
@@ -273,8 +270,8 @@ bool JSObjectIsFunction(JSContextRef, JSObjectRef object)
 
 JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     JSObject* jsObject = toJS(object);
     JSObject* jsThisObject = toJS(thisObject);
 
@@ -309,8 +306,8 @@ bool JSObjectIsConstructor(JSContextRef, JSObjectRef object)
 
 JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     JSObject* jsObject = toJS(object);
 
     ConstructData constructData;
@@ -343,9 +340,9 @@ struct OpaqueJSPropertyNameArray
 
 JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object)
 {
-    JSLock lock;
     JSObject* jsObject = toJS(object);
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
     
     JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(&exec->globalData());
     jsObject->getPropertyNames(exec, propertyNames->array);
@@ -355,16 +352,16 @@ JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef o
 
 JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array)
 {
-    JSLock lock;
     ++array->refCount;
     return array;
 }
 
 void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array)
 {
-    JSLock lock;
-    if (--array->refCount == 0)
+    if (--array->refCount == 0) {
+        JSLock lock(array->array.globalData()->isSharedInstance);
         delete array;
+    }
 }
 
 size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array)
@@ -379,8 +376,9 @@ JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size
 
 void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStringRef propertyName)
 {
-    JSLock lock;
     PropertyNameArray* propertyNames = toJS(array);
     UString::Rep* rep = toJS(propertyName);
+
+    JSLock lock(propertyNames->globalData()->isSharedInstance);
     propertyNames->add(rep);
 }
index f6d73af..25efa07 100644 (file)
@@ -43,14 +43,11 @@ using namespace WTF::Unicode;
 
 JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars)
 {
-    JSLock lock;
     return toRef(UString(chars, static_cast<int>(numChars)).rep()->ref());
 }
 
 JSStringRef JSStringCreateWithUTF8CString(const char* string)
 {
-    JSLock lock;
-
     RefPtr<UString::Rep> result = UString::Rep::createFromUTF8(string);
     if (result.get() == &UString::Rep::null)
         return 0;
@@ -60,16 +57,21 @@ JSStringRef JSStringCreateWithUTF8CString(const char* string)
 
 JSStringRef JSStringRetain(JSStringRef string)
 {
-    JSLock lock;
     UString::Rep* rep = toJS(string);
     return toRef(rep->ref());
 }
 
 void JSStringRelease(JSStringRef string)
 {
-    JSLock lock;
     UString::Rep* rep = toJS(string);
-    rep->deref();
+    bool needsLocking = rep->identifierTable;
+    if (needsLocking) {
+        // It is wasteful to take the lock for per-thread contexts, but we don't have a good way
+        // to determine what the context is.
+        JSLock lock(true);
+        rep->deref();
+    } else
+        rep->deref();
 }
 
 size_t JSStringGetLength(JSStringRef string)
@@ -94,7 +96,6 @@ size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string)
 
 size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSize)
 {
-    JSLock lock;
     UString::Rep* rep = toJS(string);
     CString cString = UString(rep).UTF8String();
 
@@ -105,8 +106,6 @@ size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSiz
 
 bool JSStringIsEqual(JSStringRef a, JSStringRef b)
 {
-    JSLock lock;
-
     UString::Rep* aRep = toJS(a);
     UString::Rep* bRep = toJS(b);
     
index f79f048..55a571c 100644 (file)
@@ -37,7 +37,6 @@ using namespace KJS;
 
 JSStringRef JSStringCreateWithCFString(CFStringRef string)
 {
-    JSLock lock;
     CFIndex length = CFStringGetLength(string);
     UString::Rep* rep;
     if (!length)
index ffc8ba3..0139fa2 100644 (file)
@@ -118,8 +118,9 @@ bool JSValueIsObjectOfClass(JSContextRef, JSValueRef value, JSClassRef jsClass)
 
 bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
+
     JSValue* jsA = toJS(a);
     JSValue* jsB = toJS(b);
 
@@ -132,11 +133,8 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex
     return result;
 }
 
-bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
+bool JSValueIsStrictEqual(JSContextRef, JSValueRef a, JSValueRef b)
 {
-    UNUSED_PARAM(ctx);
-
-    JSLock lock;
     JSValue* jsA = toJS(a);
     JSValue* jsB = toJS(b);
     
@@ -146,8 +144,9 @@ bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
 
 bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
+
     JSValue* jsValue = toJS(value);
     JSObject* jsConstructor = toJS(constructor);
     if (!jsConstructor->implementsHasInstance())
@@ -178,15 +177,19 @@ JSValueRef JSValueMakeBoolean(JSContextRef, bool value)
 
 JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
 {
-    JSLock lock;
-    return toRef(jsNumber(toJS(ctx), value));
+    ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
+
+    return toRef(jsNumber(exec, value));
 }
 
 JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
 {
-    JSLock lock;
+    ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
+
     UString::Rep* rep = toJS(string);
-    return toRef(jsString(toJS(ctx), UString(rep)));
+    return toRef(jsString(exec, UString(rep)));
 }
 
 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
@@ -198,9 +201,10 @@ bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
 
 double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
 {
-    JSLock lock;
-    JSValue* jsValue = toJS(value);
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
+
+    JSValue* jsValue = toJS(value);
 
     double number = jsValue->toNumber(exec);
     if (exec->hadException()) {
@@ -214,9 +218,10 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception
 
 JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
 {
-    JSLock lock;
-    JSValue* jsValue = toJS(value);
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
+
+    JSValue* jsValue = toJS(value);
     
     JSStringRef stringRef = toRef(jsValue->toString(exec).rep()->ref());
     if (exec->hadException()) {
@@ -230,8 +235,9 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef*
 
 JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
 {
-    JSLock lock;
     ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
+
     JSValue* jsValue = toJS(value);
     
     JSObjectRef objectRef = toRef(jsValue->toObject(exec));
@@ -244,16 +250,20 @@ JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exce
     return objectRef;
 }    
 
-void JSValueProtect(JSContextRef, JSValueRef value)
+void JSValueProtect(JSContextRef ctx, JSValueRef value)
 {
-    JSLock lock;
+    ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
+
     JSValue* jsValue = toJS(value);
     gcProtect(jsValue);
 }
 
-void JSValueUnprotect(JSContextRef, JSValueRef value)
+void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
 {
-    JSLock lock;
+    ExecState* exec = toJS(ctx);
+    JSLock lock(exec);
+
     JSValue* jsValue = toJS(value);
     gcUnprotect(jsValue);
 }
index 48e97c1..e451c0b 100644 (file)
@@ -1,3 +1,155 @@
+2008-06-30  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        Disable JSLock for per-thread contexts.
+
+        No change on SunSpider.
+
+        * kjs/JSGlobalData.h:
+        * kjs/JSGlobalData.cpp:
+        (KJS::JSGlobalData::JSGlobalData):
+        (KJS::JSGlobalData::sharedInstance):
+        Added isSharedInstance as a better way to tell whether the instance is shared (legacy).
+
+        * kjs/JSLock.cpp:
+        (KJS::createJSLockCount):
+        (KJS::JSLock::lockCount):
+        (KJS::setLockCount):
+        (KJS::JSLock::JSLock):
+        (KJS::JSLock::lock):
+        (KJS::JSLock::unlock):
+        (KJS::JSLock::currentThreadIsHoldingLock):
+        (KJS::JSLock::DropAllLocks::DropAllLocks):
+        (KJS::JSLock::DropAllLocks::~DropAllLocks):
+        * kjs/JSLock.h:
+        (KJS::JSLock::JSLock):
+        (KJS::JSLock::~JSLock):
+        Made JSLock and JSLock::DropAllLocks constructors take a parameter to decide whether to
+        actually lock a mutex, or only to increment recursion count. We cannot turn it into no-op
+        if we want to keep existing assertions working.
+        Made recursion count per-thread, now that locks may not lock.
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript): Take JSLock after casting JSContextRef to ExecState* (which doesn't need
+        locking in any case), so that a decision whether to actually lock can be made.
+        (JSCheckScriptSyntax): Ditto.
+        (JSGarbageCollect): Only lock while collecting the shared heap, not the per-thread one.
+
+        * API/JSObjectRef.cpp:
+        (JSClassCreate): Don't lock, as there is no reason to.
+        (JSClassRetain): Ditto.
+        (JSClassRelease): Ditto.
+        (JSPropertyNameArrayRetain): Ditto.
+        (JSPropertyNameArrayRelease): Only lock while deleting the array, as that may touch
+        identifier table.
+        (JSPropertyNameAccumulatorAddName): Adding a string also involves an identifier table
+        lookup, and possibly modification.
+
+        * API/JSStringRef.cpp:
+        (JSStringCreateWithCharacters):
+        (JSStringCreateWithUTF8CString):
+        (JSStringRetain):
+        (JSStringRelease):
+        (JSStringGetUTF8CString):
+        (JSStringIsEqual):
+        * API/JSStringRefCF.cpp:
+        (JSStringCreateWithCFString):
+        JSStringRef operations other than releasing do not need locking.
+
+        * VM/Machine.cpp: Don't include unused JSLock.h.
+
+        * kjs/CollectorHeapIntrospector.cpp: (KJS::CollectorHeapIntrospector::statistics):
+        Don't take the lock for real, as heap introspection pauses the process anyway. It seems that
+        the existing code could cause deadlocks.
+
+        * kjs/Shell.cpp:
+        (functionGC):
+        (main):
+        (jscmain):
+        The test tool uses a per-thread context, so no real locking is required.
+
+        * kjs/collector.h:
+        (KJS::Heap::setGCProtectNeedsLocking): Optionally protect m_protectedValues access with a
+        per-heap mutex. This is only needed for WebCore Database code, which violates the "no data
+        migration between threads" by using ProtectedPtr on a background thread.
+        (KJS::Heap::isShared): Keep a shared flag here, as well.
+
+        * kjs/protect.h:
+        (KJS::::ProtectedPtr):
+        (KJS::::~ProtectedPtr):
+        (KJS::::operator):
+        (KJS::operator==):
+        (KJS::operator!=):
+        ProtectedPtr is ony used from WebCore, so it doesn't need to take JSLock. An assertion in
+        Heap::protect/unprotect guards agains possible future unlocked uses of ProtectedPtr in JSC.
+
+        * kjs/collector.cpp:
+        (KJS::Heap::Heap): Initialize m_isShared.
+        (KJS::Heap::~Heap): No need to lock for real during destruction, but must keep assertions
+        in sweep() working.
+        (KJS::destroyRegisteredThread): Registered thread list is only accessed for shared heap,
+        so locking is always needed here.
+        (KJS::Heap::registerThread): Ditto.
+        (KJS::Heap::markStackObjectsConservatively): Use m_isShared instead of comparing to a shared
+        instance for a small speedup.
+        (KJS::Heap::setGCProtectNeedsLocking): Create m_protectedValuesMutex. There is currently no
+        way to undo this - and ideally, Database code will be fixed to lo longer require this quirk.
+        (KJS::Heap::protect): Take m_protectedValuesMutex (if it exists) while accessing
+        m_protectedValues.
+        (KJS::Heap::unprotect): Ditto.
+        (KJS::Heap::markProtectedObjects): Ditto.
+        (KJS::Heap::protectedGlobalObjectCount): Ditto.
+        (KJS::Heap::protectedObjectCount): Ditto.
+        (KJS::Heap::protectedObjectTypeCounts): Ditto.
+
+        * kjs/ustring.cpp:
+        * kjs/ustring.h:
+        Don't include JSLock.h, which is no longer used here. As a result, an explicit include had
+        to be added to many files in JavaScriptGlue, WebCore and WebKit.
+
+        * kjs/JSGlobalObject.cpp:
+        (KJS::JSGlobalObject::init):
+        * API/JSCallbackConstructor.cpp:
+        (KJS::constructJSCallback):
+        * API/JSCallbackFunction.cpp:
+        (KJS::JSCallbackFunction::call):
+        * API/JSCallbackObjectFunctions.h:
+        (KJS::::init):
+        (KJS::::getOwnPropertySlot):
+        (KJS::::put):
+        (KJS::::deleteProperty):
+        (KJS::::construct):
+        (KJS::::hasInstance):
+        (KJS::::call):
+        (KJS::::getPropertyNames):
+        (KJS::::toNumber):
+        (KJS::::toString):
+        (KJS::::staticValueGetter):
+        (KJS::::callbackGetter):
+        * API/JSContextRef.cpp:
+        (JSGlobalContextCreate):
+        (JSGlobalContextRetain):
+        (JSGlobalContextRelease):
+        * API/JSValueRef.cpp:
+        (JSValueIsEqual):
+        (JSValueIsStrictEqual):
+        (JSValueIsInstanceOfConstructor):
+        (JSValueMakeNumber):
+        (JSValueMakeString):
+        (JSValueToNumber):
+        (JSValueToStringCopy):
+        (JSValueToObject):
+        (JSValueProtect):
+        (JSValueUnprotect):
+        * JavaScriptCore.exp:
+        * kjs/PropertyNameArray.h:
+        (KJS::PropertyNameArray::globalData):
+        * kjs/interpreter.cpp:
+        (KJS::Interpreter::checkSyntax):
+        (KJS::Interpreter::evaluate):
+        Pass a parameter to JSLock/JSLock::DropAllLocks to decide whether the lock needs to be taken.
+
 2008-07-01  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Darin.
         * wtf/HashTraits.h:
         (WTF::): Updated HashTraits for HashTable change.
 
-2008-06-30  Alexey Proskuryakov  <ap@webkit.org>
+2008-07-01  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Cameron Zwarich.
 
index 03d8b18..d79ab85 100644 (file)
@@ -147,6 +147,7 @@ __ZN3KJS4Heap14allocateNumberEm
 __ZN3KJS4Heap15recordExtraCostEm
 __ZN3KJS4Heap17globalObjectCountEv
 __ZN3KJS4Heap20protectedObjectCountEv
+__ZN3KJS4Heap24setGCProtectNeedsLockingEv
 __ZN3KJS4Heap25protectedObjectTypeCountsEv
 __ZN3KJS4Heap26protectedGlobalObjectCountEv
 __ZN3KJS4Heap4heapEPKNS_7JSValueE
@@ -169,12 +170,14 @@ __ZN3KJS6JSCell3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
 __ZN3KJS6JSCell3putEPNS_9ExecStateEjPNS_7JSValueE
 __ZN3KJS6JSCell9getObjectEv
 __ZN3KJS6JSCellnwEmPNS_9ExecStateE
-__ZN3KJS6JSLock12DropAllLocksC1Ev
+__ZN3KJS6JSLock12DropAllLocksC1Eb
+__ZN3KJS6JSLock12DropAllLocksC1EPNS_9ExecStateE
 __ZN3KJS6JSLock12DropAllLocksD1Ev
 __ZN3KJS6JSLock14registerThreadEv
-__ZN3KJS6JSLock4lockEv
-__ZN3KJS6JSLock6unlockEv
+__ZN3KJS6JSLock4lockEb
+__ZN3KJS6JSLock6unlockEb
 __ZN3KJS6JSLock9lockCountEv
+__ZN3KJS6JSLockC1EPNS_9ExecStateE
 __ZN3KJS6Parser5parseEPNS_9ExecStateERKNS_7UStringEiN3WTF10PassRefPtrINS_14SourceProviderEEEPiSA_PS3_
 __ZN3KJS6strtodEPKcPPc
 __ZN3KJS7ArgList10slowAppendEPNS_7JSValueE
index e6b70ef..a116b86 100644 (file)
@@ -37,7 +37,6 @@
 #include "JSActivation.h"
 #include "JSArray.h"
 #include "JSFunction.h"
-#include "JSLock.h"
 #include "JSPropertyNameIterator.h"
 #include "JSString.h"
 #include "ObjectPrototype.h"
index 72673ef..afb8adc 100644 (file)
@@ -95,7 +95,7 @@ kern_return_t CollectorHeapIntrospector::enumerate(task_t task, void* context, u
 
 void CollectorHeapIntrospector::statistics(malloc_zone_t* zone, malloc_statistics_t* stats)
 {
-    JSLock lock;
+    JSLock lock(false);
     CollectorHeapIntrospector* introspector = reinterpret_cast<CollectorHeapIntrospector*>(zone);
     CollectorHeap* primaryHeap = introspector->m_primaryHeap;
     CollectorHeap* numberHeap = introspector->m_numberHeap;
index 9565337..49aed82 100644 (file)
@@ -56,9 +56,9 @@ extern const HashTable regExpConstructorTable;
 extern const HashTable stringTable;
 
 
-JSGlobalData::JSGlobalData()
+JSGlobalData::JSGlobalData(bool isShared)
     : machine(new Machine)
-    , heap(new Heap)
+    , heap(new Heap(isShared))
 #if USE(MULTIPLE_THREADS)
     , arrayTable(new HashTable(KJS::arrayTable))
     , dateTable(new HashTable(KJS::dateTable))
@@ -83,6 +83,7 @@ JSGlobalData::JSGlobalData()
     , lexer(new Lexer(this))
     , parser(new Parser)
     , head(0)
+    , isSharedInstance(isShared)
 {
 }
 
@@ -132,11 +133,12 @@ JSGlobalData& JSGlobalData::threadInstance()
 JSGlobalData& JSGlobalData::sharedInstance()
 {
 #if USE(MULTIPLE_THREADS)
-    AtomicallyInitializedStatic(JSGlobalData, sharedInstance);
-#else
-    static JSGlobalData sharedInstance;
+    MutexLocker locker(*atomicallyInitializedStaticMutex);
 #endif
-    return sharedInstance;
+    static JSGlobalData* sharedInstance;
+    if (!sharedInstance)
+        sharedInstance = new JSGlobalData(true);
+    return *sharedInstance;
 }
 
 }
index 1eccc34..d040087 100644 (file)
@@ -81,10 +81,12 @@ namespace KJS {
 
         JSGlobalObject* head;
 
+        bool isSharedInstance;
+
     private:
         friend class WTF::ThreadSpecific<JSGlobalData>;
 
-        JSGlobalData();
+        JSGlobalData(bool isShared = false);
         ~JSGlobalData();
     };
 
index 07a3c67..0795efa 100644 (file)
@@ -101,7 +101,7 @@ void JSGlobalObject::init(JSObject* thisValue)
 {
     ASSERT(JSLock::currentThreadIsHoldingLock());
 
-    d()->globalData = (Heap::heap(this) == JSGlobalData::sharedInstance().heap) ? &JSGlobalData::sharedInstance() : &JSGlobalData::threadInstance();
+    d()->globalData = Heap::heap(this)->isShared() ? &JSGlobalData::sharedInstance() : &JSGlobalData::threadInstance();
 
     if (JSGlobalObject*& headObject = head()) {
         d()->prev = headObject;
index dbddb73..c008a96 100644 (file)
@@ -24,6 +24,8 @@
 #include "JSLock.h"
 
 #include "collector.h"
+#include "ExecState.h"
+
 #if USE(MULTIPLE_THREADS)
 #include <pthread.h>
 #endif
@@ -35,49 +37,89 @@ namespace KJS {
 // Acquire this mutex before accessing lock-related data.
 static pthread_mutex_t JSMutex = PTHREAD_MUTEX_INITIALIZER;
 
-// Thread-specific key that tells whether a thread holds the JSMutex.
-pthread_key_t didLockJSMutex;
+// Thread-specific key that tells whether a thread holds the JSMutex, and how many times it was taken recursively.
+pthread_key_t JSLockCount;
+
+static void createJSLockCount()
+{
+    pthread_key_create(&JSLockCount, 0);
+}
+
+pthread_once_t createJSLockCountOnce = PTHREAD_ONCE_INIT;
 
 // Lock nesting count.
-static int JSLockCount;
+int JSLock::lockCount()
+{
+    pthread_once(&createJSLockCountOnce, createJSLockCount);
 
-static void createDidLockJSMutex()
+    return reinterpret_cast<int>(pthread_getspecific(JSLockCount));
+}
+
+static void setLockCount(int count)
 {
-    pthread_key_create(&didLockJSMutex, 0);
+    pthread_setspecific(JSLockCount, reinterpret_cast<void*>(count));
 }
-pthread_once_t createDidLockJSMutexOnce = PTHREAD_ONCE_INIT;
 
-void JSLock::lock()
+JSLock::JSLock(ExecState* exec)
+    : m_lockingForReal(exec->globalData().isSharedInstance)
 {
-    pthread_once(&createDidLockJSMutexOnce, createDidLockJSMutex);
+    lock(m_lockingForReal);
+    if (m_lockingForReal)
+        registerThread();
+}
+
+void JSLock::lock(bool lockForReal)
+{
+#ifdef NDEBUG
+    // For per-thread contexts, locking is a debug-only feature.
+    if (!lockForReal)
+        return;
+#endif
+
+    pthread_once(&createJSLockCountOnce, createJSLockCount);
 
-    if (!pthread_getspecific(didLockJSMutex)) {
+    int currentLockCount = lockCount();
+    if (!currentLockCount && lockForReal) {
         int result;
         result = pthread_mutex_lock(&JSMutex);
         ASSERT(!result);
-        pthread_setspecific(didLockJSMutex, &didLockJSMutex);
     }
-    ++JSLockCount;
+    setLockCount(currentLockCount + 1);
 }
 
-void JSLock::unlock()
+void JSLock::unlock(bool lockForReal)
 {
-    ASSERT(JSLockCount);
-    ASSERT(!!pthread_getspecific(didLockJSMutex));
+    ASSERT(lockCount());
+
+#ifdef NDEBUG
+    // For per-thread contexts, locking is a debug-only feature.
+    if (!lockForReal)
+        return;
+#endif
 
-    --JSLockCount;
-    if (!JSLockCount) {
-        pthread_setspecific(didLockJSMutex, 0);
+    int newLockCount = lockCount() - 1;
+    setLockCount(newLockCount);
+    if (!newLockCount && lockForReal) {
         int result;
         result = pthread_mutex_unlock(&JSMutex);
         ASSERT(!result);
     }
 }
 
+void JSLock::lock(ExecState* exec)
+{
+    lock(exec->globalData().isSharedInstance);
+}
+
+void JSLock::unlock(ExecState* exec)
+{
+    unlock(exec->globalData().isSharedInstance);
+}
+
 bool JSLock::currentThreadIsHoldingLock()
 {
-    pthread_once(&createDidLockJSMutexOnce, createDidLockJSMutex);
-    return !!pthread_getspecific(didLockJSMutex);
+    pthread_once(&createJSLockCountOnce, createJSLockCount);
+    return !!pthread_getspecific(JSLockCount);
 }
 
 void JSLock::registerThread()
@@ -85,28 +127,43 @@ void JSLock::registerThread()
     Heap::registerThread();
 }
 
-JSLock::DropAllLocks::DropAllLocks()
-    : m_lockCount(0)
+JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
+    : m_lockingForReal(exec->globalData().isSharedInstance)
 {
-    pthread_once(&createDidLockJSMutexOnce, createDidLockJSMutex);
+    pthread_once(&createJSLockCountOnce, createJSLockCount);
 
-    m_lockCount = !!pthread_getspecific(didLockJSMutex) ? JSLock::lockCount() : 0;
+    m_lockCount = JSLock::lockCount();
     for (int i = 0; i < m_lockCount; i++)
-        JSLock::unlock();
+        JSLock::unlock(m_lockingForReal);
+}
+
+JSLock::DropAllLocks::DropAllLocks(bool lockingForReal)
+    : m_lockingForReal(lockingForReal)
+{
+    pthread_once(&createJSLockCountOnce, createJSLockCount);
+
+    // It is necessary to drop even "unreal" locks, because having a non-zero lock count
+    // will prevent a real lock from being taken.
+
+    m_lockCount = JSLock::lockCount();
+    for (int i = 0; i < m_lockCount; i++)
+        JSLock::unlock(m_lockingForReal);
 }
 
 JSLock::DropAllLocks::~DropAllLocks()
 {
     for (int i = 0; i < m_lockCount; i++)
-        JSLock::lock();
-    m_lockCount = 0;
+        JSLock::lock(m_lockingForReal);
 }
 
 #else
 
 // If threading support is off, set the lock count to a constant value of 1 so assertions
 // that the lock is held don't fail
-const int JSLockCount = 1;
+int JSLock::lockCount()
+{
+    return 1;
+}
 
 bool JSLock::currentThreadIsHoldingLock()
 {
@@ -135,9 +192,4 @@ JSLock::DropAllLocks::~DropAllLocks()
 
 #endif // USE(MULTIPLE_THREADS)
 
-int JSLock::lockCount()
-{
-    return JSLockCount;
-}
-
 }
index f6cda5d..a09e967 100644 (file)
@@ -46,33 +46,60 @@ namespace KJS {
     // DropAllLocks object takes care to release the JSLock only if your
     // thread acquired it to begin with.
 
+    // For per-thread contexts, JSLock doesn't do any locking, but we
+    // still need to perform all the counting in order to keep debug
+    // assertions working, so that clients that use a shared context don't break.
+
+    class ExecState;
+
     class JSLock : Noncopyable {
     public:
-        JSLock()
+        JSLock(ExecState* exec);
+
+        JSLock(bool lockingForReal)
+            : m_lockingForReal(lockingForReal)
         {
-            lock();
-            registerThread();
+#ifdef NDEBUG
+            // For per-thread contexts, locking is a debug-only feature.
+            if (!lockingForReal)
+                return;
+#endif
+            lock(lockingForReal);
+            if (lockingForReal)
+                registerThread();
         }
 
-        ~JSLock() 
+        ~JSLock()
         { 
-            unlock(); 
+#ifdef NDEBUG
+            // For per-thread contexts, locking is a debug-only feature.
+            if (!m_lockingForReal)
+                return;
+#endif
+            unlock(m_lockingForReal); 
         }
         
-        static void lock();
-        static void unlock();
+        static void lock(bool);
+        static void unlock(bool);
+        static void lock(ExecState*);
+        static void unlock(ExecState*);
+
         static int lockCount();
         static bool currentThreadIsHoldingLock();
 
         static void registerThread();
 
+        bool m_lockingForReal;
+
         class DropAllLocks : Noncopyable {
         public:
-            DropAllLocks();
+            DropAllLocks(ExecState* exec);
+            DropAllLocks(bool);
             ~DropAllLocks();
             
         private:
             int m_lockCount;
+            bool m_lockingForReal;
         };
     };
 
index c04a908..3edef4f 100644 (file)
@@ -37,6 +37,8 @@ namespace KJS {
         PropertyNameArray(JSGlobalData* globalData) : m_globalData(globalData) {}
         PropertyNameArray(ExecState* exec) : m_globalData(&exec->globalData()) {}
 
+        JSGlobalData* globalData() { return m_globalData; }
+
         void add(const Identifier& identifier) { add(identifier.ustring().rep()); }
         void add(UString::Rep*);
         void addKnownUnique(UString::Rep* identifier) { m_vector.append(Identifier(m_globalData, identifier)); }
index 50244c6..71fc259 100644 (file)
@@ -206,7 +206,7 @@ JSValue* functionDebug(ExecState* exec, JSObject*, JSValue*, const ArgList& args
 
 JSValue* functionGC(ExecState* exec, JSObject*, JSValue*, const ArgList&)
 {
-    JSLock lock;
+    JSLock lock(false);
     exec->heap()->collect();
     return jsUndefined();
 }
@@ -301,9 +301,9 @@ int main(int argc, char** argv)
     TRY
         res = jscmain(argc, argv);
 #ifndef NDEBUG
-        JSLock::lock();
+        JSLock::lock(false);
         JSGlobalData::threadInstance().heap->collect();
-        JSLock::unlock();
+        JSLock::unlock(false);
 #endif
     EXCEPT(res = 3)
     return res;
@@ -447,9 +447,9 @@ static void parseArguments(int argc, char** argv, Options& options)
 
 int jscmain(int argc, char** argv)
 {
-    initializeThreading();
+    KJS::initializeThreading();
 
-    JSLock lock;
+    JSLock lock(false);
 
     Options options;
     parseArguments(argc, argv, options);
index e3846c9..65b6bf5 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "ExecState.h"
 #include "JSGlobalObject.h"
+#include "JSLock.h"
 #include "JSString.h"
 #include "JSValue.h"
 #include "list.h"
@@ -90,8 +91,9 @@ const size_t ALLOCATIONS_PER_COLLECTION = 4000;
 
 static void freeHeap(CollectorHeap*);
 
-Heap::Heap()
+Heap::Heap(bool isShared)
     : m_markListSet(0)
+    , m_isShared(isShared)
 {
     memset(&primaryHeap, 0, sizeof(CollectorHeap));
     memset(&numberHeap, 0, sizeof(CollectorHeap));
@@ -99,7 +101,7 @@ Heap::Heap()
 
 Heap::~Heap()
 {
-    JSLock lock;
+    JSLock lock(false);
 
     delete m_markListSet;
     sweep<PrimaryHeap>();
@@ -438,7 +440,9 @@ static void destroyRegisteredThread(void* data)
 
     // Can't use JSLock convenience object here because we don't want to re-register
     // an exiting thread.
-    JSLock::lock();
+    // JSLock is only used for code simplicity here, as we only need to protect registeredThreads
+    // list manipulation, not JS data structures.
+    JSLock::lock(true);
 
     if (registeredThreads == thread) {
         registeredThreads = registeredThreads->next;
@@ -455,7 +459,7 @@ static void destroyRegisteredThread(void* data)
         ASSERT(t); // If t is NULL, we never found ourselves in the list.
     }
 
-    JSLock::unlock();
+    JSLock::unlock(true);
 
     delete thread;
 }
@@ -467,6 +471,7 @@ static void initializeRegisteredThreadKey()
 
 void Heap::registerThread()
 {
+    // Since registerThread() is only called when using a shared heap, these locks will be real.
     ASSERT(JSLock::lockCount() > 0);
     ASSERT(JSLock::currentThreadIsHoldingLock());
 
@@ -728,7 +733,7 @@ void Heap::markStackObjectsConservatively()
 
 #if USE(MULTIPLE_THREADS)
 
-    if (this == JSGlobalData::sharedInstance().heap) {
+    if (m_isShared) {
 
 #ifndef NDEBUG
         // Forbid malloc during the mark phase. Marking a thread suspends it, so 
@@ -736,6 +741,8 @@ void Heap::markStackObjectsConservatively()
         // suspended while holding the malloc lock.
         fastMallocForbid();
 #endif
+        // It is safe to access the registeredThreads list, because we earlier asserted that locks are being held,
+        // and since this is a shared heap, they are real locks.
         for (Thread* thread = registeredThreads; thread != NULL; thread = thread->next) {
             if (!pthread_equal(thread->posixThread, pthread_self()))
                 markOtherThreadConservatively(thread);
@@ -747,28 +754,48 @@ void Heap::markStackObjectsConservatively()
 #endif
 }
 
+void Heap::setGCProtectNeedsLocking()
+{
+    // Most clients do not need to call this, with the notable exception of WebCore.
+    // Clients that use shared heap have JSLock protection, while others are not supposed
+    // to migrate JS objects between threads. WebCore violates this contract in Database code,
+    // which calls gcUnprotect from a secondary thread.
+    if (!m_protectedValuesMutex)
+        m_protectedValuesMutex.set(new Mutex);
+}
+
 void Heap::protect(JSValue* k)
 {
     ASSERT(k);
-    ASSERT(JSLock::lockCount() > 0);
-    ASSERT(JSLock::currentThreadIsHoldingLock());
+    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_isShared);
 
     if (JSImmediate::isImmediate(k))
         return;
 
-    protectedValues.add(k->asCell());
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->lock();
+
+    m_protectedValues.add(k->asCell());
+
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->unlock();
 }
 
 void Heap::unprotect(JSValue* k)
 {
     ASSERT(k);
-    ASSERT(JSLock::lockCount() > 0);
-    ASSERT(JSLock::currentThreadIsHoldingLock());
+    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_isShared);
 
     if (JSImmediate::isImmediate(k))
         return;
 
-    protectedValues.remove(k->asCell());
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->lock();
+
+    m_protectedValues.remove(k->asCell());
+
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->unlock();
 }
 
 Heap* Heap::heap(const JSValue* v)
@@ -780,12 +807,18 @@ Heap* Heap::heap(const JSValue* v)
 
 void Heap::markProtectedObjects()
 {
-    ProtectCountSet::iterator end = protectedValues.end();
-    for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it) {
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->lock();
+
+    ProtectCountSet::iterator end = m_protectedValues.end();
+    for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) {
         JSCell* val = it->first;
         if (!val->marked())
             val->mark();
     }
+
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->unlock();
 }
 
 template <Heap::HeapType heapType> size_t Heap::sweep()
@@ -940,21 +973,36 @@ size_t Heap::globalObjectCount()
 
 size_t Heap::protectedGlobalObjectCount()
 {
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->lock();
+
     size_t count = 0;
     if (JSGlobalObject* head = JSGlobalData::threadInstance().head) {
         JSGlobalObject* o = head;
         do {
-            if (protectedValues.contains(o))
+            if (m_protectedValues.contains(o))
                 ++count;
             o = o->next();
         } while (o != head);
     }
+
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->unlock();
+
     return count;
 }
 
 size_t Heap::protectedObjectCount()
 {
-    return protectedValues.size();
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->lock();
+
+    size_t result = m_protectedValues.size();
+
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->unlock();
+
+    return result;
 }
 
 static const char* typeName(JSCell* val)
@@ -994,10 +1042,16 @@ HashCountedSet<const char*>* Heap::protectedObjectTypeCounts()
 {
     HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
 
-    ProtectCountSet::iterator end = protectedValues.end();
-    for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it)
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->lock();
+
+    ProtectCountSet::iterator end = m_protectedValues.end();
+    for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
         counts->add(typeName(it->first));
 
+    if (m_protectedValuesMutex)
+        m_protectedValuesMutex->unlock();
+
     return counts;
 }
 
index 5698f78..76c0db5 100644 (file)
@@ -26,6 +26,8 @@
 #include <wtf/HashCountedSet.h>
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/Threading.h>
 
 namespace KJS {
 
@@ -75,6 +77,7 @@ namespace KJS {
 
         size_t size();
 
+        void setGCProtectNeedsLocking();
         void protect(JSValue*);
         void unprotect(JSValue*);
 
@@ -98,6 +101,8 @@ namespace KJS {
 
         HashSet<ArgList*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<ArgList*>; return *m_markListSet; }
 
+        bool isShared() const { return m_isShared; }
+
     private:
         template <Heap::HeapType heapType> void* heapAllocate(size_t);
         template <Heap::HeapType heapType> size_t sweep();
@@ -105,9 +110,8 @@ namespace KJS {
         static CollectorBlock* cellBlock(JSCell*);
         static size_t cellOffset(const JSCell*);
 
-        friend class Machine;
         friend class JSGlobalData;
-        Heap();
+        Heap(bool isShared);
         ~Heap();
 
         void recordExtraCost(size_t);
@@ -121,8 +125,13 @@ namespace KJS {
 
         CollectorHeap primaryHeap;
         CollectorHeap numberHeap;
-        ProtectCountSet protectedValues;
+
+        OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking().
+        ProtectCountSet m_protectedValues;
+
         HashSet<ArgList*>* m_markListSet;
+
+        bool m_isShared;
     };
 
     // tunable parameters
index f6dc025..695c037 100644 (file)
@@ -45,7 +45,7 @@ Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, i
 
 Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, PassRefPtr<SourceProvider> source)
 {
-    JSLock lock;
+    JSLock lock(exec);
 
     int errLine;
     UString errMsg;
@@ -63,7 +63,7 @@ Completion Interpreter::evaluate(ExecState* exec, ScopeChain& scopeChain, const
 
 Completion Interpreter::evaluate(ExecState* exec, ScopeChain& scopeChain, const UString& sourceURL, int startingLineNumber, PassRefPtr<SourceProvider> source, JSValue* thisValue)
 {
-    JSLock lock;
+    JSLock lock(exec);
     
     // parse the source code
     int sourceId;
index 3cb601b..2a8f054 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "JSValue.h"
 #include "collector.h"
-#include "JSLock.h"
 
 namespace KJS {
 
@@ -62,10 +61,10 @@ namespace KJS {
     public:
         ProtectedPtr() : m_ptr(NULL) { }
         ProtectedPtr(T *ptr);
-        ProtectedPtr(const ProtectedPtr &);
+        ProtectedPtr(const ProtectedPtr&);
         ~ProtectedPtr();
 
-        template <class U> ProtectedPtr(const ProtectedPtr<U> &);
+        template <class U> ProtectedPtr(const ProtectedPtr<U>&);
         
         T *get() const { return m_ptr; }
         operator T *() const { return m_ptr; }
@@ -73,8 +72,8 @@ namespace KJS {
         
         bool operator!() const { return m_ptr == NULL; }
 
-        ProtectedPtr &operator=(const ProtectedPtr &);
-        ProtectedPtr &operator=(T *);
+        ProtectedPtr& operator=(const ProtectedPtr&);
+        ProtectedPtr& operator=(T*);
         
     private:
         T *m_ptr;
@@ -83,41 +82,32 @@ namespace KJS {
     template <class T> ProtectedPtr<T>::ProtectedPtr(T *ptr)
         : m_ptr(ptr)
     {
-        if (ptr) {
-            JSLock lock;
+        if (ptr)
             gcProtect(ptr);
-        }
     }
 
-    template <class T> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr &o)
+    template <class T> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtro)
         : m_ptr(o.get())
     {
-        if (T *ptr = m_ptr) {
-            JSLock lock;
+        if (T *ptr = m_ptr)
             gcProtect(ptr);
-        }
     }
 
     template <class T> ProtectedPtr<T>::~ProtectedPtr()
     {
-        if (T *ptr = m_ptr) {
-            JSLock lock;
+        if (T *ptr = m_ptr)
             gcUnprotect(ptr);
-        }
     }
 
-    template <class T> template <class U> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U> &o)
+    template <class T> template <class U> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U>o)
         : m_ptr(o.get())
     {
-        if (T *ptr = m_ptr) {
-            JSLock lock;
+        if (T *ptr = m_ptr)
             gcProtect(ptr);
-        }
     }
 
-    template <class T> ProtectedPtr<T> &ProtectedPtr<T>::operator=(const ProtectedPtr<T> &o) 
+    template <class T> ProtectedPtr<T>& ProtectedPtr<T>::operator=(const ProtectedPtr<T>& o) 
     {
-        JSLock lock;
         T *optr = o.m_ptr;
         gcProtectNullTolerant(optr);
         gcUnprotectNullTolerant(m_ptr);
@@ -125,22 +115,21 @@ namespace KJS {
          return *this;
      }
 
-    template <class T> inline ProtectedPtr<T> &ProtectedPtr<T>::operator=(T *optr)
+    template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(T* optr)
     {
-        JSLock lock;
         gcProtectNullTolerant(optr);
         gcUnprotectNullTolerant(m_ptr);
         m_ptr = optr;
         return *this;
     }
 
-    template <class T> inline bool operator==(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b) { return a.get() == b.get(); }
-    template <class T> inline bool operator==(const ProtectedPtr<T> &a, const T *b) { return a.get() == b; }
-    template <class T> inline bool operator==(const T *a, const ProtectedPtr<T> &b) { return a == b.get(); }
+    template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() == b.get(); }
+    template <class T> inline bool operator==(const ProtectedPtr<T>& a, const T* b) { return a.get() == b; }
+    template <class T> inline bool operator==(const T* a, const ProtectedPtr<T>& b) { return a == b.get(); }
 
-    template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b) { return a.get() != b.get(); }
-    template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const T *b) { return a.get() != b; }
-    template <class T> inline bool operator!=(const T *a, const ProtectedPtr<T> &b) { return a != b.get(); }
+    template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() != b.get(); }
+    template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const T* b) { return a.get() != b; }
+    template <class T> inline bool operator!=(const T* a, const ProtectedPtr<T>& b) { return a != b.get(); }
  
 } // namespace
 
index 699ef79..0209bb1 100644 (file)
@@ -24,7 +24,6 @@
 #include "config.h"
 #include "ustring.h"
 
-#include "JSLock.h"
 #include "collector.h"
 #include "dtoa.h"
 #include "JSFunction.h"
index 77cd687..3a5df69 100644 (file)
@@ -23,7 +23,6 @@
 #ifndef _KJS_USTRING_H_
 #define _KJS_USTRING_H_
 
-#include "JSLock.h"
 #include "collector.h"
 #include <stdint.h>
 #include <wtf/Assertions.h>
index e69d7d3..8efb8e0 100644 (file)
@@ -1,3 +1,37 @@
+2008-07-01  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        Disable JSLock for per-thread contexts.
+
+        * ForwardingHeaders/wtf/Locker.h: Added.
+        * ForwardingHeaders/wtf/Threading.h: Added.
+        * JSBase.cpp:
+        (JSBase::Release):
+        * JSUtils.cpp:
+        (JSObjectKJSValue):
+        (KJSValueToCFTypeInternal):
+        (unprotectGlobalObject):
+        * JSUtils.h:
+        * JSValueWrapper.cpp:
+        (JSValueWrapper::JSObjectCopyPropertyNames):
+        (JSValueWrapper::JSObjectCopyProperty):
+        (JSValueWrapper::JSObjectSetProperty):
+        (JSValueWrapper::JSObjectCallFunction):
+        (JSValueWrapper::JSObjectCopyCFValue):
+        * JavaScriptGlue.cpp:
+        (JSRunCreate):
+        (JSRunEvaluate):
+        (JSRunCheckSyntax):
+        (JSCollect):
+        (JSLockInterpreter):
+        (JSUnlockInterpreter):
+        * UserObjectImp.cpp:
+        (UserObjectImp::callAsFunction):
+        Pass a parameter (always true) to JSLock and JSLock::DropAllLocks to indicate that JSG
+        clients always need implicit mutex protection.
+        Added includes that are now needed.
+
 2008-06-26  Darin Adler  <darin@apple.com>
 
         Reviewed by Geoff.
diff --git a/JavaScriptGlue/ForwardingHeaders/wtf/Locker.h b/JavaScriptGlue/ForwardingHeaders/wtf/Locker.h
new file mode 100644 (file)
index 0000000..75b0acd
--- /dev/null
@@ -0,0 +1 @@
+#include <JavaScriptCore/Locker.h>
diff --git a/JavaScriptGlue/ForwardingHeaders/wtf/Threading.h b/JavaScriptGlue/ForwardingHeaders/wtf/Threading.h
new file mode 100644 (file)
index 0000000..17359e5
--- /dev/null
@@ -0,0 +1 @@
+#include <JavaScriptCore/Threading.h>
index 0a622c0..8728096 100644 (file)
@@ -46,7 +46,7 @@ void JSBase::Release()
 {
     if (--fRetainCount == 0)
     {
-        JSLock lock;
+        JSLock lock(true);
         delete this;
     }
 }
index 93d0ce8..d59f8f6 100644 (file)
@@ -128,7 +128,7 @@ JSUserObject* KJSValueToJSObject(JSValue *inValue, ExecState *exec)
 //--------------------------------------------------------------------------
 JSValue *JSObjectKJSValue(JSUserObject* ptr)
 {
-    JSLock lock;
+    JSLock lock(true);
 
     JSValue *result = jsUndefined();
     if (ptr)
@@ -202,7 +202,7 @@ CFTypeRef KJSValueToCFTypeInternal(JSValue *inValue, ExecState *exec, ObjectImpL
 
     CFTypeRef result = 0;
 
-    JSLock lock;
+    JSLock lock(true);
 
     switch (inValue->type())
     {
@@ -399,7 +399,7 @@ static pthread_once_t globalObjectKeyOnce = PTHREAD_ONCE_INIT;
 
 static void unprotectGlobalObject(void* data) 
 {
-    JSLock lock;
+    JSLock lock(true);
     gcUnprotect(static_cast<JSGlobalObject*>(data));
 }
 
index f9f5d1d..dd440bc 100644 (file)
@@ -32,6 +32,7 @@
 #include "JavaScriptGlue.h"
 
 #include <JavaScriptCore/JSValue.h>
+#include <JavaScriptCore/JSLock.h>
 #include <JavaScriptCore/JSObject.h>
 #include <JavaScriptCore/JSGlobalObject.h>
 #include <JavaScriptCore/interpreter.h>
index ac75977..cbfa8f3 100644 (file)
@@ -66,7 +66,7 @@ void JSValueWrapper::JSObjectDispose(void *data)
 
 CFArrayRef JSValueWrapper::JSObjectCopyPropertyNames(void *data)
 {
-    JSLock lock;
+    JSLock lock(true);
 
     CFMutableArrayRef result = 0;
     JSValueWrapper* ptr = (JSValueWrapper*)data;
@@ -101,7 +101,7 @@ CFArrayRef JSValueWrapper::JSObjectCopyPropertyNames(void *data)
 
 JSObjectRef JSValueWrapper::JSObjectCopyProperty(void *data, CFStringRef propertyName)
 {
-    JSLock lock;
+    JSLock lock(true);
 
     JSObjectRef result = 0;
     JSValueWrapper* ptr = (JSValueWrapper*)data;
@@ -125,7 +125,7 @@ JSObjectRef JSValueWrapper::JSObjectCopyProperty(void *data, CFStringRef propert
 
 void JSValueWrapper::JSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue)
 {
-    JSLock lock;
+    JSLock lock(true);
 
     JSValueWrapper* ptr = (JSValueWrapper*)data;
     if (ptr)
@@ -139,7 +139,7 @@ void JSValueWrapper::JSObjectSetProperty(void *data, CFStringRef propertyName, J
 
 JSObjectRef JSValueWrapper::JSObjectCallFunction(void *data, JSObjectRef thisObj, CFArrayRef args)
 {
-    JSLock lock;
+    JSLock lock(true);
 
     JSObjectRef result = 0;
     JSValueWrapper* ptr = (JSValueWrapper*)data;
@@ -179,7 +179,7 @@ JSObjectRef JSValueWrapper::JSObjectCallFunction(void *data, JSObjectRef thisObj
 
 CFTypeRef JSValueWrapper::JSObjectCopyCFValue(void *data)
 {
-    JSLock lock;
+    JSLock lock(true);
 
     CFTypeRef result = 0;
     JSValueWrapper* ptr = (JSValueWrapper*)data;
index eda5dbf..2b91178 100644 (file)
@@ -246,7 +246,7 @@ JSRunRef JSRunCreate(CFStringRef jsSource, JSFlags inFlags)
     JSRunRef result = 0;
     if (jsSource)
     {
-        JSLock lock;
+        JSLock lock(true);
         result = (JSRunRef) new JSRun(jsSource, inFlags);
     }
     return result;
@@ -291,7 +291,7 @@ JSObjectRef JSRunEvaluate(JSRunRef ref)
     JSRun* ptr = (JSRun*)ref;
     if (ptr)
     {
-        JSLock lock;
+        JSLock lock(true);
         Completion completion = ptr->Evaluate();
         if (completion.isValueCompletion())
         {
@@ -325,7 +325,7 @@ bool JSRunCheckSyntax(JSRunRef ref)
     JSRun* ptr = (JSRun*)ref;
     if (ptr)
     {
-            JSLock lock;
+            JSLock lock(true);
             result = ptr->CheckSyntax();
     }
     return result;
@@ -338,7 +338,7 @@ void JSCollect()
 {
     initializeThreading();
 
-    JSLock lock;
+    JSLock lock(true);
     getThreadGlobalExecState()->heap()->collect();
 }
 
@@ -649,11 +649,11 @@ CFMutableArrayRef JSCreateJSArrayFromCFArray(CFArrayRef array)
 void JSLockInterpreter()
 {
     initializeThreading();
-    JSLock::lock();
+    JSLock::lock(true);
 }
 
 
 void JSUnlockInterpreter()
 {
-    JSLock::unlock();
+    JSLock::unlock(true);
 }
index 67ecd0f..cbfa49e 100644 (file)
@@ -74,7 +74,7 @@ JSValue *UserObjectImp::callAsFunction(ExecState *exec, JSObject *thisObj, const
 
         JSUserObject* jsResult;
         { // scope
-            JSLock::DropAllLocks dropLocks;
+            JSLock::DropAllLocks dropLocks(exec);
 
             // getCallData should have guarded against a NULL fJSUserObject.
             assert(fJSUserObject);
index d3ed162..72c94d0 100644 (file)
@@ -1,3 +1,192 @@
+2008-07-01  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        Disable JSLock for per-thread contexts.
+
+        * bridge/runtime_root.cpp:
+        (KJS::Bindings::RootObject::invalidate):
+        (KJS::Bindings::RootObject::gcProtect):
+        (KJS::Bindings::RootObject::gcUnprotect):
+        Don't lock while calling gcProtect/gcUnprotect, which now has its own implicit lock.
+
+        * storage/Database.cpp: (WebCore::Database::Database): Call Heap::setGCProtectNeedsLocking
+        to indicate that protected value list can be concurrently accessed from multiple threads now.
+
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::loadRequestSynchronously): There is no need to drop the locks here,
+        as fake locks cannot deadlock, and there is no danger that someone will try to take a real
+        JSLock on the main thread while we are waiting for response.
+        (WebCore::XMLHttpRequest::loadRequestAsynchronously): There is no need to explicitly lock
+        around gcProtect/gcUnprotect now.
+        (WebCore::XMLHttpRequest::dropProtection): Access heap directly, rather than via
+        JSGlobalData::threadInstance().
+
+        * bindings/js/GCController.cpp:
+        (WebCore::collect):
+        (WebCore::GCController::gcTimerFired):
+        (WebCore::GCController::garbageCollectNow):
+        (WebCore::GCController::garbageCollectOnAlternateThreadForDebugging):
+        * bindings/js/JSCustomSQLStatementCallback.cpp:
+        (WebCore::JSCustomSQLStatementCallback::handleEvent):
+        * bindings/js/JSCustomSQLStatementErrorCallback.cpp:
+        (WebCore::JSCustomSQLStatementErrorCallback::handleEvent):
+        * bindings/js/JSCustomSQLTransactionCallback.cpp:
+        (WebCore::JSCustomSQLTransactionCallback::handleEvent):
+        * bindings/js/JSCustomSQLTransactionErrorCallback.cpp:
+        (WebCore::JSCustomSQLTransactionErrorCallback::handleEvent):
+        * bindings/js/JSCustomVoidCallback.cpp:
+        (WebCore::JSCustomVoidCallback::handleEvent):
+        * bindings/js/JSCustomXPathNSResolver.cpp:
+        (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
+        * bindings/js/JSDOMWindowBase.cpp:
+        (WebCore::DOMWindowTimer::~DOMWindowTimer):
+        (WebCore::JSDOMWindowBase::clear):
+        (WebCore::JSDOMWindowBase::timerFired):
+        * bindings/js/JSEventCustom.cpp:
+        (WebCore::toJS):
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::JSAbstractEventListener::handleEvent):
+        (WebCore::JSLazyEventListener::parseCode):
+        * bindings/js/JSNodeFilterCondition.cpp:
+        (WebCore::JSNodeFilterCondition::acceptNode):
+        * bindings/js/ScheduledAction.cpp:
+        (WebCore::ScheduledAction::execute):
+        * bindings/js/ScriptController.cpp:
+        (WebCore::ScriptController::evaluate):
+        (WebCore::ScriptController::clear):
+        (WebCore::ScriptController::createHTMLEventHandler):
+        (WebCore::ScriptController::createSVGEventHandler):
+        (WebCore::ScriptController::initScript):
+        (WebCore::ScriptController::updateDocument):
+        * bindings/objc/WebScriptObject.mm:
+        (-[WebScriptObject callWebScriptMethod:withArguments:]):
+        (-[WebScriptObject evaluateWebScript:]):
+        (-[WebScriptObject setValue:forKey:]):
+        (-[WebScriptObject valueForKey:]):
+        (-[WebScriptObject removeWebScriptKey:]):
+        (-[WebScriptObject stringRepresentation]):
+        (-[WebScriptObject webScriptValueAtIndex:]):
+        (-[WebScriptObject setWebScriptValueAtIndex:value:]):
+        (+[WebScriptObject _convertValueToObjcValue:originRootObject:rootObject:]):
+        * bridge/NP_jsobject.cpp:
+        (_NPN_InvokeDefault):
+        (_NPN_Invoke):
+        (_NPN_Evaluate):
+        (_NPN_GetProperty):
+        (_NPN_SetProperty):
+        (_NPN_RemoveProperty):
+        (_NPN_HasProperty):
+        (_NPN_HasMethod):
+        (_NPN_SetException):
+        (_NPN_Enumerate):
+        * bridge/c/c_class.cpp:
+        (KJS::Bindings::CClass::~CClass):
+        (KJS::Bindings::CClass::methodsNamed):
+        (KJS::Bindings::CClass::fieldNamed):
+        * bridge/c/c_instance.cpp:
+        (KJS::Bindings::CInstance::invokeMethod):
+        (KJS::Bindings::CInstance::invokeDefaultMethod):
+        (KJS::Bindings::CInstance::getPropertyNames):
+        * bridge/c/c_runtime.cpp:
+        (KJS::Bindings::CField::valueFromInstance):
+        (KJS::Bindings::CField::setValueToInstance):
+        * bridge/c/c_utility.cpp:
+        (KJS::Bindings::convertValueToNPVariant):
+        (KJS::Bindings::convertNPVariantToValue):
+        * bridge/jni/jni_class.cpp:
+        (JavaClass::JavaClass):
+        (JavaClass::~JavaClass):
+        * bridge/jni/jni_instance.cpp:
+        (JavaInstance::stringValue):
+        * 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:
+        (KJS::Bindings::dispatchJNICall):
+        * bridge/jni/jni_runtime.cpp:
+        (JavaMethod::signature):
+        * bridge/jni/jni_runtime.h:
+        (KJS::Bindings::JavaString::JavaString):
+        (KJS::Bindings::JavaString::_commonInit):
+        (KJS::Bindings::JavaString::~JavaString):
+        (KJS::Bindings::JavaString::UTF8String):
+        * bridge/jni/jni_utility.cpp:
+        (KJS::Bindings::convertArrayInstanceToJavaArray):
+        (KJS::Bindings::convertValueToJValue):
+        * bridge/npruntime.cpp:
+        (_NPN_GetStringIdentifier):
+        * bridge/objc/objc_instance.mm:
+        (ObjcInstance::moveGlobalExceptionToExecState):
+        (ObjcInstance::invokeMethod):
+        (ObjcInstance::invokeDefaultMethod):
+        (ObjcInstance::setValueOfUndefinedField):
+        (ObjcInstance::getValueOfUndefinedField):
+        * bridge/objc/objc_runtime.mm:
+        (ObjcField::valueFromInstance):
+        (ObjcField::setValueToInstance):
+        * bridge/objc/objc_utility.mm:
+        (KJS::Bindings::convertValueToObjcValue):
+        (KJS::Bindings::convertNSStringToString):
+        (KJS::Bindings::convertObjcValueToValue):
+        * bridge/runtime.cpp:
+        (KJS::Bindings::Instance::createRuntimeObject):
+        * dom/Document.cpp:
+        (WebCore::Document::~Document):
+        * dom/Node.cpp:
+        (WebCore::Node::setDocument):
+        * history/CachedPage.cpp:
+        (WebCore::CachedPage::CachedPage):
+        (WebCore::CachedPage::restore):
+        (WebCore::CachedPage::clear):
+        * html/HTMLPlugInElement.cpp:
+        (WebCore::HTMLPlugInElement::createNPObject):
+        * loader/FrameLoader.cpp:
+        (WebCore::getString):
+        * page/Frame.cpp:
+        (WebCore::Frame::bindingRootObject):
+        (WebCore::Frame::windowScriptNPObject):
+        (WebCore::Frame::clearScriptObjects):
+        * page/InspectorController.cpp:
+        (WebCore::jsStringRef):
+        (WebCore::ConsoleMessage::ConsoleMessage):
+        (WebCore::XMLHttpRequestResource::XMLHttpRequestResource):
+        (WebCore::XMLHttpRequestResource::~XMLHttpRequestResource):
+        (WebCore::getResourceDocumentNode):
+        (WebCore::search):
+        (WebCore::inspectedWindow):
+        (WebCore::wrapCallback):
+        (WebCore::currentCallFrame):
+        (WebCore::profiles):
+        (WebCore::InspectorController::focusNode):
+        (WebCore::InspectorController::addDatabaseScriptResource):
+        (WebCore::InspectorController::addScriptProfile):
+        * page/JavaScriptCallFrame.cpp:
+        (WebCore::JavaScriptCallFrame::evaluate):
+        * page/JavaScriptProfileNode.cpp:
+        (WebCore::getTotalTime):
+        (WebCore::getSelfTime):
+        (WebCore::getTotalPercent):
+        (WebCore::getSelfPercent):
+        (WebCore::getNumberOfCalls):
+        (WebCore::getChildren):
+        (WebCore::getVisible):
+        * page/mac/FrameMac.mm:
+        (WebCore::Frame::windowScriptObject):
+        Pass a parameter (always false) to JSLock and JSLock::DropAllLocks to indicate that WebCore
+        doesn't need locking. In the future, it may be possible to remove some of these if we
+        establish that this won't make JSC assertions fail (and that we don't want to add such
+        assertions either).
+        Added includes that are now needed.
+
 2008-07-01  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Oliver Hunt.
index 4691828..7a1e039 100644 (file)
@@ -42,7 +42,7 @@ namespace WebCore {
 
 static void* collect(void*)
 {
-    JSLock lock;
+    JSLock lock(false);
     JSGlobalData::threadInstance().heap->collect();
     return 0;
 }
@@ -68,13 +68,13 @@ void GCController::garbageCollectSoon()
 
 void GCController::gcTimerFired(Timer<GCController>*)
 {
-    JSLock lock;
+    JSLock lock(false);
     JSGlobalData::threadInstance().heap->collect();
 }
 
 void GCController::garbageCollectNow()
 {
-    JSLock lock;
+    JSLock lock(false);
     JSGlobalData::threadInstance().heap->collect();
 }
 
@@ -84,10 +84,8 @@ void GCController::garbageCollectOnAlternateThreadForDebugging(bool waitUntilDon
     pthread_t thread;
     pthread_create(&thread, NULL, collect, NULL);
 
-    if (waitUntilDone) {
-        JSLock::DropAllLocks dropLocks; // Otherwise our lock would deadlock the collect thread we're joining
+    if (waitUntilDone)
         pthread_join(thread, NULL);
-    }
 #endif
 }
 
index df8cce0..cceca29 100644 (file)
@@ -36,6 +36,7 @@
 #include "ScriptController.h"
 #include "JSSQLResultSet.h"
 #include "JSSQLTransaction.h"
+#include <kjs/JSLock.h>
 
 namespace WebCore {
     
@@ -58,7 +59,7 @@ void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR
     JSGlobalObject* globalObject = m_frame->script()->globalObject();
     ExecState* exec = globalObject->globalExec();
         
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
         
     JSValue* function = m_callback->get(exec, Identifier(exec, "handleEvent"));
     CallData callData;
index 0e4adc3..ffa7c29 100644 (file)
@@ -36,6 +36,7 @@
 #include "ScriptController.h"
 #include "JSSQLError.h"
 #include "JSSQLTransaction.h"
+#include <kjs/JSLock.h>
 
 namespace WebCore {
     
@@ -58,7 +59,7 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction,
     JSGlobalObject* globalObject = m_frame->script()->globalObject();
     ExecState* exec = globalObject->globalExec();
         
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
         
     JSValue* handleEventFunction = m_callback->get(exec, Identifier(exec, "handleEvent"));
     CallData handleEventCallData;
index 668667c..17de42c 100644 (file)
@@ -37,6 +37,7 @@
 #include "ScriptController.h"
 #include "JSSQLTransaction.h"
 #include "Page.h"
+#include <kjs/JSLock.h>
 #include <wtf/MainThread.h>
 
 namespace WebCore {
@@ -112,7 +113,7 @@ void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo
     JSGlobalObject* globalObject = m_data->frame()->script()->globalObject();
     ExecState* exec = globalObject->globalExec();
         
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
         
     JSValue* handleEventFunction = m_data->callback()->get(exec, Identifier(exec, "handleEvent"));
     CallData handleEventCallData;
index 7501573..76e86f8 100644 (file)
@@ -35,6 +35,7 @@
 #include "Frame.h"
 #include "ScriptController.h"
 #include "JSSQLError.h"
+#include <kjs/JSLock.h>
 
 namespace WebCore {
     
@@ -57,7 +58,7 @@ bool JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
     JSGlobalObject* globalObject = m_frame->script()->globalObject();
     ExecState* exec = globalObject->globalExec();
         
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
         
     JSValue* function = m_callback->get(exec, Identifier(exec, "handleEvent"));
     CallData callData;
index f5ca6fe..9227e9b 100644 (file)
@@ -36,6 +36,7 @@
 #include "JSDOMWindowCustom.h"
 #include "JSDOMBinding.h"
 #include "ScriptController.h"
+#include <kjs/JSLock.h>
 
 namespace WebCore {
     
@@ -58,7 +59,7 @@ void JSCustomVoidCallback::handleEvent()
     JSGlobalObject* globalObject = m_frame->script()->globalObject();
     ExecState* exec = globalObject->globalExec();
         
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
         
     JSValue* function = m_callback->get(exec, Identifier(exec, "handleEvent"));
     CallData callData;
index 66761e7..1bbe84f 100644 (file)
@@ -37,6 +37,7 @@
 #include "JSDOMWindowCustom.h"
 #include "JSDOMBinding.h"
 #include "ScriptController.h"
+#include <kjs/JSLock.h>
 
 namespace WebCore {
 
@@ -75,7 +76,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
     if (!m_frame->script()->isEnabled())
         return String();
 
-    JSLock lock;
+    JSLock lock(false);
 
     JSGlobalObject* globalObject = m_frame->script()->globalObject();
     ExecState* exec = globalObject->globalExec();
index 8bd5e71..4d7923c 100644 (file)
@@ -60,6 +60,7 @@
 #include "WindowFeatures.h"
 #include "htmlediting.h"
 #include "ScriptController.h"
+#include <kjs/JSLock.h>
 #include <wtf/AlwaysInline.h>
 #include <wtf/MathExtras.h>
 
@@ -108,7 +109,7 @@ public:
 
     virtual ~DOMWindowTimer()
     {
-        JSLock lock;
+        JSLock lock(false);
         delete m_action;
     }
 
@@ -869,7 +870,7 @@ void JSDOMWindowBase::clearHelperObjectProperties()
 
 void JSDOMWindowBase::clear()
 {
-  JSLock lock;
+  JSLock lock(false);
 
   if (d->m_returnValueSlot && !*d->m_returnValueSlot)
     *d->m_returnValueSlot = getDirect(Identifier(globalExec(), "returnValue"));
@@ -1263,7 +1264,7 @@ void JSDOMWindowBase::timerFired(DOMWindowTimer* timer)
     delete timer;
     action->execute(shell());
 
-    JSLock lock;
+    JSLock lock(false);
     delete action;
 }
 
index cce47e6..57b8331 100644 (file)
@@ -52,6 +52,7 @@
 #include "UIEvent.h"
 #include "WheelEvent.h"
 #include "XMLHttpRequestProgressEvent.h"
+#include <kjs/JSLock.h>
 
 #if ENABLE(DOM_STORAGE)
 #include "JSStorageEvent.h"
@@ -74,7 +75,7 @@ JSValue* JSEvent::clipboardData(ExecState* exec) const
 
 JSValue* toJS(ExecState* exec, Event* event)
 {
-    JSLock lock;
+    JSLock lock(false);
 
     if (!event)
         return jsNull();
index f0526bb..0092377 100644 (file)
@@ -33,6 +33,7 @@
 #include "JSEventTargetNode.h"
 #include "ScriptController.h"
 #include <kjs/FunctionConstructor.h>
+#include <kjs/JSLock.h>
 
 using namespace KJS;
 
@@ -58,7 +59,7 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
     if (!script->isEnabled() || script->isPaused())
         return;
 
-    JSLock lock;
+    JSLock lock(false);
 
     ExecState* exec = window->globalExec();
 
@@ -273,7 +274,7 @@ void JSLazyEventListener::parseCode() const
     if (frame && frame->script()->isEnabled()) {
         ExecState* exec = window()->globalExec();
 
-        JSLock lock;
+        JSLock lock(false);
         ArgList args;
 
         UString sourceURL(frame->loader()->url().string());
index 938fb25..61c394a 100644 (file)
@@ -26,6 +26,7 @@
 #include "JSNodeFilter.h"
 #include "NodeFilter.h"
 #include "ScriptController.h"
+#include <kjs/JSLock.h>
 
 namespace WebCore {
 
@@ -57,7 +58,7 @@ short JSNodeFilterCondition::acceptNode(Node* filterNode, JSValue*& exception) c
     if (!frame)
         return NodeFilter::FILTER_REJECT;
 
-    JSLock lock;
+    JSLock lock(false);
 
     CallData callData;
     CallType callType = m_filter->getCallData(callData);
index cd960ac..40d41ef 100644 (file)
@@ -31,6 +31,7 @@
 #include "FrameLoader.h"
 #include "JSDOMWindow.h"
 #include "ScriptController.h"
+#include <kjs/JSLock.h>
 
 using namespace KJS;
 
@@ -56,7 +57,7 @@ void ScheduledAction::execute(JSDOMWindowShell* windowShell)
 
     frame->script()->setProcessingTimerCallback(true);
 
-    JSLock lock;
+    JSLock lock(false);
 
     if (m_function) {
         CallData callData;
index ccacc30..a19b744 100644 (file)
@@ -38,6 +38,7 @@
 #include "JSEventListener.h"
 #include <kjs/completion.h>
 #include <kjs/debugger.h>
+#include <kjs/JSLock.h>
 
 #if ENABLE(SVG)
 #include "JSSVGLazyEventListener.h"
@@ -80,7 +81,7 @@ JSValue* ScriptController::evaluate(const String& filename, int baseLine, const
     ExecState* exec = m_windowShell->window()->globalExec();
     m_processingInlineCode = filename.isNull();
 
-    JSLock lock;
+    JSLock lock(false);
 
     // Evaluating the JavaScript could cause the frame to be deallocated
     // so we start the keep alive timer here.
@@ -111,7 +112,7 @@ void ScriptController::clear()
     if (!m_windowShell)
         return;
 
-    JSLock lock;
+    JSLock lock(false);
     m_windowShell->window()->clear();
     m_liveFormerWindows.add(m_windowShell->window());
     m_windowShell->setWindow(new JSDOMWindow(m_frame->domWindow(), m_windowShell));
@@ -127,7 +128,7 @@ void ScriptController::clear()
 PassRefPtr<EventListener> ScriptController::createHTMLEventHandler(const String& functionName, const String& code, Node* node)
 {
     initScriptIfNeeded();
-    JSLock lock;
+    JSLock lock(false);
     return JSLazyEventListener::create(functionName, code, m_windowShell->window(), node, m_handlerLineno);
 }
 
@@ -135,7 +136,7 @@ PassRefPtr<EventListener> ScriptController::createHTMLEventHandler(const String&
 PassRefPtr<EventListener> ScriptController::createSVGEventHandler(const String& functionName, const String& code, Node* node)
 {
     initScriptIfNeeded();
-    JSLock lock;
+    JSLock lock(false);
     return JSSVGLazyEventListener::create(functionName, code, m_windowShell->window(), node, m_handlerLineno);
 }
 #endif
@@ -154,7 +155,7 @@ void ScriptController::initScript()
     if (m_windowShell)
         return;
 
-    JSLock lock;
+    JSLock lock(false);
 
     m_windowShell = new JSDOMWindowShell(m_frame->domWindow());
     updateDocument();
@@ -217,7 +218,7 @@ void ScriptController::updateDocument()
     if (!m_frame->document())
         return;
 
-    JSLock lock;
+    JSLock lock(false);
     if (m_windowShell)
         m_windowShell->window()->updateDocument();
     HashSet<JSDOMWindow*>::iterator end = m_liveFormerWindows.end();
index 3741ba8..f3203c3 100644 (file)
@@ -37,6 +37,7 @@
 #import <JavaScriptCore/ExecState.h>
 #import <JavaScriptCore/APICast.h>
 #import <JavaScriptCore/JSGlobalObject.h>
+#import <JavaScriptCore/JSLock.h>
 #import <JavaScriptCore/completion.h>
 #import <JavaScriptCore/interpreter.h>
 #import "objc_instance.h"
@@ -281,7 +282,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     if (![self _isSafeScript])
         return nil;
 
-    JSLock lock;
+    JSLock lock(false);
     
     // Look up the function object.
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
@@ -326,7 +327,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ASSERT(!exec->hadException());
 
     JSValue *result;
-    JSLock lock;
+    JSLock lock(false);
     
     [self _rootObject]->globalObject()->startTimeoutCheck();
     Completion completion = Interpreter::evaluate([self _rootObject]->globalObject()->globalExec(), [self _rootObject]->globalObject()->globalScopeChain(), UString(), 1, String(script));
@@ -361,7 +362,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     ASSERT(!exec->hadException());
 
-    JSLock lock;
+    JSLock lock(false);
     [self _imp]->put(exec, Identifier(exec, String(key)), convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]));
 
     if (exec->hadException()) {
@@ -385,7 +386,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;
+        JSLock lock(false);
         
         JSValue *result = [self _imp]->get(exec, Identifier(exec, String(key)));
         
@@ -401,7 +402,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;
+    JSLock lock(false);
     _didExecute(self);
     
     return resultObj;
@@ -415,7 +416,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     ASSERT(!exec->hadException());
 
-    JSLock lock;
+    JSLock lock(false);
     [self _imp]->deleteProperty(exec, Identifier(exec, String(key)));
 
     if (exec->hadException()) {
@@ -432,7 +433,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
         // This is a workaround for a gcc 3.3 internal compiler error.
         return @"Undefined";
 
-    JSLock lock;
+    JSLock lock(false);
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     
     id result = convertValueToObjcValue(exec, [self _imp], ObjcObjectType).objectValue;
@@ -452,7 +453,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     ASSERT(!exec->hadException());
 
-    JSLock lock;
+    JSLock lock(false);
     JSValue *result = [self _imp]->get(exec, index);
 
     if (exec->hadException()) {
@@ -476,7 +477,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     ExecState* exec = [self _rootObject]->globalObject()->globalExec();
     ASSERT(!exec->hadException());
 
-    JSLock lock;
+    JSLock lock(false);
     [self _imp]->put(exec, index, convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]));
 
     if (exec->hadException()) {
@@ -507,7 +508,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     if (value->isObject()) {
         JSObject* object = static_cast<JSObject*>(value);
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock;
+        JSLock lock(false);
         
         if (object->classInfo() != &RuntimeObjectImp::s_info) {
             JSValue* runtimeObject = object->get(exec, Identifier(exec, "__apple_runtime_object"));
index c950f2c..3c73d98 100644 (file)
@@ -30,6 +30,7 @@
 #include "NP_jsobject.h"
 
 #include <kjs/JSGlobalObject.h>
+#include <kjs/JSLock.h>
 #include <kjs/PropertyNameArray.h>
 #include "c_utility.h"
 #include <kjs/completion.h>
@@ -104,7 +105,7 @@ bool _NPN_InvokeDefault(NPP, NPObject* o, const NPVariant* args, uint32_t argCou
             return false;
         
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock;
+        JSLock lock(false);
         
         // Call the function object.
         JSValue* function = obj->imp;
@@ -153,7 +154,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;
+        JSLock lock(false);
         JSValue* function = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string));
         CallData callData;
         CallType callType = function->getCallData(callData);
@@ -190,7 +191,7 @@ bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant)
 
         ExecState* exec = rootObject->globalObject()->globalExec();
         
-        JSLock lock;
+        JSLock lock(false);
         String scriptString = convertNPStringToUTF16(s);
         rootObject->globalObject()->startTimeoutCheck();
         Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), UString(), 1, scriptString);
@@ -226,7 +227,7 @@ bool _NPN_GetProperty(NPP, NPObject* o, NPIdentifier propertyName, NPVariant* va
         ExecState* exec = rootObject->globalObject()->globalExec();
         PrivateIdentifier* i = (PrivateIdentifier*)propertyName;
         
-        JSLock lock;
+        JSLock lock(false);
         JSValue *result;
         if (i->isString)
             result = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string));
@@ -257,7 +258,7 @@ bool _NPN_SetProperty(NPP, NPObject* o, NPIdentifier propertyName, const NPVaria
             return false;
 
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock;
+        JSLock lock(false);
         PrivateIdentifier* i = (PrivateIdentifier*)propertyName;
         if (i->isString)
             obj->imp->put(exec, identifierFromNPIdentifier(i->value.string), convertNPVariantToValue(exec, variant, rootObject));
@@ -291,7 +292,7 @@ bool _NPN_RemoveProperty(NPP, NPObject* o, NPIdentifier propertyName)
                 return false;
         }
 
-        JSLock lock;
+        JSLock lock(false);
         if (i->isString)
             obj->imp->deleteProperty(exec, identifierFromNPIdentifier(i->value.string));
         else
@@ -313,7 +314,7 @@ bool _NPN_HasProperty(NPP, NPObject* o, NPIdentifier propertyName)
 
         ExecState* exec = rootObject->globalObject()->globalExec();
         PrivateIdentifier* i = (PrivateIdentifier*)propertyName;
-        JSLock lock;
+        JSLock lock(false);
         if (i->isString)
             return obj->imp->hasProperty(exec, identifierFromNPIdentifier(i->value.string));
         return obj->imp->hasProperty(exec, i->value.number);
@@ -339,7 +340,7 @@ bool _NPN_HasMethod(NPP, NPObject* o, NPIdentifier methodName)
             return false;
 
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock;
+        JSLock lock(false);
         JSValue* func = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string));
         return !func->isUndefined();
     }
@@ -359,7 +360,7 @@ void _NPN_SetException(NPObject* o, const NPUTF8* message)
             return;
 
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock;
+        JSLock lock(false);
         throwError(exec, GeneralError, message);
     }
 }
@@ -374,7 +375,7 @@ bool _NPN_Enumerate(NPP, NPObject *o, NPIdentifier **identifier, uint32_t *count
             return false;
         
         ExecState* exec = rootObject->globalObject()->globalExec();
-        JSLock lock;
+        JSLock lock(false);
         PropertyNameArray propertyNames(exec);
 
         obj->imp->getPropertyNames(exec, propertyNames);
index 206e0eb..9882901 100644 (file)
@@ -33,6 +33,7 @@
 #include "c_runtime.h"
 #include "npruntime_impl.h"
 #include <kjs/identifier.h>
+#include <kjs/JSLock.h>
 
 namespace KJS { namespace Bindings {
 
@@ -43,7 +44,7 @@ CClass::CClass(NPClass* aClass)
 
 CClass::~CClass()
 {
-    JSLock lock;
+    JSLock lock(false);
 
     deleteAllValues(_methods);
     _methods.clear();
@@ -90,7 +91,7 @@ MethodList CClass::methodsNamed(const Identifier& identifier, Instance* instance
     if (_isa->hasMethod && _isa->hasMethod(obj, ident)){
         Method* aMethod = new CMethod(ident); // deleted in the CClass destructor
         {
-            JSLock lock;
+            JSLock lock(false);
             _methods.set(identifier.ustring().rep(), aMethod);
         }
         methodList.append(aMethod);
@@ -111,7 +112,7 @@ Field* CClass::fieldNamed(const Identifier& identifier, Instance* instance) cons
     if (_isa->hasProperty && _isa->hasProperty(obj, ident)){
         aField = new CField(ident); // deleted in the CClass destructor
         {
-            JSLock lock;
+            JSLock lock(false);
             _fields.set(identifier.ustring().rep(), aField);
         }
     }
index 71fb5ea..61a98a9 100644 (file)
@@ -35,6 +35,7 @@
 #include "npruntime_impl.h"
 #include "runtime_root.h"
 #include <kjs/ExecState.h>
+#include <kjs/JSLock.h>
 #include <kjs/JSNumberCell.h>
 #include <kjs/PropertyNameArray.h>
 #include <wtf/Assertions.h>
@@ -92,7 +93,7 @@ JSValue* CInstance::invokeMethod(ExecState* exec, const MethodList& methodList,
     VOID_TO_NPVARIANT(resultVariant);
 
     {
-       JSLock::DropAllLocks dropAllLocks;
+        JSLock::DropAllLocks dropAllLocks(false);
         _object->_class->invoke(_object, ident, cArgs.data(), count, &resultVariant);
     }
 
@@ -121,7 +122,7 @@ JSValue* CInstance::invokeDefaultMethod(ExecState* exec, const ArgList& args)
     NPVariant resultVariant;
     VOID_TO_NPVARIANT(resultVariant);
     {
-       JSLock::DropAllLocks dropAllLocks;
+        JSLock::DropAllLocks dropAllLocks(false);
         _object->_class->invokeDefault(_object, cArgs.data(), count, &resultVariant);
     }
     
@@ -179,7 +180,7 @@ void CInstance::getPropertyNames(ExecState* exec, PropertyNameArray& nameArray)
     NPIdentifier* identifiers;
     
     {
-        JSLock::DropAllLocks dropAllLocks;
+        JSLock::DropAllLocks dropAllLocks(false);
         if (!_object->_class->enumerate(_object, &identifiers, &count))
             return;
     }
index bd23211..66f14d8 100644 (file)
@@ -32,6 +32,7 @@
 #include "c_instance.h"
 #include "c_utility.h"
 #include "npruntime_impl.h"
+#include <kjs/JSLock.h>
 
 namespace KJS {
 namespace Bindings {
@@ -62,7 +63,7 @@ JSValue* CField::valueFromInstance(ExecState* exec, const Instance* inst) const
 
         bool result;
         {
-           JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(false);
             result = obj->_class->getProperty(obj, _fieldIdentifier, &property);
         }
         if (result) {
@@ -83,7 +84,7 @@ void CField::setValueToInstance(ExecState *exec, const Instance *inst, JSValue *
         convertValueToNPVariant(exec, aValue, &variant);
 
         {
-           JSLock::DropAllLocks dropAllLocks;
+            JSLock::DropAllLocks dropAllLocks(false);
             obj->_class->setProperty(obj, _fieldIdentifier, &variant);
         }
 
index 0d78b93..22eb795 100644 (file)
@@ -33,6 +33,7 @@
 #include "NP_jsobject.h"
 #include "c_instance.h"
 #include <kjs/JSGlobalObject.h>
+#include <kjs/JSLock.h>
 #include "PlatformString.h"
 #include "npruntime_impl.h"
 #include "npruntime_priv.h"
@@ -66,7 +67,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;
+    JSLock lock(false);
     
     JSType type = value->type();
     
@@ -109,7 +110,7 @@ void convertValueToNPVariant(ExecState* exec, JSValue* value, NPVariant* result)
 
 JSValue* convertNPVariantToValue(ExecState* exec, const NPVariant* variant, RootObject* rootObject)
 {
-    JSLock lock;
+    JSLock lock(false);
     
     NPVariantType type = variant->type;
 
index b914f39..5fc81c0 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(MAC_JAVA_BRIDGE)
 
 #include <kjs/identifier.h>
+#include <kjs/JSLock.h>
 #include "jni_utility.h"
 #include "jni_runtime.h"
 
@@ -60,7 +61,7 @@ JavaClass::JavaClass(jobject anInstance)
         jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
         Field *aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
         {
-            JSLock lock;
+            JSLock lock(false);
             _fields.set(Identifier(globalData, UString(aField->name())).ustring().rep(), aField);
         }
         env->DeleteLocalRef(aJField);
@@ -74,7 +75,7 @@ JavaClass::JavaClass(jobject anInstance)
         Method *aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor
         MethodList* methodList;
         {
-            JSLock lock;
+            JSLock lock(false);
 
             methodList = _methods.get(Identifier(globalData, UString(aMethod->name())).ustring().rep());
             if (!methodList) {
@@ -90,7 +91,7 @@ JavaClass::JavaClass(jobject anInstance)
 JavaClass::~JavaClass() {
     free((void *)_name);
 
-    JSLock lock;
+    JSLock lock(false);
 
     deleteAllValues(_fields);
     _fields.clear();
index 57562bc..cefae3a 100644 (file)
@@ -33,6 +33,7 @@
 #include "jni_utility.h"
 #include "runtime_object.h"
 #include "runtime_root.h"
+#include <kjs/JSLock.h>
 
 #ifdef NDEBUG
 #define JS_LOG(formatAndArgs...) ((void)0)
@@ -79,7 +80,7 @@ Class *JavaInstance::getClass() const
 
 JSValue* JavaInstance::stringValue(ExecState* exec) const
 {
-    JSLock lock;
+    JSLock lock(false);
     
     jstring stringValue = (jstring)callJNIMethod<jobject>(_instance->_instance, "toString", "()Ljava/lang/String;");
     JNIEnv *env = getJNIEnv();
index 6f926ab..39bd4f8 100644 (file)
@@ -37,6 +37,7 @@
 #include "runtime_root.h"
 #include <kjs/ExecState.h>
 #include <kjs/JSGlobalObject.h>
+#include <kjs/JSLock.h>
 #include <kjs/completion.h>
 #include <kjs/interpreter.h>
 #include <wtf/Assertions.h>
@@ -288,7 +289,7 @@ jobject JavaJSObject::call(jstring methodName, jobjectArray args) const
     
     // Lookup the function object.
     ExecState* exec = rootObject->globalObject()->globalExec();
-    JSLock lock;
+    JSLock lock(false);
     
     Identifier identifier(exec, JavaString(methodName).ustring());
     JSValue* function = _imp->get(exec, identifier);
@@ -313,7 +314,7 @@ jobject JavaJSObject::eval(jstring script) const
     
     JSValue* result;
 
-    JSLock lock;
+    JSLock lock(false);
     
     RootObject* rootObject = this->rootObject();
     if (!rootObject)
@@ -344,7 +345,7 @@ jobject JavaJSObject::getMember(jstring memberName) const
 
     ExecState* exec = rootObject->globalObject()->globalExec();
     
-    JSLock lock;
+    JSLock lock(false);
     JSValue* result = _imp->get(exec, Identifier(exec, JavaString(memberName).ustring()));
 
     return convertValueToJObject(result);
@@ -359,7 +360,7 @@ void JavaJSObject::setMember(jstring memberName, jobject value) const
         return;
 
     ExecState* exec = rootObject->globalObject()->globalExec();
-    JSLock lock;
+    JSLock lock(false);
     _imp->put(exec, Identifier(exec, JavaString(memberName).ustring()), convertJObjectToValue(exec, value));
 }
 
@@ -373,7 +374,7 @@ void JavaJSObject::removeMember(jstring memberName) const
         return;
 
     ExecState* exec = rootObject->globalObject()->globalExec();
-    JSLock lock;
+    JSLock lock(false);
     _imp->deleteProperty(exec, Identifier(exec, JavaString(memberName).ustring()));
 }
 
@@ -392,7 +393,7 @@ jobject JavaJSObject::getSlot(jint index) const
 
     ExecState* exec = rootObject->globalObject()->globalExec();
 
-    JSLock lock;
+    JSLock lock(false);
     JSValue *result = _imp->get (exec, (unsigned)index);
 
     return convertValueToJObject(result);
@@ -412,7 +413,7 @@ void JavaJSObject::setSlot(jint index, jobject value) const
         return;
 
     ExecState* exec = rootObject->globalObject()->globalExec();
-    JSLock lock;
+    JSLock lock(false);
     _imp->put(exec, (unsigned)index, convertJObjectToValue(exec, value));
 }
 
@@ -425,7 +426,7 @@ jstring JavaJSObject::toString() const
     if (!rootObject)
         return 0;
 
-    JSLock lock;
+    JSLock lock(false);
     JSObject *thisObj = const_cast<JSObject*>(_imp);
     ExecState* exec = rootObject->globalObject()->globalExec();
     
@@ -483,7 +484,7 @@ jlong JavaJSObject::createNative(jlong nativeHandle)
 
 jobject JavaJSObject::convertValueToJObject (JSValue *value) const
 {
-    JSLock lock;
+    JSLock lock(false);
     
     RootObject* rootObject = this->rootObject();
     if (!rootObject)
@@ -599,7 +600,7 @@ JSValue* JavaJSObject::convertJObjectToValue(ExecState* exec, jobject theObject)
         return imp;
     }
 
-    JSLock lock;
+    JSLock lock(false);
 
     return KJS::Bindings::Instance::createRuntimeObject(exec, JavaInstance::create(theObject, _rootObject));
 }
index 6288000..4968212 100644 (file)
@@ -30,6 +30,7 @@
 #import <Foundation/Foundation.h>
 #import "jni_utility.h"
 #import "objc_utility.h"
+#include <kjs/JSLock.h>
 
 using namespace KJS::Bindings;
 
@@ -60,7 +61,7 @@ bool KJS::Bindings::dispatchJNICall(ExecState* exec, const void* targetAppletVie
         // implemented in WebCore will guarantee that only appropriate JavaScript
         // can reference the applet.
         {
-           JSLock::DropAllLocks dropAllLocks;
+           JSLock::DropAllLocks dropAllLocks(false);
             result = [view webPlugInCallJava:obj isStatic:isStatic returnType:returnType method:methodID arguments:args callingURL:nil exceptionDescription:&_exceptionDescription];
         }
 
@@ -70,7 +71,7 @@ bool KJS::Bindings::dispatchJNICall(ExecState* exec, const void* targetAppletVie
         return true;
     }
     else if ([view respondsToSelector:@selector(webPlugInCallJava:method:returnType:arguments:)]) {
-       JSLock::DropAllLocks dropAllLocks;
+        JSLock::DropAllLocks dropAllLocks(false);
         result = [view webPlugInCallJava:obj method:methodID returnType:returnType arguments:args];
         return true;
     }
index 9d45472..267584d 100644 (file)
@@ -33,6 +33,7 @@
 #include "runtime_array.h"
 #include "runtime_object.h"
 #include "runtime_root.h"
+#include <kjs/JSLock.h>
 
 #ifdef NDEBUG
 #define JS_LOG(formatAndArgs...) ((void)0)
@@ -314,7 +315,7 @@ static void appendClassName(UString& aString, const char* className)
 const char *JavaMethod::signature() const 
 {
     if (!_signature) {
-        JSLock lock;
+        JSLock lock(false);
 
         UString signatureBuilder("(");
         for (int i = 0; i < _numParameters; i++) {
index 3d6b742..a6f7114 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <jni_utility.h>
 #include <jni_instance.h>
+#include <kjs/JSLock.h>
 
 
 namespace KJS
@@ -45,7 +46,7 @@ class JavaString
 public:
     JavaString()
     {
-        JSLock lock;
+        JSLock lock(false);
         _rep = UString().rep();
     }
 
@@ -54,7 +55,7 @@ public:
         int _size = e->GetStringLength (s);
         const jchar *uc = getUCharactersFromJStringInEnv (e, s);
         {
-            JSLock lock;
+            JSLock lock(false);
             _rep = UString((UChar *)uc,_size).rep();
         }
         releaseUCharactersForJStringInEnv (e, s, uc);
@@ -70,13 +71,13 @@ public:
     
     ~JavaString()
     {
-        JSLock lock;
+        JSLock lock(false);
         _rep = 0;
     }
     
     const char *UTF8String() const { 
         if (_utf8String.c_str() == 0) {
-            JSLock lock;
+            JSLock lock(false);
             _utf8String = UString(_rep).UTF8String();
         }
         return _utf8String.c_str();
index 951d2e9..6f5200d 100644 (file)
@@ -32,6 +32,7 @@
 #include "runtime_array.h"
 #include "runtime_object.h"
 #include <kjs/JSArray.h>
+#include <kjs/JSLock.h>
 #include <dlfcn.h>
 
 namespace KJS {
@@ -346,10 +347,9 @@ jvalue getJNIField( jobject obj, JNIType type, const char *name, const char *sig
     return result;
 }
 
-static jobject convertArrayInstanceToJavaArray(ExecState *exec, JSValue *value, const char *javaClassName) {
+static jobject convertArrayInstanceToJavaArray(ExecState *exec, JSValue *value, const char *javaClassName)
+{
 
-    ASSERT(JSLock::lockCount() > 0);
-    
     JNIEnv *env = getJNIEnv();
     // As JS Arrays can contain a mixture of objects, assume we can convert to
     // the requested Java Array type requested, unless the array type is some object array
@@ -472,7 +472,7 @@ static jobject convertArrayInstanceToJavaArray(ExecState *exec, JSValue *value,
 
 jvalue convertValueToJValue (ExecState *exec, JSValue *value, JNIType _JNIType, const char *javaClassName)
 {
-    JSLock lock;
+    JSLock lock(false);
     
     jvalue result;
    
index 59bdf0c..f5a93ec 100644 (file)
@@ -66,7 +66,7 @@ NPIdentifier _NPN_GetStringIdentifier(const NPUTF8* name)
     if (name) {
         PrivateIdentifier* identifier = 0;
         
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         
         identifier = getStringIdentifierMap()->get(identifierFromNPIdentifier(name).ustring().rep());
         if (identifier == 0) {
index 26effab..2ebae20 100644 (file)
@@ -28,6 +28,7 @@
 
 #import "FoundationExtras.h"
 #import "WebScriptObject.h"
+#include <kjs/JSLock.h>
 #include <wtf/Assertions.h>
 
 #ifdef NDEBUG
@@ -62,7 +63,7 @@ void ObjcInstance::moveGlobalExceptionToExecState(ExecState* exec)
     }
 
     if (!s_exceptionEnvironment || s_exceptionEnvironment == exec->dynamicGlobalObject()) {
-        JSLock lock;
+        JSLock lock(false);
         throwError(exec, GeneralError, s_exception);
     }
 
@@ -126,7 +127,7 @@ JSValue* ObjcInstance::invokeMethod(ExecState* exec, const MethodList &methodLis
 {
     JSValue* result = jsUndefined();
     
-    JSLock::DropAllLocks dropAllLocks; // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(false); // Can't put this inside the @try scope because it unwinds incorrectly.
 
     setGlobalException(nil);
     
@@ -248,7 +249,7 @@ JSValue* ObjcInstance::invokeDefaultMethod(ExecState* exec, const ArgList &args)
 {
     JSValue* result = jsUndefined();
 
-    JSLock::DropAllLocks dropAllLocks; // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(false); // Can't put this inside the @try scope because it unwinds incorrectly.
     setGlobalException(nil);
     
 @try {
@@ -304,7 +305,7 @@ void ObjcInstance::setValueOfUndefinedField(ExecState* exec, const Identifier &p
 {
     id targetObject = getObject();
 
-   JSLock::DropAllLocks dropAllLocks; // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(false); // Can't put this inside the @try scope because it unwinds incorrectly.
 
     // This check is not really necessary because NSObject implements
     // setValue:forUndefinedKey:, and unfortnately the default implementation
@@ -330,7 +331,7 @@ JSValue* ObjcInstance::getValueOfUndefinedField(ExecState* exec, const Identifie
     
     id targetObject = getObject();
 
-   JSLock::DropAllLocks dropAllLocks; // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(false); // Can't put this inside the @try scope because it unwinds incorrectly.
 
     // This check is not really necessary because NSObject implements
     // valueForUndefinedKey:, and unfortnately the default implementation
index 7e33f58..c51cd2c 100644 (file)
@@ -30,6 +30,7 @@
 #include "runtime_array.h"
 #include "runtime_object.h"
 #include "WebScriptObject.h"
+#include <kjs/JSLock.h>
 #include <wtf/RetainPtr.h>
 
 using namespace KJS;
@@ -107,16 +108,16 @@ JSValue* ObjcField::valueFromInstance(ExecState* exec, const Instance* instance)
     
     id targetObject = (static_cast<const ObjcInstance*>(instance))->getObject();
 
-   JSLock::DropAllLocks dropAllLocks; // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(false); // Can't put this inside the @try scope because it unwinds incorrectly.
 
     @try {
         NSString* key = [NSString stringWithCString:name() encoding:NSASCIIStringEncoding];
         if (id objcValue = [targetObject valueForKey:key])
             result = convertObjcValueToValue(exec, &objcValue, ObjcObjectType, instance->rootObject());
     } @catch(NSException* localException) {
-        JSLock::lock();
+        JSLock::lock(false);
         throwError(exec, GeneralError, [localException reason]);
-        JSLock::unlock();
+        JSLock::unlock(false);
     }
 
     return result;
@@ -135,15 +136,15 @@ 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; // Can't put this inside the @try scope because it unwinds incorrectly.
+    JSLock::DropAllLocks dropAllLocks(false); // Can't put this inside the @try scope because it unwinds incorrectly.
 
     @try {
         NSString* key = [NSString stringWithCString:name() encoding:NSASCIIStringEncoding];
         [targetObject setValue:value forKey:key];
     } @catch(NSException* localException) {
-        JSLock::lock();
+        JSLock::lock(false);
         throwError(exec, GeneralError, [localException reason]);
-        JSLock::unlock();
+        JSLock::unlock(false);
     }
 }
 
index 209de44..fb14c04 100644 (file)
@@ -31,6 +31,7 @@
 #include "runtime_object.h"
 #include "WebScriptObject.h"
 #include <kjs/JSGlobalObject.h>
+#include <kjs/JSLock.h>
 #include <wtf/Assertions.h>
 
 #if !defined(_C_LNG_LNG)
@@ -135,7 +136,7 @@ ObjcValue convertValueToObjcValue(ExecState *exec, JSValue *value, ObjcValueType
 
     switch (type) {
         case ObjcObjectType: {
-            JSLock lock;
+            JSLock lock(false);
             
             JSGlobalObject *originGlobalObject = exec->dynamicGlobalObject();
             RootObject* originRootObject = findRootObject(originGlobalObject);
@@ -195,7 +196,7 @@ ObjcValue convertValueToObjcValue(ExecState *exec, JSValue *value, ObjcValueType
 
 JSValue* convertNSStringToString(ExecState* exec, NSString *nsstring)
 {
-    JSLock lock;
+    JSLock lock(false);
     
     unichar *chars;
     unsigned int length = [nsstring length];
@@ -227,7 +228,7 @@ JSValue* convertNSStringToString(ExecState* exec, NSString *nsstring)
 */
 JSValue* convertObjcValueToValue(ExecState* exec, void* buffer, ObjcValueType type, RootObject* rootObject)
 {
-    JSLock lock;
+    JSLock lock(false);
     
     switch (type) {
         case ObjcObjectType: {
index 091e76a..dfe8d3f 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "runtime_object.h"
 #include "runtime_root.h"
+#include <kjs/JSLock.h>
 
 #if PLATFORM(QT)
 #include "qt_instance.h"
@@ -93,7 +94,7 @@ RuntimeObjectImp* Instance::createRuntimeObject(ExecState* exec, PassRefPtr<Inst
     if (instance->getBindingLanguage() == QtLanguage)
         return QtInstance::getRuntimeObject(exec, static_cast<QtInstance*>(instance.get()));
 #endif
-    JSLock lock;
+    JSLock lock(false);
 
     return new (exec) RuntimeObjectImp(instance);
 }
index c8ab7fd..80f4ce0 100644 (file)
@@ -108,10 +108,8 @@ void RootObject::invalidate()
     m_globalObject = 0;
 
     ProtectCountSet::iterator end = m_protectCountSet.end();
-    for (ProtectCountSet::iterator it = m_protectCountSet.begin(); it != end; ++it) {
-        JSLock lock;
+    for (ProtectCountSet::iterator it = m_protectCountSet.begin(); it != end; ++it)
         KJS::gcUnprotect(it->first);
-    }
     m_protectCountSet.clear();
 
     rootObjectSet()->remove(this);
@@ -121,10 +119,8 @@ void RootObject::gcProtect(JSObject* jsObject)
 {
     ASSERT(m_isValid);
     
-    if (!m_protectCountSet.contains(jsObject)) {
-        JSLock lock;
+    if (!m_protectCountSet.contains(jsObject))
         KJS::gcProtect(jsObject);
-    }
     m_protectCountSet.add(jsObject);
 }
 
@@ -135,10 +131,8 @@ void RootObject::gcUnprotect(JSObject* jsObject)
     if (!jsObject)
         return;
 
-    if (m_protectCountSet.count(jsObject) == 1) {
-        JSLock lock;
+    if (m_protectCountSet.count(jsObject) == 1)
         KJS::gcUnprotect(jsObject);
-    }
     m_protectCountSet.remove(jsObject);
 }
 
index a0eceb4..40d7922 100644 (file)
 #include "XMLTokenizer.h"
 #include "JSDOMBinding.h"
 #include "ScriptController.h"
+#include <JavaScriptCore/JSLock.h>
 
 #if ENABLE(DATABASE)
 #include "Database.h"
@@ -406,7 +407,7 @@ Document::~Document()
 
     XMLHttpRequest::detachRequests(this);
     {
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         ScriptInterpreter::forgetAllDOMNodesForDocument(this);
     }
 
index fbc7f78..9d40664 100644 (file)
@@ -53,6 +53,7 @@
 #include "XMLNames.h"
 #include "htmlediting.h"
 #include "JSDOMBinding.h"
+#include <JavaScriptCore/JSLock.h>
 
 namespace WebCore {
 
@@ -157,7 +158,7 @@ void Node::setDocument(Document* doc)
     willMoveToNewOwnerDocument();
 
     {
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         ScriptInterpreter::updateDOMNodeDocument(this, m_document.get(), doc);
     }    
     m_document = doc;
index b726e82..2cf8f46 100644 (file)
@@ -91,7 +91,7 @@ CachedPage::CachedPage(Page* page)
     Frame* mainFrame = page->mainFrame();
     mainFrame->clearTimers();
 
-    JSLock lock;
+    JSLock lock(false);
 
     ScriptController* proxy = mainFrame->script();
     if (proxy->haveWindowShell()) {
@@ -117,7 +117,7 @@ void CachedPage::restore(Page* page)
 
     Frame* mainFrame = page->mainFrame();
 
-    JSLock lock;
+    JSLock lock(false);
 
     ScriptController* proxy = mainFrame->script();
     if (proxy->haveWindowShell()) {
@@ -179,7 +179,7 @@ void CachedPage::clear()
     m_mousePressNode = 0;
     m_URL = KURL();
 
-    JSLock lock;
+    JSLock lock(false);
     m_pausedTimeouts.clear();
     m_window = 0;
 
index 2f4c20b..bdd6952 100644 (file)
@@ -36,6 +36,7 @@
 #include "Settings.h"
 #include "Widget.h"
 #include "ScriptController.h"
+#include <kjs/JSLock.h>
 
 #if USE(JAVASCRIPTCORE_BINDINGS)
 #include "runtime.h"
@@ -188,7 +189,7 @@ NPObject* HTMLPlugInElement::createNPObject()
         return _NPN_CreateNoScriptObject();
     
     // Create a JSObject bound to this element
-    JSLock lock;
+    JSLock lock(false);
     ExecState *exec = frame->script()->globalObject()->globalExec();
     JSValue* jsElementValue = toJS(exec, this);
     if (!jsElementValue || !jsElementValue->isObject())
index e55dc0c..32739bc 100644 (file)
@@ -192,7 +192,7 @@ static bool getString(JSValue* result, String& string)
 {
     if (!result)
         return false;
-    JSLock lock;
+    JSLock lock(false);
     UString ustring;
     if (!result->getString(ustring))
         return false;
index ef4ed78..5e9bb07 100644 (file)
@@ -75,6 +75,7 @@
 #include "npruntime_impl.h"
 #include "runtime_root.h"
 #include "visible_units.h"
+#include <JavaScriptCore/JSLock.h>
 
 #if FRAME_LOADS_USER_STYLESHEET
 #include "UserStyleSheetLoader.h"
@@ -1076,7 +1077,7 @@ KJS::Bindings::RootObject* Frame::bindingRootObject()
         return 0;
 
     if (!d->m_bindingRootObject) {
-        JSLock lock;
+        JSLock lock(false);
         d->m_bindingRootObject = KJS::Bindings::RootObject::create(0, script()->globalObject());
     }
     return d->m_bindingRootObject.get();
@@ -1101,7 +1102,7 @@ NPObject* Frame::windowScriptNPObject()
         if (script()->isEnabled()) {
             // JavaScript is enabled, so there is a JavaScript window object.  Return an NPObject bound to the window
             // object.
-            KJS::JSLock lock;
+            KJS::JSLock lock(false);
             KJS::JSObject* win = toJSDOMWindow(this);
             ASSERT(win);
             KJS::Bindings::RootObject* root = bindingRootObject();
@@ -1144,7 +1145,7 @@ void Frame::cleanupScriptObjectsForPlugin(void* nativeHandle)
     
 void Frame::clearScriptObjects()
 {
-    JSLock lock;
+    JSLock lock(false);
 
     RootObjectMap::const_iterator end = d->m_rootObjects.end();
     for (RootObjectMap::const_iterator it = d->m_rootObjects.begin(); it != end; ++it)
index ee698c6..580fae8 100644 (file)
@@ -103,7 +103,7 @@ static JSRetainPtr<JSStringRef> jsStringRef(const String& str)
 
 static JSRetainPtr<JSStringRef> jsStringRef(const UString& str)
 {
-    JSLock lock;
+    JSLock lock(false);
     return JSRetainPtr<JSStringRef>(toRef(str.rep()));
 }
 
@@ -168,7 +168,7 @@ struct ConsoleMessage {
         , line(li)
         , url(u)
     {
-        JSLock lock;
+        JSLock lock(false);
         for (unsigned i = 0; i < args.size(); ++i)
             wrappedArguments[i] = JSInspectedObjectWrapper::wrap(exec, args[i]);
     }
@@ -186,13 +186,13 @@ struct ConsoleMessage {
 struct XMLHttpRequestResource {
     XMLHttpRequestResource(KJS::UString& sourceString)
     {
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         this->sourceString = sourceString.rep();
     }
 
     ~XMLHttpRequestResource()
     {
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         sourceString.clear();
     }
 
@@ -516,7 +516,7 @@ static JSValueRef getResourceDocumentNode(JSContextRef ctx, JSObjectRef /*functi
 
     ExecState* exec = toJSDOMWindowShell(resource->frame.get())->window()->globalExec();
 
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
     JSValueRef documentValue = toRef(JSInspectedObjectWrapper::wrap(exec, toJS(exec, document)));
     return documentValue;
 }
@@ -645,7 +645,7 @@ static JSValueRef search(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef
         if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
             break;
 
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         JSValueRef arg0 = toRef(toJS(toJS(ctx), resultRange.get()));
         JSObjectCallAsFunction(ctx, pushFunction, result, 1, &arg0, exception);
         if (exception && *exception)
@@ -720,7 +720,7 @@ static JSValueRef inspectedWindow(JSContextRef ctx, JSObjectRef /*function*/, JS
         return JSValueMakeUndefined(ctx);
 
     JSDOMWindow* inspectedWindow = toJSDOMWindow(controller->inspectedPage()->mainFrame());
-    JSLock lock;
+    JSLock lock(false);
     return toRef(JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow));
 }
 
@@ -793,7 +793,7 @@ static JSValueRef wrapCallback(JSContextRef ctx, JSObjectRef /*function*/, JSObj
     if (argumentCount < 1)
         return JSValueMakeUndefined(ctx);
 
-    JSLock lock;
+    JSLock lock(false);
     return toRef(JSInspectorCallbackWrapper::wrap(toJS(ctx), toJS(arguments[0])));
 }
 
@@ -839,7 +839,7 @@ static JSValueRef currentCallFrame(JSContextRef ctx, JSObjectRef /*function*/, J
 
     ExecState* globalExec = callFrame->scopeChain()->globalObject()->globalExec();
 
-    JSLock lock;
+    JSLock lock(false);
     return toRef(JSInspectedObjectWrapper::wrap(globalExec, toJS(toJS(ctx), callFrame)));
 }
 
@@ -972,7 +972,7 @@ static JSValueRef profiles(JSContextRef ctx, JSObjectRef /*function*/, JSObjectR
     if (!controller)
         return JSValueMakeUndefined(ctx);
 
-    JSLock lock;
+    JSLock lock(false);
 
     const Vector<RefPtr<Profile> >& profiles = controller->profiles();
 
@@ -1127,7 +1127,7 @@ void InspectorController::focusNode()
     JSValueRef arg0;
 
     {
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         arg0 = toRef(JSInspectedObjectWrapper::wrap(exec, toJS(exec, m_nodeToFocus.get())));
     }
 
@@ -1793,7 +1793,7 @@ JSObjectRef InspectorController::addDatabaseScriptResource(InspectorDatabaseReso
     JSValueRef database;
 
     {
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         database = toRef(JSInspectedObjectWrapper::wrap(exec, toJS(exec, resource->database.get())));
     }
 
@@ -1884,7 +1884,7 @@ void InspectorController::addScriptConsoleMessage(const ConsoleMessage* message)
 
 void InspectorController::addScriptProfile(Profile* profile)
 {
-    JSLock lock;
+    JSLock lock(false);
     JSValueRef exception = 0;
     JSValueRef profileObject = toRef(toJS(toJS(m_scriptContext), profile));
     callFunction(m_scriptContext, m_scriptObject, "addProfile", 1, &profileObject, exception);
index a58f129..61a3d25 100644 (file)
@@ -30,6 +30,7 @@
 #include <kjs/DebuggerCallFrame.h>
 #include <kjs/JSGlobalObject.h>
 #include <kjs/interpreter.h>
+#include <kjs/JSLock.h>
 #include <kjs/JSObject.h>
 #include <kjs/JSValue.h>
 
@@ -93,7 +94,7 @@ JSValue* JavaScriptCallFrame::evaluate(const UString& script, JSValue*& exceptio
     if (!m_isValid)
         return jsNull();
 
-    JSLock lock;
+    JSLock lock(false);
     return m_debuggerCallFrame.evaluate(script, exception);
 }
 
index 56078c3..f2bc75e 100644 (file)
 #include <JavaScriptCore/APICast.h>
 #include <JavaScriptCore/JSObjectRef.h>
 #include <JavaScriptCore/JSContextRef.h>
+#include <JavaScriptCore/JSLock.h>
 #include <JavaScriptCore/JSRetainPtr.h>
 #include <JavaScriptCore/JSStringRef.h>
-#include <kjs/JSValue.h>
+#include <JavaScriptCore/JSValue.h>
 
 using namespace KJS;
 
@@ -80,7 +81,7 @@ static JSValueRef getLineNumber(JSContextRef ctx, JSObjectRef thisObject, JSStri
 
 static JSValueRef getTotalTime(JSContextRef ctx, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
 {
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
 
     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
         return JSValueMakeUndefined(ctx);
@@ -91,7 +92,7 @@ static JSValueRef getTotalTime(JSContextRef ctx, JSObjectRef thisObject, JSStrin
 
 static JSValueRef getSelfTime(JSContextRef ctx, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
 {
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
 
     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
         return JSValueMakeUndefined(ctx);
@@ -102,7 +103,7 @@ static JSValueRef getSelfTime(JSContextRef ctx, JSObjectRef thisObject, JSString
 
 static JSValueRef getTotalPercent(JSContextRef ctx, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
 {
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
 
     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
         return JSValueMakeUndefined(ctx);
@@ -113,7 +114,7 @@ static JSValueRef getTotalPercent(JSContextRef ctx, JSObjectRef thisObject, JSSt
 
 static JSValueRef getSelfPercent(JSContextRef ctx, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
 {
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
 
     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
         return JSValueMakeUndefined(ctx);
@@ -124,7 +125,7 @@ static JSValueRef getSelfPercent(JSContextRef ctx, JSObjectRef thisObject, JSStr
 
 static JSValueRef getNumberOfCalls(JSContextRef ctx, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
 {
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
 
     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
         return JSValueMakeUndefined(ctx);
@@ -135,7 +136,7 @@ static JSValueRef getNumberOfCalls(JSContextRef ctx, JSObjectRef thisObject, JSS
 
 static JSValueRef getChildren(JSContextRef ctx, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
 {
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
 
     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
         return JSValueMakeUndefined(ctx);
@@ -181,7 +182,7 @@ static JSValueRef getChildren(JSContextRef ctx, JSObjectRef thisObject, JSString
 
 static JSValueRef getVisible(JSContextRef ctx, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
 {
-    KJS::JSLock lock;
+    KJS::JSLock lock(false);
 
     if (!JSValueIsObjectOfClass(ctx, thisObject, ProfileNodeClass()))
         return JSValueMakeUndefined(ctx);
index a942009..ad0ab12 100644 (file)
@@ -89,6 +89,7 @@
 #import "visible_units.h"
 #import <Carbon/Carbon.h>
 #import <JavaScriptCore/APICast.h>
+#import <JavaScriptCore/JSLock.h>
 
 #if ENABLE(NETSCAPE_PLUGIN_API)
 #import "c_instance.h"
@@ -598,7 +599,7 @@ WebScriptObject* Frame::windowScriptObject()
         return 0;
 
     if (!d->m_windowScriptObject) {
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         KJS::JSObject* win = toJSDOMWindowShell(this);
         KJS::Bindings::RootObject *root = bindingRootObject();
         d->m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(win) originRootObject:root rootObject:root];
index 9822ab0..9b31719 100644 (file)
@@ -126,6 +126,8 @@ Database::Database(Document* document, const String& name, const String& expecte
         m_name = "";
 
     KJS::initializeThreading();
+    // Database code violates the normal JSCore contract by calling jsUnprotect from a secondary thread, and thus needs additional locking.
+    KJS::JSGlobalData::threadInstance().heap->setGCProtectNeedsLocking();
 
     m_guid = guidForOriginAndName(m_securityOrigin->toString(), name);
 
index 75ab2bc..f398098 100644 (file)
@@ -41,6 +41,7 @@
 #include "XMLHttpRequestException.h"
 #include "XMLHttpRequestProgressEvent.h"
 #include "markup.h"
+#include <JavaScriptCore/JSLock.h>
 
 namespace WebCore {
 
@@ -633,12 +634,8 @@ void XMLHttpRequest::loadRequestSynchronously(ResourceRequest& request, Exceptio
     ResourceError error;
     ResourceResponse response;
 
-    {
-        // avoid deadlock in case the loader wants to use JS on a background thread
-        KJS::JSLock::DropAllLocks dropLocks;
-        if (m_doc->frame())
-            m_identifier = m_doc->frame()->loader()->loadResourceSynchronously(request, error, response, data);
-    }
+    if (m_doc->frame())
+        m_identifier = m_doc->frame()->loader()->loadResourceSynchronously(request, error, response, data);
 
     m_loader = 0;
 
@@ -678,7 +675,6 @@ void XMLHttpRequest::loadRequestAsynchronously(ResourceRequest& request)
         // and they are referenced by the JavaScript wrapper.
         ref();
 
-        KJS::JSLock lock;
         gcProtectNullTolerant(ScriptInterpreter::getDOMObject(this));
     }
 }
@@ -728,7 +724,7 @@ void XMLHttpRequest::clearResponse()
 {
     m_response = ResourceResponse();
     {
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         m_responseText = "";
     }
     m_createdDocument = false;
@@ -767,7 +763,6 @@ void XMLHttpRequest::abortError()
 void XMLHttpRequest::dropProtection()        
 {
     {
-        KJS::JSLock lock;
         KJS::JSValue* wrapper = ScriptInterpreter::getDOMObject(this);
         KJS::gcUnprotectNullTolerant(wrapper);
     
@@ -779,7 +774,7 @@ void XMLHttpRequest::dropProtection()
         // report the extra cost at that point.
     
         if (wrapper)
-            KJS::JSGlobalData::threadInstance().heap->reportExtraMemoryCost(m_responseText.size() * 2);
+            KJS::Heap::heap(wrapper)->reportExtraMemoryCost(m_responseText.size() * 2);
     }
 
     deref();
@@ -979,7 +974,7 @@ void XMLHttpRequest::didFinishLoading(SubresourceLoader* loader)
         changeState(HEADERS_RECEIVED);
 
     {
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         if (m_decoder)
             m_responseText += m_decoder->flush();
     }
@@ -1081,7 +1076,7 @@ void XMLHttpRequest::didReceiveData(SubresourceLoader*, const char* data, int le
     String decoded = m_decoder->decode(data, len);
 
     {
-        KJS::JSLock lock;
+        KJS::JSLock lock(false);
         m_responseText += decoded;
     }
 
index 6db6bb7..d2181f6 100644 (file)
@@ -1,3 +1,46 @@
+2008-07-01  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        Disable JSLock for per-thread contexts.
+
+        * Misc/WebCoreStatistics.mm:
+        (+[WebCoreStatistics javaScriptObjectsCount]):
+        (+[WebCoreStatistics javaScriptGlobalObjectsCount]):
+        (+[WebCoreStatistics javaScriptProtectedObjectsCount]):
+        (+[WebCoreStatistics javaScriptProtectedGlobalObjectsCount]):
+        (+[WebCoreStatistics javaScriptProtectedObjectTypeCounts]):
+        (+[WebCoreStatistics shouldPrintExceptions]):
+        (+[WebCoreStatistics setShouldPrintExceptions:]):
+        (+[WebCoreStatistics javaScriptReferencedObjectsCount]):
+        * Plugins/WebBaseNetscapePluginView.mm:
+        (-[WebBaseNetscapePluginView sendEvent:isDrawRect:]):
+        (-[WebBaseNetscapePluginView setWindowIfNecessary]):
+        (-[WebBaseNetscapePluginView start]):
+        (-[WebBaseNetscapePluginView createPluginScriptableObject]):
+        (-[WebBaseNetscapePluginView evaluateJavaScriptPluginRequest:]):
+        (-[WebBaseNetscapePluginView webFrame:didFinishLoadWithReason:]):
+        (-[WebBaseNetscapePluginView loadPluginRequest:]):
+        (-[WebBaseNetscapePluginView _printedPluginBitmap]):
+        * Plugins/WebPluginController.mm:
+        (+[WebPluginController plugInViewWithArguments:fromPluginPackage:]):
+        (-[WebPluginController startAllPlugins]):
+        (-[WebPluginController stopAllPlugins]):
+        (-[WebPluginController addPlugin:]):
+        (-[WebPluginController destroyPlugin:]):
+        (-[WebPluginController destroyAllPlugins]):
+        * WebView/WebFrame.mm:
+        (-[WebFrame _stringByEvaluatingJavaScriptFromString:forceUserGesture:]):
+        * WebView/WebScriptDebugDelegate.mm:
+        (-[WebScriptCallFrame evaluateWebScript:]):
+        * WebView/WebView.mm:
+        (-[WebView aeDescByEvaluatingJavaScriptFromString:]):
+        Pass a parameter (always false) to JSLock and JSLock::DropAllLocks to indicate that WebKit
+        doesn't need locking. In the future, it may be possible to remove some of these if we
+        establish that this won't make JSC assertions fail (and that we don't want to add such
+        assertions either).
+        Added includes that are now needed.
+
 2008-07-01  Kevin McCullough  <kmccullough@apple.com>
 
         Build fix.
index 15f5d0c..f834614 100644 (file)
@@ -31,6 +31,7 @@
 #import "WebCache.h"
 #import "WebFrameInternal.h"
 #import <JavaScriptCore/interpreter.h>
+#import <JavaScriptCore/JSLock.h>
 #import <WebCore/FontCache.h>
 #import <WebCore/Frame.h>
 #import <WebCore/GCController.h>
@@ -51,31 +52,31 @@ using namespace WebCore;
 
 + (size_t)javaScriptObjectsCount
 {
-    JSLock lock;
+    JSLock lock(false);
     return JSGlobalData::threadInstance().heap->size();
 }
 
 + (size_t)javaScriptGlobalObjectsCount
 {
-    JSLock lock;
+    JSLock lock(false);
     return JSGlobalData::threadInstance().heap->globalObjectCount();
 }
 
 + (size_t)javaScriptProtectedObjectsCount
 {
-    JSLock lock;
+    JSLock lock(false);
     return JSGlobalData::threadInstance().heap->protectedObjectCount();
 }
 
 + (size_t)javaScriptProtectedGlobalObjectsCount
 {
-    JSLock lock;
+    JSLock lock(false);
     return JSGlobalData::threadInstance().heap->protectedGlobalObjectCount();
 }
 
 + (NSCountedSet *)javaScriptProtectedObjectTypeCounts
 {
-    JSLock lock;
+    JSLock lock(false);
     
     NSCountedSet *result = [NSCountedSet set];
 
@@ -140,13 +141,13 @@ using namespace WebCore;
 
 + (BOOL)shouldPrintExceptions
 {
-    JSLock lock;
+    JSLock lock(false);
     return Interpreter::shouldPrintExceptions();
 }
 
 + (void)setShouldPrintExceptions:(BOOL)print
 {
-    JSLock lock;
+    JSLock lock(false);
     Interpreter::setShouldPrintExceptions(print);
 }
 
@@ -178,7 +179,7 @@ using namespace WebCore;
 
 + (size_t)javaScriptReferencedObjectsCount
 {
-    JSLock lock;
+    JSLock lock(false);
     return JSGlobalData::threadInstance().heap->protectedObjectCount();
 }
 
index cfe1f5a..8e93faa 100644 (file)
@@ -746,7 +746,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     BOOL acceptedEvent;
     [self willCallPlugInFunction];
     {
-        KJS::JSLock::DropAllLocks dropAllLocks;
+        KJS::JSLock::DropAllLocks dropAllLocks(false);
         acceptedEvent = NPP_HandleEvent(plugin, event);
     }
     [self didCallPlugInFunction];
@@ -1044,7 +1044,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
         
         [self willCallPlugInFunction];
         {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             npErr = NPP_SetWindow(plugin, &window);
         }
         [self didCallPlugInFunction];
@@ -1244,7 +1244,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     if (eventModel == NPEventModelCocoa) {
         [self willCallPlugInFunction];
         {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             NPPluginTextInputFuncs *value;
             if (NPP_GetValue(plugin, NPPVpluginTextInputFuncs, &value) == NPERR_NO_ERROR && value)
                 textInputFuncs = value;
@@ -1791,7 +1791,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     NPError error;
     [self willCallPlugInFunction];
     {
-        KJS::JSLock::DropAllLocks dropAllLocks;
+        KJS::JSLock::DropAllLocks dropAllLocks(false);
         error = NPP_GetValue(plugin, NPPVpluginScriptableNPObject, &value);
     }
     [self didCallPlugInFunction];
@@ -2080,7 +2080,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
         if ([JSPluginRequest sendNotification]) {
             [self willCallPlugInFunction];
             {
-                KJS::JSLock::DropAllLocks dropAllLocks;
+                KJS::JSLock::DropAllLocks dropAllLocks(false);
                 NPP_URLNotify(plugin, [URL _web_URLCString], NPRES_DONE, [JSPluginRequest notifyData]);
             }
             [self didCallPlugInFunction];
@@ -2113,7 +2113,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
         
     [self willCallPlugInFunction];
     {
-        KJS::JSLock::DropAllLocks dropAllLocks;
+        KJS::JSLock::DropAllLocks dropAllLocks(false);
         NPP_URLNotify(plugin, [[[pluginRequest request] URL] _web_URLCString], reason, [pluginRequest notifyData]);
     }
     [self didCallPlugInFunction];
@@ -2158,7 +2158,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
                 if ([pluginRequest sendNotification]) {
                     [self willCallPlugInFunction];
                     {
-                        KJS::JSLock::DropAllLocks dropAllLocks;
+                        KJS::JSLock::DropAllLocks dropAllLocks(false);
                         NPP_URLNotify(plugin, [[[pluginRequest request] URL] _web_URLCString], NPERR_GENERIC_ERROR, [pluginRequest notifyData]);
                     }
                     [self didCallPlugInFunction];
@@ -2899,7 +2899,7 @@ static NPBrowserTextInputFuncs *browserTextInputFuncs()
     // Tell the plugin to print into the GWorld
     [self willCallPlugInFunction];
     {
-        KJS::JSLock::DropAllLocks dropAllLocks;
+        KJS::JSLock::DropAllLocks dropAllLocks(false);
         NPP_Print(plugin, &npPrint);
     }
     [self didCallPlugInFunction];
index 4bc8676..5afeffa 100644 (file)
@@ -29,6 +29,7 @@
 
 #import <WebKit/WebPluginController.h>
 
+#import <JavaScriptCore/JSLock.h>
 #import <Foundation/NSURLRequest.h>
 #import <WebCore/Frame.h>
 #import <WebCore/FrameLoader.h>
@@ -82,10 +83,10 @@ static NSMutableSet *pluginViews = nil;
     NSView *view = nil;
 
     if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
-        KJS::JSLock::DropAllLocks dropAllLocks;
+        KJS::JSLock::DropAllLocks dropAllLocks(false);
         view = [viewFactory plugInViewWithArguments:arguments];
     } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
-        KJS::JSLock::DropAllLocks dropAllLocks;
+        KJS::JSLock::DropAllLocks dropAllLocks(false);
         view = [viewFactory pluginViewWithArguments:arguments];
     }
     
@@ -139,10 +140,10 @@ static NSMutableSet *pluginViews = nil;
     for (i = 0; i < count; i++) {
         id aView = [_views objectAtIndex:i];
         if ([aView respondsToSelector:@selector(webPlugInStart)]) {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             [aView webPlugInStart];
         } else if ([aView respondsToSelector:@selector(pluginStart)]) {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             [aView pluginStart];
         }
     }
@@ -162,10 +163,10 @@ static NSMutableSet *pluginViews = nil;
     for (i = 0; i < count; i++) {
         id aView = [_views objectAtIndex:i];
         if ([aView respondsToSelector:@selector(webPlugInStop)]) {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             [aView webPlugInStop];
         } else if ([aView respondsToSelector:@selector(pluginStop)]) {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             [aView pluginStop];
         }
     }
@@ -185,25 +186,25 @@ static NSMutableSet *pluginViews = nil;
 
         LOG(Plugins, "initializing plug-in %@", view);
         if ([view respondsToSelector:@selector(webPlugInInitialize)]) {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             [view webPlugInInitialize];
         } else if ([view respondsToSelector:@selector(pluginInitialize)]) {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             [view pluginInitialize];
         }
 
         if (_started) {
             LOG(Plugins, "starting plug-in %@", view);
             if ([view respondsToSelector:@selector(webPlugInStart)]) {
-                KJS::JSLock::DropAllLocks dropAllLocks;
+                KJS::JSLock::DropAllLocks dropAllLocks(false);
                 [view webPlugInStart];
             } else if ([view respondsToSelector:@selector(pluginStart)]) {
-                KJS::JSLock::DropAllLocks dropAllLocks;
+                KJS::JSLock::DropAllLocks dropAllLocks(false);
                 [view pluginStart];
             }
             
             if ([view respondsToSelector:@selector(setContainingWindow:)]) {
-                KJS::JSLock::DropAllLocks dropAllLocks;
+                KJS::JSLock::DropAllLocks dropAllLocks(false);
                 [view setContainingWindow:[_documentView window]];
             }
         }
@@ -215,19 +216,19 @@ static NSMutableSet *pluginViews = nil;
     if ([_views containsObject:view]) {
         if (_started) {
             if ([view respondsToSelector:@selector(webPlugInStop)]) {
-                KJS::JSLock::DropAllLocks dropAllLocks;
+                KJS::JSLock::DropAllLocks dropAllLocks(false);
                 [view webPlugInStop];
             } else if ([view respondsToSelector:@selector(pluginStop)]) {
-                KJS::JSLock::DropAllLocks dropAllLocks;
+                KJS::JSLock::DropAllLocks dropAllLocks(false);
                 [view pluginStop];
             }
         }
         
         if ([view respondsToSelector:@selector(webPlugInDestroy)]) {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             [view webPlugInDestroy];
         } else if ([view respondsToSelector:@selector(pluginDestroy)]) {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             [view pluginDestroy];
         }
         
@@ -274,10 +275,10 @@ static void cancelOutstandingCheck(const void *item, void *context)
     for (i = 0; i < count; i++) {
         id aView = [_views objectAtIndex:i];
         if ([aView respondsToSelector:@selector(webPlugInDestroy)]) {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             [aView webPlugInDestroy];
         } else if ([aView respondsToSelector:@selector(pluginDestroy)]) {
-            KJS::JSLock::DropAllLocks dropAllLocks;
+            KJS::JSLock::DropAllLocks dropAllLocks(false);
             [aView pluginDestroy];
         }
         
index ff8c945..9fc82dc 100644 (file)
@@ -49,6 +49,7 @@
 #import "WebScriptDebugger.h"
 #import "WebViewInternal.h"
 #import <JavaScriptCore/APICast.h>
+#import <JavaScriptCore/JSLock.h>
 #import <WebCore/AccessibilityObject.h>
 #import <WebCore/AXObjectCache.h>
 #import <WebCore/ColorMac.h>
@@ -617,7 +618,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
     if (!result || !result->isBoolean() && !result->isString() && !result->isNumber())
         return @"";
 
-    JSLock lock;
+    JSLock lock(false);
     return String(result->toString(_private->coreFrame->script()->globalObject()->globalExec()));
 }
 
index bd29d1a..9218d45 100644 (file)
@@ -36,6 +36,7 @@
 #import <JavaScriptCore/ExecState.h>
 #import <JavaScriptCore/JSGlobalObject.h>
 #import <JavaScriptCore/JSFunction.h>
+#import <JavaScriptCore/JSLock.h>
 #import <JavaScriptCore/interpreter.h>
 #import <WebCore/Frame.h>
 #import <WebCore/WebScriptObjectPrivate.h>
@@ -218,7 +219,7 @@ NSString * const WebScriptErrorLineNumberKey = @"WebScriptErrorLineNumber";
     if (!_private->debuggerCallFrame)
         return nil;
 
-    JSLock lock;
+    JSLock lock(false);
 
     JSValue* exception = 0;
     JSValue* result = _private->debuggerCallFrame->evaluate(String(script), exception);
index 4e9e695..e6559a4 100644 (file)
@@ -93,6 +93,7 @@
 #import <JavaScriptCore/RefPtr.h>
 #import <JavaScriptCore/ArrayPrototype.h>
 #import <JavaScriptCore/DateInstance.h>
+#import <JavaScriptCore/JSLock.h>
 #import <WebCore/ApplicationCacheStorage.h>
 #import <WebCore/Cache.h>
 #import <WebCore/ColorMac.h>
@@ -3283,7 +3284,7 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsVal
     JSValue* result = coreFrame->loader()->executeScript(script, true);
     if (!result) // FIXME: pass errors
         return 0;
-    JSLock lock;
+    JSLock lock(false);
     return aeDescFromJSValue(coreFrame->script()->globalObject()->globalExec(), result);
 }
 
index 7b8cfb0..814aa60 100644 (file)
@@ -60,6 +60,7 @@
 #include "ScriptController.h"
 #include "JSDOMBinding.h"
 #include "ExecState.h"
+#include "JSLock.h"
 #include "JSObject.h"
 #include "qt_runtime.h"
 
@@ -210,7 +211,7 @@ QWebFrame::~QWebFrame()
 */
 void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object)
 {
-      KJS::JSLock lock;
+      KJS::JSLock lock(false);
       JSDOMWindow *window = toJSDOMWindow(d->frame);
       KJS::Bindings::RootObject *root = d->frame->bindingRootObject();
       if (!window) {
index 6654035..2376468 100644 (file)
@@ -1,3 +1,14 @@
+2008-07-01  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        Disable JSLock for per-thread contexts.
+
+        * Api/qwebframe.cpp:
+        (QWebFrame::addToJavaScriptWindowObject):
+        Pass a parameter (false) to JSLock to indicate that WebKit doesn't need locking.
+        Include JSLock.h, as it is no longer brought in implicitly.
+
 2008-07-01  Tor Arne Vestbø  <tavestbo@trolltech.com>
 
         Reviewed by Simon.
index 89e3f40..5b667e1 100644 (file)
@@ -1,3 +1,21 @@
+2008-07-01  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        Disable JSLock for per-thread contexts.
+
+        * WebCoreStatistics.cpp:
+        (WebCoreStatistics::javaScriptObjectsCount):
+        (WebCoreStatistics::javaScriptGlobalObjectsCount):
+        (WebCoreStatistics::javaScriptProtectedObjectsCount):
+        (WebCoreStatistics::javaScriptProtectedGlobalObjectsCount):
+        * WebScriptCallFrame.cpp:
+        (WebScriptCallFrame::stringByEvaluatingJavaScriptFromString):
+        * WebView.cpp:
+        (WebView::stringByEvaluatingJavaScriptFromString):
+        Pass a parameter (false) to JSLock to indicate that WebKit doesn't need locking.
+        Include JSLock.h, as it is no longer brought in implicitly.
+
 2008-06-27  Adam Roben  <aroben@apple.com>
 
         Change WebKitGraphics truncation functions to return the length of the
index 2ff1e4f..027dee4 100644 (file)
@@ -34,6 +34,7 @@
 #pragma warning(push, 0)
 #include <JavaScriptCore/collector.h>
 #pragma warning(pop)
+#include <JavaScriptCore/JSLock.h>
 
 using namespace KJS;
 using namespace WebCore;
@@ -96,7 +97,7 @@ HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptObjectsCount(
     if (!count)
         return E_POINTER;
 
-    JSLock lock;
+    JSLock lock(false);
     *count = (UINT)JSGlobalData::threadInstance().heap->size();
     return S_OK;
 }
@@ -107,7 +108,7 @@ HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptGlobalObjectsCount(
     if (!count)
         return E_POINTER;
 
-    JSLock lock;
+    JSLock lock(false);
     *count = (UINT)JSGlobalData::threadInstance().heap->globalObjectCount();
     return S_OK;
 }
@@ -118,7 +119,7 @@ HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptProtectedObjectsCount(
     if (!count)
         return E_POINTER;
 
-    JSLock lock;
+    JSLock lock(false);
     *count = (UINT)JSGlobalData::threadInstance().heap->protectedObjectCount();
     return S_OK;
 }
@@ -129,7 +130,7 @@ HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptProtectedGlobalObjectsCou
     if (!count)
         return E_POINTER;
 
-    JSLock lock;
+    JSLock lock(false);
     *count = (UINT)JSGlobalData::threadInstance().heap->protectedGlobalObjectCount();
     return S_OK;
 }
index 0e83714..7023789 100644 (file)
@@ -187,7 +187,7 @@ HRESULT STDMETHODCALLTYPE WebScriptCallFrame::stringByEvaluatingJavaScriptFromSt
 
     *result = 0;
 
-    JSLock lock;
+    JSLock lock(false);
 
     JSValue* scriptExecutionResult = valueByEvaluatingJavaScriptFromString(script);
     *result = WebCore::BString(jsValueToString(m_state, scriptExecutionResult)).release();
index 9c14af7..f539db6 100644 (file)
@@ -96,7 +96,8 @@
 #include <WebCore/TypingCommand.h>
 #include <WebCore/WindowMessageBroadcaster.h>
 #pragma warning(pop)
-#include <kjs/InitializeThreading.h>
+#include <JavaScriptCore/InitializeThreading.h>
+#include <JavaScriptCore/JSLock.h>
 #include <JavaScriptCore/JSValue.h>
 #include <CFNetwork/CFURLCachePriv.h>
 #include <CFNetwork/CFURLProtocolPriv.h>
@@ -2624,7 +2625,7 @@ HRESULT STDMETHODCALLTYPE WebView::stringByEvaluatingJavaScriptFromString(
     if(!scriptExecutionResult)
         return E_FAIL;
     else if (scriptExecutionResult->isString()) {
-        JSLock lock;
+        JSLock lock(false);
         *result = BString(String(scriptExecutionResult->getString()));
     }