<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[196614] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/196614">196614</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2016-02-15 20:07:11 -0800 (Mon, 15 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Stop using NSMapTable in places where we were only using it to be GC safe
&lt;rdar://problem/24063723&gt;
https://bugs.webkit.org/show_bug.cgi?id=154264

Reviewed by Dan Bernstein.

Switch from NSMapTable to HashMap.

* WebCore.xcodeproj/project.pbxproj:
* bindings/objc/DOMInternal.h:
* bindings/objc/DOMInternal.mm:
* bindings/objc/WebScriptObject.mm:
* bridge/objc/objc_instance.mm:
* platform/spi/cocoa/NSPointerFunctionsSPI.h: Removed. No longer used.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorebindingsobjcDOMInternalh">trunk/Source/WebCore/bindings/objc/DOMInternal.h</a></li>
<li><a href="#trunkSourceWebCorebindingsobjcDOMInternalmm">trunk/Source/WebCore/bindings/objc/DOMInternal.mm</a></li>
<li><a href="#trunkSourceWebCorebindingsobjcWebScriptObjectmm">trunk/Source/WebCore/bindings/objc/WebScriptObject.mm</a></li>
<li><a href="#trunkSourceWebCorebridgeobjcobjc_instancemm">trunk/Source/WebCore/bridge/objc/objc_instance.mm</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformspicocoaNSPointerFunctionsSPIh">trunk/Source/WebCore/platform/spi/cocoa/NSPointerFunctionsSPI.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (196613 => 196614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-02-16 02:32:55 UTC (rev 196613)
+++ trunk/Source/WebCore/ChangeLog        2016-02-16 04:07:11 UTC (rev 196614)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-02-15  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        Stop using NSMapTable in places where we were only using it to be GC safe
+        &lt;rdar://problem/24063723&gt;
+        https://bugs.webkit.org/show_bug.cgi?id=154264
+
+        Reviewed by Dan Bernstein.
+
+        Switch from NSMapTable to HashMap.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/objc/DOMInternal.h:
+        * bindings/objc/DOMInternal.mm:
+        * bindings/objc/WebScriptObject.mm:
+        * bridge/objc/objc_instance.mm:
+        * platform/spi/cocoa/NSPointerFunctionsSPI.h: Removed. No longer used.
+
</ins><span class="cx"> 2016-02-15  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Font Loading] Implement FontFace JavaScript object
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (196613 => 196614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-02-16 02:32:55 UTC (rev 196613)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-02-16 04:07:11 UTC (rev 196614)
</span><span class="lines">@@ -6186,7 +6186,6 @@
</span><span class="cx">                 CE1252411A16B1B600864480 /* MediaPlayerSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252401A16B1B600864480 /* MediaPlayerSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 CE1252431A16C01A00864480 /* CoreUISPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252421A16C01A00864480 /* CoreUISPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 CE1252451A16C22500864480 /* DynamicLinkerSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252441A16C22500864480 /* DynamicLinkerSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                CE1252471A16C2C200864480 /* NSPointerFunctionsSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252461A16C2C200864480 /* NSPointerFunctionsSPI.h */; };
</del><span class="cx">                 CE1252491A16C3BC00864480 /* MobileGestaltSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252481A16C3BC00864480 /* MobileGestaltSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 CE12524D1A1A77DE00864480 /* IOPMLibSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE12524C1A1A77DE00864480 /* IOPMLibSPI.h */; };
</span><span class="cx">                 CE12524F1A1A78D200864480 /* MachVMSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE12524E1A1A78D200864480 /* MachVMSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -14165,7 +14164,6 @@
</span><span class="cx">                 CE1252401A16B1B600864480 /* MediaPlayerSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CE1252421A16C01A00864480 /* CoreUISPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreUISPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CE1252441A16C22500864480 /* DynamicLinkerSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLinkerSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                CE1252461A16C2C200864480 /* NSPointerFunctionsSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSPointerFunctionsSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 CE1252481A16C3BC00864480 /* MobileGestaltSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MobileGestaltSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CE12524C1A1A77DE00864480 /* IOPMLibSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOPMLibSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CE12524E1A1A78D200864480 /* MachVMSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachVMSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -17525,7 +17523,6 @@
</span><span class="cx">                                 31DF63561AF187DD0078FD91 /* NSColorSPI.h */,
</span><span class="cx">                                 2DDB97F319F9AECA002025D8 /* NSExtensionSPI.h */,
</span><span class="cx">                                 CE12523A1A16711000864480 /* NSFileManagerSPI.h */,
</span><del>-                                CE1252461A16C2C200864480 /* NSPointerFunctionsSPI.h */,
</del><span class="cx">                                 CE1252521A1BEC0600864480 /* NSStringSPI.h */,
</span><span class="cx">                                 31B313DA1B69871600F2AABC /* NSURLConnectionSPI.h */,
</span><span class="cx">                                 CE1252541A1BEC0E00864480 /* NSURLDownloadSPI.h */,
</span><span class="lines">@@ -27210,7 +27207,6 @@
</span><span class="cx">                                 1C6466281A12C4200094603C /* NSFontSPI.h in Headers */,
</span><span class="cx">                                 9321D5901A390704008052BE /* NSImmediateActionGestureRecognizerSPI.h in Headers */,
</span><span class="cx">                                 937F4CCE1A2D4B0100BB39F5 /* NSMenuSPI.h in Headers */,
</span><del>-                                CE1252471A16C2C200864480 /* NSPointerFunctionsSPI.h in Headers */,
</del><span class="cx">                                 93F1E1EC1A40FDDC00348D13 /* NSPopoverSPI.h in Headers */,
</span><span class="cx">                                 93500F3213FDE3BE0099EC24 /* NSScrollerImpDetails.h in Headers */,
</span><span class="cx">                                 F40EA8AB1B867E4400CE5581 /* NSScrollingInputFilterSPI.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsobjcDOMInternalh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/objc/DOMInternal.h (196613 => 196614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/objc/DOMInternal.h        2016-02-16 02:32:55 UTC (rev 196613)
+++ trunk/Source/WebCore/bindings/objc/DOMInternal.h        2016-02-16 04:07:11 UTC (rev 196614)
</span><span class="lines">@@ -58,9 +58,6 @@
</span><span class="cx"> 
</span><span class="cx"> // Helper functions for DOM wrappers and gluing to Objective-C
</span><span class="cx"> 
</span><del>-// Create an NSMapTable mapping from pointers to ObjC objects held with zeroing weak references.
-NSMapTable* createWrapperCache();
-
</del><span class="cx"> id createDOMWrapper(JSC::JSObject*, PassRefPtr&lt;JSC::Bindings::RootObject&gt; origin, PassRefPtr&lt;JSC::Bindings::RootObject&gt; current);
</span><span class="cx"> 
</span><span class="cx"> NSObject* getDOMWrapper(DOMObjectInternal*);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsobjcDOMInternalmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/objc/DOMInternal.mm (196613 => 196614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/objc/DOMInternal.mm        2016-02-16 02:32:55 UTC (rev 196613)
+++ trunk/Source/WebCore/bindings/objc/DOMInternal.mm        2016-02-16 04:07:11 UTC (rev 196614)
</span><span class="lines">@@ -29,13 +29,12 @@
</span><span class="cx"> #import &quot;DOMNodeInternal.h&quot;
</span><span class="cx"> #import &quot;Frame.h&quot;
</span><span class="cx"> #import &quot;JSNode.h&quot;
</span><del>-#import &quot;NSPointerFunctionsSPI.h&quot;
</del><span class="cx"> #import &quot;ScriptController.h&quot;
</span><span class="cx"> #import &quot;WebScriptObjectPrivate.h&quot;
</span><span class="cx"> #import &quot;runtime_root.h&quot;
</span><ins>+#import &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> #import &lt;wtf/Lock.h&gt;
</span><span class="cx"> #import &lt;wtf/NeverDestroyed.h&gt;
</span><del>-#import &lt;wtf/spi/cocoa/NSMapTableSPI.h&gt;
</del><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> #define NEEDS_WRAPPER_CACHE_LOCK 1
</span><span class="lines">@@ -44,33 +43,22 @@
</span><span class="cx"> //------------------------------------------------------------------------------------------
</span><span class="cx"> // Wrapping WebCore implementation objects
</span><span class="cx"> 
</span><del>-static NSMapTable* DOMWrapperCache;
-    
</del><span class="cx"> #ifdef NEEDS_WRAPPER_CACHE_LOCK
</span><span class="cx"> static StaticLock wrapperCacheLock;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#pragma clang diagnostic push
-#pragma clang diagnostic ignored &quot;-Wdeprecated-declarations&quot;
-
-NSMapTable* createWrapperCache()
</del><ins>+static HashMap&lt;DOMObjectInternal*, NSObject *&gt;&amp; wrapperCache()
</ins><span class="cx"> {
</span><del>-    // NSMapTable with zeroing weak pointers is the recommended way to build caches like this under garbage collection.
-    NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
-    NSPointerFunctionsOptions valueOptions = NSPointerFunctionsZeroingWeakMemory | NSPointerFunctionsObjectPersonality;
-    return [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
</del><ins>+    static NeverDestroyed&lt;HashMap&lt;DOMObjectInternal*, NSObject *&gt;&gt; map;
+    return map;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-#pragma clang diagnostic pop
-
</del><span class="cx"> NSObject* getDOMWrapper(DOMObjectInternal* impl)
</span><span class="cx"> {
</span><span class="cx"> #ifdef NEEDS_WRAPPER_CACHE_LOCK
</span><span class="cx">     std::lock_guard&lt;StaticLock&gt; lock(wrapperCacheLock);
</span><span class="cx"> #endif
</span><del>-    if (!DOMWrapperCache)
-        return nil;
-    return static_cast&lt;NSObject*&gt;(NSMapGet(DOMWrapperCache, impl));
</del><ins>+    return wrapperCache().get(impl);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void addDOMWrapper(NSObject* wrapper, DOMObjectInternal* impl)
</span><span class="lines">@@ -78,9 +66,7 @@
</span><span class="cx"> #ifdef NEEDS_WRAPPER_CACHE_LOCK
</span><span class="cx">     std::lock_guard&lt;StaticLock&gt; lock(wrapperCacheLock);
</span><span class="cx"> #endif
</span><del>-    if (!DOMWrapperCache)
-        DOMWrapperCache = createWrapperCache();
-    NSMapInsert(DOMWrapperCache, impl, wrapper);
</del><ins>+    wrapperCache().set(impl, wrapper);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void removeDOMWrapper(DOMObjectInternal* impl)
</span><span class="lines">@@ -88,9 +74,7 @@
</span><span class="cx"> #ifdef NEEDS_WRAPPER_CACHE_LOCK
</span><span class="cx">     std::lock_guard&lt;StaticLock&gt; lock(wrapperCacheLock);
</span><span class="cx"> #endif
</span><del>-    if (!DOMWrapperCache)
-        return;
-    NSMapRemove(DOMWrapperCache, impl);
</del><ins>+    wrapperCache().remove(impl);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> //------------------------------------------------------------------------------------------
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsobjcWebScriptObjectmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/objc/WebScriptObject.mm (196613 => 196614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/objc/WebScriptObject.mm        2016-02-16 02:32:55 UTC (rev 196613)
+++ trunk/Source/WebCore/bindings/objc/WebScriptObject.mm        2016-02-16 04:07:11 UTC (rev 196614)
</span><span class="lines">@@ -43,14 +43,14 @@
</span><span class="cx"> #import &lt;JavaScriptCore/JSContextInternal.h&gt;
</span><span class="cx"> #import &lt;JavaScriptCore/JSValueInternal.h&gt;
</span><span class="cx"> #import &lt;interpreter/CallFrame.h&gt;
</span><ins>+#import &lt;runtime/Completion.h&gt;
</ins><span class="cx"> #import &lt;runtime/InitializeThreading.h&gt;
</span><span class="cx"> #import &lt;runtime/JSGlobalObject.h&gt;
</span><span class="cx"> #import &lt;runtime/JSLock.h&gt;
</span><del>-#import &lt;runtime/Completion.h&gt;
-#import &lt;runtime/Completion.h&gt;
</del><ins>+#import &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> #import &lt;wtf/Lock.h&gt;
</span><ins>+#import &lt;wtf/NeverDestroyed.h&gt;
</ins><span class="cx"> #import &lt;wtf/Threading.h&gt;
</span><del>-#import &lt;wtf/spi/cocoa/NSMapTableSPI.h&gt;
</del><span class="cx"> #import &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> using namespace JSC::Bindings;
</span><span class="lines">@@ -71,17 +71,20 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-static NSMapTable* JSWrapperCache;
</del><span class="cx"> static StaticLock spinLock;
</span><span class="cx"> 
</span><ins>+static HashMap&lt;JSObject*, NSObject *&gt;&amp; wrapperCache()
+{
+    static NeverDestroyed&lt;HashMap&lt;JSObject*, NSObject *&gt;&gt; map;
+    return map;
+}
+
</ins><span class="cx"> NSObject* getJSWrapper(JSObject* impl)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx">     LockHolder holder(&amp;spinLock);
</span><span class="cx"> 
</span><del>-    if (!JSWrapperCache)
-        return nil;
-    NSObject* wrapper = static_cast&lt;NSObject*&gt;(NSMapGet(JSWrapperCache, impl));
</del><ins>+    NSObject* wrapper = wrapperCache().get(impl);
</ins><span class="cx">     return wrapper ? [[wrapper retain] autorelease] : nil;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -90,28 +93,22 @@
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx">     LockHolder holder(&amp;spinLock);
</span><span class="cx"> 
</span><del>-    if (!JSWrapperCache)
-        JSWrapperCache = createWrapperCache();
-    NSMapInsert(JSWrapperCache, impl, wrapper);
</del><ins>+    wrapperCache().set(impl, wrapper);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void removeJSWrapper(JSObject* impl)
</span><span class="cx"> {
</span><span class="cx">     LockHolder holder(&amp;spinLock);
</span><span class="cx"> 
</span><del>-    if (!JSWrapperCache)
-        return;
-    NSMapRemove(JSWrapperCache, impl);
</del><ins>+    wrapperCache().remove(impl);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void removeJSWrapperIfRetainCountOne(NSObject* wrapper, JSObject* impl)
</span><span class="cx"> {
</span><span class="cx">     LockHolder holder(&amp;spinLock);
</span><span class="cx"> 
</span><del>-    if (!JSWrapperCache)
-        return;
</del><span class="cx">     if ([wrapper retainCount] == 1)
</span><del>-        NSMapRemove(JSWrapperCache, impl);
</del><ins>+        wrapperCache().remove(impl);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> id createJSWrapper(JSC::JSObject* object, PassRefPtr&lt;JSC::Bindings::RootObject&gt; origin, PassRefPtr&lt;JSC::Bindings::RootObject&gt; root)
</span></span></pre></div>
<a id="trunkSourceWebCorebridgeobjcobjc_instancemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bridge/objc/objc_instance.mm (196613 => 196614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bridge/objc/objc_instance.mm        2016-02-16 02:32:55 UTC (rev 196613)
+++ trunk/Source/WebCore/bridge/objc/objc_instance.mm        2016-02-16 04:07:11 UTC (rev 196614)
</span><span class="lines">@@ -27,7 +27,6 @@
</span><span class="cx"> #import &quot;objc_instance.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #import &quot;JSDOMBinding.h&quot;
</span><del>-#import &quot;NSPointerFunctionsSPI.h&quot;
</del><span class="cx"> #import &quot;ObjCRuntimeObject.h&quot;
</span><span class="cx"> #import &quot;WebScriptObject.h&quot;
</span><span class="cx"> #import &quot;WebScriptObjectProtocol.h&quot;
</span><span class="lines">@@ -37,7 +36,8 @@
</span><span class="cx"> #import &lt;runtime/JSLock.h&gt;
</span><span class="cx"> #import &lt;runtime/ObjectPrototype.h&gt;
</span><span class="cx"> #import &lt;wtf/Assertions.h&gt;
</span><del>-#import &lt;wtf/spi/cocoa/NSMapTableSPI.h&gt;
</del><ins>+#import &lt;wtf/HashMap.h&gt;
+#import &lt;wtf/NeverDestroyed.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #ifdef NDEBUG
</span><span class="cx"> #define OBJC_LOG(formatAndArgs...) ((void)0)
</span><span class="lines">@@ -53,21 +53,13 @@
</span><span class="cx"> 
</span><span class="cx"> static NSString *s_exception;
</span><span class="cx"> static JSGlobalObject* s_exceptionEnvironment; // No need to protect this value, since we just use it for a pointer comparison.
</span><del>-static NSMapTable *s_instanceWrapperCache;
</del><span class="cx"> 
</span><del>-#pragma clang diagnostic push
-#pragma clang diagnostic ignored &quot;-Wdeprecated-declarations&quot;
-
-static NSMapTable *createInstanceWrapperCache()
</del><ins>+static HashMap&lt;id, ObjcInstance*&gt;&amp; wrapperCache()
</ins><span class="cx"> {
</span><del>-    // NSMapTable with zeroing weak pointers is the recommended way to build caches like this under garbage collection.
-    NSPointerFunctionsOptions keyOptions = NSPointerFunctionsZeroingWeakMemory | NSPointerFunctionsOpaquePersonality;
-    NSPointerFunctionsOptions valueOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
-    return [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
</del><ins>+    static NeverDestroyed&lt;HashMap&lt;id, ObjcInstance*&gt;&gt; map;
+    return map;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-#pragma clang diagnostic pop
-
</del><span class="cx"> RuntimeObject* ObjcInstance::newRuntimeObject(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     // FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object.
</span><span class="lines">@@ -111,13 +103,14 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;ObjcInstance&gt; ObjcInstance::create(id instance, RefPtr&lt;RootObject&gt;&amp;&amp; rootObject)
</span><span class="cx"> {
</span><del>-    if (!s_instanceWrapperCache)
-        s_instanceWrapperCache = createInstanceWrapperCache();
-    if (void* existingWrapper = NSMapGet(s_instanceWrapperCache, instance))
-        return static_cast&lt;ObjcInstance*&gt;(existingWrapper);
-    RefPtr&lt;ObjcInstance&gt; wrapper = adoptRef(new ObjcInstance(instance, WTFMove(rootObject)));
-    NSMapInsert(s_instanceWrapperCache, instance, wrapper.get());
-    return wrapper;
</del><ins>+    auto result = wrapperCache().add(instance, nullptr);
+    if (result.isNewEntry) {
+        RefPtr&lt;ObjcInstance&gt; wrapper = adoptRef(new ObjcInstance(instance, WTFMove(rootObject)));
+        result.iterator-&gt;value = wrapper.get();
+        return wrapper;
+    }
+
+    return result.iterator-&gt;value;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ObjcInstance::~ObjcInstance() 
</span><span class="lines">@@ -125,9 +118,8 @@
</span><span class="cx">     // Both -finalizeForWebScript and -dealloc/-finalize of _instance may require autorelease pools.
</span><span class="cx">     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
</span><span class="cx"> 
</span><del>-    ASSERT(s_instanceWrapperCache);
</del><span class="cx">     ASSERT(_instance);
</span><del>-    NSMapRemove(s_instanceWrapperCache, _instance.get());
</del><ins>+    wrapperCache().remove(_instance.get());
</ins><span class="cx"> 
</span><span class="cx">     if ([_instance.get() respondsToSelector:@selector(finalizeForWebScript)])
</span><span class="cx">         [_instance.get() performSelector:@selector(finalizeForWebScript)];
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformspicocoaNSPointerFunctionsSPIh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/platform/spi/cocoa/NSPointerFunctionsSPI.h (196613 => 196614)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/spi/cocoa/NSPointerFunctionsSPI.h        2016-02-16 02:32:55 UTC (rev 196613)
+++ trunk/Source/WebCore/platform/spi/cocoa/NSPointerFunctionsSPI.h        2016-02-16 04:07:11 UTC (rev 196614)
</span><span class="lines">@@ -1,41 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 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 NSPointerFunctionsSPI_h
-#define NSPointerFunctionsSPI_h
-
-#if PLATFORM(MAC) || (PLATFORM(IOS) &amp;&amp; USE(APPLE_INTERNAL_SDK))
-
-#include &lt;Foundation/NSPointerFunctions.h&gt;
-
-#else
-
-enum {
-    NSPointerFunctionsZeroingWeakMemory = 1UL &lt;&lt; 0,
-};
-
-#endif
-
-#endif // NSPointerFunctionsSPI_h
</del></span></pre>
</div>
</div>

</body>
</html>