RESOLVED FIXED 101989
JSC: JSEventListener's m_jsFunction should be a weak ref
https://bugs.webkit.org/show_bug.cgi?id=101989
Summary JSC: JSEventListener's m_jsFunction should be a weak ref
Mark Lam
Reported 2012-11-12 14:19:41 PST
The GC can collect the JSFunction object without JSEventListener's knowledge. Hence, JSEventListener's m_jsFunction ref should be a weak ref to reflect this.
Attachments
1st draft. (8.99 KB, patch)
2012-11-12 17:49 PST, Mark Lam
webkit-ews: commit-queue-
2nd draft: added missing file from last patch. (10.76 KB, patch)
2012-11-12 18:03 PST, Mark Lam
webkit-ews: commit-queue-
3rd time's the charm. (11.29 KB, patch)
2012-11-12 19:57 PST, Mark Lam
ggaren: review-
Fix. (9.98 KB, patch)
2012-11-13 20:51 PST, Mark Lam
ggaren: review+
Mark Lam
Comment 1 2012-11-12 17:49:36 PST
Created attachment 173774 [details] 1st draft.
Early Warning System Bot
Comment 2 2012-11-12 17:56:24 PST
Mark Lam
Comment 3 2012-11-12 18:03:07 PST
Created attachment 173777 [details] 2nd draft: added missing file from last patch.
Early Warning System Bot
Comment 4 2012-11-12 18:11:16 PST
Comment on attachment 173777 [details] 2nd draft: added missing file from last patch. Attachment 173777 [details] did not pass qt-ews (qt): Output: http://queues.webkit.org/results/14810702
Early Warning System Bot
Comment 5 2012-11-12 18:11:58 PST
Comment on attachment 173777 [details] 2nd draft: added missing file from last patch. Attachment 173777 [details] did not pass qt-wk2-ews (qt): Output: http://queues.webkit.org/results/14809661
Mark Lam
Comment 6 2012-11-12 18:31:02 PST
Comment on attachment 173777 [details] 2nd draft: added missing file from last patch. Something is fishy. Why is it not building? Will investigate.
Mark Lam
Comment 7 2012-11-12 19:57:56 PST
Created attachment 173801 [details] 3rd time's the charm.
Geoffrey Garen
Comment 8 2012-11-12 20:27:17 PST
Comment on attachment 173801 [details] 3rd time's the charm. View in context: https://bugs.webkit.org/attachment.cgi?id=173801&action=review You mentioned that you saw problems on websites with an earlier version of this patch. Does this patch fix those problems? > Source/JavaScriptCore/heap/SlotVisitor.h:61 > + void appendUnbarrieredWeakRef(Weak<T>*); We don't usually use the abbreviation "Ref" outside of CoreFoundation classes. How about just calling this "appendUnbarrieredWeak" or "appendUnbarriered"? > Source/JavaScriptCore/heap/SlotVisitorInlines.h:73 > + if (weakRef && *weakRef) I don't think weakRef can ever be NULL here. Instead of the *weakRef test, I think you either need a call to .get() or a call to operator!(). It's an error to use operator*() after a weak pointer has been collected. > Source/JavaScriptCore/heap/Weak.h:160 > +template<typename T> inline JSValue Weak<T>::referee() > +{ > + return m_impl ? m_impl->jsValue() : JSValue(); > +} Why do we need this function, when we already have operator*() and .get()? > Source/WebCore/bindings/js/JSEventListener.cpp:69 > + // JSEventListener may outlive its m_jsFunction. In this case, we will > + // m_jsFunction to be 0. "we will": seems like you meant something else here. There's a lot of commentary about m_jsFunction here, but this function doesn't use that data member. Does any of this explain why the base class implementation of initializeJSFunction() should return 0?
Mark Lam
Comment 9 2012-11-12 20:46:00 PST
(In reply to comment #8) > (From update of attachment 173801 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=173801&action=review > > You mentioned that you saw problems on websites with an earlier version of this patch. Does this patch fix those problems? Unfortunately not. Just presenting it to let you have a look in case I made some major mistake. > > Source/JavaScriptCore/heap/SlotVisitor.h:61 > > + void appendUnbarrieredWeakRef(Weak<T>*); > > We don't usually use the abbreviation "Ref" outside of CoreFoundation classes. How about just calling this "appendUnbarrieredWeak" or "appendUnbarriered"? OK, will change to "appendUnbarrieredWeak" to be consistent (plus it's easier to grep for when we don't use overloaded names). There are already 2 other pre-existing "appendUnbarrieredX" functions. > > Source/JavaScriptCore/heap/SlotVisitorInlines.h:73 > > + if (weakRef && *weakRef) > > I don't think weakRef can ever be NULL here. > > Instead of the *weakRef test, I think you either need a call to .get() or a call to operator!(). It's an error to use operator*() after a weak pointer has been collected. Thanks. Will fix and change to .get(). > > Source/JavaScriptCore/heap/Weak.h:160 > > +template<typename T> inline JSValue Weak<T>::referee() > > +{ > > + return m_impl ? m_impl->jsValue() : JSValue(); > > +} > > Why do we need this function, when we already have operator*() and .get()? It's a remnant from when I was still trying to understand this code. I should be able to change it to use .get() and remove this. > > Source/WebCore/bindings/js/JSEventListener.cpp:69 > > + // JSEventListener may outlive its m_jsFunction. In this case, we will > > + // m_jsFunction to be 0. > > "we will": seems like you meant something else here. > > There's a lot of commentary about m_jsFunction here, but this function doesn't use that data member. Does any of this explain why the base class implementation of initializeJSFunction() should return 0? There used to be an assertion here that was invalidated by the change to use weak refs. This comment was meant to explain the circumstances behind why the assertion should not be there, but appears to be incomplete (my thought was probably interrupted in mid edit). After making the change to check if m_wrapper is 0 at the top of JSEventListener::jsFunction(), the change is no longer necessary and can be reverted. Thanks.
Mark Lam
Comment 10 2012-11-13 20:51:22 PST
Created attachment 174061 [details] Fix. All the issues that Geoff pointed out has been addressed. The website rendering issue turned out to be because the Weak implementation did not have an operation==() implementation. As a result, when we changed m_jsFunction to be a Weak ref, JSEventListener::operator==() (which was comparing m_jsFunctions) was getting the wrong result. This is now fixed by providing an implementation of operator==(const Weak<T>&, const Weak<T>&).
Geoffrey Garen
Comment 11 2012-11-14 13:07:22 PST
Comment on attachment 174061 [details] Fix. r=me
Mark Lam
Comment 12 2012-11-14 17:03:59 PST
Note You need to log in before you can comment on or make changes to this bug.