<!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>[196482] 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/196482">196482</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2016-02-12 10:30:43 -0800 (Fri, 12 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Modern IDB: Ref cycle between IDBObjectStore and IDBIndex.
https://bugs.webkit.org/show_bug.cgi?id=154110

Reviewed by Darin Adler.

No new tests (Currently untestable).

The lifetime of IDBObjectStore and IDBIndex are closely intertwined, but we have to break the ref cycle.

This patch does a few semi-gnarly things:
1 - Makes both IDBIndex and IDBObjectStore have a custom marking function so they can add each other as
    opaque roots.
2 - Adds a lock to protect IDBObjectStore's collection of referenced indexes to support #1, as GC marking
    can happen on any thread.
3 - Makes IDBIndex not be traditionally RefCounted; Instead, IDBIndex::ref()/deref() simply ref()/deref()
    the owning IDBObjectStore.
4 - ...Except when somebody deletes an IDBIndex from its IDBObjectStore. Once that happens, the object
    store no longer has a reference back to the index, but the index still needs a reference back to the
    object store. To support this, the IDBIndex becomes &quot;traditionally RefCounted&quot; while holding a ref to
    its IDBObjectStore.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:

* Modules/indexeddb/IDBIndex.h:
(WebCore::IDBIndex::isModern):
* Modules/indexeddb/IDBIndex.idl:

* Modules/indexeddb/IDBObjectStore.h:
(WebCore::IDBObjectStore::isModern):
* Modules/indexeddb/IDBObjectStore.idl:

* Modules/indexeddb/client/IDBIndexImpl.cpp:
(WebCore::IDBClient::IDBIndex::objectStore):
(WebCore::IDBClient::IDBIndex::openCursor):
(WebCore::IDBClient::IDBIndex::doCount):
(WebCore::IDBClient::IDBIndex::openKeyCursor):
(WebCore::IDBClient::IDBIndex::doGet):
(WebCore::IDBClient::IDBIndex::doGetKey):
(WebCore::IDBClient::IDBIndex::markAsDeleted):
(WebCore::IDBClient::IDBIndex::ref):
(WebCore::IDBClient::IDBIndex::deref):
(WebCore::IDBClient::IDBIndex::create): Deleted.
* Modules/indexeddb/client/IDBIndexImpl.h:
(WebCore::IDBClient::IDBIndex::modernObjectStore):

* Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
(WebCore::IDBClient::IDBObjectStore::createIndex):
(WebCore::IDBClient::IDBObjectStore::index):
(WebCore::IDBClient::IDBObjectStore::deleteIndex):
(WebCore::IDBClient::IDBObjectStore::visitReferencedIndexes):
* Modules/indexeddb/client/IDBObjectStoreImpl.h:

* Modules/indexeddb/client/IDBTransactionImpl.cpp:
(WebCore::IDBClient::IDBTransaction::createIndex):
* Modules/indexeddb/client/IDBTransactionImpl.h:

* Modules/indexeddb/legacy/LegacyIndex.cpp:
(WebCore::LegacyIndex::ref):
(WebCore::LegacyIndex::deref):
* Modules/indexeddb/legacy/LegacyIndex.h:

* bindings/js/JSIDBIndexCustom.cpp: Added.
(WebCore::JSIDBIndex::visitAdditionalChildren):

* bindings/js/JSIDBObjectStoreCustom.cpp:
(WebCore::JSIDBObjectStore::visitAdditionalChildren):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBIndexh">trunk/Source/WebCore/Modules/indexeddb/IDBIndex.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBIndexidl">trunk/Source/WebCore/Modules/indexeddb/IDBIndex.idl</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBObjectStoreh">trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBObjectStoreidl">trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBIndexImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBIndexImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBObjectStoreImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBObjectStoreImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddblegacyLegacyIndexcpp">trunk/Source/WebCore/Modules/indexeddb/legacy/LegacyIndex.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddblegacyLegacyIndexh">trunk/Source/WebCore/Modules/indexeddb/legacy/LegacyIndex.h</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSIDBObjectStoreCustomcpp">trunk/Source/WebCore/bindings/js/JSIDBObjectStoreCustom.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorebindingsjsJSIDBIndexCustomcpp">trunk/Source/WebCore/bindings/js/JSIDBIndexCustom.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -1180,6 +1180,7 @@
</span><span class="cx">     bindings/js/JSIDBCursorCustom.cpp
</span><span class="cx">     bindings/js/JSIDBCursorWithValueCustom.cpp
</span><span class="cx">     bindings/js/JSIDBDatabaseCustom.cpp
</span><ins>+    bindings/js/JSIDBIndexCustom.cpp
</ins><span class="cx">     bindings/js/JSIDBObjectStoreCustom.cpp
</span><span class="cx">     bindings/js/JSImageConstructor.cpp
</span><span class="cx">     bindings/js/JSImageDataCustom.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/ChangeLog        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -1,3 +1,73 @@
</span><ins>+2016-02-12  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Modern IDB: Ref cycle between IDBObjectStore and IDBIndex.
+        https://bugs.webkit.org/show_bug.cgi?id=154110
+
+        Reviewed by Darin Adler.
+
+        No new tests (Currently untestable).
+
+        The lifetime of IDBObjectStore and IDBIndex are closely intertwined, but we have to break the ref cycle.
+        
+        This patch does a few semi-gnarly things:
+        1 - Makes both IDBIndex and IDBObjectStore have a custom marking function so they can add each other as 
+            opaque roots.
+        2 - Adds a lock to protect IDBObjectStore's collection of referenced indexes to support #1, as GC marking
+            can happen on any thread.
+        3 - Makes IDBIndex not be traditionally RefCounted; Instead, IDBIndex::ref()/deref() simply ref()/deref()
+            the owning IDBObjectStore.
+        4 - ...Except when somebody deletes an IDBIndex from its IDBObjectStore. Once that happens, the object
+            store no longer has a reference back to the index, but the index still needs a reference back to the
+            object store. To support this, the IDBIndex becomes &quot;traditionally RefCounted&quot; while holding a ref to
+            its IDBObjectStore.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * Modules/indexeddb/IDBIndex.h:
+        (WebCore::IDBIndex::isModern):
+        * Modules/indexeddb/IDBIndex.idl:
+        
+        * Modules/indexeddb/IDBObjectStore.h:
+        (WebCore::IDBObjectStore::isModern):
+        * Modules/indexeddb/IDBObjectStore.idl:
+        
+        * Modules/indexeddb/client/IDBIndexImpl.cpp:
+        (WebCore::IDBClient::IDBIndex::objectStore):
+        (WebCore::IDBClient::IDBIndex::openCursor):
+        (WebCore::IDBClient::IDBIndex::doCount):
+        (WebCore::IDBClient::IDBIndex::openKeyCursor):
+        (WebCore::IDBClient::IDBIndex::doGet):
+        (WebCore::IDBClient::IDBIndex::doGetKey):
+        (WebCore::IDBClient::IDBIndex::markAsDeleted):
+        (WebCore::IDBClient::IDBIndex::ref):
+        (WebCore::IDBClient::IDBIndex::deref):
+        (WebCore::IDBClient::IDBIndex::create): Deleted.
+        * Modules/indexeddb/client/IDBIndexImpl.h:
+        (WebCore::IDBClient::IDBIndex::modernObjectStore):
+        
+        * Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
+        (WebCore::IDBClient::IDBObjectStore::createIndex):
+        (WebCore::IDBClient::IDBObjectStore::index):
+        (WebCore::IDBClient::IDBObjectStore::deleteIndex):
+        (WebCore::IDBClient::IDBObjectStore::visitReferencedIndexes):
+        * Modules/indexeddb/client/IDBObjectStoreImpl.h:
+        
+        * Modules/indexeddb/client/IDBTransactionImpl.cpp:
+        (WebCore::IDBClient::IDBTransaction::createIndex):
+        * Modules/indexeddb/client/IDBTransactionImpl.h:
+        
+        * Modules/indexeddb/legacy/LegacyIndex.cpp:
+        (WebCore::LegacyIndex::ref):
+        (WebCore::LegacyIndex::deref):
+        * Modules/indexeddb/legacy/LegacyIndex.h:
+        
+        * bindings/js/JSIDBIndexCustom.cpp: Added.
+        (WebCore::JSIDBIndex::visitAdditionalChildren):
+        
+        * bindings/js/JSIDBObjectStoreCustom.cpp:
+        (WebCore::JSIDBObjectStore::visitAdditionalChildren):
+
</ins><span class="cx"> 2016-02-12  Csaba Osztrogonác  &lt;ossy@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [EFL][GTK] Fix ENABLE(SVG_OTF_CONVERTER) build
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBIndexh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBIndex.h (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBIndex.h        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBIndex.h        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx"> 
</span><span class="cx"> class IDBObjectStore;
</span><span class="cx"> 
</span><del>-class IDBIndex : public RefCounted&lt;IDBIndex&gt; {
</del><ins>+class IDBIndex {
</ins><span class="cx"> public:
</span><span class="cx">     virtual ~IDBIndex() { }
</span><span class="cx"> 
</span><span class="lines">@@ -77,6 +77,14 @@
</span><span class="cx">     virtual RefPtr&lt;IDBRequest&gt; getKey(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&amp;) = 0;
</span><span class="cx">     virtual RefPtr&lt;IDBRequest&gt; getKey(ScriptExecutionContext*, const Deprecated::ScriptValue&amp; key, ExceptionCodeWithMessage&amp;) = 0;
</span><span class="cx"> 
</span><ins>+    virtual bool isModern() const { return false; }
+
+    // We use our own ref/deref function because Legacy IDB and Modern IDB have very different
+    // lifetime management of their indexes.
+    // This will go away once Legacy IDB is dropped.
+    virtual void ref() = 0;
+    virtual void deref() = 0;
+
</ins><span class="cx"> protected:
</span><span class="cx">     IDBIndex();
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBIndexidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBIndex.idl (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBIndex.idl        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBIndex.idl        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -27,6 +27,8 @@
</span><span class="cx">     Conditional=INDEXED_DATABASE,
</span><span class="cx">     EnabledAtRuntime=IndexedDB,
</span><span class="cx">     SkipVTableValidation,
</span><ins>+    JSCustomMarkFunction,
+    GenerateIsReachable=Impl,
</ins><span class="cx"> ] interface IDBIndex {
</span><span class="cx">     readonly attribute DOMString name;
</span><span class="cx">     readonly attribute IDBObjectStore objectStore;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBObjectStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -92,6 +92,8 @@
</span><span class="cx">     virtual RefPtr&lt;IDBRequest&gt; count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&amp;) = 0;
</span><span class="cx">     virtual RefPtr&lt;IDBRequest&gt; count(ScriptExecutionContext*, const Deprecated::ScriptValue&amp; key, ExceptionCodeWithMessage&amp;) = 0;
</span><span class="cx"> 
</span><ins>+    virtual bool isModern() const { return false; }
+
</ins><span class="cx"> protected:
</span><span class="cx">     IDBObjectStore();
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBObjectStoreidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.idl        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -27,6 +27,8 @@
</span><span class="cx">     Conditional=INDEXED_DATABASE,
</span><span class="cx">     EnabledAtRuntime=IndexedDB,
</span><span class="cx">     SkipVTableValidation,
</span><ins>+    JSCustomMarkFunction,
+    GenerateIsReachable=Impl,
</ins><span class="cx"> ] interface IDBObjectStore {
</span><span class="cx">     [TreatReturnedNullStringAs=Null] readonly attribute DOMString name;
</span><span class="cx">     [ImplementedAs=keyPathAny] readonly attribute IDBAny keyPath;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBIndexImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.cpp (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.cpp        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.cpp        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -41,11 +41,6 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBClient {
</span><span class="cx"> 
</span><del>-Ref&lt;IDBIndex&gt; IDBIndex::create(const IDBIndexInfo&amp; info, IDBObjectStore&amp; objectStore)
-{
-    return adoptRef(*new IDBIndex(info, objectStore));
-}
-
</del><span class="cx"> IDBIndex::IDBIndex(const IDBIndexInfo&amp; info, IDBObjectStore&amp; objectStore)
</span><span class="cx">     : m_info(info)
</span><span class="cx">     , m_objectStore(objectStore)
</span><span class="lines">@@ -63,7 +58,7 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBObjectStore&gt; IDBIndex::objectStore()
</span><span class="cx"> {
</span><del>-    return &amp;m_objectStore.get();
</del><ins>+    return &amp;m_objectStore;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBAny&gt; IDBIndex::keyPathAny() const
</span><span class="lines">@@ -90,13 +85,13 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBIndex::openCursor&quot;);
</span><span class="cx"> 
</span><del>-    if (m_deleted || m_objectStore-&gt;isDeleted()) {
</del><ins>+    if (m_deleted || m_objectStore.isDeleted()) {
</ins><span class="cx">         ec.code = IDBDatabaseException::InvalidStateError;
</span><span class="cx">         ec.message = ASCIILiteral(&quot;Failed to execute 'openCursor' on 'IDBIndex': The index or its object store has been deleted.&quot;);
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_objectStore-&gt;modernTransaction().isActive()) {
</del><ins>+    if (!m_objectStore.modernTransaction().isActive()) {
</ins><span class="cx">         ec.code = IDBDatabaseException::TransactionInactiveError;
</span><span class="cx">         ec.message = ASCIILiteral(&quot;Failed to execute 'openCursor' on 'IDBIndex': The transaction is inactive or finished.&quot;);
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -114,9 +109,8 @@
</span><span class="cx">     if (rangeData.upperKey.isNull())
</span><span class="cx">         rangeData.upperKey = IDBKeyData::maximum();
</span><span class="cx"> 
</span><del>-    auto info = IDBCursorInfo::indexCursor(m_objectStore-&gt;modernTransaction(), m_objectStore-&gt;info().identifier(), m_info.identifier(), rangeData, direction, IndexedDB::CursorType::KeyAndValue);
-    Ref&lt;IDBRequest&gt; request = m_objectStore-&gt;modernTransaction().requestOpenCursor(*context, *this, info);
-    return WTFMove(request);
</del><ins>+    auto info = IDBCursorInfo::indexCursor(m_objectStore.modernTransaction(), m_objectStore.info().identifier(), m_info.identifier(), rangeData, direction, IndexedDB::CursorType::KeyAndValue);
+    return m_objectStore.modernTransaction().requestOpenCursor(*context, *this, info);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue&amp; key, const String&amp; direction, ExceptionCodeWithMessage&amp; ec)
</span><span class="lines">@@ -177,7 +171,7 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::doCount(ScriptExecutionContext&amp; context, const IDBKeyRangeData&amp; range, ExceptionCodeWithMessage&amp; ec)
</span><span class="cx"> {
</span><del>-    if (m_deleted || m_objectStore-&gt;isDeleted()) {
</del><ins>+    if (m_deleted || m_objectStore.isDeleted()) {
</ins><span class="cx">         ec.code = IDBDatabaseException::InvalidStateError;
</span><span class="cx">         ec.message = ASCIILiteral(&quot;Failed to execute 'count' on 'IDBIndex': The index or its object store has been deleted.&quot;);
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -188,7 +182,7 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto&amp; transaction = m_objectStore-&gt;modernTransaction();
</del><ins>+    auto&amp; transaction = m_objectStore.modernTransaction();
</ins><span class="cx">     if (!transaction.isActive()) {
</span><span class="cx">         ec.code = IDBDatabaseException::TransactionInactiveError;
</span><span class="cx">         ec.message = ASCIILiteral(&quot;Failed to execute 'count' on 'IDBIndex': The transaction is inactive or finished.&quot;);
</span><span class="lines">@@ -202,13 +196,13 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBIndex::openKeyCursor&quot;);
</span><span class="cx"> 
</span><del>-    if (m_deleted || m_objectStore-&gt;isDeleted()) {
</del><ins>+    if (m_deleted || m_objectStore.isDeleted()) {
</ins><span class="cx">         ec.code = IDBDatabaseException::InvalidStateError;
</span><span class="cx">         ec.message = ASCIILiteral(&quot;Failed to execute 'openKeyCursor' on 'IDBIndex': The index or its object store has been deleted.&quot;);
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_objectStore-&gt;modernTransaction().isActive()) {
</del><ins>+    if (!m_objectStore.modernTransaction().isActive()) {
</ins><span class="cx">         ec.code = IDBDatabaseException::TransactionInactiveError;
</span><span class="cx">         ec.message = ASCIILiteral(&quot;Failed to execute 'openKeyCursor' on 'IDBIndex': The transaction is inactive or finished.&quot;);
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -220,9 +214,8 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto info = IDBCursorInfo::indexCursor(m_objectStore-&gt;modernTransaction(), m_objectStore-&gt;info().identifier(), m_info.identifier(), range, direction, IndexedDB::CursorType::KeyOnly);
-    Ref&lt;IDBRequest&gt; request = m_objectStore-&gt;modernTransaction().requestOpenCursor(*context, *this, info);
-    return WTFMove(request);
</del><ins>+    auto info = IDBCursorInfo::indexCursor(m_objectStore.modernTransaction(), m_objectStore.info().identifier(), m_info.identifier(), range, direction, IndexedDB::CursorType::KeyOnly);
+    return m_objectStore.modernTransaction().requestOpenCursor(*context, *this, info);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::openKeyCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue&amp; key, const String&amp; direction, ExceptionCodeWithMessage&amp; ec)
</span><span class="lines">@@ -270,7 +263,7 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::doGet(ScriptExecutionContext&amp; context, const IDBKeyRangeData&amp; range, ExceptionCodeWithMessage&amp; ec)
</span><span class="cx"> {
</span><del>-    if (m_deleted || m_objectStore-&gt;isDeleted()) {
</del><ins>+    if (m_deleted || m_objectStore.isDeleted()) {
</ins><span class="cx">         ec.code = IDBDatabaseException::InvalidStateError;
</span><span class="cx">         ec.message = ASCIILiteral(&quot;Failed to execute 'get' on 'IDBIndex': The index or its object store has been deleted.&quot;);
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -281,7 +274,7 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto&amp; transaction = m_objectStore-&gt;modernTransaction();
</del><ins>+    auto&amp; transaction = m_objectStore.modernTransaction();
</ins><span class="cx">     if (!transaction.isActive()) {
</span><span class="cx">         ec.code = IDBDatabaseException::TransactionInactiveError;
</span><span class="cx">         ec.message = ASCIILiteral(&quot;Failed to execute 'get' on 'IDBIndex': The transaction is inactive or finished.&quot;);
</span><span class="lines">@@ -325,7 +318,7 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::doGetKey(ScriptExecutionContext&amp; context, const IDBKeyRangeData&amp; range, ExceptionCodeWithMessage&amp; ec)
</span><span class="cx"> {
</span><del>-    if (m_deleted || m_objectStore-&gt;isDeleted()) {
</del><ins>+    if (m_deleted || m_objectStore.isDeleted()) {
</ins><span class="cx">         ec.code = IDBDatabaseException::InvalidStateError;
</span><span class="cx">         ec.message = ASCIILiteral(&quot;Failed to execute 'getKey' on 'IDBIndex': The index or its object store has been deleted.&quot;);
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -336,7 +329,7 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto&amp; transaction = m_objectStore-&gt;modernTransaction();
</del><ins>+    auto&amp; transaction = m_objectStore.modernTransaction();
</ins><span class="cx">     if (!transaction.isActive()) {
</span><span class="cx">         ec.code = IDBDatabaseException::TransactionInactiveError;
</span><span class="cx">         ec.message = ASCIILiteral(&quot;Failed to execute 'getKey' on 'IDBIndex': The transaction is inactive or finished.&quot;);
</span><span class="lines">@@ -346,11 +339,51 @@
</span><span class="cx">     return transaction.requestGetKey(context, *this, range);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void IDBIndex::markAsDeleted()
</del><ins>+void IDBIndex::markAsDeleted(std::unique_ptr&lt;IDBIndex&gt;&amp;&amp; indexOwner)
</ins><span class="cx"> {
</span><ins>+    ASSERT(!m_deleted);
+    ASSERT(!m_selfOwner);
+    ASSERT(indexOwner.get() == this);
+
+    // If nobody was keeping a ref to this IDBIndex while under IDBObjectStore ownership,
+    // it can be deleted now by letting indexOwner go out of scope.
+    if (!m_refCount)
+        return;
+
+    m_selfOwner = WTFMove(indexOwner);
+
+    // Now that the IDBIndex is managing its own lifetime, it must ref() its IDBObjectStore to keep it alive.
+    m_objectStoreRef = &amp;m_objectStore;
+
+    // It must undo all of the refs it had previously given its IDBObjectStore when the lifetimes were intertwined.
+    for (unsigned i = m_refCount; i &gt; 0; --i)
+        m_objectStore.deref();
+
</ins><span class="cx">     m_deleted = true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void IDBIndex::ref()
+{
+    ++m_refCount;
+
+    if (!m_deleted)
+        m_objectStore.ref();
+}
+
+void IDBIndex::deref()
+{
+    --m_refCount;
+
+    if (!m_deleted)
+        m_objectStore.deref();
+    else {
+        // This IDBIndex has been detached from its IDBObjectStore so if its RefCount
+        // just went to 0 it should be destroyed.
+        if (!m_refCount)
+            m_selfOwner = nullptr;
+    }
+}
+
</ins><span class="cx"> } // namespace IDBClient
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBIndexImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.h (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.h        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.h        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx"> 
</span><span class="cx"> class IDBIndex : public WebCore::IDBIndex {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;IDBIndex&gt; create(const IDBIndexInfo&amp;, IDBObjectStore&amp;);
</del><ins>+    IDBIndex(const IDBIndexInfo&amp;, IDBObjectStore&amp;);
</ins><span class="cx"> 
</span><span class="cx">     virtual ~IDBIndex();
</span><span class="cx"> 
</span><span class="lines">@@ -77,22 +77,38 @@
</span><span class="cx"> 
</span><span class="cx">     const IDBIndexInfo&amp; info() const { return m_info; }
</span><span class="cx"> 
</span><del>-    IDBObjectStore&amp; modernObjectStore() { return m_objectStore.get(); }
</del><ins>+    IDBObjectStore&amp; modernObjectStore() { return m_objectStore; }
</ins><span class="cx"> 
</span><del>-    void markAsDeleted();
</del><ins>+    void markAsDeleted(std::unique_ptr&lt;IDBIndex&gt;&amp;&amp;);
</ins><span class="cx">     bool isDeleted() const { return m_deleted; }
</span><span class="cx"> 
</span><ins>+    virtual bool isModern() const override { return true; }
+
+    void ref() override;
+    void deref() override;
+
</ins><span class="cx"> private:
</span><del>-    IDBIndex(const IDBIndexInfo&amp;, IDBObjectStore&amp;);
-
</del><span class="cx">     RefPtr&lt;WebCore::IDBRequest&gt; doCount(ScriptExecutionContext&amp;, const IDBKeyRangeData&amp;, ExceptionCodeWithMessage&amp;);
</span><span class="cx">     RefPtr&lt;WebCore::IDBRequest&gt; doGet(ScriptExecutionContext&amp;, const IDBKeyRangeData&amp;, ExceptionCodeWithMessage&amp;);
</span><span class="cx">     RefPtr&lt;WebCore::IDBRequest&gt; doGetKey(ScriptExecutionContext&amp;, const IDBKeyRangeData&amp;, ExceptionCodeWithMessage&amp;);
</span><span class="cx"> 
</span><span class="cx">     IDBIndexInfo m_info;
</span><del>-    Ref&lt;IDBObjectStore&gt; m_objectStore;
</del><span class="cx"> 
</span><span class="cx">     bool m_deleted { false };
</span><ins>+
+    // Most of the time, an IDBObjectStore owns an IDBIndex through a std::unique_ptr.
+    // In that scenario, attempts to ref() the IDBIndex directly ref the IDBObjectStore, so it is okay to
+    // keep a raw reference to the IDBObjectStore because it will always outlive the IDBIndex.
+    IDBObjectStore&amp; m_objectStore;
+
+    // But when an IDBIndex is deleted from its IDBObjectStore that lifetime is no longer guaranteed.
+    // The IDBObjectStore no longer owns the IDBIndex, so the following needs to change:
+    // 1 - The IDBIndex must directly ref its IDBObjectStore to keep it alive.
+    // 2 - The IDBIndex becomes traditionally RefCounted.
+    // 2 - The IDBIndex holds its own std::unique_ptr, which it will clear out when its RefCount reaches 0.
+    RefPtr&lt;IDBObjectStore&gt; m_objectStoreRef;
+    unsigned m_refCount { 0 };
+    std::unique_ptr&lt;IDBIndex&gt; m_selfOwner;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBClient
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBObjectStoreImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include &quot;IndexedDB.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="cx"> #include &quot;SerializedScriptValue.h&quot;
</span><ins>+#include &lt;wtf/Locker.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBClient {
</span><span class="lines">@@ -486,10 +487,13 @@
</span><span class="cx">     m_transaction-&gt;database().didCreateIndexInfo(info);
</span><span class="cx"> 
</span><span class="cx">     // Create the actual IDBObjectStore from the transaction, which also schedules the operation server side.
</span><del>-    Ref&lt;IDBIndex&gt; index = m_transaction-&gt;createIndex(*this, info);
-    m_referencedIndexes.set(name, &amp;index.get());
</del><ins>+    auto index = m_transaction-&gt;createIndex(*this, info);
+    RefPtr&lt;IDBIndex&gt; refIndex = index.get();
</ins><span class="cx"> 
</span><del>-    return WTFMove(index);
</del><ins>+    Locker&lt;Lock&gt; locker(m_referencedIndexLock);
+    m_referencedIndexes.set(name, WTFMove(index));
+
+    return WTFMove(refIndex);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBIndex&gt; IDBObjectStore::index(const String&amp; indexName, ExceptionCodeWithMessage&amp; ec)
</span><span class="lines">@@ -508,9 +512,10 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    Locker&lt;Lock&gt; locker(m_referencedIndexLock);
</ins><span class="cx">     auto iterator = m_referencedIndexes.find(indexName);
</span><span class="cx">     if (iterator != m_referencedIndexes.end())
</span><del>-        return iterator-&gt;value;
</del><ins>+        return iterator-&gt;value.get();
</ins><span class="cx"> 
</span><span class="cx">     auto* info = m_info.infoForExistingIndex(indexName);
</span><span class="cx">     if (!info) {
</span><span class="lines">@@ -519,10 +524,11 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto index = IDBIndex::create(*info, *this);
-    m_referencedIndexes.set(indexName, &amp;index.get());
</del><ins>+    auto index = std::make_unique&lt;IDBIndex&gt;(*info, *this);
+    RefPtr&lt;IDBIndex&gt; refIndex = index.get();
+    m_referencedIndexes.set(indexName, WTFMove(index));
</ins><span class="cx"> 
</span><del>-    return WTFMove(index);
</del><ins>+    return refIndex;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void IDBObjectStore::deleteIndex(const String&amp; name, ExceptionCodeWithMessage&amp; ec)
</span><span class="lines">@@ -559,8 +565,11 @@
</span><span class="cx"> 
</span><span class="cx">     m_info.deleteIndex(name);
</span><span class="cx"> 
</span><del>-    if (auto index = m_referencedIndexes.take(name))
-        index-&gt;markAsDeleted();
</del><ins>+    {
+        Locker&lt;Lock&gt; locker(m_referencedIndexLock);
+        if (auto index = m_referencedIndexes.take(name))
+            index-&gt;markAsDeleted(WTFMove(index));
+    }
</ins><span class="cx"> 
</span><span class="cx">     m_transaction-&gt;deleteIndex(m_info.identifier(), name);
</span><span class="cx"> }
</span><span class="lines">@@ -646,6 +655,13 @@
</span><span class="cx">     m_info = m_originalInfo;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void IDBObjectStore::visitReferencedIndexes(JSC::SlotVisitor&amp; visitor) const
+{
+    Locker&lt;Lock&gt; locker(m_referencedIndexLock);
+    for (auto&amp; index : m_referencedIndexes.values())
+        visitor.addOpaqueRoot(index.get());
+}
+
</ins><span class="cx"> } // namespace IDBClient
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBObjectStoreImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -93,6 +93,10 @@
</span><span class="cx"> 
</span><span class="cx">     void rollbackInfoForVersionChangeAbort();
</span><span class="cx"> 
</span><ins>+    virtual bool isModern() const override { return true; }
+
+    void visitReferencedIndexes(JSC::SlotVisitor&amp;) const;
+
</ins><span class="cx"> private:
</span><span class="cx">     IDBObjectStore(const IDBObjectStoreInfo&amp;, IDBTransaction&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -111,7 +115,8 @@
</span><span class="cx"> 
</span><span class="cx">     bool m_deleted { false };
</span><span class="cx"> 
</span><del>-    HashMap&lt;String, RefPtr&lt;IDBIndex&gt;&gt; m_referencedIndexes;
</del><ins>+    mutable Lock m_referencedIndexLock;
+    HashMap&lt;String, std::unique_ptr&lt;IDBIndex&gt;&gt; m_referencedIndexes;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBClient
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -494,17 +494,15 @@
</span><span class="cx">     ASSERT_UNUSED(resultData, resultData.type() == IDBResultType::CreateObjectStoreSuccess || resultData.type() == IDBResultType::Error);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;IDBIndex&gt; IDBTransaction::createIndex(IDBObjectStore&amp; objectStore, const IDBIndexInfo&amp; info)
</del><ins>+std::unique_ptr&lt;IDBIndex&gt; IDBTransaction::createIndex(IDBObjectStore&amp; objectStore, const IDBIndexInfo&amp; info)
</ins><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBTransaction::createIndex&quot;);
</span><span class="cx">     ASSERT(isVersionChange());
</span><span class="cx"> 
</span><del>-    Ref&lt;IDBIndex&gt; index = IDBIndex::create(info, objectStore);
-
</del><span class="cx">     auto operation = createTransactionOperation(*this, &amp;IDBTransaction::didCreateIndexOnServer, &amp;IDBTransaction::createIndexOnServer, info);
</span><span class="cx">     scheduleOperation(WTFMove(operation));
</span><span class="cx"> 
</span><del>-    return index;
</del><ins>+    return std::make_unique&lt;IDBIndex&gt;(info, objectStore);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void IDBTransaction::createIndexOnServer(TransactionOperation&amp; operation, const IDBIndexInfo&amp; info)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx">     bool isActive() const;
</span><span class="cx"> 
</span><span class="cx">     Ref&lt;IDBObjectStore&gt; createObjectStore(const IDBObjectStoreInfo&amp;);
</span><del>-    Ref&lt;IDBIndex&gt; createIndex(IDBObjectStore&amp;, const IDBIndexInfo&amp;);
</del><ins>+    std::unique_ptr&lt;IDBIndex&gt; createIndex(IDBObjectStore&amp;, const IDBIndexInfo&amp;);
</ins><span class="cx"> 
</span><span class="cx">     Ref&lt;IDBRequest&gt; requestPutOrAdd(ScriptExecutionContext&amp;, IDBObjectStore&amp;, IDBKey*, SerializedScriptValue&amp;, IndexedDB::ObjectStoreOverwriteMode);
</span><span class="cx">     Ref&lt;IDBRequest&gt; requestGetRecord(ScriptExecutionContext&amp;, IDBObjectStore&amp;, const IDBKeyRangeData&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddblegacyLegacyIndexcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/legacy/LegacyIndex.cpp (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/legacy/LegacyIndex.cpp        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/legacy/LegacyIndex.cpp        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -54,6 +54,19 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void LegacyIndex::ref()
+{
+    ++m_refCount;
+}
+
+void LegacyIndex::deref()
+{
+    if (--m_refCount)
+        return;
+
+    delete this;
+}
+
</ins><span class="cx"> RefPtr&lt;IDBRequest&gt; LegacyIndex::openCursor(ScriptExecutionContext* context, IDBKeyRange* keyRange, const String&amp; directionString, ExceptionCodeWithMessage&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     LOG(StorageAPI, &quot;LegacyIndex::openCursor&quot;);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddblegacyLegacyIndexh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/legacy/LegacyIndex.h (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/legacy/LegacyIndex.h        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/Modules/indexeddb/legacy/LegacyIndex.h        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -89,6 +89,9 @@
</span><span class="cx"> 
</span><span class="cx">     IDBDatabaseBackend* backendDB() const;
</span><span class="cx"> 
</span><ins>+    virtual void ref() override;
+    virtual void deref() override;
+
</ins><span class="cx"> private:
</span><span class="cx">     LegacyIndex(const IDBIndexMetadata&amp;, LegacyObjectStore*, LegacyTransaction*);
</span><span class="cx"> 
</span><span class="lines">@@ -96,6 +99,8 @@
</span><span class="cx">     RefPtr&lt;LegacyObjectStore&gt; m_objectStore;
</span><span class="cx">     RefPtr&lt;LegacyTransaction&gt; m_transaction;
</span><span class="cx">     bool m_deleted;
</span><ins>+
+    unsigned m_refCount { 1 };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -1981,6 +1981,7 @@
</span><span class="cx">                 514129901C601ACC0059E714 /* ScopeGuard.h in Headers */ = {isa = PBXBuildFile; fileRef = 5141298F1C601A890059E714 /* ScopeGuard.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 514129981C6976900059E714 /* IDBRequestCompletionEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 514129961C6976150059E714 /* IDBRequestCompletionEvent.cpp */; };
</span><span class="cx">                 514129991C6976900059E714 /* IDBRequestCompletionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 514129971C6976150059E714 /* IDBRequestCompletionEvent.h */; };
</span><ins>+                5141299B1C6C16740059E714 /* JSIDBIndexCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5141299A1C6C166D0059E714 /* JSIDBIndexCustom.cpp */; };
</ins><span class="cx">                 5145B1091BC48E2E00E86219 /* IDBResourceIdentifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5145B1071BC4890B00E86219 /* IDBResourceIdentifier.cpp */; };
</span><span class="cx">                 5145B10A1BC48E2E00E86219 /* IDBResourceIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 5145B1081BC4890B00E86219 /* IDBResourceIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 5148453E1BB9D07E006A72ED /* IDBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5148453C1BB9D076006A72ED /* IDBError.cpp */; };
</span><span class="lines">@@ -9489,6 +9490,7 @@
</span><span class="cx">                 5141298F1C601A890059E714 /* ScopeGuard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeGuard.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 514129961C6976150059E714 /* IDBRequestCompletionEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBRequestCompletionEvent.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 514129971C6976150059E714 /* IDBRequestCompletionEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBRequestCompletionEvent.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                5141299A1C6C166D0059E714 /* JSIDBIndexCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBIndexCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 5145B1071BC4890B00E86219 /* IDBResourceIdentifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBResourceIdentifier.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5145B1081BC4890B00E86219 /* IDBResourceIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBResourceIdentifier.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5148453C1BB9D076006A72ED /* IDBError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBError.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -22352,6 +22354,7 @@
</span><span class="cx">                                 512BDB4C1C46B0FF006494DF /* JSIDBCursorCustom.cpp */,
</span><span class="cx">                                 5141298D1C5FD7E90059E714 /* JSIDBCursorWithValueCustom.cpp */,
</span><span class="cx">                                 511EF2CD17F0FDF100E4FA16 /* JSIDBDatabaseCustom.cpp */,
</span><ins>+                                5141299A1C6C166D0059E714 /* JSIDBIndexCustom.cpp */,
</ins><span class="cx">                                 511EF2CE17F0FDF100E4FA16 /* JSIDBObjectStoreCustom.cpp */,
</span><span class="cx">                                 A7D0318D0E93540300E24ACD /* JSImageDataCustom.cpp */,
</span><span class="cx">                                 7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */,
</span><span class="lines">@@ -29426,6 +29429,7 @@
</span><span class="cx">                                 3F2B33EC165AF15600E3987C /* DOMWebKitCSSViewportRule.mm in Sources */,
</span><span class="cx">                                 8A195933147EA16E00D1EA61 /* DOMWebKitNamedFlow.mm in Sources */,
</span><span class="cx">                                 31C0FF4D0E4CEFDD007D6FE5 /* DOMWebKitTransitionEvent.mm in Sources */,
</span><ins>+                                5141299B1C6C16740059E714 /* JSIDBIndexCustom.cpp in Sources */,
</ins><span class="cx">                                 85C7F5E80AAFBAFB004014DD /* DOMWheelEvent.mm in Sources */,
</span><span class="cx">                                 1403B99809EB13AF00797C7F /* DOMWindow.cpp in Sources */,
</span><span class="cx">                                 FD677738195CAF3D0072E0D3 /* DOMWindowCSS.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSIDBIndexCustomcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/js/JSIDBIndexCustom.cpp (0 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSIDBIndexCustom.cpp                                (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSIDBIndexCustom.cpp        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;JSIDBIndex.h&quot;
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include &quot;IDBIndexImpl.h&quot;
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSIDBIndex::visitAdditionalChildren(SlotVisitor&amp; visitor)
+{
+    if (!wrapped().isModern())
+        return;
+
+    visitor.addOpaqueRoot(&amp;static_cast&lt;IDBClient::IDBIndex&amp;&gt;(wrapped()).modernObjectStore());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSIDBObjectStoreCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSIDBObjectStoreCustom.cpp (196481 => 196482)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSIDBObjectStoreCustom.cpp        2016-02-12 17:33:00 UTC (rev 196481)
+++ trunk/Source/WebCore/bindings/js/JSIDBObjectStoreCustom.cpp        2016-02-12 18:30:43 UTC (rev 196482)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx"> #include &quot;IDBBindingUtilities.h&quot;
</span><span class="cx"> #include &quot;IDBDatabaseException.h&quot;
</span><span class="cx"> #include &quot;IDBKeyPath.h&quot;
</span><del>-#include &quot;IDBObjectStore.h&quot;
</del><ins>+#include &quot;IDBObjectStoreImpl.h&quot;
</ins><span class="cx"> #include &quot;JSDOMBinding.h&quot;
</span><span class="cx"> #include &quot;JSIDBIndex.h&quot;
</span><span class="cx"> #include &quot;JSIDBRequest.h&quot;
</span><span class="lines">@@ -45,6 +45,14 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+void JSIDBObjectStore::visitAdditionalChildren(SlotVisitor&amp; visitor)
+{
+    if (!wrapped().isModern())
+        return;
+
+    static_cast&lt;IDBClient::IDBObjectStore&amp;&gt;(wrapped()).visitReferencedIndexes(visitor);
+}
+
</ins><span class="cx"> static JSValue putOrAdd(JSC::ExecState&amp; state, bool overwrite)
</span><span class="cx"> {
</span><span class="cx">     JSValue thisValue = state.thisValue();
</span></span></pre>
</div>
</div>

</body>
</html>