Title: [163574] trunk/Source/_javascript_Core
Revision
163574
Author
[email protected]
Date
2014-02-06 16:29:57 -0800 (Thu, 06 Feb 2014)

Log Message

JSManagedValue should automatically call removeManagedReference:withOwner: upon dealloc
https://bugs.webkit.org/show_bug.cgi?id=124053

Reviewed by Geoffrey Garen.

* API/JSManagedValue.h:
* API/JSManagedValue.mm:
(+[JSManagedValue managedValueWithValue:andOwner:]):
(-[JSManagedValue initWithValue:]):
(-[JSManagedValue dealloc]):
(-[JSManagedValue didAddOwner:]):
(-[JSManagedValue didRemoveOwner:]):
* API/JSManagedValueInternal.h: Added.
* API/JSVirtualMachine.mm:
(-[JSVirtualMachine addManagedReference:withOwner:]):
(-[JSVirtualMachine removeManagedReference:withOwner:]):
* API/WebKitAvailability.h:
* API/tests/testapi.mm:
(-[TextXYZ click]):
* _javascript_Core.xcodeproj/project.pbxproj:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/API/JSManagedValue.h (163573 => 163574)


--- trunk/Source/_javascript_Core/API/JSManagedValue.h	2014-02-07 00:29:03 UTC (rev 163573)
+++ trunk/Source/_javascript_Core/API/JSManagedValue.h	2014-02-07 00:29:57 UTC (rev 163574)
@@ -27,6 +27,7 @@
 #define JSManagedValue_h
 
 #import <_javascript_Core/JSBase.h>
+#import <_javascript_Core/WebKitAvailability.h>
 
 #if JSC_OBJC_API_ENABLED
 
@@ -63,6 +64,18 @@
 @result The new JSManagedValue.
 */
 + (JSManagedValue *)managedValueWithValue:(JSValue *)value;
+// FIXME: There's a bug in earlier versions of clang that shipped on 10.8 that causes the NS_AVAILABLE macro
+// to be ignored by the preprocessor when it follows a class method. The compiler then tries to treat the 
+// macro as part of the selector.
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
++ (JSManagedValue *)managedValueWithValue:(JSValue *)value andOwner:(id)owner NS_AVAILABLE(10_10, 8_0);
+#else
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
++ (JSManagedValue *)managedValueWithValue:(JSValue *)value andOwner:(id)owner __attribute__((availability(macosx,__NSi_10_10)));
+#else
++ (JSManagedValue *)managedValueWithValue:(JSValue *)value andOwner:(id)owner __attribute__((availability(ios,__NSi_8_0)));
+#endif
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
 
 /*!
 @method

Modified: trunk/Source/_javascript_Core/API/JSManagedValue.mm (163573 => 163574)


--- trunk/Source/_javascript_Core/API/JSManagedValue.mm	2014-02-07 00:29:03 UTC (rev 163573)
+++ trunk/Source/_javascript_Core/API/JSManagedValue.mm	2014-02-07 00:29:57 UTC (rev 163574)
@@ -169,6 +169,7 @@
 @implementation JSManagedValue {
     JSC::Weak<JSC::JSGlobalObject> m_globalObject;
     WeakValueRef m_weakValue;
+    NSMapTable *m_owners;
 }
 
 + (JSManagedValue *)managedValueWithValue:(JSValue *)value
@@ -176,6 +177,13 @@
     return [[[self alloc] initWithValue:value] autorelease];
 }
 
++ (JSManagedValue *)managedValueWithValue:(JSValue *)value andOwner:(id)owner
+{
+    JSManagedValue *managedValue = [[self alloc] initWithValue:value];
+    [value.context.virtualMachine addManagedReference:managedValue withOwner:owner];
+    return [managedValue autorelease];
+}
+
 - (instancetype)init
 {
     return [self initWithValue:nil];
@@ -195,6 +203,10 @@
     JSC::Weak<JSC::JSGlobalObject> weak(globalObject, managedValueHandleOwner(), self);
     m_globalObject.swap(weak);
 
+    NSPointerFunctionsOptions weakIDOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
+    NSPointerFunctionsOptions integerOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsIntegerPersonality;
+    m_owners = [[NSMapTable alloc] initWithKeyOptions:weakIDOptions valueOptions:integerOptions capacity:1];
+
     JSC::JSValue jsValue = toJS(exec, [value JSValueRef]);
     if (jsValue.isObject())
         m_weakValue.setObject(JSC::jsCast<JSC::JSObject*>(jsValue.asCell()), self);
@@ -205,6 +217,43 @@
     return self;
 }
 
+- (void)dealloc
+{
+    JSVirtualMachine *virtualMachine = [[[self value] context] virtualMachine];
+    if (virtualMachine) {
+        for (id owner in [m_owners keyEnumerator]) {
+            size_t count = reinterpret_cast<size_t>(NSMapGet(m_owners, owner));
+            while (count--)
+                [virtualMachine removeManagedReference:self withOwner:owner];
+        }
+    }
+
+    [self disconnectValue];
+    [m_owners release];
+    [super dealloc];
+}
+
+- (void)didAddOwner:(id)owner
+{
+    size_t count = reinterpret_cast<size_t>(NSMapGet(m_owners, owner));
+    NSMapInsert(m_owners, owner, reinterpret_cast<void*>(count + 1));
+}
+
+- (void)didRemoveOwner:(id)owner
+{
+    size_t count = reinterpret_cast<size_t>(NSMapGet(m_owners, owner));
+
+    if (!count)
+        return;
+
+    if (count == 1) {
+        NSMapRemove(m_owners, owner);
+        return;
+    }
+
+    NSMapInsert(m_owners, owner, reinterpret_cast<void*>(count - 1));
+}
+
 - (JSValue *)value
 {
     if (!m_globalObject)

Added: trunk/Source/_javascript_Core/API/JSManagedValueInternal.h (0 => 163574)


--- trunk/Source/_javascript_Core/API/JSManagedValueInternal.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/API/JSManagedValueInternal.h	2014-02-07 00:29:57 UTC (rev 163574)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSManagedValueInternal_h
+#define JSManagedValueInternal_h
+
+#import <_javascript_Core/JSBase.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@interface JSManagedValue(Internal)
+
+- (void)didAddOwner:(id)owner;
+- (void)didRemoveOwner:(id)owner;
+
+@end
+
+#endif // JSC_OBJC_API_ENABLED
+
+#endif // JSManagedValueInternal_h

Modified: trunk/Source/_javascript_Core/API/JSVirtualMachine.mm (163573 => 163574)


--- trunk/Source/_javascript_Core/API/JSVirtualMachine.mm	2014-02-07 00:29:03 UTC (rev 163573)
+++ trunk/Source/_javascript_Core/API/JSVirtualMachine.mm	2014-02-07 00:29:57 UTC (rev 163574)
@@ -31,6 +31,7 @@
 
 #import "APICast.h"
 #import "APIShims.h"
+#import "JSManagedValueInternal.h"
 #import "JSVirtualMachine.h"
 #import "JSVirtualMachineInternal.h"
 #import "JSWrapperMap.h"
@@ -161,7 +162,12 @@
         [m_externalObjectGraph setObject:ownedObjects forKey:owner];
         [ownedObjects release];
     }
-    NSMapInsert(ownedObjects, object, reinterpret_cast<void*>(reinterpret_cast<size_t>(NSMapGet(ownedObjects, object)) + 1));
+
+    if ([object isKindOfClass:[JSManagedValue class]])
+        [object didAddOwner:owner];
+        
+    size_t count = reinterpret_cast<size_t>(NSMapGet(ownedObjects, object));
+    NSMapInsert(ownedObjects, object, reinterpret_cast<void*>(count + 1));
 }
 
 - (void)removeManagedReference:(id)object withOwner:(id)owner
@@ -187,6 +193,9 @@
     if (count == 1)
         NSMapRemove(ownedObjects, object);
 
+    if ([object isKindOfClass:[JSManagedValue class]])
+        [object didRemoveOwner:owner];
+
     if (![ownedObjects count])
         [m_externalObjectGraph removeObjectForKey:owner];
 }

Modified: trunk/Source/_javascript_Core/API/WebKitAvailability.h (163573 => 163574)


--- trunk/Source/_javascript_Core/API/WebKitAvailability.h	2014-02-07 00:29:03 UTC (rev 163573)
+++ trunk/Source/_javascript_Core/API/WebKitAvailability.h	2014-02-07 00:29:57 UTC (rev 163574)
@@ -27,10 +27,30 @@
 #define __WebKitAvailability__
 
 #ifdef __APPLE__
+
 #include <AvailabilityMacros.h>
 #include <CoreFoundation/CoreFoundation.h>
-#else
+
+#if !defined(NS_AVAILABLE)
+#define NS_AVAILABLE(_mac, _ios)
+#endif // !defined(NS_AVAILABLE)
+#if !defined(CF_AVAILABLE)
 #define CF_AVAILABLE(_mac, _ios)
+#endif // !defined(CF_AVAILABLE)
+
+#else // __APPLE__
+
+#define CF_AVAILABLE(_mac, _ios)
+#define NS_AVAILABLE(_mac, _ios)
+
+#endif // __APPLE__
+
+#if !defined(__NSi_10_10)
+#define __NSi_10_10 introduced=10.10
 #endif
 
+#if !defined(__NSi_8_0)
+#define __NSi_8_0 introduced=8.0
+#endif
+
 #endif /* __WebKitAvailability__ */

Modified: trunk/Source/_javascript_Core/API/tests/testapi.mm (163573 => 163574)


--- trunk/Source/_javascript_Core/API/tests/testapi.mm	2014-02-07 00:29:03 UTC (rev 163573)
+++ trunk/Source/_javascript_Core/API/tests/testapi.mm	2014-02-07 00:29:57 UTC (rev 163574)
@@ -172,13 +172,6 @@
     JSValue *function = [m_onclickHandler value];
     [function callWithArguments:[NSArray array]];
 }
-- (void)dealloc
-{
-    [[m_onclickHandler value].context.virtualMachine removeManagedReference:m_onclickHandler withOwner:self];
-#if !__has_feature(objc_arc)
-    [super dealloc];
-#endif
-}
 @end
 
 @class TinyDOMNode;
@@ -213,18 +206,6 @@
     return self;
 }
 
-- (void)dealloc
-{
-    for (TinyDOMNode *child in m_children)
-        [m_sharedVirtualMachine removeManagedReference:child withOwner:self];
-
-#if !__has_feature(objc_arc)
-    [m_children release];
-    [m_sharedVirtualMachine release];
-    [super dealloc];
-#endif
-}
-
 - (void)appendChild:(TinyDOMNode *)child
 {
     [m_sharedVirtualMachine addManagedReference:child withOwner:self];

Modified: trunk/Source/_javascript_Core/ChangeLog (163573 => 163574)


--- trunk/Source/_javascript_Core/ChangeLog	2014-02-07 00:29:03 UTC (rev 163573)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-02-07 00:29:57 UTC (rev 163574)
@@ -1,3 +1,26 @@
+2014-02-06  Mark Hahnenberg  <[email protected]>
+
+        JSManagedValue should automatically call removeManagedReference:withOwner: upon dealloc
+        https://bugs.webkit.org/show_bug.cgi?id=124053
+
+        Reviewed by Geoffrey Garen.
+
+        * API/JSManagedValue.h:
+        * API/JSManagedValue.mm:
+        (+[JSManagedValue managedValueWithValue:andOwner:]):
+        (-[JSManagedValue initWithValue:]):
+        (-[JSManagedValue dealloc]):
+        (-[JSManagedValue didAddOwner:]):
+        (-[JSManagedValue didRemoveOwner:]):
+        * API/JSManagedValueInternal.h: Added.
+        * API/JSVirtualMachine.mm:
+        (-[JSVirtualMachine addManagedReference:withOwner:]):
+        (-[JSVirtualMachine removeManagedReference:withOwner:]):
+        * API/WebKitAvailability.h:
+        * API/tests/testapi.mm:
+        (-[TextXYZ click]):
+        * _javascript_Core.xcodeproj/project.pbxproj:
+
 2014-02-06  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: Add Console support to JSContext Inspection

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (163573 => 163574)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2014-02-07 00:29:03 UTC (rev 163573)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2014-02-07 00:29:57 UTC (rev 163574)
@@ -743,6 +743,7 @@
 		2A343F7618A1748B0039B085 /* GCSegmentedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A343F7418A1748B0039B085 /* GCSegmentedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2A343F7818A1749D0039B085 /* GCSegmentedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = C211B574176A224D000E2A23 /* APICallbackFunction.h */; };
+		2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */; };
 		2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */; };
 		2A4EC90C1860D6C20094F782 /* WriteBarrierBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A4EC90A1860D6C20094F782 /* WriteBarrierBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2147,6 +2148,7 @@
 		2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DelayedReleaseScope.h; sourceTree = "<group>"; };
 		2A343F7418A1748B0039B085 /* GCSegmentedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCSegmentedArray.h; sourceTree = "<group>"; };
 		2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCSegmentedArrayInlines.h; sourceTree = "<group>"; };
+		2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSManagedValueInternal.h; sourceTree = "<group>"; };
 		2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierBuffer.cpp; sourceTree = "<group>"; };
 		2A4EC90A1860D6C20094F782 /* WriteBarrierBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierBuffer.h; sourceTree = "<group>"; };
 		2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyWriteBarrier.h; sourceTree = "<group>"; };
@@ -3438,6 +3440,7 @@
 		1432EBD70A34CAD400717B9F /* API */ = {
 			isa = PBXGroup;
 			children = (
+				2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */,
 				C211B574176A224D000E2A23 /* APICallbackFunction.h */,
 				1482B78A0A4305AB00517CFC /* APICast.h */,
 				865F408710E7D56300947361 /* APIShims.h */,
@@ -4811,6 +4814,7 @@
 				A7D9A29517A0BC7400EE2618 /* DFGAtTailAbstractState.h in Headers */,
 				0F714CA516EA92F200F3EBEB /* DFGBackwardsPropagationPhase.h in Headers */,
 				0F620176143FCD3B0068B77C /* DFGBasicBlock.h in Headers */,
+				2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */,
 				0FFB921A16D02EC50055A5DB /* DFGBasicBlockInlines.h in Headers */,
 				A70B083317A0B79B00DAF14B /* DFGBinarySwitch.h in Headers */,
 				A7D89CF417A0B8CC00773AD8 /* DFGBlockInsertionSet.h in Headers */,
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to