<!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>[208467] trunk</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/208467">208467</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2016-11-09 12:23:11 -0800 (Wed, 09 Nov 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>IndexedDB 2.0: Clean up more transaction abort behavior, including tweaks to Index/ObjectStore lifetime.
https://bugs.webkit.org/show_bug.cgi?id=164466
Reviewed by Alex Christensen.
LayoutTests/imported/w3c:
* web-platform-tests/IndexedDB/transaction-abort-index-metadata-revert-expected.txt:
* web-platform-tests/IndexedDB/transaction-abort-multiple-metadata-revert-expected.txt:
* web-platform-tests/IndexedDB/transaction-abort-object-store-metadata-revert-expected.txt:
Source/WebCore:
No new tests (Covered by existing tests that now pass).
Previously, IDBIndex ref/deref didn't track a traditional ref count but instead kept the owning object store alive.
Now, IDBObjectStore ref/deref do the same thing for the owning transaction.
Now when a version change transaction is rolled back, some object stores and indexes get pulled out of the "deleted"
set and get promoted back up into the "referenced" set.
Now deleted object stores/indexes are considered opaque roots, as live objects in the deleted state *can* get back
to the owning objects.
* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
* Modules/indexeddb/IDBIndex.cpp:
(WebCore::IDBIndex::rollbackInfoForVersionChangeAbort):
* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::IDBObjectStore):
(WebCore::IDBObjectStore::indexNames):
(WebCore::IDBObjectStore::transaction):
(WebCore::IDBObjectStore::openCursor):
(WebCore::IDBObjectStore::openKeyCursor):
(WebCore::IDBObjectStore::deleteIndex):
(WebCore::IDBObjectStore::rollbackForVersionChangeAbort):
(WebCore::IDBObjectStore::visitReferencedIndexes):
(WebCore::IDBObjectStore::ref):
(WebCore::IDBObjectStore::deref):
(WebCore::IDBObjectStore::create): Deleted.
* Modules/indexeddb/IDBObjectStore.h:
* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::objectStore):
(WebCore::IDBTransaction::transitionedToFinishing):
(WebCore::IDBTransaction::internalAbort):
(WebCore::IDBTransaction::createObjectStore):
(WebCore::IDBTransaction::deleteObjectStore):
(WebCore::IDBTransaction::visitReferencedObjectStores):
* Modules/indexeddb/IDBTransaction.h:
* Modules/indexeddb/IDBTransaction.idl:
* bindings/js/JSIDBTransactionCustom.cpp: Added.
(WebCore::JSIDBTransaction::visitAdditionalChildren):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsimportedw3cChangeLog">trunk/LayoutTests/imported/w3c/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsIndexedDBtransactionabortindexmetadatarevertexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-index-metadata-revert-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsIndexedDBtransactionabortmultiplemetadatarevertexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-multiple-metadata-revert-expected.txt</a></li>
<li><a href="#trunkLayoutTestsimportedw3cwebplatformtestsIndexedDBtransactionabortobjectstoremetadatarevertexpectedtxt">trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-object-store-metadata-revert-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBIndexcpp">trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBObjectStorecpp">trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBObjectStoreh">trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBTransactioncpp">trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBTransactionh">trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBTransactionidl">trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.idl</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorebindingsjsJSIDBTransactionCustomcpp">trunk/Source/WebCore/bindings/js/JSIDBTransactionCustom.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsimportedw3cChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/ChangeLog (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/ChangeLog        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/LayoutTests/imported/w3c/ChangeLog        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-11-09 Brady Eidson <beidson@apple.com>
+
+ IndexedDB 2.0: Clean up more transaction abort behavior, including tweaks to Index/ObjectStore lifetime.
+ https://bugs.webkit.org/show_bug.cgi?id=164466
+
+ Reviewed by Alex Christensen.
+
+ * web-platform-tests/IndexedDB/transaction-abort-index-metadata-revert-expected.txt:
+ * web-platform-tests/IndexedDB/transaction-abort-multiple-metadata-revert-expected.txt:
+ * web-platform-tests/IndexedDB/transaction-abort-object-store-metadata-revert-expected.txt:
+
</ins><span class="cx"> 2016-11-09 Alex Christensen <achristensen@webkit.org>
</span><span class="cx">
</span><span class="cx"> Ignore URL.origin in URL web-platform-tests
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsIndexedDBtransactionabortindexmetadatarevertexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-index-metadata-revert-expected.txt (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-index-metadata-revert-expected.txt        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-index-metadata-revert-expected.txt        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -1,8 +1,8 @@
</span><span class="cx">
</span><span class="cx"> PASS Created stores get their indexes marked as deleted after the transaction that created them aborts
</span><del>-FAIL Deleted stores get their indexes marked as not-deleted after the transaction that deleted them aborts assert_array_equals: IDBObjectStore.indexNames should be empty immediately after IDBDatabase.deleteObjectStore() returns lengths differ, expected 0 got 2
-FAIL Created+deleted stores still have their indexes marked as deleted after the transaction aborts assert_array_equals: IDBObjectStore.indexNames should be empty immediately after IDBDatabase.deleteObjectStore() returns lengths differ, expected 0 got 2
</del><ins>+PASS Deleted stores get their indexes marked as not-deleted after the transaction that deleted them aborts
+PASS Created+deleted stores still have their indexes marked as deleted after the transaction aborts
</ins><span class="cx"> PASS Created indexes get marked as deleted after their transaction aborts
</span><del>-FAIL Deleted indexes get marked as not-deleted after the transaction aborts assert_throws: IDBIndex.get should throw TransactionInactiveError, indicating that the index is no longer marked for deletion, immediately after IDBTransaction.abort() returns function "() => index.get('query')" threw object "InvalidStateError (DOM IDBDatabase Exception 11): Failed ..." that is not a DOMException TransactionInactiveError: property "code" is equal to 11, expected 0
</del><ins>+PASS Deleted indexes get marked as not-deleted after the transaction aborts
</ins><span class="cx"> PASS Created+deleted indexes are still marked as deleted after their transaction aborts
</span><span class="cx">
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsIndexedDBtransactionabortmultiplemetadatarevertexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-multiple-metadata-revert-expected.txt (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-multiple-metadata-revert-expected.txt        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-multiple-metadata-revert-expected.txt        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx">
</span><span class="cx"> PASS Deleted indexes in newly created stores are still marked as deleted after the transaction aborts
</span><del>-FAIL Deleted indexes in deleted stores are still marked as not-deleted after the transaction aborts assert_array_equals: IDBObjectStore.indexNames for the deleted store should be empty immediately after IDBDatabase.deleteObjectStore() returns lengths differ, expected 0 got 1
-FAIL Deleted indexes in created+deleted stores are still marked as deleted after their transaction aborts assert_array_equals: IDBObjectStore.indexNames should be empty immediately after IDBDatabase.deleteObjectStore() returns lengths differ, expected 0 got 1
</del><ins>+PASS Deleted indexes in deleted stores are still marked as not-deleted after the transaction aborts
+PASS Deleted indexes in created+deleted stores are still marked as deleted after their transaction aborts
</ins><span class="cx">
</span></span></pre></div>
<a id="trunkLayoutTestsimportedw3cwebplatformtestsIndexedDBtransactionabortobjectstoremetadatarevertexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-object-store-metadata-revert-expected.txt (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-object-store-metadata-revert-expected.txt        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/transaction-abort-object-store-metadata-revert-expected.txt        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx">
</span><span class="cx"> PASS Created stores get marked as deleted after their transaction aborts
</span><del>-FAIL Deleted stores get marked as not-deleted after the transaction aborts assert_throws: IDBObjectStore.get should throw TransactionInactiveError, indicating that the store is no longer marked for deletion, immediately after IDBTransaction.abort() returns function "() => store.get('query')" threw object "InvalidStateError (DOM IDBDatabase Exception 11): Failed ..." that is not a DOMException TransactionInactiveError: property "code" is equal to 11, expected 0
</del><ins>+PASS Deleted stores get marked as not-deleted after the transaction aborts
</ins><span class="cx"> PASS Created+deleted stores are still marked as deleted after their transaction aborts
</span><span class="cx"> PASS Un-instantiated deleted stores get marked as not-deleted after the transaction aborts
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -1152,6 +1152,7 @@
</span><span class="cx"> bindings/js/JSIDBIndexCustom.cpp
</span><span class="cx"> bindings/js/JSIDBObjectStoreCustom.cpp
</span><span class="cx"> bindings/js/JSIDBRequestCustom.cpp
</span><ins>+ bindings/js/JSIDBTransactionCustom.cpp
</ins><span class="cx"> bindings/js/JSImageConstructor.cpp
</span><span class="cx"> bindings/js/JSImageDataCustom.cpp
</span><span class="cx"> bindings/js/JSInspectorFrontendHostCustom.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/Source/WebCore/ChangeLog        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -1,3 +1,54 @@
</span><ins>+2016-11-09 Brady Eidson <beidson@apple.com>
+
+ IndexedDB 2.0: Clean up more transaction abort behavior, including tweaks to Index/ObjectStore lifetime.
+ https://bugs.webkit.org/show_bug.cgi?id=164466
+
+ Reviewed by Alex Christensen.
+
+ No new tests (Covered by existing tests that now pass).
+
+ Previously, IDBIndex ref/deref didn't track a traditional ref count but instead kept the owning object store alive.
+ Now, IDBObjectStore ref/deref do the same thing for the owning transaction.
+
+ Now when a version change transaction is rolled back, some object stores and indexes get pulled out of the "deleted"
+ set and get promoted back up into the "referenced" set.
+
+ Now deleted object stores/indexes are considered opaque roots, as live objects in the deleted state *can* get back
+ to the owning objects.
+
+ * CMakeLists.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+
+ * Modules/indexeddb/IDBIndex.cpp:
+ (WebCore::IDBIndex::rollbackInfoForVersionChangeAbort):
+
+ * Modules/indexeddb/IDBObjectStore.cpp:
+ (WebCore::IDBObjectStore::IDBObjectStore):
+ (WebCore::IDBObjectStore::indexNames):
+ (WebCore::IDBObjectStore::transaction):
+ (WebCore::IDBObjectStore::openCursor):
+ (WebCore::IDBObjectStore::openKeyCursor):
+ (WebCore::IDBObjectStore::deleteIndex):
+ (WebCore::IDBObjectStore::rollbackForVersionChangeAbort):
+ (WebCore::IDBObjectStore::visitReferencedIndexes):
+ (WebCore::IDBObjectStore::ref):
+ (WebCore::IDBObjectStore::deref):
+ (WebCore::IDBObjectStore::create): Deleted.
+ * Modules/indexeddb/IDBObjectStore.h:
+
+ * Modules/indexeddb/IDBTransaction.cpp:
+ (WebCore::IDBTransaction::objectStore):
+ (WebCore::IDBTransaction::transitionedToFinishing):
+ (WebCore::IDBTransaction::internalAbort):
+ (WebCore::IDBTransaction::createObjectStore):
+ (WebCore::IDBTransaction::deleteObjectStore):
+ (WebCore::IDBTransaction::visitReferencedObjectStores):
+ * Modules/indexeddb/IDBTransaction.h:
+ * Modules/indexeddb/IDBTransaction.idl:
+
+ * bindings/js/JSIDBTransactionCustom.cpp: Added.
+ (WebCore::JSIDBTransaction::visitAdditionalChildren):
+
</ins><span class="cx"> 2016-11-09 Simon Fraser <simon.fraser@apple.com>
</span><span class="cx">
</span><span class="cx"> Allow customization of TextStream-based logging for geometry types
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBIndexcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBIndex.cpp        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -146,6 +146,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> m_info = m_originalInfo;
</span><ins>+ m_deleted = false;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> ExceptionOr<Ref<IDBRequest>> IDBIndex::openCursor(ExecState& execState, IDBKeyRange* range, const String& directionString)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBObjectStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -53,16 +53,11 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-Ref<IDBObjectStore> IDBObjectStore::create(ScriptExecutionContext& context, const IDBObjectStoreInfo& info, IDBTransaction& transaction)
-{
- return adoptRef(*new IDBObjectStore(context, info, transaction));
-}
-
</del><span class="cx"> IDBObjectStore::IDBObjectStore(ScriptExecutionContext& context, const IDBObjectStoreInfo& info, IDBTransaction& transaction)
</span><span class="cx"> : ActiveDOMObject(&context)
</span><span class="cx"> , m_info(info)
</span><span class="cx"> , m_originalInfo(info)
</span><del>- , m_transaction(transaction)
</del><ins>+ , m_transaction(&transaction)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(currentThread() == m_transaction->database().originThreadID());
</span><span class="cx">
</span><span class="lines">@@ -131,10 +126,13 @@
</span><span class="cx"> ASSERT(currentThread() == m_transaction->database().originThreadID());
</span><span class="cx">
</span><span class="cx"> RefPtr<DOMStringList> indexNames = DOMStringList::create();
</span><del>- for (auto& name : m_info.indexNames())
- indexNames->append(name);
- indexNames->sort();
</del><span class="cx">
</span><ins>+ if (!m_deleted) {
+ for (auto& name : m_info.indexNames())
+ indexNames->append(name);
+ indexNames->sort();
+ }
+
</ins><span class="cx"> return indexNames;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -141,7 +139,7 @@
</span><span class="cx"> IDBTransaction& IDBObjectStore::transaction()
</span><span class="cx"> {
</span><span class="cx"> ASSERT(currentThread() == m_transaction->database().originThreadID());
</span><del>- return m_transaction.get();
</del><ins>+ return *m_transaction;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool IDBObjectStore::autoIncrement() const
</span><span class="lines">@@ -165,7 +163,7 @@
</span><span class="cx"> if (!direction)
</span><span class="cx"> return Exception { TypeError };
</span><span class="cx">
</span><del>- auto info = IDBCursorInfo::objectStoreCursor(m_transaction.get(), m_info.identifier(), range.get(), direction.value(), IndexedDB::CursorType::KeyAndValue);
</del><ins>+ auto info = IDBCursorInfo::objectStoreCursor(*m_transaction, m_info.identifier(), range.get(), direction.value(), IndexedDB::CursorType::KeyAndValue);
</ins><span class="cx"> return m_transaction->requestOpenCursor(execState, *this, info);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -193,7 +191,7 @@
</span><span class="cx"> if (!direction)
</span><span class="cx"> return Exception { TypeError };
</span><span class="cx">
</span><del>- auto info = IDBCursorInfo::objectStoreCursor(m_transaction.get(), m_info.identifier(), range.get(), direction.value(), IndexedDB::CursorType::KeyOnly);
</del><ins>+ auto info = IDBCursorInfo::objectStoreCursor(*m_transaction, m_info.identifier(), range.get(), direction.value(), IndexedDB::CursorType::KeyOnly);
</ins><span class="cx"> return m_transaction->requestOpenCursor(execState, *this, info);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -494,9 +492,8 @@
</span><span class="cx"> Locker<Lock> locker(m_referencedIndexLock);
</span><span class="cx"> if (auto index = m_referencedIndexes.take(name)) {
</span><span class="cx"> index->markAsDeleted();
</span><del>- m_deletedIndexes.add(WTFMove(index));
</del><ins>+ m_deletedIndexes.add(index->info().identifier(), WTFMove(index));
</ins><span class="cx"> }
</span><del>-
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> m_transaction->deleteIndex(m_info.identifier(), name);
</span><span class="lines">@@ -608,6 +605,8 @@
</span><span class="cx"> m_info.rename(currentName);
</span><span class="cx"> m_deleted = true;
</span><span class="cx"> } else {
</span><ins>+ m_deleted = false;
+
</ins><span class="cx"> HashSet<uint64_t> indexesToRemove;
</span><span class="cx"> for (auto indexIdentifier : objectStoreInfo->indexMap().keys()) {
</span><span class="cx"> if (!objectStoreInfo->hasIndex(indexIdentifier))
</span><span class="lines">@@ -619,6 +618,13 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> Locker<Lock> locker(m_referencedIndexLock);
</span><ins>+ for (auto& iterator : m_deletedIndexes) {
+ if (m_info.hasIndex(iterator.key)) {
+ auto name = iterator.value->info().name();
+ m_referencedIndexes.set(name, WTFMove(iterator.value));
+ }
+ }
+
</ins><span class="cx"> for (auto& index : m_referencedIndexes.values())
</span><span class="cx"> index->rollbackInfoForVersionChangeAbort();
</span><span class="cx"> }
</span><span class="lines">@@ -628,6 +634,8 @@
</span><span class="cx"> Locker<Lock> locker(m_referencedIndexLock);
</span><span class="cx"> for (auto& index : m_referencedIndexes.values())
</span><span class="cx"> visitor.addOpaqueRoot(index.get());
</span><ins>+ for (auto& index : m_deletedIndexes.values())
+ visitor.addOpaqueRoot(index.get());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void IDBObjectStore::renameReferencedIndex(IDBIndex& index, const String& newName)
</span><span class="lines">@@ -645,6 +653,16 @@
</span><span class="cx"> m_referencedIndexes.set(newName, m_referencedIndexes.take(index.info().name()));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void IDBObjectStore::ref()
+{
+ m_transaction->ref();
+}
+
+void IDBObjectStore::deref()
+{
+ m_transaction->deref();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(INDEXED_DATABASE)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBObjectStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -54,10 +54,9 @@
</span><span class="cx"> enum class ObjectStoreOverwriteMode;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-class IDBObjectStore final : public RefCounted<IDBObjectStore>, public ActiveDOMObject {
</del><ins>+class IDBObjectStore final : public ActiveDOMObject {
</ins><span class="cx"> public:
</span><del>- static Ref<IDBObjectStore> create(ScriptExecutionContext&, const IDBObjectStoreInfo&, IDBTransaction&);
-
</del><ins>+ IDBObjectStore(ScriptExecutionContext&, const IDBObjectStoreInfo&, IDBTransaction&);
</ins><span class="cx"> ~IDBObjectStore();
</span><span class="cx">
</span><span class="cx"> const String& name() const;
</span><span class="lines">@@ -102,12 +101,13 @@
</span><span class="cx">
</span><span class="cx"> void rollbackForVersionChangeAbort();
</span><span class="cx">
</span><ins>+ void ref();
+ void deref();
+
</ins><span class="cx"> void visitReferencedIndexes(JSC::SlotVisitor&) const;
</span><span class="cx"> void renameReferencedIndex(IDBIndex&, const String& newName);
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- IDBObjectStore(ScriptExecutionContext&, const IDBObjectStoreInfo&, IDBTransaction&);
-
</del><span class="cx"> enum class InlineKeyCheck { Perform, DoNotPerform };
</span><span class="cx"> ExceptionOr<Ref<IDBRequest>> putOrAdd(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, InlineKeyCheck);
</span><span class="cx"> ExceptionOr<Ref<IDBRequest>> doCount(JSC::ExecState&, const IDBKeyRangeData&);
</span><span class="lines">@@ -119,13 +119,20 @@
</span><span class="cx">
</span><span class="cx"> IDBObjectStoreInfo m_info;
</span><span class="cx"> IDBObjectStoreInfo m_originalInfo;
</span><del>- Ref<IDBTransaction> m_transaction;
</del><span class="cx">
</span><ins>+ // IDBObjectStore objects are always owned by their referencing IDBTransaction.
+ // ObjectStores will never outlive transactions so its okay to keep a raw C++ reference here.
+
+ // FIXME: This should be a reference instead of a pointer (as mentioned by the above comment)
+ // but leaving it a pointer for now makes this patch much easier to review.
+ // I'll make the ptr->ref change right after this patch lands.
+ IDBTransaction* m_transaction;
+
</ins><span class="cx"> bool m_deleted { false };
</span><span class="cx">
</span><span class="cx"> mutable Lock m_referencedIndexLock;
</span><span class="cx"> HashMap<String, std::unique_ptr<IDBIndex>> m_referencedIndexes;
</span><del>- HashSet<std::unique_ptr<IDBIndex>> m_deletedIndexes;
</del><ins>+ HashMap<uint64_t, std::unique_ptr<IDBIndex>> m_deletedIndexes;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBTransactioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -149,6 +149,8 @@
</span><span class="cx"> if (isFinishedOrFinishing())
</span><span class="cx"> return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The transaction finished.") };
</span><span class="cx">
</span><ins>+ Locker<Lock> locker(m_referencedObjectStoreLock);
+
</ins><span class="cx"> auto iterator = m_referencedObjectStores.find(objectStoreName);
</span><span class="cx"> if (iterator != m_referencedObjectStores.end())
</span><span class="cx"> return Ref<IDBObjectStore> { *iterator->value };
</span><span class="lines">@@ -169,10 +171,11 @@
</span><span class="cx"> if (!info || (!found && !isVersionChange()))
</span><span class="cx"> return Exception { IDBDatabaseException::NotFoundError, ASCIILiteral("Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found.") };
</span><span class="cx">
</span><del>- auto objectStore = IDBObjectStore::create(*scriptExecutionContext(), *info, *this);
- m_referencedObjectStores.set(objectStoreName, objectStore.ptr());
</del><ins>+ auto objectStore = std::make_unique<IDBObjectStore>(*scriptExecutionContext(), *info, *this);
+ auto* rawObjectStore = objectStore.get();
+ m_referencedObjectStores.set(objectStoreName, WTFMove(objectStore));
</ins><span class="cx">
</span><del>- return WTFMove(objectStore);
</del><ins>+ return Ref<IDBObjectStore>(*rawObjectStore);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -195,7 +198,6 @@
</span><span class="cx"> ASSERT(!isFinishedOrFinishing());
</span><span class="cx"> m_state = state;
</span><span class="cx"> ASSERT(isFinishedOrFinishing());
</span><del>- m_referencedObjectStores.clear();
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> ExceptionOr<void> IDBTransaction::abort()
</span><span class="lines">@@ -220,6 +222,16 @@
</span><span class="cx"> m_database->willAbortTransaction(*this);
</span><span class="cx">
</span><span class="cx"> if (isVersionChange()) {
</span><ins>+ Locker<Lock> locker(m_referencedObjectStoreLock);
+
+ auto& info = m_database->info();
+ for (auto& iterator : m_deletedObjectStores) {
+ if (info.infoForExistingObjectStore(iterator.key)) {
+ auto name = iterator.value->info().name();
+ m_referencedObjectStores.set(name, WTFMove(iterator.value));
+ }
+ }
+
</ins><span class="cx"> for (auto& objectStore : m_referencedObjectStores.values())
</span><span class="cx"> objectStore->rollbackForVersionChangeAbort();
</span><span class="cx"> }
</span><span class="lines">@@ -517,12 +529,15 @@
</span><span class="cx"> ASSERT(scriptExecutionContext());
</span><span class="cx"> ASSERT(currentThread() == m_database->originThreadID());
</span><span class="cx">
</span><del>- Ref<IDBObjectStore> objectStore = IDBObjectStore::create(*scriptExecutionContext(), info, *this);
- m_referencedObjectStores.set(info.name(), &objectStore.get());
</del><ins>+ Locker<Lock> locker(m_referencedObjectStoreLock);
</ins><span class="cx">
</span><ins>+ auto objectStore = std::make_unique<IDBObjectStore>(*scriptExecutionContext(), info, *this);
+ auto* rawObjectStore = objectStore.get();
+ m_referencedObjectStores.set(info.name(), WTFMove(objectStore));
+
</ins><span class="cx"> scheduleOperation(IDBClient::createTransactionOperation(*this, &IDBTransaction::didCreateObjectStoreOnServer, &IDBTransaction::createObjectStoreOnServer, info));
</span><span class="cx">
</span><del>- return objectStore;
</del><ins>+ return *rawObjectStore;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void IDBTransaction::createObjectStoreOnServer(IDBClient::TransactionOperation& operation, const IDBObjectStoreInfo& info)
</span><span class="lines">@@ -544,6 +559,9 @@
</span><span class="cx"> void IDBTransaction::renameObjectStore(IDBObjectStore& objectStore, const String& newName)
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "IDBTransaction::renameObjectStore");
</span><ins>+
+ Locker<Lock> locker(m_referencedObjectStoreLock);
+
</ins><span class="cx"> ASSERT(isVersionChange());
</span><span class="cx"> ASSERT(scriptExecutionContext());
</span><span class="cx"> ASSERT(currentThread() == m_database->originThreadID());
</span><span class="lines">@@ -618,6 +636,8 @@
</span><span class="cx"> void IDBTransaction::renameIndex(IDBIndex& index, const String& newName)
</span><span class="cx"> {
</span><span class="cx"> LOG(IndexedDB, "IDBTransaction::renameIndex");
</span><ins>+ Locker<Lock> locker(m_referencedObjectStoreLock);
+
</ins><span class="cx"> ASSERT(isVersionChange());
</span><span class="cx"> ASSERT(scriptExecutionContext());
</span><span class="cx"> ASSERT(currentThread() == m_database->originThreadID());
</span><span class="lines">@@ -1088,8 +1108,13 @@
</span><span class="cx"> ASSERT(currentThread() == m_database->originThreadID());
</span><span class="cx"> ASSERT(isVersionChange());
</span><span class="cx">
</span><del>- if (auto objectStore = m_referencedObjectStores.take(objectStoreName))
</del><ins>+ Locker<Lock> locker(m_referencedObjectStoreLock);
+
+ if (auto objectStore = m_referencedObjectStores.take(objectStoreName)) {
</ins><span class="cx"> objectStore->markAsDeleted();
</span><ins>+ auto identifier = objectStore->info().identifier();
+ m_deletedObjectStores.set(identifier, WTFMove(objectStore));
+ }
</ins><span class="cx">
</span><span class="cx"> scheduleOperation(IDBClient::createTransactionOperation(*this, &IDBTransaction::didDeleteObjectStoreOnServer, &IDBTransaction::deleteObjectStoreOnServer, objectStoreName));
</span><span class="cx"> }
</span><span class="lines">@@ -1197,6 +1222,15 @@
</span><span class="cx"> fireOnAbort();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void IDBTransaction::visitReferencedObjectStores(JSC::SlotVisitor& visitor) const
+{
+ Locker<Lock> locker(m_referencedObjectStoreLock);
+ for (auto& objectStore : m_referencedObjectStores.values())
+ visitor.addOpaqueRoot(objectStore.get());
+ for (auto& objectStore : m_deletedObjectStores.values())
+ visitor.addOpaqueRoot(objectStore.get());
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(INDEXED_DATABASE)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBTransactionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -146,6 +146,8 @@
</span><span class="cx">
</span><span class="cx"> void connectionClosedFromServer(const IDBError&);
</span><span class="cx">
</span><ins>+ void visitReferencedObjectStores(JSC::SlotVisitor&) const;
+
</ins><span class="cx"> private:
</span><span class="cx"> IDBTransaction(IDBDatabase&, const IDBTransactionInfo&, IDBOpenDBRequest*);
</span><span class="cx">
</span><span class="lines">@@ -234,7 +236,9 @@
</span><span class="cx"> Deque<RefPtr<IDBClient::TransactionOperation>> m_abortQueue;
</span><span class="cx"> HashMap<IDBResourceIdentifier, RefPtr<IDBClient::TransactionOperation>> m_transactionOperationMap;
</span><span class="cx">
</span><del>- HashMap<String, RefPtr<IDBObjectStore>> m_referencedObjectStores;
</del><ins>+ mutable Lock m_referencedObjectStoreLock;
+ HashMap<String, std::unique_ptr<IDBObjectStore>> m_referencedObjectStores;
+ HashMap<uint64_t, std::unique_ptr<IDBObjectStore>> m_deletedObjectStores;
</ins><span class="cx">
</span><span class="cx"> HashSet<RefPtr<IDBRequest>> m_openRequests;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBTransactionidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.idl (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.idl        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.idl        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> ActiveDOMObject,
</span><span class="cx"> Conditional=INDEXED_DATABASE,
</span><span class="cx"> EnabledAtRuntime=IndexedDB,
</span><ins>+ JSCustomMarkFunction,
</ins><span class="cx"> SkipVTableValidation,
</span><span class="cx"> ] interface IDBTransaction : EventTarget {
</span><span class="cx"> readonly attribute DOMStringList objectStoreNames;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (208466 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-11-09 20:22:37 UTC (rev 208466)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -2256,6 +2256,7 @@
</span><span class="cx">                 51E1ECC10C91C90400DC255B /* IconRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 51E1ECBB0C91C90400DC255B /* IconRecord.h */; };
</span><span class="cx">                 51E1ECC20C91C90400DC255B /* PageURLRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51E1ECBC0C91C90400DC255B /* PageURLRecord.cpp */; };
</span><span class="cx">                 51E1ECC30C91C90400DC255B /* PageURLRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 51E1ECBD0C91C90400DC255B /* PageURLRecord.h */; };
</span><ins>+                51E269331DD3BC4E006B6A58 /* JSIDBTransactionCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51E269321DD3BC43006B6A58 /* JSIDBTransactionCustom.cpp */; };
</ins><span class="cx">                 51E399001D6E4750009C8831 /* GameControllerGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 51E398FC1D6E474B009C8831 /* GameControllerGamepad.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 51E399011D6E4750009C8831 /* GameControllerGamepad.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51E398FD1D6E474B009C8831 /* GameControllerGamepad.mm */; };
</span><span class="cx">                 51E399021D6E4750009C8831 /* GameControllerGamepadProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 51E398FE1D6E474B009C8831 /* GameControllerGamepadProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -9405,6 +9406,7 @@
</span><span class="cx">                 51E1ECBB0C91C90400DC255B /* IconRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IconRecord.h; sourceTree = "<group>"; };
</span><span class="cx">                 51E1ECBC0C91C90400DC255B /* PageURLRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageURLRecord.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 51E1ECBD0C91C90400DC255B /* PageURLRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageURLRecord.h; sourceTree = "<group>"; };
</span><ins>+                51E269321DD3BC43006B6A58 /* JSIDBTransactionCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBTransactionCustom.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 51E398FC1D6E474B009C8831 /* GameControllerGamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameControllerGamepad.h; sourceTree = "<group>"; };
</span><span class="cx">                 51E398FD1D6E474B009C8831 /* GameControllerGamepad.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GameControllerGamepad.mm; sourceTree = "<group>"; };
</span><span class="cx">                 51E398FE1D6E474B009C8831 /* GameControllerGamepadProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameControllerGamepadProvider.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -21828,6 +21830,7 @@
</span><span class="cx">                                 5141299A1C6C166D0059E714 /* JSIDBIndexCustom.cpp */,
</span><span class="cx">                                 511EF2CE17F0FDF100E4FA16 /* JSIDBObjectStoreCustom.cpp */,
</span><span class="cx">                                 934F31B41CC0737200DB43DC /* JSIDBRequestCustom.cpp */,
</span><ins>+                                51E269321DD3BC43006B6A58 /* JSIDBTransactionCustom.cpp */,
</ins><span class="cx">                                 A7D0318D0E93540300E24ACD /* JSImageDataCustom.cpp */,
</span><span class="cx">                                 7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */,
</span><span class="cx">                                 BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */,
</span><span class="lines">@@ -28884,6 +28887,7 @@
</span><span class="cx">                                 FD6ED2C3136B8E42003CF072 /* DynamicsCompressorNode.cpp in Sources */,
</span><span class="cx">                                 93309DE3099E64920056E581 /* EditCommand.cpp in Sources */,
</span><span class="cx">                                 9BAB6C6D12550631001626D4 /* EditingStyle.cpp in Sources */,
</span><ins>+                                51E269331DD3BC4E006B6A58 /* JSIDBTransactionCustom.cpp in Sources */,
</ins><span class="cx">                                 4B3043CC0AE0373B00A82647 /* Editor.cpp in Sources */,
</span><span class="cx">                                 9B55EEE91B3E8898005342BC /* EditorCocoa.mm in Sources */,
</span><span class="cx">                                 93A38B4B0D0E5808006872C2 /* EditorCommand.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSIDBTransactionCustomcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/js/JSIDBTransactionCustom.cpp (0 => 208467)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSIDBTransactionCustom.cpp         (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSIDBTransactionCustom.cpp        2016-11-09 20:23:11 UTC (rev 208467)
</span><span class="lines">@@ -0,0 +1,44 @@
</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 "JSIDBTransaction.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "JSDOMBinding.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSIDBTransaction::visitAdditionalChildren(SlotVisitor& visitor)
+{
+ static_cast<IDBTransaction&>(wrapped()).visitReferencedObjectStores(visitor);
+}
+
+}
+
+#endif
</ins></span></pre>
</div>
</div>
</body>
</html>