Bug 112856 - Objective-C API: wrapperClass holds a static JSClassRef, which causes JSGlobalObjects to leak
Summary: Objective-C API: wrapperClass holds a static JSClassRef, which causes JSGloba...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Mark Hahnenberg
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-03-20 16:31 PDT by Mark Hahnenberg
Modified: 2013-03-21 12:08 PDT (History)
6 users (show)

See Also:


Attachments
Patch (9.83 KB, patch)
2013-03-20 21:29 PDT, Mark Hahnenberg
no flags Details | Formatted Diff | Diff
Patch (17.00 KB, patch)
2013-03-20 21:42 PDT, Mark Hahnenberg
no flags Details | Formatted Diff | Diff
Patch (32.33 KB, patch)
2013-03-21 08:30 PDT, Mark Hahnenberg
no flags Details | Formatted Diff | Diff
Patch (32.80 KB, patch)
2013-03-21 08:54 PDT, Mark Hahnenberg
ggaren: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Hahnenberg 2013-03-20 16:31:33 PDT
Through a very convoluted path that involves the caching of prototypes on the JSClassRef, we can leak JSGlobalObjects when inserting an Objective-C object into multiple independent JSContexts.

The solution is simply to divorce JSWrapperMap and JSObjCClassInfo from the C API and use JSAPIWrapperObjects directly (without going through JSCallbackObject).
Comment 1 Mark Hahnenberg 2013-03-20 21:29:48 PDT
Created attachment 194180 [details]
Patch
Comment 2 Early Warning System Bot 2013-03-20 21:35:00 PDT
Comment on attachment 194180 [details]
Patch

Attachment 194180 [details] did not pass qt-ews (qt):
Output: http://webkit-commit-queue.appspot.com/results/17211574
Comment 3 Early Warning System Bot 2013-03-20 21:37:35 PDT
Comment on attachment 194180 [details]
Patch

Attachment 194180 [details] did not pass qt-wk2-ews (qt):
Output: http://webkit-commit-queue.appspot.com/results/17213776
Comment 4 Mark Hahnenberg 2013-03-20 21:42:58 PDT
Created attachment 194182 [details]
Patch
Comment 5 Mark Hahnenberg 2013-03-20 22:03:01 PDT
<rdar://problem/13467942>
Comment 6 Geoffrey Garen 2013-03-20 23:27:55 PDT
Comment on attachment 194182 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=194182&action=review

> Source/JavaScriptCore/API/JSAPIWrapperObject.cpp:55
> +    CFRelease(wrapperObject->wrappedObject());

CFRelease is not always the same as -[NSObject release], so this is a no-no.

Let's compile this file as Objective-C++ and call -release.

> Source/JavaScriptCore/API/JSWrapperMap.mm:360
> +            constructor = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sConstructor", className], [m_class retain]);

Why are we calling -retain here? You should only call -retain when storing a reference into a data member.
Comment 7 Mark Hahnenberg 2013-03-21 07:17:53 PDT
Comment on attachment 194182 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=194182&action=review

>> Source/JavaScriptCore/API/JSAPIWrapperObject.cpp:55
>> +    CFRelease(wrapperObject->wrappedObject());
> 
> CFRelease is not always the same as -[NSObject release], so this is a no-no.
> 
> Let's compile this file as Objective-C++ and call -release.

Okiedokie.

>> Source/JavaScriptCore/API/JSWrapperMap.mm:360
>> +            constructor = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sConstructor", className], [m_class retain]);
> 
> Why are we calling -retain here? You should only call -retain when storing a reference into a data member.

That was in the original code. I think we call retain there because we use it as our "wrapped object" in the JSAPIWrapperObject and which is later released during finalization. I guess I could refactor the code so that JSAPIWrapperObject does the retain when storing its wrappedObject data member.
Comment 8 Mark Hahnenberg 2013-03-21 08:30:24 PDT
Created attachment 194266 [details]
Patch
Comment 9 Early Warning System Bot 2013-03-21 08:41:00 PDT
Comment on attachment 194266 [details]
Patch

Attachment 194266 [details] did not pass qt-ews (qt):
Output: http://webkit-commit-queue.appspot.com/results/17197714
Comment 10 Early Warning System Bot 2013-03-21 08:43:44 PDT
Comment on attachment 194266 [details]
Patch

Attachment 194266 [details] did not pass qt-wk2-ews (qt):
Output: http://webkit-commit-queue.appspot.com/results/17225485
Comment 11 Mark Hahnenberg 2013-03-21 08:54:51 PDT
Created attachment 194273 [details]
Patch
Comment 12 Geoffrey Garen 2013-03-21 12:05:47 PDT
Comment on attachment 194273 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=194273&action=review

r=me

> Source/JavaScriptCore/API/JSAPIWrapperObject.mm:85
> +    m_wrappedObject = [static_cast<id>(wrappedObject) retain];

Let's make m_wrappedObject a RetainPtr. This can be a follow-up patch.
Comment 13 Mark Hahnenberg 2013-03-21 12:08:29 PDT
Committed r146494: <http://trac.webkit.org/changeset/146494>