<!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 "traditionally RefCounted" 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 <beidson@apple.com>
+
+ 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 "traditionally RefCounted" 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 <ossy@webkit.org>
</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<IDBIndex> {
</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<IDBRequest> getKey(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
</span><span class="cx"> virtual RefPtr<IDBRequest> getKey(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 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<IDBRequest> count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCodeWithMessage&) = 0;
</span><span class="cx"> virtual RefPtr<IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) = 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<IDBIndex> IDBIndex::create(const IDBIndexInfo& info, IDBObjectStore& objectStore)
-{
- return adoptRef(*new IDBIndex(info, objectStore));
-}
-
</del><span class="cx"> IDBIndex::IDBIndex(const IDBIndexInfo& info, IDBObjectStore& 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<WebCore::IDBObjectStore> IDBIndex::objectStore()
</span><span class="cx"> {
</span><del>- return &m_objectStore.get();
</del><ins>+ return &m_objectStore;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RefPtr<WebCore::IDBAny> IDBIndex::keyPathAny() const
</span><span class="lines">@@ -90,13 +85,13 @@
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "IDBIndex::openCursor");
</span><span class="cx">
</span><del>- if (m_deleted || m_objectStore->isDeleted()) {
</del><ins>+ if (m_deleted || m_objectStore.isDeleted()) {
</ins><span class="cx"> ec.code = IDBDatabaseException::InvalidStateError;
</span><span class="cx"> ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The index or its object store has been deleted.");
</span><span class="cx"> return nullptr;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (!m_objectStore->modernTransaction().isActive()) {
</del><ins>+ if (!m_objectStore.modernTransaction().isActive()) {
</ins><span class="cx"> ec.code = IDBDatabaseException::TransactionInactiveError;
</span><span class="cx"> ec.message = ASCIILiteral("Failed to execute 'openCursor' on 'IDBIndex': The transaction is inactive or finished.");
</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->modernTransaction(), m_objectStore->info().identifier(), m_info.identifier(), rangeData, direction, IndexedDB::CursorType::KeyAndValue);
- Ref<IDBRequest> request = m_objectStore->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<WebCore::IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage& ec)
</span><span class="lines">@@ -177,7 +171,7 @@
</span><span class="cx">
</span><span class="cx"> RefPtr<WebCore::IDBRequest> IDBIndex::doCount(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
</span><span class="cx"> {
</span><del>- if (m_deleted || m_objectStore->isDeleted()) {
</del><ins>+ if (m_deleted || m_objectStore.isDeleted()) {
</ins><span class="cx"> ec.code = IDBDatabaseException::InvalidStateError;
</span><span class="cx"> ec.message = ASCIILiteral("Failed to execute 'count' on 'IDBIndex': The index or its object store has been deleted.");
</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& transaction = m_objectStore->modernTransaction();
</del><ins>+ auto& 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("Failed to execute 'count' on 'IDBIndex': The transaction is inactive or finished.");
</span><span class="lines">@@ -202,13 +196,13 @@
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "IDBIndex::openKeyCursor");
</span><span class="cx">
</span><del>- if (m_deleted || m_objectStore->isDeleted()) {
</del><ins>+ if (m_deleted || m_objectStore.isDeleted()) {
</ins><span class="cx"> ec.code = IDBDatabaseException::InvalidStateError;
</span><span class="cx"> ec.message = ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The index or its object store has been deleted.");
</span><span class="cx"> return nullptr;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (!m_objectStore->modernTransaction().isActive()) {
</del><ins>+ if (!m_objectStore.modernTransaction().isActive()) {
</ins><span class="cx"> ec.code = IDBDatabaseException::TransactionInactiveError;
</span><span class="cx"> ec.message = ASCIILiteral("Failed to execute 'openKeyCursor' on 'IDBIndex': The transaction is inactive or finished.");
</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->modernTransaction(), m_objectStore->info().identifier(), m_info.identifier(), range, direction, IndexedDB::CursorType::KeyOnly);
- Ref<IDBRequest> request = m_objectStore->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<WebCore::IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, const String& direction, ExceptionCodeWithMessage& ec)
</span><span class="lines">@@ -270,7 +263,7 @@
</span><span class="cx">
</span><span class="cx"> RefPtr<WebCore::IDBRequest> IDBIndex::doGet(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
</span><span class="cx"> {
</span><del>- if (m_deleted || m_objectStore->isDeleted()) {
</del><ins>+ if (m_deleted || m_objectStore.isDeleted()) {
</ins><span class="cx"> ec.code = IDBDatabaseException::InvalidStateError;
</span><span class="cx"> ec.message = ASCIILiteral("Failed to execute 'get' on 'IDBIndex': The index or its object store has been deleted.");
</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& transaction = m_objectStore->modernTransaction();
</del><ins>+ auto& 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("Failed to execute 'get' on 'IDBIndex': The transaction is inactive or finished.");
</span><span class="lines">@@ -325,7 +318,7 @@
</span><span class="cx">
</span><span class="cx"> RefPtr<WebCore::IDBRequest> IDBIndex::doGetKey(ScriptExecutionContext& context, const IDBKeyRangeData& range, ExceptionCodeWithMessage& ec)
</span><span class="cx"> {
</span><del>- if (m_deleted || m_objectStore->isDeleted()) {
</del><ins>+ if (m_deleted || m_objectStore.isDeleted()) {
</ins><span class="cx"> ec.code = IDBDatabaseException::InvalidStateError;
</span><span class="cx"> ec.message = ASCIILiteral("Failed to execute 'getKey' on 'IDBIndex': The index or its object store has been deleted.");
</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& transaction = m_objectStore->modernTransaction();
</del><ins>+ auto& 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("Failed to execute 'getKey' on 'IDBIndex': The transaction is inactive or finished.");
</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<IDBIndex>&& 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 = &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 > 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<IDBIndex> create(const IDBIndexInfo&, IDBObjectStore&);
</del><ins>+ IDBIndex(const IDBIndexInfo&, IDBObjectStore&);
</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& info() const { return m_info; }
</span><span class="cx">
</span><del>- IDBObjectStore& modernObjectStore() { return m_objectStore.get(); }
</del><ins>+ IDBObjectStore& modernObjectStore() { return m_objectStore; }
</ins><span class="cx">
</span><del>- void markAsDeleted();
</del><ins>+ void markAsDeleted(std::unique_ptr<IDBIndex>&&);
</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&, IDBObjectStore&);
-
</del><span class="cx"> RefPtr<WebCore::IDBRequest> doCount(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
</span><span class="cx"> RefPtr<WebCore::IDBRequest> doGet(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
</span><span class="cx"> RefPtr<WebCore::IDBRequest> doGetKey(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
</span><span class="cx">
</span><span class="cx"> IDBIndexInfo m_info;
</span><del>- Ref<IDBObjectStore> 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& 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<IDBObjectStore> m_objectStoreRef;
+ unsigned m_refCount { 0 };
+ std::unique_ptr<IDBIndex> 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 "IndexedDB.h"
</span><span class="cx"> #include "Logging.h"
</span><span class="cx"> #include "SerializedScriptValue.h"
</span><ins>+#include <wtf/Locker.h>
</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->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<IDBIndex> index = m_transaction->createIndex(*this, info);
- m_referencedIndexes.set(name, &index.get());
</del><ins>+ auto index = m_transaction->createIndex(*this, info);
+ RefPtr<IDBIndex> refIndex = index.get();
</ins><span class="cx">
</span><del>- return WTFMove(index);
</del><ins>+ Locker<Lock> 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<WebCore::IDBIndex> IDBObjectStore::index(const String& indexName, ExceptionCodeWithMessage& 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<Lock> 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->value;
</del><ins>+ return iterator->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, &index.get());
</del><ins>+ auto index = std::make_unique<IDBIndex>(*info, *this);
+ RefPtr<IDBIndex> 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& name, ExceptionCodeWithMessage& 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->markAsDeleted();
</del><ins>+ {
+ Locker<Lock> locker(m_referencedIndexLock);
+ if (auto index = m_referencedIndexes.take(name))
+ index->markAsDeleted(WTFMove(index));
+ }
</ins><span class="cx">
</span><span class="cx"> m_transaction->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& visitor) const
+{
+ Locker<Lock> locker(m_referencedIndexLock);
+ for (auto& 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&) const;
+
</ins><span class="cx"> private:
</span><span class="cx"> IDBObjectStore(const IDBObjectStoreInfo&, IDBTransaction&);
</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<String, RefPtr<IDBIndex>> m_referencedIndexes;
</del><ins>+ mutable Lock m_referencedIndexLock;
+ HashMap<String, std::unique_ptr<IDBIndex>> 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<IDBIndex> IDBTransaction::createIndex(IDBObjectStore& objectStore, const IDBIndexInfo& info)
</del><ins>+std::unique_ptr<IDBIndex> IDBTransaction::createIndex(IDBObjectStore& objectStore, const IDBIndexInfo& info)
</ins><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "IDBTransaction::createIndex");
</span><span class="cx"> ASSERT(isVersionChange());
</span><span class="cx">
</span><del>- Ref<IDBIndex> index = IDBIndex::create(info, objectStore);
-
</del><span class="cx"> auto operation = createTransactionOperation(*this, &IDBTransaction::didCreateIndexOnServer, &IDBTransaction::createIndexOnServer, info);
</span><span class="cx"> scheduleOperation(WTFMove(operation));
</span><span class="cx">
</span><del>- return index;
</del><ins>+ return std::make_unique<IDBIndex>(info, objectStore);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void IDBTransaction::createIndexOnServer(TransactionOperation& operation, const IDBIndexInfo& 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<IDBObjectStore> createObjectStore(const IDBObjectStoreInfo&);
</span><del>- Ref<IDBIndex> createIndex(IDBObjectStore&, const IDBIndexInfo&);
</del><ins>+ std::unique_ptr<IDBIndex> createIndex(IDBObjectStore&, const IDBIndexInfo&);
</ins><span class="cx">
</span><span class="cx"> Ref<IDBRequest> requestPutOrAdd(ScriptExecutionContext&, IDBObjectStore&, IDBKey*, SerializedScriptValue&, IndexedDB::ObjectStoreOverwriteMode);
</span><span class="cx"> Ref<IDBRequest> requestGetRecord(ScriptExecutionContext&, IDBObjectStore&, const IDBKeyRangeData&);
</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<IDBRequest> LegacyIndex::openCursor(ScriptExecutionContext* context, IDBKeyRange* keyRange, const String& directionString, ExceptionCodeWithMessage& ec)
</span><span class="cx"> {
</span><span class="cx"> LOG(StorageAPI, "LegacyIndex::openCursor");
</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&, LegacyObjectStore*, LegacyTransaction*);
</span><span class="cx">
</span><span class="lines">@@ -96,6 +99,8 @@
</span><span class="cx"> RefPtr<LegacyObjectStore> m_objectStore;
</span><span class="cx"> RefPtr<LegacyTransaction> 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 = "<group>"; };
</span><span class="cx">                 514129961C6976150059E714 /* IDBRequestCompletionEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBRequestCompletionEvent.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 514129971C6976150059E714 /* IDBRequestCompletionEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBRequestCompletionEvent.h; sourceTree = "<group>"; };
</span><ins>+                5141299A1C6C166D0059E714 /* JSIDBIndexCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBIndexCustom.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 5145B1071BC4890B00E86219 /* IDBResourceIdentifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBResourceIdentifier.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 5145B1081BC4890B00E86219 /* IDBResourceIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBResourceIdentifier.h; sourceTree = "<group>"; };
</span><span class="cx">                 5148453C1BB9D076006A72ED /* IDBError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBError.cpp; sourceTree = "<group>"; };
</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 "config.h"
+#include "JSIDBIndex.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBIndexImpl.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSIDBIndex::visitAdditionalChildren(SlotVisitor& visitor)
+{
+ if (!wrapped().isModern())
+ return;
+
+ visitor.addOpaqueRoot(&static_cast<IDBClient::IDBIndex&>(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 "IDBBindingUtilities.h"
</span><span class="cx"> #include "IDBDatabaseException.h"
</span><span class="cx"> #include "IDBKeyPath.h"
</span><del>-#include "IDBObjectStore.h"
</del><ins>+#include "IDBObjectStoreImpl.h"
</ins><span class="cx"> #include "JSDOMBinding.h"
</span><span class="cx"> #include "JSIDBIndex.h"
</span><span class="cx"> #include "JSIDBRequest.h"
</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& visitor)
+{
+ if (!wrapped().isModern())
+ return;
+
+ static_cast<IDBClient::IDBObjectStore&>(wrapped()).visitReferencedIndexes(visitor);
+}
+
</ins><span class="cx"> static JSValue putOrAdd(JSC::ExecState& state, bool overwrite)
</span><span class="cx"> {
</span><span class="cx"> JSValue thisValue = state.thisValue();
</span></span></pre>
</div>
</div>
</body>
</html>