<!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>[181297] trunk/Source</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/181297">181297</a></dd>
<dt>Author</dt> <dd>akling@apple.com</dd>
<dt>Date</dt> <dd>2015-03-09 17:09:39 -0700 (Mon, 09 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Stale entries in WeakGCMaps are keeping tons of WeakBlocks alive unnecessarily.
&lt;https://webkit.org/b/142115&gt;
&lt;rdar://problem/19992268&gt;

Reviewed by Geoffrey Garen.

Prune stale entries from WeakGCMaps as part of every full garbage collection.
This frees up tons of previously-stuck WeakBlocks that were only sitting around
with finalized handles waiting to die.

Note that WeakGCMaps register/unregister themselves with the GC heap in their
ctor/dtor, so creating one now requires passing the VM.

Average time spent in the PruningStaleEntriesFromWeakGCMaps GC phase appears
to be between 0.01ms and 0.3ms, though I've seen a few longer ones at ~1.2ms.
It seems somewhat excessive to do this on every Eden collection, so it's only
doing work in full collections for now.

Because the GC may now mutate WeakGCMap below object allocation, I've made it
so that the classic HashMap::add() optimization can't be used with WeakGCMap.
This caused intermittent test failures when originally landed due to having
an invalid iterator on the stack after add() inserted a new entry and we
proceeded to allocate the new object, triggering GC.

* API/JSWeakObjectMapRefInternal.h:
(OpaqueJSWeakObjectMap::create):
(OpaqueJSWeakObjectMap::OpaqueJSWeakObjectMap):
* API/JSWeakObjectMapRefPrivate.cpp:
* API/JSWrapperMap.mm:
(-[JSWrapperMap initWithContext:]):
(-[JSWrapperMap jsWrapperForObject:]): Pass VM to WeakGCMap constructor.

* JavaScriptCore.xcodeproj/project.pbxproj: Add WeakGCMapInlines.h and make
it project-private so WebCore clients can access it.

* heap/Heap.cpp:
(JSC::Heap::collect):
(JSC::Heap::pruneStaleEntriesFromWeakGCMaps): Added a new GC phase for pruning
stale entries from WeakGCMaps. This is only executed during full collections.

* heap/Heap.h:
* heap/HeapInlines.h:
(JSC::Heap::registerWeakGCMap):
(JSC::Heap::unregisterWeakGCMap): Added a mechanism for WeakGCMaps to register
themselves with the Heap and provide a pruning callback.

* runtime/PrototypeMap.h:
(JSC::PrototypeMap::PrototypeMap):
* runtime/Structure.cpp:
(JSC::StructureTransitionTable::add): Pass VM to WeakGCMap constructor.

* runtime/JSCInlines.h: Add &quot;WeakGCMapInlines.h&quot;

* runtime/JSGlobalObject.cpp: Include &quot;WeakGCMapInlines.h&quot; so this builds.

* runtime/JSString.cpp:
(JSC::jsStringWithCacheSlowCase):
* runtime/PrototypeMap.cpp:
(JSC::PrototypeMap::addPrototype):
(JSC::PrototypeMap::emptyObjectStructureForPrototype): Remove HashMap add()
optimization since it's not safe in the GC-managed WeakGCMap world.

* runtime/VM.cpp:
(JSC::VM::VM): Pass VM to WeakGCMap constructor.

* runtime/WeakGCMap.h:
(JSC::WeakGCMap::set):
(JSC::WeakGCMap::add):
(JSC::WeakGCMap::WeakGCMap): Deleted.
(JSC::WeakGCMap::gcMap): Deleted.
(JSC::WeakGCMap::gcMapIfNeeded): Deleted.
* runtime/WeakGCMapInlines.h: Added.
(JSC::WeakGCMap::WeakGCMap):
(JSC::WeakGCMap::~WeakGCMap):
(JSC::WeakGCMap::pruneStaleEntries): Moved ctor, dtor and pruning callback
to WeakGCMapInlines.h to fix interdependent header issues. Removed code that
prunes WeakGCMap at certain growth milestones and instead rely on the GC
callback for housekeeping.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreAPIJSWeakObjectMapRefInternalh">trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreAPIJSWeakObjectMapRefPrivatecpp">trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreAPIJSWrapperMapmm">trunk/Source/JavaScriptCore/API/JSWrapperMap.mm</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeaph">trunk/Source/JavaScriptCore/heap/Heap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapInlinesh">trunk/Source/JavaScriptCore/heap/HeapInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSCInlinesh">trunk/Source/JavaScriptCore/runtime/JSCInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSStringcpp">trunk/Source/JavaScriptCore/runtime/JSString.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimePrototypeMapcpp">trunk/Source/JavaScriptCore/runtime/PrototypeMap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimePrototypeMaph">trunk/Source/JavaScriptCore/runtime/PrototypeMap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructurecpp">trunk/Source/JavaScriptCore/runtime/Structure.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeWeakGCMaph">trunk/Source/JavaScriptCore/runtime/WeakGCMap.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsScriptCachedFrameDatacpp">trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreruntimeWeakGCMapInlinesh">trunk/Source/JavaScriptCore/runtime/WeakGCMapInlines.h</a></li>
<li><a href="#trunkSourceWebCoreForwardingHeadersruntimeWeakGCMapInlinesh">trunk/Source/WebCore/ForwardingHeaders/runtime/WeakGCMapInlines.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreAPIJSWeakObjectMapRefInternalh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -41,9 +41,9 @@
</span><span class="cx"> 
</span><span class="cx"> struct OpaqueJSWeakObjectMap : public RefCounted&lt;OpaqueJSWeakObjectMap&gt; {
</span><span class="cx"> public:
</span><del>-    static PassRefPtr&lt;OpaqueJSWeakObjectMap&gt; create(void* data, JSWeakMapDestroyedCallback callback)
</del><ins>+    static Ref&lt;OpaqueJSWeakObjectMap&gt; create(JSC::VM&amp; vm, void* data, JSWeakMapDestroyedCallback callback)
</ins><span class="cx">     {
</span><del>-        return adoptRef(new OpaqueJSWeakObjectMap(data, callback));
</del><ins>+        return adoptRef(*new OpaqueJSWeakObjectMap(vm, data, callback));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     WeakMapType&amp; map() { return m_map; }
</span><span class="lines">@@ -54,8 +54,9 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    OpaqueJSWeakObjectMap(void* data, JSWeakMapDestroyedCallback callback)
-        : m_data(data)
</del><ins>+    OpaqueJSWeakObjectMap(JSC::VM&amp; vm, void* data, JSWeakMapDestroyedCallback callback)
+        : m_map(vm)
+        , m_data(data)
</ins><span class="cx">         , m_callback(callback)
</span><span class="cx">     {
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreAPIJSWeakObjectMapRefPrivatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;JSWeakObjectMapRefInternal.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;Weak.h&quot;
</span><ins>+#include &quot;WeakGCMapInlines.h&quot;
</ins><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringHash.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -46,7 +47,7 @@
</span><span class="cx"> {
</span><span class="cx">     ExecState* exec = toJS(context);
</span><span class="cx">     JSLockHolder locker(exec);
</span><del>-    RefPtr&lt;OpaqueJSWeakObjectMap&gt; map = OpaqueJSWeakObjectMap::create(privateData, callback);
</del><ins>+    RefPtr&lt;OpaqueJSWeakObjectMap&gt; map = OpaqueJSWeakObjectMap::create(exec-&gt;vm(), privateData, callback);
</ins><span class="cx">     exec-&gt;lexicalGlobalObject()-&gt;registerWeakMap(map.get());
</span><span class="cx">     return map.get();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreAPIJSWrapperMapmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSWrapperMap.mm (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSWrapperMap.mm        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/API/JSWrapperMap.mm        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #import &quot;ObjCCallbackFunction.h&quot;
</span><span class="cx"> #import &quot;ObjcRuntimeExtras.h&quot;
</span><span class="cx"> #import &quot;WeakGCMap.h&quot;
</span><ins>+#import &quot;WeakGCMapInlines.h&quot;
</ins><span class="cx"> #import &lt;wtf/HashSet.h&gt;
</span><span class="cx"> #import &lt;wtf/TCSpinLock.h&gt;
</span><span class="cx"> #import &lt;wtf/Vector.h&gt;
</span><span class="lines">@@ -546,7 +547,7 @@
</span><span class="cx"> @implementation JSWrapperMap {
</span><span class="cx">     JSContext *m_context;
</span><span class="cx">     NSMutableDictionary *m_classMap;
</span><del>-    JSC::WeakGCMap&lt;id, JSC::JSObject&gt; m_cachedJSWrappers;
</del><ins>+    std::unique_ptr&lt;JSC::WeakGCMap&lt;id, JSC::JSObject&gt;&gt; m_cachedJSWrappers;
</ins><span class="cx">     NSMapTable *m_cachedObjCWrappers;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -559,7 +560,9 @@
</span><span class="cx">     NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
</span><span class="cx">     NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
</span><span class="cx">     m_cachedObjCWrappers = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
</span><del>-    
</del><ins>+
+    m_cachedJSWrappers = std::make_unique&lt;JSC::WeakGCMap&lt;id, JSC::JSObject&gt;&gt;(toJS([context JSGlobalContextRef])-&gt;vm());
+
</ins><span class="cx">     m_context = context;
</span><span class="cx">     m_classMap = [[NSMutableDictionary alloc] init];
</span><span class="cx">     return self;
</span><span class="lines">@@ -590,7 +593,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (JSValue *)jsWrapperForObject:(id)object
</span><span class="cx"> {
</span><del>-    JSC::JSObject* jsWrapper = m_cachedJSWrappers.get(object);
</del><ins>+    JSC::JSObject* jsWrapper = m_cachedJSWrappers-&gt;get(object);
</ins><span class="cx">     if (jsWrapper)
</span><span class="cx">         return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
</span><span class="cx"> 
</span><span class="lines">@@ -606,7 +609,7 @@
</span><span class="cx">     // (1) For immortal objects JSValues will effectively leak and this results in error output being logged - we should avoid adding associated objects to immortal objects.
</span><span class="cx">     // (2) A long lived object may rack up many JSValues. When the contexts are released these will unprotect the associated JavaScript objects,
</span><span class="cx">     //     but still, would probably nicer if we made it so that only one associated object was required, broadcasting object dealloc.
</span><del>-    m_cachedJSWrappers.set(object, jsWrapper);
</del><ins>+    m_cachedJSWrappers-&gt;set(object, jsWrapper);
</ins><span class="cx">     return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -1,3 +1,84 @@
</span><ins>+2015-03-09  Andreas Kling  &lt;akling@apple.com&gt;
+
+        Stale entries in WeakGCMaps are keeping tons of WeakBlocks alive unnecessarily.
+        &lt;https://webkit.org/b/142115&gt;
+        &lt;rdar://problem/19992268&gt;
+
+        Reviewed by Geoffrey Garen.
+
+        Prune stale entries from WeakGCMaps as part of every full garbage collection.
+        This frees up tons of previously-stuck WeakBlocks that were only sitting around
+        with finalized handles waiting to die.
+
+        Note that WeakGCMaps register/unregister themselves with the GC heap in their
+        ctor/dtor, so creating one now requires passing the VM.
+
+        Average time spent in the PruningStaleEntriesFromWeakGCMaps GC phase appears
+        to be between 0.01ms and 0.3ms, though I've seen a few longer ones at ~1.2ms.
+        It seems somewhat excessive to do this on every Eden collection, so it's only
+        doing work in full collections for now.
+
+        Because the GC may now mutate WeakGCMap below object allocation, I've made it
+        so that the classic HashMap::add() optimization can't be used with WeakGCMap.
+        This caused intermittent test failures when originally landed due to having
+        an invalid iterator on the stack after add() inserted a new entry and we
+        proceeded to allocate the new object, triggering GC.
+
+        * API/JSWeakObjectMapRefInternal.h:
+        (OpaqueJSWeakObjectMap::create):
+        (OpaqueJSWeakObjectMap::OpaqueJSWeakObjectMap):
+        * API/JSWeakObjectMapRefPrivate.cpp:
+        * API/JSWrapperMap.mm:
+        (-[JSWrapperMap initWithContext:]):
+        (-[JSWrapperMap jsWrapperForObject:]): Pass VM to WeakGCMap constructor.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Add WeakGCMapInlines.h and make
+        it project-private so WebCore clients can access it.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::collect):
+        (JSC::Heap::pruneStaleEntriesFromWeakGCMaps): Added a new GC phase for pruning
+        stale entries from WeakGCMaps. This is only executed during full collections.
+
+        * heap/Heap.h:
+        * heap/HeapInlines.h:
+        (JSC::Heap::registerWeakGCMap):
+        (JSC::Heap::unregisterWeakGCMap): Added a mechanism for WeakGCMaps to register
+        themselves with the Heap and provide a pruning callback.
+
+        * runtime/PrototypeMap.h:
+        (JSC::PrototypeMap::PrototypeMap):
+        * runtime/Structure.cpp:
+        (JSC::StructureTransitionTable::add): Pass VM to WeakGCMap constructor.
+
+        * runtime/JSCInlines.h: Add &quot;WeakGCMapInlines.h&quot;
+
+        * runtime/JSGlobalObject.cpp: Include &quot;WeakGCMapInlines.h&quot; so this builds.
+
+        * runtime/JSString.cpp:
+        (JSC::jsStringWithCacheSlowCase):
+        * runtime/PrototypeMap.cpp:
+        (JSC::PrototypeMap::addPrototype):
+        (JSC::PrototypeMap::emptyObjectStructureForPrototype): Remove HashMap add()
+        optimization since it's not safe in the GC-managed WeakGCMap world.
+
+        * runtime/VM.cpp:
+        (JSC::VM::VM): Pass VM to WeakGCMap constructor.
+
+        * runtime/WeakGCMap.h:
+        (JSC::WeakGCMap::set):
+        (JSC::WeakGCMap::add):
+        (JSC::WeakGCMap::WeakGCMap): Deleted.
+        (JSC::WeakGCMap::gcMap): Deleted.
+        (JSC::WeakGCMap::gcMapIfNeeded): Deleted.
+        * runtime/WeakGCMapInlines.h: Added.
+        (JSC::WeakGCMap::WeakGCMap):
+        (JSC::WeakGCMap::~WeakGCMap):
+        (JSC::WeakGCMap::pruneStaleEntries): Moved ctor, dtor and pruning callback
+        to WeakGCMapInlines.h to fix interdependent header issues. Removed code that
+        prunes WeakGCMap at certain growth milestones and instead rely on the GC
+        callback for housekeeping.
+
</ins><span class="cx"> 2015-03-09  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Support extends and super keywords
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -1433,6 +1433,7 @@
</span><span class="cx">                 A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 A7FCC26D17A0B6AA00786D1A /* FTLSwitchCase.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FCC26C17A0B6AA00786D1A /* FTLSwitchCase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 A8A4748E151A8306004123FF /* libWTF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8A4748D151A8306004123FF /* libWTF.a */; };
</span><ins>+                AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 ADDB1F6318D77DBE009B58A8 /* OpaqueRootSet.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */; };
</span><span class="cx">                 B59F89391891F29F00D5CCDC /* UnlinkedInstructionStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */; };
</span><span class="lines">@@ -3153,6 +3154,7 @@
</span><span class="cx">                 A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObjectFunctions.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A8E894330CD0603F00367179 /* JSGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObject.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyTable.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueRootSet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedInstructionStream.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 B59F89381891ADB500D5CCDC /* UnlinkedInstructionStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedInstructionStream.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4635,6 +4637,7 @@
</span><span class="cx">                                 FED94F2C171E3E2300BE77A4 /* Watchdog.h */,
</span><span class="cx">                                 FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */,
</span><span class="cx">                                 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */,
</span><ins>+                                AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */,
</ins><span class="cx">                                 A7CA3ADD17DA41AE006538AF /* WeakMapConstructor.cpp */,
</span><span class="cx">                                 A7CA3ADE17DA41AE006538AF /* WeakMapConstructor.h */,
</span><span class="cx">                                 A7CA3AE917DA5168006538AF /* WeakMapData.cpp */,
</span><span class="lines">@@ -5529,6 +5532,7 @@
</span><span class="cx">                                 0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */,
</span><span class="cx">                                 0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */,
</span><span class="cx">                                 BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */,
</span><ins>+                                AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */,
</ins><span class="cx">                                 1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
</span><span class="cx">                                 A7C1EAEF17987AB600299DB2 /* CallFrameInlines.h in Headers */,
</span><span class="cx">                                 95E3BC050E1AE68200B2D1C1 /* CallIdentifier.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -1065,6 +1065,7 @@
</span><span class="cx">         vm()-&gt;typeProfiler()-&gt;invalidateTypeSetCache();
</span><span class="cx"> 
</span><span class="cx">     reapWeakHandles();
</span><ins>+    pruneStaleEntriesFromWeakGCMaps();
</ins><span class="cx">     sweepArrayBuffers();
</span><span class="cx">     snapshotMarkedSpace();
</span><span class="cx"> 
</span><span class="lines">@@ -1178,6 +1179,15 @@
</span><span class="cx">     m_objectSpace.reapWeakSets();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Heap::pruneStaleEntriesFromWeakGCMaps()
+{
+    GCPHASE(PruningStaleEntriesFromWeakGCMaps);
+    if (m_operationInProgress != FullCollection)
+        return;
+    for (auto&amp; pruneCallback : m_weakGCMaps.values())
+        pruneCallback();
+}
+
</ins><span class="cx"> void Heap::sweepArrayBuffers()
</span><span class="cx"> {
</span><span class="cx">     GCPHASE(SweepingArrayBuffers);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.h (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.h        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/heap/Heap.h        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -227,6 +227,9 @@
</span><span class="cx"> 
</span><span class="cx">     static bool isZombified(JSCell* cell) { return *(void**)cell == zombifiedBits; }
</span><span class="cx"> 
</span><ins>+    void registerWeakGCMap(void* weakGCMap, std::function&lt;void()&gt; pruningCallback);
+    void unregisterWeakGCMap(void* weakGCMap);
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class CodeBlock;
</span><span class="cx">     friend class CopiedBlock;
</span><span class="lines">@@ -301,6 +304,7 @@
</span><span class="cx">     void resetVisitors();
</span><span class="cx"> 
</span><span class="cx">     void reapWeakHandles();
</span><ins>+    void pruneStaleEntriesFromWeakGCMaps();
</ins><span class="cx">     void sweepArrayBuffers();
</span><span class="cx">     void snapshotMarkedSpace();
</span><span class="cx">     void deleteSourceProviderCaches();
</span><span class="lines">@@ -393,6 +397,8 @@
</span><span class="cx">     Vector&lt;RetainPtr&lt;CFTypeRef&gt;&gt; m_delayedReleaseObjects;
</span><span class="cx">     unsigned m_delayedReleaseRecursionCount;
</span><span class="cx"> #endif
</span><ins>+
+    HashMap&lt;void*, std::function&lt;void()&gt;&gt; m_weakGCMaps;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/HeapInlines.h (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/HeapInlines.h        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/heap/HeapInlines.h        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -314,6 +314,16 @@
</span><span class="cx">         m_markListSet = std::make_unique&lt;HashSet&lt;MarkedArgumentBuffer*&gt;&gt;();
</span><span class="cx">     return *m_markListSet;
</span><span class="cx"> }
</span><ins>+
+inline void Heap::registerWeakGCMap(void* weakGCMap, std::function&lt;void()&gt; pruningCallback)
+{
+    m_weakGCMaps.add(weakGCMap, WTF::move(pruningCallback));
+}
+
+inline void Heap::unregisterWeakGCMap(void* weakGCMap)
+{
+    m_weakGCMaps.remove(weakGCMap);
+}
</ins><span class="cx">     
</span><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCInlines.h (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCInlines.h        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/runtime/JSCInlines.h        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -51,5 +51,6 @@
</span><span class="cx"> #include &quot;Operations.h&quot;
</span><span class="cx"> #include &quot;SlotVisitorInlines.h&quot;
</span><span class="cx"> #include &quot;StructureInlines.h&quot;
</span><ins>+#include &quot;WeakGCMapInlines.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> #endif // JSCInlines_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -123,6 +123,7 @@
</span><span class="cx"> #include &quot;SymbolConstructor.h&quot;
</span><span class="cx"> #include &quot;SymbolPrototype.h&quot;
</span><span class="cx"> #include &quot;VariableWatchpointSetInlines.h&quot;
</span><ins>+#include &quot;WeakGCMapInlines.h&quot;
</ins><span class="cx"> #include &quot;WeakMapConstructor.h&quot;
</span><span class="cx"> #include &quot;WeakMapPrototype.h&quot;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSStringcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSString.cpp (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSString.cpp        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/runtime/JSString.cpp        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -437,11 +437,12 @@
</span><span class="cx"> 
</span><span class="cx"> JSString* jsStringWithCacheSlowCase(VM&amp; vm, StringImpl&amp; stringImpl)
</span><span class="cx"> {
</span><del>-    auto addResult = vm.stringCache.add(&amp;stringImpl, nullptr);
-    if (addResult.isNewEntry)
-        addResult.iterator-&gt;value = jsString(&amp;vm, String(stringImpl));
-    vm.lastCachedString.set(vm, addResult.iterator-&gt;value.get());
-    return addResult.iterator-&gt;value.get();
</del><ins>+    if (JSString* string = vm.stringCache.get(&amp;stringImpl))
+        return string;
+
+    JSString* string = jsString(&amp;vm, String(stringImpl));
+    vm.lastCachedString.set(vm, string);
+    return string;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimePrototypeMapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/PrototypeMap.cpp (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/PrototypeMap.cpp        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/runtime/PrototypeMap.cpp        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> void PrototypeMap::addPrototype(JSObject* object)
</span><span class="cx"> {
</span><del>-    m_prototypes.add(object, object);
</del><ins>+    m_prototypes.set(object, object);
</ins><span class="cx"> 
</span><span class="cx">     // Note that this method makes the somewhat odd decision to not check if this
</span><span class="cx">     // object currently has indexed accessors. We could do that check here, and if
</span><span class="lines">@@ -54,16 +54,16 @@
</span><span class="cx"> 
</span><span class="cx"> Structure* PrototypeMap::emptyObjectStructureForPrototype(JSObject* prototype, unsigned inlineCapacity)
</span><span class="cx"> {
</span><del>-    StructureMap::AddResult addResult = m_structures.add(std::make_pair(prototype, inlineCapacity), nullptr);
-    if (!addResult.isNewEntry) {
</del><ins>+    auto key = std::make_pair(prototype, inlineCapacity);
+    if (Structure* structure = m_structures.get(key)) {
</ins><span class="cx">         ASSERT(isPrototype(prototype));
</span><del>-        return addResult.iterator-&gt;value.get();
</del><ins>+        return structure;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     addPrototype(prototype);
</span><span class="cx">     Structure* structure = JSFinalObject::createStructure(
</span><span class="cx">         prototype-&gt;globalObject()-&gt;vm(), prototype-&gt;globalObject(), prototype, inlineCapacity);
</span><del>-    addResult.iterator-&gt;value = Weak&lt;Structure&gt;(structure);
</del><ins>+    m_structures.set(key, Weak&lt;Structure&gt;(structure));
</ins><span class="cx">     return structure;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimePrototypeMaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/PrototypeMap.h (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/PrototypeMap.h        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/runtime/PrototypeMap.h        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -33,10 +33,17 @@
</span><span class="cx"> 
</span><span class="cx"> class JSObject;
</span><span class="cx"> class Structure;
</span><ins>+class VM;
</ins><span class="cx"> 
</span><span class="cx"> // Tracks the canonical structure an object should be allocated with when inheriting from a given prototype.
</span><span class="cx"> class PrototypeMap {
</span><span class="cx"> public:
</span><ins>+    explicit PrototypeMap(VM&amp; vm)
+        : m_prototypes(vm)
+        , m_structures(vm)
+    {
+    }
+
</ins><span class="cx">     JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity);
</span><span class="cx">     void clearEmptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity);
</span><span class="cx">     void addPrototype(JSObject*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Structure.cpp (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Structure.cpp        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/runtime/Structure.cpp        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> #include &quot;PropertyNameArray.h&quot;
</span><span class="cx"> #include &quot;StructureChain.h&quot;
</span><span class="cx"> #include &quot;StructureRareDataInlines.h&quot;
</span><ins>+#include &quot;WeakGCMapInlines.h&quot;
</ins><span class="cx"> #include &lt;wtf/CommaPrinter.h&gt;
</span><span class="cx"> #include &lt;wtf/ProcessID.h&gt;
</span><span class="cx"> #include &lt;wtf/RefCountedLeakCounter.h&gt;
</span><span class="lines">@@ -90,7 +91,7 @@
</span><span class="cx"> 
</span><span class="cx">         // This handles the second transition being added
</span><span class="cx">         // (or the first transition being despecified!)
</span><del>-        setMap(new TransitionMap());
</del><ins>+        setMap(new TransitionMap(vm));
</ins><span class="cx">         add(vm, existingTransition);
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -83,6 +83,7 @@
</span><span class="cx"> #include &quot;TypeProfiler.h&quot;
</span><span class="cx"> #include &quot;TypeProfilerLog.h&quot;
</span><span class="cx"> #include &quot;UnlinkedCodeBlock.h&quot;
</span><ins>+#include &quot;WeakGCMapInlines.h&quot;
</ins><span class="cx"> #include &quot;WeakMapData.h&quot;
</span><span class="cx"> #include &lt;wtf/ProcessID.h&gt;
</span><span class="cx"> #include &lt;wtf/RetainPtr.h&gt;
</span><span class="lines">@@ -153,6 +154,8 @@
</span><span class="cx">     , m_atomicStringTable(vmType == Default ? wtfThreadData().atomicStringTable() : new AtomicStringTable)
</span><span class="cx">     , propertyNames(nullptr)
</span><span class="cx">     , emptyList(new MarkedArgumentBuffer)
</span><ins>+    , stringCache(*this)
+    , prototypeMap(*this)
</ins><span class="cx">     , keywords(std::make_unique&lt;Keywords&gt;(*this))
</span><span class="cx">     , interpreter(0)
</span><span class="cx">     , jsArrayClassInfo(JSArray::info())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeWeakGCMaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/WeakGCMap.h (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/WeakGCMap.h        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/JavaScriptCore/runtime/WeakGCMap.h        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -47,10 +47,8 @@
</span><span class="cx">     typedef typename HashMapType::iterator iterator;
</span><span class="cx">     typedef typename HashMapType::const_iterator const_iterator;
</span><span class="cx"> 
</span><del>-    WeakGCMap()
-        : m_gcThreshold(minGCThreshold)
-    {
-    }
</del><ins>+    explicit WeakGCMap(VM&amp;);
+    ~WeakGCMap();
</ins><span class="cx"> 
</span><span class="cx">     ValueArg* get(const KeyType&amp; key) const
</span><span class="cx">     {
</span><span class="lines">@@ -59,21 +57,9 @@
</span><span class="cx"> 
</span><span class="cx">     AddResult set(const KeyType&amp; key, ValueType value)
</span><span class="cx">     {
</span><del>-        gcMapIfNeeded();
</del><span class="cx">         return m_map.set(key, WTF::move(value));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ALWAYS_INLINE AddResult add(const KeyType&amp; key, ValueType value)
-    {
-        gcMapIfNeeded();
-        AddResult addResult = m_map.fastAdd(key, nullptr);
-        if (!addResult.iterator-&gt;value) { // New value or found a zombie value.
-            addResult.isNewEntry = true;
-            addResult.iterator-&gt;value = WTF::move(value);
-        }
-        return addResult;
-    }
-
</del><span class="cx">     bool remove(const KeyType&amp; key)
</span><span class="cx">     {
</span><span class="cx">         return m_map.remove(key);
</span><span class="lines">@@ -103,38 +89,13 @@
</span><span class="cx">         return find(key) != m_map.end();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-private:
-    static const int minGCThreshold = 3;
</del><ins>+    void pruneStaleEntries();
</ins><span class="cx"> 
</span><del>-    NEVER_INLINE void gcMap()
-    {
-        Vector&lt;KeyType, 4&gt; zombies;
-
-        for (iterator it = m_map.begin(), end = m_map.end(); it != end; ++it) {
-            if (!it-&gt;value)
-                zombies.append(it-&gt;key);
-        }
-
-        for (size_t i = 0; i &lt; zombies.size(); ++i)
-            m_map.remove(zombies[i]);
-    }
-
-    void gcMapIfNeeded()
-    {
-        if (m_map.size() &lt; m_gcThreshold)
-            return;
-
-        gcMap();
-        m_gcThreshold = std::max(minGCThreshold, m_map.size() * 2 - 1);
-    }
-
</del><ins>+private:
</ins><span class="cx">     HashMapType m_map;
</span><del>-    int m_gcThreshold;
</del><ins>+    VM&amp; m_vm;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-template&lt;typename KeyArg, typename RawMappedArg, typename HashArg, typename KeyTraitsArg&gt;
-const int WeakGCMap&lt;KeyArg, RawMappedArg, HashArg, KeyTraitsArg&gt;::minGCThreshold;
-
</del><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // WeakGCMap_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeWeakGCMapInlineshfromrev181293trunkSourceJavaScriptCoreAPIJSWeakObjectMapRefInternalh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/runtime/WeakGCMapInlines.h (from rev 181293, trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h) (0 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/WeakGCMapInlines.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/WeakGCMapInlines.h        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+/*
+ * Copyright (C) 2015 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 WeakGCMapInlines_h
+#define WeakGCMapInlines_h
+
+#include &quot;HeapInlines.h&quot;
+#include &quot;WeakGCMap.h&quot;
+
+namespace JSC {
+
+template&lt;typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg&gt;
+inline WeakGCMap&lt;KeyArg, ValueArg, HashArg, KeyTraitsArg&gt;::WeakGCMap(VM&amp; vm)
+    : m_vm(vm)
+{
+    vm.heap.registerWeakGCMap(this, [this]() {
+        pruneStaleEntries();
+    });
+}
+
+template&lt;typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg&gt;
+inline WeakGCMap&lt;KeyArg, ValueArg, HashArg, KeyTraitsArg&gt;::~WeakGCMap()
+{
+    m_vm.heap.unregisterWeakGCMap(this);
+}
+
+template&lt;typename KeyArg, typename ValueArg, typename HashArg, typename KeyTraitsArg&gt;
+NEVER_INLINE void WeakGCMap&lt;KeyArg, ValueArg, HashArg, KeyTraitsArg&gt;::pruneStaleEntries()
+{
+    m_map.removeIf([](typename HashMapType::KeyValuePairType&amp; entry) {
+        return !entry.value;
+    });
+}
+
+} // namespace JSC
+
+#endif // WeakGCMapInlines_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreForwardingHeadersruntimeWeakGCMapInlinesh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/ForwardingHeaders/runtime/WeakGCMapInlines.h (0 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ForwardingHeaders/runtime/WeakGCMapInlines.h                                (rev 0)
+++ trunk/Source/WebCore/ForwardingHeaders/runtime/WeakGCMapInlines.h        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+#ifndef WebCore_FWD_WeakGCMapInlines_h
+#define WebCore_FWD_WeakGCMapInlines_h
+#include &lt;JavaScriptCore/WeakGCMapInlines.h&gt;
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsjsScriptCachedFrameDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp (181296 => 181297)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp        2015-03-09 23:57:55 UTC (rev 181296)
+++ trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp        2015-03-10 00:09:39 UTC (rev 181297)
</span><span class="lines">@@ -38,10 +38,11 @@
</span><span class="cx"> #include &quot;Page.h&quot;
</span><span class="cx"> #include &quot;PageConsoleClient.h&quot;
</span><span class="cx"> #include &quot;PageGroup.h&quot;
</span><ins>+#include &quot;ScriptController.h&quot;
</ins><span class="cx"> #include &lt;heap/StrongInlines.h&gt;
</span><span class="cx"> #include &lt;profiler/Profile.h&gt;
</span><span class="cx"> #include &lt;runtime/JSLock.h&gt;
</span><del>-#include &quot;ScriptController.h&quot;
</del><ins>+#include &lt;runtime/WeakGCMapInlines.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> using namespace JSC;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>