- Revision
- 125873
- Author
- [email protected]
- Date
- 2012-08-17 02:42:31 -0700 (Fri, 17 Aug 2012)
Log Message
[Qt] Replace use of internal Weak smart pointer with JSWeakObjectMap
https://bugs.webkit.org/show_bug.cgi?id=93872
Reviewed by Kenneth Rohde Christiansen.
Source/_javascript_Core:
* Target.pri: Add missing JSWeakObjectMap file to build.
Source/WebCore:
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 one JSWeakObjectMap per context group and store the
map in a separate context.
* bridge/qt/qt_instance.cpp:
(JSC::Bindings::unusedWeakObjectMapCallback):
(Bindings):
(JSC::Bindings::WeakMapImpl::WeakMapImpl):
(JSC::Bindings::WeakMapImpl::~WeakMapImpl):
(JSC::Bindings::WeakMap::~WeakMap):
(JSC::Bindings::WeakMap::set):
(JSC::Bindings::WeakMap::get):
(JSC::Bindings::WeakMap::remove):
* bridge/qt/qt_instance.h:
(WeakMapImpl):
(Bindings):
(WeakMap):
(QtInstance):
* bridge/qt/qt_runtime.cpp:
(JSC::Bindings::QtRuntimeMethod::~QtRuntimeMethod):
(JSC::Bindings::QtRuntimeMethod::jsObjectRef):
* bridge/qt/qt_runtime.h:
(QtRuntimeMethod):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (125872 => 125873)
--- trunk/Source/_javascript_Core/ChangeLog 2012-08-17 09:25:13 UTC (rev 125872)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-08-17 09:42:31 UTC (rev 125873)
@@ -1,3 +1,12 @@
+2012-08-16 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.
+
+ * Target.pri: Add missing JSWeakObjectMap file to build.
+
2012-08-16 Filip Pizlo <[email protected]>
Structure check hoisting should be less expensive
Modified: trunk/Source/_javascript_Core/Target.pri (125872 => 125873)
--- trunk/Source/_javascript_Core/Target.pri 2012-08-17 09:25:13 UTC (rev 125872)
+++ trunk/Source/_javascript_Core/Target.pri 2012-08-17 09:42:31 UTC (rev 125873)
@@ -40,6 +40,7 @@
API/JSObjectRef.cpp \
API/JSStringRef.cpp \
API/JSValueRef.cpp \
+ API/JSWeakObjectMapRefPrivate.cpp \
API/OpaqueJSString.cpp \
assembler/ARMAssembler.cpp \
assembler/ARMv7Assembler.cpp \
Modified: trunk/Source/WebCore/ChangeLog (125872 => 125873)
--- trunk/Source/WebCore/ChangeLog 2012-08-17 09:25:13 UTC (rev 125872)
+++ trunk/Source/WebCore/ChangeLog 2012-08-17 09:42:31 UTC (rev 125873)
@@ -1,3 +1,42 @@
+2012-08-16 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 one JSWeakObjectMap per context group and store the
+ map in a separate context.
+
+ * bridge/qt/qt_instance.cpp:
+ (JSC::Bindings::unusedWeakObjectMapCallback):
+ (Bindings):
+ (JSC::Bindings::WeakMapImpl::WeakMapImpl):
+ (JSC::Bindings::WeakMapImpl::~WeakMapImpl):
+ (JSC::Bindings::WeakMap::~WeakMap):
+ (JSC::Bindings::WeakMap::set):
+ (JSC::Bindings::WeakMap::get):
+ (JSC::Bindings::WeakMap::remove):
+ * bridge/qt/qt_instance.h:
+ (WeakMapImpl):
+ (Bindings):
+ (WeakMap):
+ (QtInstance):
+ * bridge/qt/qt_runtime.cpp:
+ (JSC::Bindings::QtRuntimeMethod::~QtRuntimeMethod):
+ (JSC::Bindings::QtRuntimeMethod::jsObjectRef):
+ * bridge/qt/qt_runtime.h:
+ (QtRuntimeMethod):
+
+
2012-08-16 Pavel Feldman <[email protected]>
Web Inspector: build Elements, Resources, Timeline, Audits and Console panels lazily.
Modified: trunk/Source/WebCore/bridge/qt/qt_instance.cpp (125872 => 125873)
--- trunk/Source/WebCore/bridge/qt/qt_instance.cpp 2012-08-17 09:25:13 UTC (rev 125872)
+++ trunk/Source/WebCore/bridge/qt/qt_instance.cpp 2012-08-17 09:42:31 UTC (rev 125873)
@@ -40,6 +40,63 @@
namespace JSC {
namespace Bindings {
+static void unusedWeakObjectMapCallback(JSWeakObjectMapRef, void*)
+{
+}
+
+WeakMapImpl::WeakMapImpl(JSContextGroupRef group)
+{
+ m_context = JSGlobalContextCreateInGroup(group, 0);
+ // Deleted by GC when m_context's globalObject gets collected.
+ m_map = JSWeakObjectMapCreate(m_context, 0, unusedWeakObjectMapCallback);
+}
+
+WeakMapImpl::~WeakMapImpl()
+{
+ JSGlobalContextRelease(m_context);
+ m_context = 0;
+ m_map = 0;
+}
+
+typedef HashMap<JSContextGroupRef, RefPtr<WeakMapImpl> > WeakMapSet;
+static WeakMapSet weakMaps;
+
+WeakMap::~WeakMap()
+{
+ // If this is the last WeakMap instance left, then we should remove
+ // the cached WeakMapImpl from the global weakMaps, too.
+ if (m_impl && m_impl->refCount() == 2) {
+ weakMaps.remove(JSContextGetGroup(m_impl->m_context));
+ ASSERT(m_impl->hasOneRef());
+ }
+}
+
+void WeakMap::set(JSContextRef context, void *key, JSObjectRef object)
+{
+ if (!m_impl) {
+ JSContextGroupRef group = JSContextGetGroup(context);
+ WeakMapSet::AddResult entry = weakMaps.add(group, 0);
+ if (entry.isNewEntry)
+ entry.iterator->second = new WeakMapImpl(group);
+ m_impl = entry.iterator->second;
+ }
+ JSWeakObjectMapSet(m_impl->m_context, m_impl->m_map, key, object);
+}
+
+JSObjectRef WeakMap::get(void* key)
+{
+ if (!m_impl)
+ return 0;
+ return JSWeakObjectMapGet(m_impl->m_context, m_impl->m_map, key);
+}
+
+void WeakMap::remove(void *key)
+{
+ if (!m_impl)
+ return;
+ JSWeakObjectMapRemove(m_impl->m_context, m_impl->m_map, key);
+}
+
// Cache QtInstances
typedef QMultiHash<void*, QtInstance*> QObjectInstanceMap;
static QObjectInstanceMap cachedInstances;
Modified: trunk/Source/WebCore/bridge/qt/qt_instance.h (125872 => 125873)
--- trunk/Source/WebCore/bridge/qt/qt_instance.h 2012-08-17 09:25:13 UTC (rev 125872)
+++ trunk/Source/WebCore/bridge/qt/qt_instance.h 2012-08-17 09:42:31 UTC (rev 125873)
@@ -21,6 +21,7 @@
#define qt_instance_h
#include "BridgeJSC.h"
+#include "JSWeakObjectMapRefPrivate.h"
#include <QPointer>
#include "Weak.h"
#include "runtime_root.h"
@@ -35,6 +36,27 @@
class QtField;
class QtRuntimeMethod;
+class WeakMapImpl : public RefCounted<WeakMapImpl> {
+public:
+ WeakMapImpl(JSContextGroupRef);
+ ~WeakMapImpl();
+
+ JSGlobalContextRef m_context;
+ JSWeakObjectMapRef m_map;
+};
+
+class WeakMap {
+public:
+ ~WeakMap();
+
+ void set(JSContextRef, void* key, JSObjectRef);
+ JSObjectRef get(void* key);
+ void remove(void* key);
+
+private:
+ RefPtr<WeakMapImpl> m_impl;
+};
+
class QtInstance : public Instance {
public:
enum ValueOwnership {
@@ -81,11 +103,13 @@
friend class QtClass;
friend class QtField;
+ friend class QtRuntimeMethod;
QtInstance(QObject*, PassRefPtr<RootObject>, ValueOwnership); // Factory produced only..
mutable QtClass* m_class;
QPointer<QObject> m_object;
QObject* m_hashkey;
mutable QHash<QByteArray, QtRuntimeMethod*> m_methods;
+ WeakMap m_cachedMethods;
mutable QHash<QString, QtField*> m_fields;
ValueOwnership m_ownership;
};
Modified: trunk/Source/WebCore/bridge/qt/qt_runtime.cpp (125872 => 125873)
--- trunk/Source/WebCore/bridge/qt/qt_runtime.cpp 2012-08-17 09:25:13 UTC (rev 125872)
+++ trunk/Source/WebCore/bridge/qt/qt_runtime.cpp 2012-08-17 09:42:31 UTC (rev 125873)
@@ -1301,8 +1301,9 @@
QtRuntimeMethod::~QtRuntimeMethod()
{
- if (m_jsObject)
- JSObjectSetPrivate(toRef(m_jsObject.get()), 0);
+ if (JSObjectRef cachedWrapper = m_instance->m_cachedMethods.get(this))
+ JSObjectSetPrivate(cachedWrapper, 0);
+ m_instance->m_cachedMethods.remove(this);
}
JSValueRef QtRuntimeMethod::call(JSContextRef context, JSObjectRef function, JSObjectRef /*thisObject*/, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -1350,8 +1351,8 @@
JSObjectRef QtRuntimeMethod::jsObjectRef(JSContextRef context, JSValueRef* exception)
{
- if (m_jsObject)
- return toRef(m_jsObject.get());
+ if (JSObjectRef cachedWrapper = m_instance->m_cachedMethods.get(this))
+ return cachedWrapper;
static const JSClassDefinition classDefForConnect = {
0, 0, "connect", 0, 0, 0,
@@ -1387,7 +1388,8 @@
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));
+ m_instance->m_cachedMethods.set(context, this, object);
+
return object;
}
Modified: trunk/Source/WebCore/bridge/qt/qt_runtime.h (125872 => 125873)
--- trunk/Source/WebCore/bridge/qt/qt_runtime.h 2012-08-17 09:25:13 UTC (rev 125872)
+++ trunk/Source/WebCore/bridge/qt/qt_runtime.h 2012-08-17 09:42:31 UTC (rev 125873)
@@ -122,7 +122,6 @@
QByteArray m_identifier;
int m_index;
int m_flags;
- Weak<JSObject> m_jsObject;
QtInstance* m_instance;
};