Modified: trunk/Source/WebCore/ChangeLog (125443 => 125444)
--- trunk/Source/WebCore/ChangeLog 2012-08-13 20:38:06 UTC (rev 125443)
+++ trunk/Source/WebCore/ChangeLog 2012-08-13 20:44:33 UTC (rev 125444)
@@ -1,3 +1,31 @@
+2012-08-13 Simon Hausmann <[email protected]>
+
+ [Qt] Replace use of internal Weak smart pointer with JSWeakObjectMap
+ https://bugs.webkit.org/show_bug.cgi?id=93872
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ The intention of this patch series is to replace use of internal JSC
+ API with use of the stable and public C API.
+
+ The JSC::Weak template is internal API and the only part of the C API
+ that exposes similar functionality is the JSWeakObjectMap. It is
+ special in the sense that its life-time is tied to the life-time of the
+ JS global object, which in turn is subject to garbage collection. In
+ order to maximize re-use of the same map across different JSContextRef
+ instances, we use the associated global context ref as owner of the
+ weak maps. The key in the weak map is the identity (pointer) of the
+ runtime method object itself. The iteration through the maps is
+ tedious, but should usually not go beyond just a few.
+
+ * bridge/qt/qt_runtime.cpp:
+ (Bindings):
+ (JSC::Bindings::methodMapCleaner):
+ (JSC::Bindings::QtRuntimeMethod::~QtRuntimeMethod):
+ (JSC::Bindings::QtRuntimeMethod::jsObjectRef):
+ * bridge/qt/qt_runtime.h:
+ (QtRuntimeMethod):
+
2012-08-13 Raphael Kubo da Costa <[email protected]>
[CMake] Remove glib-related Find modules and write single new one instead.
Modified: trunk/Source/WebCore/bridge/qt/qt_runtime.cpp (125443 => 125444)
--- trunk/Source/WebCore/bridge/qt/qt_runtime.cpp 2012-08-13 20:38:06 UTC (rev 125443)
+++ trunk/Source/WebCore/bridge/qt/qt_runtime.cpp 2012-08-13 20:44:33 UTC (rev 125444)
@@ -38,6 +38,7 @@
#include "JSObject.h"
#include "JSRetainPtr.h"
#include "JSUint8ClampedArray.h"
+#include "JSWeakObjectMapRefPrivate.h"
#include "ObjectPrototype.h"
#include "PropertyNameArray.h"
#include "qdatetime.h"
@@ -1290,6 +1291,15 @@
return cls;
}
+typedef HashMap<JSGlobalContextRef, JSWeakObjectMapRef> WeakRuntimeMethodMap;
+static WeakRuntimeMethodMap weakRuntimeMethodCache;
+
+static void methodMapCleaner(JSWeakObjectMapRef, void* data)
+{
+ JSGlobalContextRef ref = static_cast<JSGlobalContextRef>(data);
+ weakRuntimeMethodCache.remove(ref);
+}
+
QtRuntimeMethod::QtRuntimeMethod(JSContextRef ctx, QObject* object, const QByteArray& identifier, int index, int flags, QtInstance* instance)
: m_object(object)
, m_identifier(identifier)
@@ -1301,8 +1311,13 @@
QtRuntimeMethod::~QtRuntimeMethod()
{
- if (m_jsObject)
- JSObjectSetPrivate(toRef(m_jsObject.get()), 0);
+ for (WeakRuntimeMethodMap::const_iterator it = weakRuntimeMethodCache.begin(), end = weakRuntimeMethodCache.end();
+ it != end; ++it) {
+ if (JSObjectRef obj = JSWeakObjectMapGet(it->first, it->second, this)) {
+ JSObjectSetPrivate(obj, 0);
+ JSWeakObjectMapRemove(it->first, it->second, this);
+ }
+ }
}
JSValueRef QtRuntimeMethod::call(JSContextRef context, JSObjectRef function, JSObjectRef /*thisObject*/, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -1350,8 +1365,12 @@
JSObjectRef QtRuntimeMethod::jsObjectRef(JSContextRef context, JSValueRef* exception)
{
- if (m_jsObject)
- return toRef(m_jsObject.get());
+ JSGlobalContextRef globalContext = JSContextGetGlobalContext(context);
+ WeakRuntimeMethodMap::iterator cache = weakRuntimeMethodCache.find(globalContext);
+ if (cache != weakRuntimeMethodCache.end()) {
+ if (JSObjectRef cachedMethod = JSWeakObjectMapGet(cache->first, cache->second, this))
+ return cachedMethod;
+ }
static const JSClassDefinition classDefForConnect = {
0, 0, "connect", 0, 0, 0,
@@ -1387,7 +1406,14 @@
JSObjectSetProperty(context, object, lengthStr, JSValueMakeNumber(context, 0), attributes, exception);
JSObjectSetProperty(context, object, nameStr, JSValueMakeString(context, actualNameStr.get()), attributes, exception);
- m_jsObject = PassWeak<JSObject>(toJS(object));
+ JSWeakObjectMapRef map;
+ if (cache == weakRuntimeMethodCache.end()) {
+ map = JSWeakObjectMapCreate(globalContext, globalContext, methodMapCleaner);
+ weakRuntimeMethodCache.add(globalContext, map);
+ } else
+ map = cache->second;
+ JSWeakObjectMapSet(globalContext, map, this, object);
+
return object;
}