[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75

ggaren at apple.com ggaren at apple.com
Thu Oct 29 20:41:30 UTC 2009


The following commit has been merged in the webkit-1.1 branch:
commit 846a4205986c3417cb61d397846f14f18b314ded
Author: ggaren at apple.com <ggaren at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 8 01:46:07 2009 +0000

    JavaScriptCore: Fixed <rdar://problem/5751979> Database code takes JSLock on secondary
    thread, permanently slowing down JavaScript
    
    Patch by Geoffrey Garen <ggaren at apple.com> on 2009-10-07
    Reviewed by Oliver Hunt.
    
    Removed the optional lock from Heap::protect, Heap::unprotect, and friends,
    since WebCore no longer uses it.
    
    * JavaScriptCore.exp:
    * runtime/Collector.cpp:
    (JSC::Heap::protect):
    (JSC::Heap::unprotect):
    (JSC::Heap::markProtectedObjects):
    (JSC::Heap::protectedGlobalObjectCount):
    (JSC::Heap::protectedObjectCount):
    (JSC::Heap::protectedObjectTypeCounts):
    * runtime/Collector.h:
    
    WebCore: Fixed <rdar://problem/5751979> Database code takes JSLock on secondary
    thread, permanently slowing down JavaScript
    
    Patch by Geoffrey Garen <ggaren at apple.com> on 2009-10-07
    Reviewed by Oliver Hunt.
    
    Changed callback objects to use a standard helper object. The helper
    object ASSERTs that it is deleted on the main thread, so no lock is
    required when unprotecting its members. It also centralizes some previously
    duplicated code.
    
    Callback objects that might be deleted on a secondary thread use
    callOnMainThread to delete their helper objects on the main thread.
    
    * WebCore.xcodeproj/project.pbxproj:
    * bindings/js/JSCallbackData.cpp: Copied from bindings/js/JSCustomSQLTransactionCallback.cpp.
    (WebCore::JSCallbackData::deleteData):
    (WebCore::JSCallbackData::invokeCallback):
    * bindings/js/JSCallbackData.h: Copied from bindings/js/JSCustomSQLTransactionCallback.cpp.
    (WebCore::JSCallbackData::JSCallbackData):
    (WebCore::JSCallbackData::~JSCallbackData):
    (WebCore::JSCallbackData::callback):
    * bindings/js/JSCustomPositionCallback.cpp:
    (WebCore::JSCustomPositionCallback::JSCustomPositionCallback):
    (WebCore::JSCustomPositionCallback::handleEvent):
    * bindings/js/JSCustomPositionCallback.h:
    * bindings/js/JSCustomPositionErrorCallback.cpp:
    (WebCore::JSCustomPositionErrorCallback::JSCustomPositionErrorCallback):
    (WebCore::JSCustomPositionErrorCallback::handleEvent):
    * bindings/js/JSCustomPositionErrorCallback.h:
    * bindings/js/JSCustomSQLStatementCallback.cpp:
    (WebCore::JSCustomSQLStatementCallback::JSCustomSQLStatementCallback):
    (WebCore::JSCustomSQLStatementCallback::~JSCustomSQLStatementCallback):
    (WebCore::JSCustomSQLStatementCallback::handleEvent):
    * bindings/js/JSCustomSQLStatementCallback.h:
    * bindings/js/JSCustomSQLStatementErrorCallback.cpp:
    (WebCore::JSCustomSQLStatementErrorCallback::JSCustomSQLStatementErrorCallback):
    (WebCore::JSCustomSQLStatementErrorCallback::~JSCustomSQLStatementErrorCallback):
    (WebCore::JSCustomSQLStatementErrorCallback::handleEvent):
    * bindings/js/JSCustomSQLStatementErrorCallback.h:
    * bindings/js/JSCustomSQLTransactionCallback.cpp:
    (WebCore::JSCustomSQLTransactionCallback::JSCustomSQLTransactionCallback):
    (WebCore::JSCustomSQLTransactionCallback::~JSCustomSQLTransactionCallback):
    (WebCore::JSCustomSQLTransactionCallback::handleEvent):
    * bindings/js/JSCustomSQLTransactionCallback.h:
    * bindings/js/JSCustomSQLTransactionErrorCallback.cpp:
    (WebCore::JSCustomSQLTransactionErrorCallback::JSCustomSQLTransactionErrorCallback):
    (WebCore::JSCustomSQLTransactionErrorCallback::~JSCustomSQLTransactionErrorCallback):
    (WebCore::JSCustomSQLTransactionErrorCallback::handleEvent):
    * bindings/js/JSCustomSQLTransactionErrorCallback.h:
    * bindings/js/JSCustomVoidCallback.cpp:
    (WebCore::JSCustomVoidCallback::JSCustomVoidCallback):
    (WebCore::JSCustomVoidCallback::~JSCustomVoidCallback):
    (WebCore::JSCustomVoidCallback::handleEvent):
    * bindings/js/JSCustomVoidCallback.h:
    * storage/Database.cpp:
    (WebCore::Database::Database):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49280 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 51f817f..53660c0 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,23 @@
+2009-10-07  Geoffrey Garen  <ggaren at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        Fixed <rdar://problem/5751979> Database code takes JSLock on secondary
+        thread, permanently slowing down JavaScript
+        
+        Removed the optional lock from Heap::protect, Heap::unprotect, and friends,
+        since WebCore no longer uses it.
+
+        * JavaScriptCore.exp:
+        * runtime/Collector.cpp:
+        (JSC::Heap::protect):
+        (JSC::Heap::unprotect):
+        (JSC::Heap::markProtectedObjects):
+        (JSC::Heap::protectedGlobalObjectCount):
+        (JSC::Heap::protectedObjectCount):
+        (JSC::Heap::protectedObjectTypeCounts):
+        * runtime/Collector.h:
+
 2009-10-07  Zoltan Horvath  <zoltan at webkit.org>
 
         Reviewed by Darin Adler.
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index d94dcfa..2934655 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -183,7 +183,6 @@ __ZN3JSC4Heap15recordExtraCostEm
 __ZN3JSC4Heap16primaryHeapBeginEv
 __ZN3JSC4Heap17globalObjectCountEv
 __ZN3JSC4Heap20protectedObjectCountEv
-__ZN3JSC4Heap24setGCProtectNeedsLockingEv
 __ZN3JSC4Heap25protectedObjectTypeCountsEv
 __ZN3JSC4Heap26protectedGlobalObjectCountEv
 __ZN3JSC4Heap6isBusyEv
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index b5aa73e..1a5eb89 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -980,16 +980,6 @@ void Heap::markStackObjectsConservatively(MarkStack& markStack)
 #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 supposed
-    // to do explicit locking. 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);
@@ -998,13 +988,7 @@ void Heap::protect(JSValue k)
     if (!k.isCell())
         return;
 
-    if (m_protectedValuesMutex)
-        m_protectedValuesMutex->lock();
-
     m_protectedValues.add(k.asCell());
-
-    if (m_protectedValuesMutex)
-        m_protectedValuesMutex->unlock();
 }
 
 void Heap::unprotect(JSValue k)
@@ -1015,28 +999,16 @@ void Heap::unprotect(JSValue k)
     if (!k.isCell())
         return;
 
-    if (m_protectedValuesMutex)
-        m_protectedValuesMutex->lock();
-
     m_protectedValues.remove(k.asCell());
-
-    if (m_protectedValuesMutex)
-        m_protectedValuesMutex->unlock();
 }
 
 void Heap::markProtectedObjects(MarkStack& markStack)
 {
-    if (m_protectedValuesMutex)
-        m_protectedValuesMutex->lock();
-
     ProtectCountSet::iterator end = m_protectedValues.end();
     for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) {
         markStack.append(it->first);
         markStack.drain();
     }
-
-    if (m_protectedValuesMutex)
-        m_protectedValuesMutex->unlock();
 }
 
 template <HeapType heapType> size_t Heap::sweep()
@@ -1228,9 +1200,6 @@ size_t Heap::globalObjectCount()
 
 size_t Heap::protectedGlobalObjectCount()
 {
-    if (m_protectedValuesMutex)
-        m_protectedValuesMutex->lock();
-
     size_t count = 0;
     if (JSGlobalObject* head = m_globalData->head) {
         JSGlobalObject* o = head;
@@ -1241,23 +1210,12 @@ size_t Heap::protectedGlobalObjectCount()
         } while (o != head);
     }
 
-    if (m_protectedValuesMutex)
-        m_protectedValuesMutex->unlock();
-
     return count;
 }
 
 size_t Heap::protectedObjectCount()
 {
-    if (m_protectedValuesMutex)
-        m_protectedValuesMutex->lock();
-
-    size_t result = m_protectedValues.size();
-
-    if (m_protectedValuesMutex)
-        m_protectedValuesMutex->unlock();
-
-    return result;
+    return m_protectedValues.size();
 }
 
 static const char* typeName(JSCell* cell)
@@ -1279,16 +1237,10 @@ HashCountedSet<const char*>* Heap::protectedObjectTypeCounts()
 {
     HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
 
-    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;
 }
 
diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h
index 0ecff19..2ce13dc 100644
--- a/JavaScriptCore/runtime/Collector.h
+++ b/JavaScriptCore/runtime/Collector.h
@@ -96,7 +96,6 @@ namespace JSC {
         };
         Statistics statistics() const;
 
-        void setGCProtectNeedsLocking();
         void protect(JSValue);
         void unprotect(JSValue);
 
@@ -151,7 +150,6 @@ namespace JSC {
         CollectorHeap primaryHeap;
         CollectorHeap numberHeap;
 
-        OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking().
         ProtectCountSet m_protectedValues;
 
         HashSet<MarkedArgumentBuffer*>* m_markListSet;
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index f76305d..cf78765 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,62 @@
+2009-10-07  Geoffrey Garen  <ggaren at apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        Fixed <rdar://problem/5751979> Database code takes JSLock on secondary
+        thread, permanently slowing down JavaScript
+
+        Changed callback objects to use a standard helper object. The helper
+        object ASSERTs that it is deleted on the main thread, so no lock is
+        required when unprotecting its members. It also centralizes some previously
+        duplicated code.
+        
+        Callback objects that might be deleted on a secondary thread use
+        callOnMainThread to delete their helper objects on the main thread.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSCallbackData.cpp: Copied from bindings/js/JSCustomSQLTransactionCallback.cpp.
+        (WebCore::JSCallbackData::deleteData):
+        (WebCore::JSCallbackData::invokeCallback):
+        * bindings/js/JSCallbackData.h: Copied from bindings/js/JSCustomSQLTransactionCallback.cpp.
+        (WebCore::JSCallbackData::JSCallbackData):
+        (WebCore::JSCallbackData::~JSCallbackData):
+        (WebCore::JSCallbackData::callback):
+        * bindings/js/JSCustomPositionCallback.cpp:
+        (WebCore::JSCustomPositionCallback::JSCustomPositionCallback):
+        (WebCore::JSCustomPositionCallback::handleEvent):
+        * bindings/js/JSCustomPositionCallback.h:
+        * bindings/js/JSCustomPositionErrorCallback.cpp:
+        (WebCore::JSCustomPositionErrorCallback::JSCustomPositionErrorCallback):
+        (WebCore::JSCustomPositionErrorCallback::handleEvent):
+        * bindings/js/JSCustomPositionErrorCallback.h:
+        * bindings/js/JSCustomSQLStatementCallback.cpp:
+        (WebCore::JSCustomSQLStatementCallback::JSCustomSQLStatementCallback):
+        (WebCore::JSCustomSQLStatementCallback::~JSCustomSQLStatementCallback):
+        (WebCore::JSCustomSQLStatementCallback::handleEvent):
+        * bindings/js/JSCustomSQLStatementCallback.h:
+        * bindings/js/JSCustomSQLStatementErrorCallback.cpp:
+        (WebCore::JSCustomSQLStatementErrorCallback::JSCustomSQLStatementErrorCallback):
+        (WebCore::JSCustomSQLStatementErrorCallback::~JSCustomSQLStatementErrorCallback):
+        (WebCore::JSCustomSQLStatementErrorCallback::handleEvent):
+        * bindings/js/JSCustomSQLStatementErrorCallback.h:
+        * bindings/js/JSCustomSQLTransactionCallback.cpp:
+        (WebCore::JSCustomSQLTransactionCallback::JSCustomSQLTransactionCallback):
+        (WebCore::JSCustomSQLTransactionCallback::~JSCustomSQLTransactionCallback):
+        (WebCore::JSCustomSQLTransactionCallback::handleEvent):
+        * bindings/js/JSCustomSQLTransactionCallback.h:
+        * bindings/js/JSCustomSQLTransactionErrorCallback.cpp:
+        (WebCore::JSCustomSQLTransactionErrorCallback::JSCustomSQLTransactionErrorCallback):
+        (WebCore::JSCustomSQLTransactionErrorCallback::~JSCustomSQLTransactionErrorCallback):
+        (WebCore::JSCustomSQLTransactionErrorCallback::handleEvent):
+        * bindings/js/JSCustomSQLTransactionErrorCallback.h:
+        * bindings/js/JSCustomVoidCallback.cpp:
+        (WebCore::JSCustomVoidCallback::JSCustomVoidCallback):
+        (WebCore::JSCustomVoidCallback::~JSCustomVoidCallback):
+        (WebCore::JSCustomVoidCallback::handleEvent):
+        * bindings/js/JSCustomVoidCallback.h:
+        * storage/Database.cpp:
+        (WebCore::Database::Database):
+
 2009-10-07  Jens Alfke  <snej at chromium.org>
 
         Reviewed by Dave Levin.
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index ef231dd..04ccb29 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -429,6 +429,8 @@
             'bindings/js/DOMObjectWithSVGContext.h',
             'bindings/js/GCController.cpp',
             'bindings/js/GCController.h',
+            'bindings/js/JSCallbackData.cpp',
+            'bindings/js/JSCallbackData.h',
             'bindings/js/JSAttrCustom.cpp',
             'bindings/js/JSAudioConstructor.cpp',
             'bindings/js/JSAudioConstructor.h',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index 34ee351..96718fb 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -671,6 +671,7 @@ SOURCES += \
     accessibility/AccessibilityTableRow.cpp \    
     accessibility/AXObjectCache.cpp \
     bindings/js/GCController.cpp \
+    bindings/js/JSCallbackData.cpp \
     bindings/js/JSAttrCustom.cpp \
     bindings/js/JSCDATASectionCustom.cpp \
     bindings/js/JSCanvasRenderingContextCustom.cpp \
@@ -1373,6 +1374,7 @@ HEADERS += \
     bindings/js/CachedScriptSourceProvider.h \
     bindings/js/DOMObjectWithSVGContext.h \
     bindings/js/GCController.h \
+    bindings/js/JSCallbackData.h \
     bindings/js/JSAudioConstructor.h \
     bindings/js/JSCSSStyleDeclarationCustom.h \
     bindings/js/JSCustomPositionCallback.h \
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index f81aae8..83e3a21 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -28955,6 +28955,14 @@
 					>
 				</File>
 				<File
+					RelativePath="..\bindings\js\JSCallbackData.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\bindings\js\JSCallbackData.h"
+					>
+				</File>
+				<File
 					RelativePath="..\bindings\js\JSAbstractWorkerCustom.cpp"
 					>
 				</File>
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index 28a1d5d..016a5ef 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -197,6 +197,8 @@
 		142011B70A003133008303F9 /* JSCSSStyleDeclaration.h in Headers */ = {isa = PBXBuildFile; fileRef = 142011B50A003133008303F9 /* JSCSSStyleDeclaration.h */; };
 		1432E8470C51493800B1500F /* GCController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1432E8460C51493800B1500F /* GCController.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1432E8490C51493F00B1500F /* GCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1432E8480C51493F00B1500F /* GCController.cpp */; };
+		1449E24C107D4A8400B5793F /* JSCallbackData.h in Headers */ = {isa = PBXBuildFile; fileRef = 1449E24A107D4A8400B5793F /* JSCallbackData.h */; };
+		1449E287107D4DB400B5793F /* JSCallbackData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1449E286107D4DB400B5793F /* JSCallbackData.cpp */; };
 		1477E7760BF4134A00152872 /* PageCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1477E7740BF4134A00152872 /* PageCache.cpp */; };
 		1477E7770BF4134A00152872 /* PageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1477E7750BF4134A00152872 /* PageCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		148AFDA50AF58360008CC700 /* ExceptionHandlers.h in Headers */ = {isa = PBXBuildFile; fileRef = 148AFDA30AF58360008CC700 /* ExceptionHandlers.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -5330,6 +5332,8 @@
 		142011B50A003133008303F9 /* JSCSSStyleDeclaration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSCSSStyleDeclaration.h; sourceTree = "<group>"; };
 		1432E8460C51493800B1500F /* GCController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GCController.h; sourceTree = "<group>"; };
 		1432E8480C51493F00B1500F /* GCController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GCController.cpp; sourceTree = "<group>"; };
+		1449E24A107D4A8400B5793F /* JSCallbackData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackData.h; sourceTree = "<group>"; };
+		1449E286107D4DB400B5793F /* JSCallbackData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCallbackData.cpp; sourceTree = "<group>"; };
 		1477E7740BF4134A00152872 /* PageCache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PageCache.cpp; sourceTree = "<group>"; };
 		1477E7750BF4134A00152872 /* PageCache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PageCache.h; sourceTree = "<group>"; };
 		14813BF309EDF88E00F757E1 /* IDLParser.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; name = IDLParser.pm; path = scripts/IDLParser.pm; sourceTree = "<group>"; };
@@ -14617,6 +14621,8 @@
 		BCCE58A71061E82F008FB35A /* Callback Objects */ = {
 			isa = PBXGroup;
 			children = (
+				1449E286107D4DB400B5793F /* JSCallbackData.cpp */,
+				1449E24A107D4A8400B5793F /* JSCallbackData.h */,
 				FE80D7A20E9C1ED2000D6F75 /* JSCustomPositionCallback.cpp */,
 				FE80D7A30E9C1ED2000D6F75 /* JSCustomPositionCallback.h */,
 				FE80D7A40E9C1ED2000D6F75 /* JSCustomPositionErrorCallback.cpp */,
@@ -17959,6 +17965,7 @@
 				BC9462D8107A7B4C00857193 /* BeforeLoadEvent.h in Headers */,
 				BC946348107A936600857193 /* JSBeforeLoadEvent.h in Headers */,
 				97BC63B91076C97F002C2142 /* PolicyCheck.h in Headers */,
+				1449E24C107D4A8400B5793F /* JSCallbackData.h in Headers */,
 				A75E497610752ACB00C9B896 /* SerializedScriptValue.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -20080,6 +20087,7 @@
 				979F43D31075E44A0000F83B /* RedirectScheduler.cpp in Sources */,
 				BC946346107A934B00857193 /* JSBeforeLoadEvent.cpp in Sources */,
 				97BC63B81076C97F002C2142 /* PolicyCheck.cpp in Sources */,
+				1449E287107D4DB400B5793F /* JSCallbackData.cpp in Sources */,
 				A75E497710752ACB00C9B896 /* SerializedScriptValue.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
diff --git a/WebCore/bindings/js/JSCallbackData.cpp b/WebCore/bindings/js/JSCallbackData.cpp
new file mode 100644
index 0000000..d08f760
--- /dev/null
+++ b/WebCore/bindings/js/JSCallbackData.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSCallbackData.h"
+
+#include "Document.h"
+#include "JSDOMBinding.h"
+
+using namespace JSC;
+    
+namespace WebCore {
+
+void JSCallbackData::deleteData(void* context)
+{
+    delete static_cast<JSCallbackData*>(context);
+}
+
+JSValue JSCallbackData::invokeCallback(MarkedArgumentBuffer& args, bool* raisedException)
+{
+    ASSERT(callback());
+    ASSERT(globalObject());
+
+    ExecState* exec = globalObject()->globalExec();
+    
+    JSValue function = callback()->get(exec, Identifier(exec, "handleEvent"));
+    CallData callData;
+    CallType callType = function.getCallData(callData);
+    if (callType == CallTypeNone) {
+        callType = callback()->getCallData(callData);
+        if (callType == CallTypeNone)
+            return JSValue();
+        function = callback();
+    }
+    
+    globalObject()->globalData()->timeoutChecker.start();
+    JSValue result = call(exec, function, callType, callData, callback(), args);
+    globalObject()->globalData()->timeoutChecker.stop();
+
+    Document::updateStyleForAllDocuments();
+
+    if (exec->hadException()) {
+        reportCurrentException(exec);
+        if (raisedException)
+            *raisedException = true;
+        return result;
+    }
+    
+    return result;
+}
+    
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSCallbackData.h b/WebCore/bindings/js/JSCallbackData.h
new file mode 100644
index 0000000..4fc9f84
--- /dev/null
+++ b/WebCore/bindings/js/JSCallbackData.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSCallbackData_h
+#define JSCallbackData_h
+
+#include "JSDOMGlobalObject.h"
+#include <runtime/JSObject.h>
+#include <runtime/Protect.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+// We have to clean up this data on the main thread because unprotecting a
+// JSObject on a non-main thread without synchronization would corrupt the heap
+// (and synchronization would be slow).
+
+class JSCallbackData {
+public:
+    static void deleteData(void*);
+
+    JSCallbackData(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)
+        : m_callback(callback)
+        , m_globalObject(globalObject)
+    {
+    }
+    
+    ~JSCallbackData()
+    {
+        ASSERT(isMainThread());
+    }
+
+    JSC::JSObject* callback() { return m_callback.get(); }
+    JSDOMGlobalObject* globalObject() { return m_globalObject.get(); }
+    
+    JSC::JSValue invokeCallback(JSC::MarkedArgumentBuffer&, bool* raisedException = 0);
+
+private:
+    JSC::ProtectedPtr<JSC::JSObject> m_callback;
+    JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
+};
+
+} // namespace WebCore
+
+#endif // JSCallbackData_h
diff --git a/WebCore/bindings/js/JSCustomPositionCallback.cpp b/WebCore/bindings/js/JSCustomPositionCallback.cpp
index 7074423..e5f83aa 100644
--- a/WebCore/bindings/js/JSCustomPositionCallback.cpp
+++ b/WebCore/bindings/js/JSCustomPositionCallback.cpp
@@ -36,45 +36,19 @@ namespace WebCore {
 using namespace JSC;
 
 JSCustomPositionCallback::JSCustomPositionCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
-    : m_callback(callback)
-    , m_globalObject(globalObject)
+    : m_data(callback, globalObject)
 {
 }
 
 void JSCustomPositionCallback::handleEvent(Geoposition* geoposition)
 {
-    ASSERT(m_callback);
-    ASSERT(m_globalObject);
-
-    ExecState* exec = m_globalObject->globalExec();
-    
-    JSC::JSLock lock(SilenceAssertionsOnly);
-    
-    JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent"));
-    CallData callData;
-    CallType callType = function.getCallData(callData);
-    if (callType == CallTypeNone) {
-        callType = m_callback->getCallData(callData);
-        if (callType == CallTypeNone) {
-            // FIXME: Should an exception be thrown here?
-            return;
-        }
-        function = m_callback;
-    }
-    
     RefPtr<JSCustomPositionCallback> protect(this);
 
+    JSC::JSLock lock(SilenceAssertionsOnly);
+    ExecState* exec = m_data.globalObject()->globalExec();
     MarkedArgumentBuffer args;
     args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), geoposition));
-
-    m_globalObject->globalData()->timeoutChecker.start();
-    call(exec, function, callType, callData, m_callback, args);
-    m_globalObject->globalData()->timeoutChecker.stop();
-
-    if (exec->hadException())
-        reportCurrentException(exec);
-    
-    Document::updateStyleForAllDocuments();
+    m_data.invokeCallback(args);
 }
 
 } // namespace WebCore
diff --git a/WebCore/bindings/js/JSCustomPositionCallback.h b/WebCore/bindings/js/JSCustomPositionCallback.h
index 15a166a..ad5528d 100644
--- a/WebCore/bindings/js/JSCustomPositionCallback.h
+++ b/WebCore/bindings/js/JSCustomPositionCallback.h
@@ -26,14 +26,14 @@
 #ifndef JSCustomPositionCallback_h
 #define JSCustomPositionCallback_h
 
+#include "JSCallbackData.h"
 #include "PositionCallback.h"
-#include "JSDOMGlobalObject.h"
-#include <runtime/Protect.h>
 #include <wtf/Forward.h>
 
 namespace WebCore {
 
 class Geoposition;
+class JSDOMGlobalObject;
 
 class JSCustomPositionCallback : public PositionCallback {
 public:
@@ -46,9 +46,8 @@ private:
     JSCustomPositionCallback(JSC::JSObject* callback, JSDOMGlobalObject*);
 
     virtual void handleEvent(Geoposition*);
-
-    JSC::ProtectedPtr<JSC::JSObject> m_callback;
-    JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
+    
+    JSCallbackData m_data;
 };
     
 } // namespace WebCore
diff --git a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
index 9109cd1..bd64deb 100644
--- a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
@@ -36,45 +36,20 @@ namespace WebCore {
 using namespace JSC;
 
 JSCustomPositionErrorCallback::JSCustomPositionErrorCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
-    : m_callback(callback)
-    , m_globalObject(globalObject)
+    : m_data(callback, globalObject)
 {
 }
 
 void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError)
 {
-    ASSERT(m_callback);
-    ASSERT(m_globalObject);
+    RefPtr<JSCustomPositionErrorCallback> protect(this);
 
-    ExecState* exec = m_globalObject->globalExec();
-    
     JSC::JSLock lock(SilenceAssertionsOnly);
-    
-    JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent"));
-    CallData callData;
-    CallType callType = function.getCallData(callData);
-    if (callType == CallTypeNone) {
-        callType = m_callback->getCallData(callData);
-        if (callType == CallTypeNone) {
-            // FIXME: Should an exception be thrown here?
-            return;
-        }
-        function = m_callback;
-    }
-    
-    RefPtr<JSCustomPositionErrorCallback> protect(this);
-    
+    ExecState* exec = m_data.globalObject()->globalExec();
     MarkedArgumentBuffer args;
     args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), positionError));
     
-    m_globalObject->globalData()->timeoutChecker.start();
-    call(exec, function, callType, callData, m_callback, args);
-    m_globalObject->globalData()->timeoutChecker.stop();
-    
-    if (exec->hadException())
-        reportCurrentException(exec);
-
-    Document::updateStyleForAllDocuments();
+    m_data.invokeCallback(args);
 }
     
 } // namespace WebCore
diff --git a/WebCore/bindings/js/JSCustomPositionErrorCallback.h b/WebCore/bindings/js/JSCustomPositionErrorCallback.h
index d97e967..59328ca 100644
--- a/WebCore/bindings/js/JSCustomPositionErrorCallback.h
+++ b/WebCore/bindings/js/JSCustomPositionErrorCallback.h
@@ -26,9 +26,8 @@
 #ifndef JSCustomPositionErrorCallback_h
 #define JSCustomPositionErrorCallback_h
 
+#include "JSCallbackData.h"
 #include "PositionErrorCallback.h"
-#include "JSDOMGlobalObject.h"
-#include <runtime/Protect.h>
 #include <wtf/Forward.h>
 
 namespace WebCore {
@@ -45,9 +44,8 @@ public:
 private:
     JSCustomPositionErrorCallback(JSC::JSObject* callback, JSDOMGlobalObject* globalObject);
     virtual void handleEvent(PositionError*);
-
-    JSC::ProtectedPtr<JSC::JSObject> m_callback;
-    JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
+    
+    JSCallbackData m_data;
 };
     
 } // namespace WebCore
diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
index cdeda8f..1f6bd95 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
@@ -36,55 +36,38 @@
 #include "JSSQLResultSet.h"
 #include "JSSQLTransaction.h"
 #include <runtime/JSLock.h>
+#include <wtf/MainThread.h>
 
 namespace WebCore {
     
 using namespace JSC;
     
 JSCustomSQLStatementCallback::JSCustomSQLStatementCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
-    : m_callback(callback)
-    , m_globalObject(globalObject)
+    : m_data(new JSCallbackData(callback, globalObject))
 {
 }
     
-void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
+JSCustomSQLStatementCallback::~JSCustomSQLStatementCallback()
 {
-    ASSERT(m_callback);
-    ASSERT(m_globalObject);
-        
-    ExecState* exec = m_globalObject->globalExec();
-        
-    JSC::JSLock lock(SilenceAssertionsOnly);
+    callOnMainThread(JSCallbackData::deleteData, m_data);
+#ifndef NDEBUG
+    m_data = 0;
+#endif
+}
 
-    JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent"));
-    CallData callData;
-    CallType callType = function.getCallData(callData);
-    if (callType == CallTypeNone) {
-        callType = m_callback->getCallData(callData);
-        if (callType == CallTypeNone) {
-            // FIXME: Should an exception be thrown here?
-            return;
-        }
-        function = m_callback;
-    }
+void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
+{
+    ASSERT(m_data);
 
     RefPtr<JSCustomSQLStatementCallback> protect(this);
 
+    JSC::JSLock lock(SilenceAssertionsOnly);
+    ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
     args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction));
     args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), resultSet));
-        
-    m_globalObject->globalData()->timeoutChecker.start();
-    call(exec, function, callType, callData, m_callback, args);
-    m_globalObject->globalData()->timeoutChecker.stop();
-
-    if (exec->hadException()) {
-        reportCurrentException(exec);
-
-        raisedException = true;
-    }
 
-    Document::updateStyleForAllDocuments();
+    m_data->invokeCallback(args, &raisedException);
 }
 
 }
diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.h b/WebCore/bindings/js/JSCustomSQLStatementCallback.h
index e6600c5..259aecf 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementCallback.h
+++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.h
@@ -31,9 +31,8 @@
 
 #if ENABLE(DATABASE)
 
-#include "JSDOMGlobalObject.h"
+#include "JSCallbackData.h"
 #include "SQLStatementCallback.h"
-#include <runtime/Protect.h>
 #include <wtf/Forward.h>
 
 namespace WebCore {
@@ -46,14 +45,15 @@ public:
     {
         return adoptRef(new JSCustomSQLStatementCallback(callback, globalObject));
     }
+    
+    virtual ~JSCustomSQLStatementCallback();
 
     virtual void handleEvent(SQLTransaction*, SQLResultSet*, bool& raisedException);
 
 private:
     JSCustomSQLStatementCallback(JSC::JSObject* callback, JSDOMGlobalObject*);
 
-    JSC::ProtectedPtr<JSC::JSObject> m_callback;
-    JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
+    JSCallbackData* m_data;
 };
 
 }
diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
index ea47c64..6178509 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
@@ -32,70 +32,51 @@
 #if ENABLE(DATABASE)
 
 #include "Frame.h"
-#include "ScriptController.h"
+#include "JSCallbackData.h"
 #include "JSSQLError.h"
 #include "JSSQLTransaction.h"
+#include "ScriptController.h"
 #include <runtime/JSLock.h>
+#include <wtf/MainThread.h>
 
 namespace WebCore {
     
 using namespace JSC;
     
 JSCustomSQLStatementErrorCallback::JSCustomSQLStatementErrorCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
-    : m_callback(callback)
-    , m_globalObject(globalObject)
+    : m_data(new JSCallbackData(callback, globalObject))
 {
 }
-    
-bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error)
+
+JSCustomSQLStatementErrorCallback::~JSCustomSQLStatementErrorCallback()
 {
-    ASSERT(m_callback);
-    ASSERT(m_globalObject);
-        
-    ExecState* exec = m_globalObject->globalExec();
-        
-    JSC::JSLock lock(SilenceAssertionsOnly);
-        
-    JSValue handleEventFunction = m_callback->get(exec, Identifier(exec, "handleEvent"));
-    CallData handleEventCallData;
-    CallType handleEventCallType = handleEventFunction.getCallData(handleEventCallData);
-    CallData callbackCallData;
-    CallType callbackCallType = CallTypeNone;
+    callOnMainThread(JSCallbackData::deleteData, m_data);
+#ifndef NDEBUG
+    m_data = 0;
+#endif
+}
 
-    if (handleEventCallType == CallTypeNone) {
-        callbackCallType = m_callback->getCallData(callbackCallData);
-        if (callbackCallType == CallTypeNone) {
-            // FIXME: Should an exception be thrown here?
-            return true;
-        }
-    }
+bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error)
+{
+    ASSERT(m_data);
         
     RefPtr<JSCustomSQLStatementErrorCallback> protect(this);
         
+    JSC::JSLock lock(SilenceAssertionsOnly);
+    ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
     args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction));
     args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), error));
-        
-    JSValue result;
-    m_globalObject->globalData()->timeoutChecker.start();
-    if (handleEventCallType != CallTypeNone)
-        result = call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_callback, args);
-    else
-        result = call(exec, m_callback, callbackCallType, callbackCallData, m_callback, args);
-    m_globalObject->globalData()->timeoutChecker.stop();
-
-    if (exec->hadException()) {
-        reportCurrentException(exec);
-            
+    
+    bool raisedException = false;
+    JSValue result = m_data->invokeCallback(args, &raisedException);
+    if (raisedException) {
         // The spec says:
         // "If the error callback returns false, then move on to the next statement..."
         // "Otherwise, the error callback did not return false, or there was no error callback"
         // Therefore an exception and returning true are the same thing - so, return true on an exception
         return true;
     }
-        
-    Document::updateStyleForAllDocuments();
-
     return result.toBoolean(exec);
 }
 
diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h
index e03ac35..ac4e45f 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h
+++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.h
@@ -37,7 +37,8 @@
 #include <wtf/Forward.h>
 
 namespace WebCore {
-    
+
+class JSCallbackData;    
 class SQLError;
     
 class JSCustomSQLStatementErrorCallback : public SQLStatementErrorCallback {
@@ -46,14 +47,15 @@ public:
     {
         return adoptRef(new JSCustomSQLStatementErrorCallback(callback, globalObject));
     }
-        
+
+    virtual ~JSCustomSQLStatementErrorCallback();
+
     virtual bool handleEvent(SQLTransaction*, SQLError*);
 
 private:
     JSCustomSQLStatementErrorCallback(JSC::JSObject* callback, JSDOMGlobalObject*);
 
-    JSC::ProtectedPtr<JSC::JSObject> m_callback;
-    JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
+    JSCallbackData* m_data;
 };
     
 }
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
index 1886345..456022f 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
@@ -32,6 +32,7 @@
 #if ENABLE(DATABASE)
 
 #include "Frame.h"
+#include "JSCallbackData.h"
 #include "JSDOMGlobalObject.h"
 #include "JSSQLTransaction.h"
 #include "Page.h"
@@ -48,42 +49,17 @@ using namespace JSC;
 static WTF::RefCountedLeakCounter counter("JSCustomSQLTransactionCallback");
 #endif
 
-// We have to clean up the data on the main thread because unprotecting the 
-// JSObject on a non-main thread would register that thread for JavaScript
-// garbage collection, which could unnecessarily slow things down.
-
-class JSCustomSQLTransactionCallback::Data {
-public:
-    Data(JSObject* callback, JSDOMGlobalObject* globalObject)
-        : m_callback(callback)
-        , m_globalObject(globalObject)
-    {
-    }
-
-    JSObject* callback() { return m_callback; }
-    JSDOMGlobalObject* globalObject() { return m_globalObject.get(); }
-
-private:
-    ProtectedPtr<JSObject> m_callback;
-    ProtectedPtr<JSDOMGlobalObject> m_globalObject;
-};
-
 JSCustomSQLTransactionCallback::JSCustomSQLTransactionCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
-    : m_data(new Data(callback, globalObject))
+    : m_data(new JSCallbackData(callback, globalObject))
 {
 #ifndef NDEBUG
     counter.increment();
 #endif
 }
 
-void JSCustomSQLTransactionCallback::deleteData(void* context)
-{
-    delete static_cast<Data*>(context);
-}
-
 JSCustomSQLTransactionCallback::~JSCustomSQLTransactionCallback()
 {
-    callOnMainThread(deleteData, m_data);
+    callOnMainThread(JSCallbackData::deleteData, m_data);
 #ifndef NDEBUG
     m_data = 0;
     counter.decrement();
@@ -93,47 +69,14 @@ JSCustomSQLTransactionCallback::~JSCustomSQLTransactionCallback()
 void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bool& raisedException)
 {
     ASSERT(m_data);
-    ASSERT(m_data->callback());
-    ASSERT(m_data->globalObject());
 
-    JSDOMGlobalObject* globalObject = m_data->globalObject();
-    ExecState* exec = globalObject->globalExec();
-        
-    JSC::JSLock lock(SilenceAssertionsOnly);
-        
-    JSValue handleEventFunction = m_data->callback()->get(exec, Identifier(exec, "handleEvent"));
-    CallData handleEventCallData;
-    CallType handleEventCallType = handleEventFunction.getCallData(handleEventCallData);
-    CallData callbackCallData;
-    CallType callbackCallType = CallTypeNone;
-
-    if (handleEventCallType == CallTypeNone) {
-        callbackCallType = m_data->callback()->getCallData(callbackCallData);
-        if (callbackCallType == CallTypeNone) {
-            // FIXME: Should an exception be thrown here?
-            return;
-        }
-    }
-        
     RefPtr<JSCustomSQLTransactionCallback> protect(this);
         
+    JSC::JSLock lock(SilenceAssertionsOnly);
+    ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
     args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction));
-
-    globalObject->globalData()->timeoutChecker.start();
-    if (handleEventCallType != CallTypeNone)
-        call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_data->callback(), args);
-    else
-        call(exec, m_data->callback(), callbackCallType, callbackCallData, m_data->callback(), args);
-    globalObject->globalData()->timeoutChecker.stop();
-        
-    if (exec->hadException()) {
-        reportCurrentException(exec);
-        
-        raisedException = true;
-    }
-        
-    Document::updateStyleForAllDocuments();
+    m_data->invokeCallback(args, &raisedException);
 }
     
 }
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.h b/WebCore/bindings/js/JSCustomSQLTransactionCallback.h
index f7f78f2..f142e59 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionCallback.h
+++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.h
@@ -41,6 +41,7 @@ namespace JSC {
 namespace WebCore {
 
 class Frame;
+class JSCallbackData;
 class JSDOMGlobalObject;
 
 class JSCustomSQLTransactionCallback : public SQLTransactionCallback {
@@ -57,10 +58,7 @@ public:
 private:
     JSCustomSQLTransactionCallback(JSC::JSObject* callback, JSDOMGlobalObject*);
 
-    static void deleteData(void*);
-
-    class Data;
-    Data* m_data;
+    JSCallbackData* m_data;
 };
 
 }
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
index b2f8280..331e014 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
@@ -32,54 +32,40 @@
 #if ENABLE(DATABASE)
 
 #include "Frame.h"
-#include "ScriptController.h"
+#include "JSCallbackData.h"
 #include "JSSQLError.h"
+#include "ScriptController.h"
 #include <runtime/JSLock.h>
+#include <wtf/MainThread.h>
 
 namespace WebCore {
     
 using namespace JSC;
     
 JSCustomSQLTransactionErrorCallback::JSCustomSQLTransactionErrorCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
-    : m_callback(callback)
-    , m_globalObject(globalObject)
+    : m_data(new JSCallbackData(callback, globalObject))
 {
 }
-    
-void JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
-{
-    ASSERT(m_callback);
-    ASSERT(m_globalObject);
-
-    ExecState* exec = m_globalObject->globalExec();
 
-    JSC::JSLock lock(SilenceAssertionsOnly);
+JSCustomSQLTransactionErrorCallback::~JSCustomSQLTransactionErrorCallback()
+{
+    callOnMainThread(JSCallbackData::deleteData, m_data);
+#ifndef NDEBUG
+    m_data = 0;
+#endif
+}
 
-    JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent"));
-    CallData callData;
-    CallType callType = function.getCallData(callData);
-    if (callType == CallTypeNone) {
-        callType = m_callback->getCallData(callData);
-        if (callType == CallTypeNone) {
-            // FIXME: Should an exception be thrown here?
-            return;
-        }
-        function = m_callback;
-    }
+void JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
+{
+    ASSERT(m_data);
 
     RefPtr<JSCustomSQLTransactionErrorCallback> protect(this);
 
+    JSC::JSLock lock(SilenceAssertionsOnly);
+    ExecState* exec = m_data->globalObject()->globalExec();
     MarkedArgumentBuffer args;
     args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), error));
-
-    m_globalObject->globalData()->timeoutChecker.start();
-    call(exec, function, callType, callData, m_callback, args);
-    m_globalObject->globalData()->timeoutChecker.stop();
-
-    if (exec->hadException())
-        reportCurrentException(exec);
-
-    Document::updateStyleForAllDocuments();
+    m_data->invokeCallback(args);
 }
 
 }
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h
index 42fcbce..54bf33b 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h
+++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.h
@@ -38,6 +38,7 @@
 
 namespace WebCore {
 
+class JSCallbackData;
 class SQLError;
 
 class JSCustomSQLTransactionErrorCallback : public SQLTransactionErrorCallback {
@@ -47,13 +48,14 @@ public:
         return adoptRef(new JSCustomSQLTransactionErrorCallback(callback, globalObject));
     }
     
+    virtual ~JSCustomSQLTransactionErrorCallback();
+    
     virtual void handleEvent(SQLError*);
 
 private:
     JSCustomSQLTransactionErrorCallback(JSC::JSObject* callback, JSDOMGlobalObject* globalObject);
 
-    JSC::ProtectedPtr<JSC::JSObject> m_callback;
-    JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
+    JSCallbackData* m_data;
 };
 
 }
diff --git a/WebCore/bindings/js/JSCustomVoidCallback.cpp b/WebCore/bindings/js/JSCustomVoidCallback.cpp
index 5300c42..0edd66f 100644
--- a/WebCore/bindings/js/JSCustomVoidCallback.cpp
+++ b/WebCore/bindings/js/JSCustomVoidCallback.cpp
@@ -30,53 +30,38 @@
 #include "JSCustomVoidCallback.h"
 
 #include "Frame.h"
+#include "JSCallbackData.h"
 #include "JSDOMWindowCustom.h"
 #include "ScriptController.h"
 #include <runtime/JSLock.h>
+#include <wtf/MainThread.h>
 
 namespace WebCore {
     
 using namespace JSC;
     
 JSCustomVoidCallback::JSCustomVoidCallback(JSObject* callback, JSDOMGlobalObject* globalObject)
-    : m_callback(callback)
-    , m_globalObject(globalObject)
+    : m_data(new JSCallbackData(callback, globalObject))
 {
 }
+
+JSCustomVoidCallback::~JSCustomVoidCallback()
+{
+    callOnMainThread(JSCallbackData::deleteData, m_data);
+#ifndef NDEBUG
+    m_data = 0;
+#endif
+}
     
 void JSCustomVoidCallback::handleEvent()
 {
-    ASSERT(m_callback);
-    ASSERT(m_globalObject);
+    ASSERT(m_data);
 
-    ExecState* exec = m_globalObject->globalExec();
-        
-    JSC::JSLock lock(SilenceAssertionsOnly);
-        
-    JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent"));
-    CallData callData;
-    CallType callType = function.getCallData(callData);
-    if (callType == CallTypeNone) {
-        callType = m_callback->getCallData(callData);
-        if (callType == CallTypeNone) {
-            // FIXME: Should an exception be thrown here?
-            return;
-        }
-        function = m_callback;
-    }
-        
     RefPtr<JSCustomVoidCallback> protect(this);
         
+    JSC::JSLock lock(SilenceAssertionsOnly);
     MarkedArgumentBuffer args;
-    
-    m_globalObject->globalData()->timeoutChecker.start();
-    call(exec, function, callType, callData, m_callback, args);
-    m_globalObject->globalData()->timeoutChecker.stop();
-
-    if (exec->hadException())
-        reportCurrentException(exec);
-        
-    Document::updateStyleForAllDocuments();
+    m_data->invokeCallback(args);
 }
 
 } // namespace WebCore
diff --git a/WebCore/bindings/js/JSCustomVoidCallback.h b/WebCore/bindings/js/JSCustomVoidCallback.h
index f3db49f..4b8d7ea 100644
--- a/WebCore/bindings/js/JSCustomVoidCallback.h
+++ b/WebCore/bindings/js/JSCustomVoidCallback.h
@@ -36,6 +36,8 @@
 
 namespace WebCore {
 
+class JSCallbackData;
+
 class JSCustomVoidCallback : public VoidCallback {
 public: 
     static PassRefPtr<JSCustomVoidCallback> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)
@@ -43,13 +45,14 @@ public:
         return adoptRef(new JSCustomVoidCallback(callback, globalObject));
     }
     
+    virtual ~JSCustomVoidCallback();
+    
     virtual void handleEvent();
     
 private:
     JSCustomVoidCallback(JSC::JSObject* callback, JSDOMGlobalObject*);
 
-    JSC::ProtectedPtr<JSC::JSObject> m_callback;
-    JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
+    JSCallbackData* m_data;
 };
 
 } // namespace WebCore
diff --git a/WebCore/storage/Database.cpp b/WebCore/storage/Database.cpp
index 9989bc0..08ea289 100644
--- a/WebCore/storage/Database.cpp
+++ b/WebCore/storage/Database.cpp
@@ -165,8 +165,6 @@ Database::Database(Document* document, const String& name, const String& expecte
 
 #if USE(JSC)
     JSC::initializeThreading();
-    // Database code violates the normal JSCore contract by calling jsUnprotect from a secondary thread, and thus needs additional locking.
-    JSDOMWindow::commonJSGlobalData()->heap.setGCProtectNeedsLocking();
 #endif
 
     m_guid = guidForOriginAndName(m_securityOrigin->toString(), name);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list