Bug 107978

Summary: Objective-C API: JSContext's dealloc causes ASSERT due to ordering of releases
Product: WebKit Reporter: Mark Hahnenberg <mhahnenberg>
Component: JavaScriptCoreAssignee: Mark Hahnenberg <mhahnenberg>
Status: RESOLVED FIXED    
Severity: Normal CC: barraclough, ggaren, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch fpizlo: review+

Description Mark Hahnenberg 2013-01-25 12:49:17 PST
JSGlobalContextRelease should be the last release of a JSContextGroupRef to make sure that Identifier table is that of the current virtual machine when that virtual machine is destroyed. In the current order, we save the Identifier table from the last JSGlobalData, load our table, deref the JSGlobalData (which is not destroyed because there's still a reference from the JSVirtualMachine object), then we restore the old Identifier table. When the JSVirtualMachine calls JSContextGroupRelease, the JSGlobalData will be destroyed with the incorrect Identifier table loaded in wtfThreadData().

We can either reorder these calls in JSContext's dealloc or make it so that JSContextGroupRelease also does the save/restore of the Identifier table like JSGlobalContextRelease.
Comment 1 Mark Hahnenberg 2013-01-29 14:56:06 PST
This is a bug in C API. We need to add the Identifier table save/restore in JSContextGroupRelease.
Comment 2 Radar WebKit Bug Importer 2013-01-30 14:22:11 PST
<rdar://problem/13118874>
Comment 3 Mark Hahnenberg 2013-01-30 14:35:37 PST
Created attachment 185578 [details]
Patch
Comment 4 Mark Hahnenberg 2013-01-30 14:48:24 PST
Committed r141321: <http://trac.webkit.org/changeset/141321>
Comment 5 Geoffrey Garen 2013-01-30 15:16:17 PST
+        JSLockHolder lock(globalData);

I don't think this is valid -- you'll end up unlocking the lock after you've deallocated the JSGlobalData. I think you can just eliminate the lock and rely on thread-safe refcounting.
Comment 6 Mark Hahnenberg 2013-01-30 18:59:05 PST
(In reply to comment #5)
> +        JSLockHolder lock(globalData);
> 
> I don't think this is valid -- you'll end up unlocking the lock after you've deallocated the JSGlobalData. I think you can just eliminate the lock and rely on thread-safe refcounting.

JSLockHolder refs the JSGlobalData when it locks it, so it will only be destroyed after the lock has released the JSGlobalData. I think you're right that we don't need the lock though. I was just trying to replicate what JSGlobalContextRelease does.
Comment 7 Geoffrey Garen 2013-01-30 21:08:34 PST
> JSLockHolder refs the JSGlobalData when it locks it, so it will only be destroyed after the lock has released the JSGlobalData.

Cool cool.