From fdaed851ce71fc474a7959d8fc30b50465a98d0d Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 23 Jul 2009 16:14:01 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to origin/qtwebkit-4.5 ( 1535d41a668e5f74f44ff3aa1313a84d5718d2d7 ) Changes in WebKit since the last update: ++ b/WebCore/ChangeLog 2009-07-23 Simon Hausmann Reviewed by Holger Freyther. Fix crashes with the QObject bindings after garbage collection. There is one QtInstance per wrapped QObject, and that QtInstance keeps references to cached JSObjects for slots. When those objects get deleted due to GC, then they becoming dangling pointers. When a cached member dies, it is now removed from the QtInstance's cache. As we cannot track the lifetime of the children, we have to remove them from QtInstance alltogether. They are not cached and were only used for mark(), but we _want_ them to be subject to gc. * bridge/qt/qt_instance.cpp: (JSC::Bindings::QtInstance::~QtInstance): Minor coding style cleanup, use qDeleteAll(). (JSC::Bindings::QtInstance::removeCachedMethod): New function, to clean m_methods and m_defaultMethod. (JSC::Bindings::QtInstance::mark): Avoid marking already marked objects. (JSC::Bindings::QtField::valueFromInstance): Don't save children for marking. * bridge/qt/qt_instance.h: Declare removeCachedMethod. * bridge/qt/qt_runtime.cpp: (JSC::Bindings::QtRuntimeMethod::~QtRuntimeMethod): Call removeCachedMethod with this on the instance. 2009-05-04 Jakub Wieczorek Reviewed by Simon Hausmann. As Qtish implementation of MIMETypeRegistry::getMIMETypeForExtension() returns the application/octet-stream mimetype when it can't associate extension with any mimetype, it can happen that the application/octet-stream mimetype will hit the list of supported image formats. For instance, it is possible when QImageReader or QImageWriter support an extension that is not in the extensions map. Make sure that this mimetype is not treated as displayable image type. * platform/MIMETypeRegistry.cpp: (WebCore::initializeSupportedImageMIMETypes): (WebCore::initializeSupportedImageMIMETypesForEncoding): ++ b/WebKit/qt/ChangeLog 2009-07-23 Simon Hausmann Reviewed by Holger Freyther. Added a testcase to verify that cached methods in the QOBject bindings remain alife even after garbage collection. * tests/qwebpage/tst_qwebpage.cpp: (tst_QWebPage::protectBindingsRuntimeObjectsFromCollector): --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 47 ++++++++++++++++++++++ .../webkit/WebCore/bridge/qt/qt_instance.cpp | 31 +++++++------- .../webkit/WebCore/bridge/qt/qt_instance.h | 3 +- .../webkit/WebCore/bridge/qt/qt_runtime.cpp | 2 + .../webkit/WebCore/platform/MIMETypeRegistry.cpp | 5 +++ src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp | 6 +++ src/3rdparty/webkit/WebKit/qt/ChangeLog | 10 +++++ .../WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 25 ++++++++++++ 9 files changed, 114 insertions(+), 17 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 88f32d9..eaa0479 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - a3e05ad8acdead3b534d0cef772b85f002e80b8d + 1535d41a668e5f74f44ff3aa1313a84d5718d2d7 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 19bb36a..83f5e6f 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,50 @@ +2009-07-23 Simon Hausmann + + Reviewed by Holger Freyther. + + Fix crashes with the QObject bindings after garbage collection. + + There is one QtInstance per wrapped QObject, and that QtInstance keeps + references to cached JSObjects for slots. When those objects get + deleted due to GC, then they becoming dangling pointers. + + When a cached member dies, it is now removed from the QtInstance's + cache. + + As we cannot track the lifetime of the children, we have to remove + them from QtInstance alltogether. They are not cached and were + only used for mark(), but we _want_ them to be subject to gc. + + * bridge/qt/qt_instance.cpp: + (JSC::Bindings::QtInstance::~QtInstance): Minor coding style cleanup, + use qDeleteAll(). + (JSC::Bindings::QtInstance::removeCachedMethod): New function, to + clean m_methods and m_defaultMethod. + (JSC::Bindings::QtInstance::mark): Avoid marking already marked objects. + (JSC::Bindings::QtField::valueFromInstance): Don't save children for + marking. + * bridge/qt/qt_instance.h: Declare removeCachedMethod. + * bridge/qt/qt_runtime.cpp: + (JSC::Bindings::QtRuntimeMethod::~QtRuntimeMethod): Call removeCachedMethod + with this on the instance. + +2009-05-04 Jakub Wieczorek + + Reviewed by Simon Hausmann. + + As Qtish implementation of MIMETypeRegistry::getMIMETypeForExtension() + returns the application/octet-stream mimetype when it can't associate + extension with any mimetype, it can happen that the application/octet-stream + mimetype will hit the list of supported image formats. For instance, + it is possible when QImageReader or QImageWriter support an extension + that is not in the extensions map. + + Make sure that this mimetype is not treated as displayable image type. + + * platform/MIMETypeRegistry.cpp: + (WebCore::initializeSupportedImageMIMETypes): + (WebCore::initializeSupportedImageMIMETypesForEncoding): + 2009-06-18 Chris Evans Reviewed by Adam Barth. diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp index 4b94a94..4fc95fa 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp @@ -110,9 +110,7 @@ QtInstance::~QtInstance() // clean up (unprotect from gc) the JSValues we've created m_methods.clear(); - foreach(QtField* f, m_fields.values()) { - delete f; - } + qDeleteAll(m_fields); m_fields.clear(); if (m_object) { @@ -158,6 +156,19 @@ RuntimeObjectImp* QtInstance::getRuntimeObject(ExecState* exec, PassRefPtr::Iterator it = m_methods.begin(), + end = m_methods.end(); it != end; ++it) + if (it.value() == method) { + m_methods.erase(it); + return; + } +} + Class* QtInstance::getClass() const { if (!m_class) @@ -167,16 +178,12 @@ Class* QtInstance::getClass() const void QtInstance::mark() { - if (m_defaultMethod) + if (m_defaultMethod && !m_defaultMethod->marked()) m_defaultMethod->mark(); foreach(JSObject* val, m_methods.values()) { if (val && !val->marked()) val->mark(); } - foreach(JSValuePtr val, m_children.values()) { - if (val && !val->marked()) - val->mark(); - } } void QtInstance::begin() @@ -329,13 +336,7 @@ JSValuePtr QtField::valueFromInstance(ExecState* exec, const Instance* inst) con else if (m_type == DynamicProperty) val = obj->property(m_dynamicProperty); - JSValuePtr ret = convertQVariantToValue(exec, inst->rootObject(), val); - - // Need to save children so we can mark them - if (m_type == ChildObject) - instance->m_children.insert(ret); - - return ret; + return convertQVariantToValue(exec, inst->rootObject(), val); } else { QString msg = QString(QLatin1String("cannot access member `%1' of deleted QObject")).arg(QLatin1String(name())); return throwError(exec, GeneralError, msg.toLatin1().constData()); diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h index 50d4cf1..bc22725 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h @@ -64,6 +64,8 @@ public: static PassRefPtr getQtInstance(QObject*, PassRefPtr, QScriptEngine::ValueOwnership ownership); static RuntimeObjectImp* getRuntimeObject(ExecState* exec, PassRefPtr); + void removeCachedMethod(JSObject*); + private: static PassRefPtr create(QObject *instance, PassRefPtr rootObject, QScriptEngine::ValueOwnership ownership) { @@ -78,7 +80,6 @@ private: QObject* m_hashkey; mutable QHash m_methods; mutable QHash m_fields; - mutable QSet m_children; mutable QtRuntimeMetaMethod* m_defaultMethod; QScriptEngine::ValueOwnership m_ownership; }; diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp index c7ba6c2..c0883a9 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp @@ -913,6 +913,8 @@ QtRuntimeMethod::QtRuntimeMethod(QtRuntimeMethodData* dd, ExecState* exec, const QtRuntimeMethod::~QtRuntimeMethod() { + QW_D(QtRuntimeMethod); + d->m_instance->removeCachedMethod(this); delete d_ptr; } diff --git a/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp b/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp index 8f98735..a85d706 100644 --- a/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp +++ b/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp @@ -100,6 +100,9 @@ static void initializeSupportedImageMIMETypes() supportedImageMIMETypes->add(mimeType); supportedImageResourceMIMETypes->add(mimeType); } + + supportedImageMIMETypes->remove("application/octet-stream"); + supportedImageResourceMIMETypes->remove("application/octet-stream"); #else // assume that all implementations at least support the following standard // image types: @@ -145,6 +148,8 @@ static void initializeSupportedImageMIMETypesForEncoding() String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData()); supportedImageMIMETypesForEncoding->add(mimeType); } + + supportedImageMIMETypesForEncoding->remove("application/octet-stream"); #elif PLATFORM(CAIRO) supportedImageMIMETypesForEncoding->add("image/png"); #endif diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp index e565476..bd43ce3 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp @@ -32,6 +32,7 @@ #include "Frame.h" #include "FrameTree.h" #include "FrameView.h" +#include "GCController.h" #include "IconDatabase.h" #include "InspectorController.h" #include "Page.h" @@ -105,6 +106,11 @@ void QWEBKIT_EXPORT qt_drt_setJavaScriptProfilingEnabled(QWebFrame* qframe, bool controller->disableProfiler(); } +void QWEBKIT_EXPORT qt_drt_garbageCollector_collect() +{ + gcController().garbageCollectNow(); +} + void QWebFramePrivate::init(QWebFrame *qframe, WebCore::Page *webcorePage, QWebFrameData *frameData) { q = qframe; diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index a7e176d..125e556 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,13 @@ +2009-07-23 Simon Hausmann + + Reviewed by Holger Freyther. + + Added a testcase to verify that cached methods in the QOBject bindings + remain alife even after garbage collection. + + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::protectBindingsRuntimeObjectsFromCollector): + 2009-06-16 Morten Engvoldsen Reviewed by Ariya Hidayat. diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 620aa31..c3ed54c 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -107,6 +107,7 @@ private slots: void textEditing(); void requestCache(); + void protectBindingsRuntimeObjectsFromCollector(); private: @@ -1037,5 +1038,29 @@ void tst_QWebPage::requestCache() (int)QNetworkRequest::PreferCache); } +void QWEBKIT_EXPORT qt_drt_garbageCollector_collect(); + +void tst_QWebPage::protectBindingsRuntimeObjectsFromCollector() +{ + QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool))); + + PluginPage* newPage = new PluginPage(m_view); + m_view->setPage(newPage); + + m_view->settings()->setAttribute(QWebSettings::PluginsEnabled, true); + + m_view->setHtml(QString("")); + QTRY_COMPARE(loadSpy.count(), 1); + + newPage->mainFrame()->evaluateJavaScript("function testme(text) { var lineedit = document.getElementById('mylineedit'); lineedit.setText(text); lineedit.selectAll(); }"); + + newPage->mainFrame()->evaluateJavaScript("testme('foo')"); + + qt_drt_garbageCollector_collect(); + + // don't crash! + newPage->mainFrame()->evaluateJavaScript("testme('bar')"); +} + QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" -- cgit v0.12