Bug 1552547 part 1. Stop using [array] in mozIStorageAsyncConnection.executeAsync. r=mak
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 20 May 2019 16:17:51 +0000
changeset 474577 63d2eaf71d022b0fdaca6f12ca8ec4219d46f4c7
parent 474576 2b968611e3dc6fd76b6a2f179198eea14081d074
child 474578 5f2932daeff2c6370358feceb7d55f60952a47a1
push id85882
push userbzbarsky@mozilla.com
push dateMon, 20 May 2019 17:42:24 +0000
treeherderautoland@5f2932daeff2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs1552547
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1552547 part 1. Stop using [array] in mozIStorageAsyncConnection.executeAsync. r=mak Differential Revision: https://phabricator.services.mozilla.com/D31658
dom/cache/Connection.cpp
storage/mozIStorageAsyncConnection.idl
storage/mozStorageConnection.cpp
storage/test/gtest/test_asyncStatementExecution_transaction.cpp
storage/test/unit/head_storage.js
toolkit/components/places/Database.cpp
toolkit/components/places/PlacesExpiration.jsm
toolkit/components/places/nsFaviconService.cpp
toolkit/components/places/nsNavHistory.cpp
--- a/dom/cache/Connection.cpp
+++ b/dom/cache/Connection.cpp
@@ -77,17 +77,17 @@ Connection::GetDatabaseFile(nsIFile** aF
 NS_IMETHODIMP
 Connection::CreateAsyncStatement(const nsACString&,
                                  mozIStorageAsyncStatement**) {
   // async methods are not supported
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-Connection::ExecuteAsync(mozIStorageBaseStatement**, uint32_t,
+Connection::ExecuteAsync(const nsTArray<RefPtr<mozIStorageBaseStatement>>&,
                          mozIStorageStatementCallback*,
                          mozIStoragePendingStatement**) {
   // async methods are not supported
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 Connection::ExecuteSimpleSQLAsync(const nsACString&,
--- a/storage/mozIStorageAsyncConnection.idl
+++ b/storage/mozIStorageAsyncConnection.idl
@@ -160,29 +160,26 @@ interface mozIStorageAsyncConnection : n
    * any currently bound parameters. When the array contains multiple
    * statements, the execution is wrapped in a single
    * transaction. These statements can be reused immediately, and
    * reset does not need to be called.
    *
    * @param aStatements
    *        The array of statements to execute asynchronously, in the order they
    *        are given in the array.
-   * @param aNumStatements
-   *        The number of statements in aStatements.
    * @param aCallback [optional]
    *        The callback object that will be notified of progress, errors, and
    *        completion.
    * @return an object that can be used to cancel the statements execution.
    *
    * @note If you have any custom defined functions, they must be
    *        re-entrant since they can be called on multiple threads.
    */
   mozIStoragePendingStatement executeAsync(
-    [array, size_is(aNumStatements)] in mozIStorageBaseStatement aStatements,
-    in unsigned long aNumStatements,
+    in Array<mozIStorageBaseStatement> aStatements,
     [optional] in mozIStorageStatementCallback aCallback
   );
 
   /**
    * Execute asynchronously an SQL expression, expecting no arguments.
    *
    * @param aSQLStatement
    *        The SQL statement to execute
--- a/storage/mozStorageConnection.cpp
+++ b/storage/mozStorageConnection.cpp
@@ -1849,22 +1849,22 @@ Connection::ExecuteSimpleSQL(const nsACS
     return rv;
   }
 
   int srv = executeSql(mDBConn, PromiseFlatCString(aSQLStatement).get());
   return convertResultCode(srv);
 }
 
 NS_IMETHODIMP
-Connection::ExecuteAsync(mozIStorageBaseStatement** aStatements,
-                         uint32_t aNumStatements,
-                         mozIStorageStatementCallback* aCallback,
-                         mozIStoragePendingStatement** _handle) {
-  nsTArray<StatementData> stmts(aNumStatements);
-  for (uint32_t i = 0; i < aNumStatements; i++) {
+Connection::ExecuteAsync(
+    const nsTArray<RefPtr<mozIStorageBaseStatement>>& aStatements,
+    mozIStorageStatementCallback* aCallback,
+    mozIStoragePendingStatement** _handle) {
+  nsTArray<StatementData> stmts(aStatements.Length());
+  for (uint32_t i = 0; i < aStatements.Length(); i++) {
     nsCOMPtr<StorageBaseStatementInternal> stmt =
         do_QueryInterface(aStatements[i]);
 
     // Obtain our StatementData.
     StatementData data;
     nsresult rv = stmt->getAsynchronousStatementData(data);
     NS_ENSURE_SUCCESS(rv, rv);
 
--- a/storage/test/gtest/test_asyncStatementExecution_transaction.cpp
+++ b/storage/test/gtest/test_asyncStatementExecution_transaction.cpp
@@ -35,26 +35,26 @@ int commit_hook(void* aArg) {
  * @param aStmts
  *        Vector of statements.
  * @param aStmtsLen
  *        Number of statements.
  * @param aTransactionExpected
  *        Whether a transaction is expected or not.
  */
 void check_transaction(mozIStorageConnection* aDB,
-                       mozIStorageBaseStatement** aStmts, uint32_t aStmtsLen,
+                       const nsTArray<RefPtr<mozIStorageBaseStatement>>& aStmts,
                        bool aTransactionExpected) {
   // -- install a transaction commit hook.
   int commit = 0;
   static_cast<Connection*>(aDB)->setCommitHook(commit_hook, &commit);
 
   RefPtr<AsyncStatementSpinner> asyncSpin(new AsyncStatementSpinner());
   nsCOMPtr<mozIStoragePendingStatement> asyncPend;
-  do_check_success(aDB->ExecuteAsync(aStmts, aStmtsLen, asyncSpin,
-                                     getter_AddRefs(asyncPend)));
+  do_check_success(
+      aDB->ExecuteAsync(aStmts, asyncSpin, getter_AddRefs(asyncPend)));
   do_check_true(asyncPend);
 
   // -- complete the execution
   asyncSpin->SpinUntilCompleted();
 
   // -- uninstall the transaction commit hook.
   static_cast<Connection*>(aDB)->setCommitHook(nullptr);
 
@@ -62,17 +62,17 @@ void check_transaction(mozIStorageConnec
   do_check_eq(aTransactionExpected, !!commit);
 
   // -- check that only one transaction was created.
   if (aTransactionExpected) {
     do_check_eq(1, commit);
   }
 
   // -- cleanup
-  for (uint32_t i = 0; i < aStmtsLen; ++i) {
+  for (uint32_t i = 0; i < aStmts.Length(); ++i) {
     aStmts[i]->Finalize();
   }
   blocking_async_close(aDB);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Tests
 
@@ -88,22 +88,23 @@ TEST(storage_asyncStatementExecution_tra
   nsCOMPtr<mozIStorageAsyncStatement> stmt1;
   db->CreateAsyncStatement(NS_LITERAL_CSTRING("SELECT * FROM sqlite_master"),
                            getter_AddRefs(stmt1));
 
   nsCOMPtr<mozIStorageAsyncStatement> stmt2;
   db->CreateAsyncStatement(NS_LITERAL_CSTRING("SELECT * FROM sqlite_master"),
                            getter_AddRefs(stmt2));
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt1,
-      stmt2,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt1.forget(),
+      stmt2.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), false);
+  check_transaction(db, nsTArray<RefPtr<mozIStorageBaseStatement>>(stmts),
+                    false);
 }
 
 /**
  * Test that executing multiple readonly Statements doesn't create a
  * transaction.
  */
 TEST(storage_asyncStatementExecution_transaction, MultipleReadStatements)
 {
@@ -113,22 +114,22 @@ TEST(storage_asyncStatementExecution_tra
   nsCOMPtr<mozIStorageStatement> stmt1;
   db->CreateStatement(NS_LITERAL_CSTRING("SELECT * FROM sqlite_master"),
                       getter_AddRefs(stmt1));
 
   nsCOMPtr<mozIStorageStatement> stmt2;
   db->CreateStatement(NS_LITERAL_CSTRING("SELECT * FROM sqlite_master"),
                       getter_AddRefs(stmt2));
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt1,
-      stmt2,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt1.forget(),
+      stmt2.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), false);
+  check_transaction(db, stmts, false);
 }
 
 /**
  * Test that executing multiple AsyncStatements causing writes creates a
  * transaction.
  */
 TEST(storage_asyncStatementExecution_transaction,
      MultipleAsyncReadWriteStatements)
@@ -140,22 +141,22 @@ TEST(storage_asyncStatementExecution_tra
   db->CreateAsyncStatement(NS_LITERAL_CSTRING("SELECT * FROM sqlite_master"),
                            getter_AddRefs(stmt1));
 
   nsCOMPtr<mozIStorageAsyncStatement> stmt2;
   db->CreateAsyncStatement(
       NS_LITERAL_CSTRING("CREATE TABLE test (id INTEGER PRIMARY KEY)"),
       getter_AddRefs(stmt2));
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt1,
-      stmt2,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt1.forget(),
+      stmt2.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), true);
+  check_transaction(db, stmts, true);
 }
 
 /**
  * Test that executing multiple Statements causing writes creates a transaction.
  */
 TEST(storage_asyncStatementExecution_transaction, MultipleReadWriteStatements)
 {
   nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
@@ -165,22 +166,22 @@ TEST(storage_asyncStatementExecution_tra
   db->CreateStatement(NS_LITERAL_CSTRING("SELECT * FROM sqlite_master"),
                       getter_AddRefs(stmt1));
 
   nsCOMPtr<mozIStorageStatement> stmt2;
   db->CreateStatement(
       NS_LITERAL_CSTRING("CREATE TABLE test (id INTEGER PRIMARY KEY)"),
       getter_AddRefs(stmt2));
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt1,
-      stmt2,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt1.forget(),
+      stmt2.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), true);
+  check_transaction(db, stmts, true);
 }
 
 /**
  * Test that executing multiple AsyncStatements causing writes creates a
  * single transaction.
  */
 TEST(storage_asyncStatementExecution_transaction, MultipleAsyncWriteStatements)
 {
@@ -192,22 +193,22 @@ TEST(storage_asyncStatementExecution_tra
       NS_LITERAL_CSTRING("CREATE TABLE test1 (id INTEGER PRIMARY KEY)"),
       getter_AddRefs(stmt1));
 
   nsCOMPtr<mozIStorageAsyncStatement> stmt2;
   db->CreateAsyncStatement(
       NS_LITERAL_CSTRING("CREATE TABLE test2 (id INTEGER PRIMARY KEY)"),
       getter_AddRefs(stmt2));
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt1,
-      stmt2,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt1.forget(),
+      stmt2.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), true);
+  check_transaction(db, stmts, true);
 }
 
 /**
  * Test that executing multiple Statements causing writes creates a
  * single transaction.
  */
 TEST(storage_asyncStatementExecution_transaction, MultipleWriteStatements)
 {
@@ -219,103 +220,103 @@ TEST(storage_asyncStatementExecution_tra
       NS_LITERAL_CSTRING("CREATE TABLE test1 (id INTEGER PRIMARY KEY)"),
       getter_AddRefs(stmt1));
 
   nsCOMPtr<mozIStorageStatement> stmt2;
   db->CreateStatement(
       NS_LITERAL_CSTRING("CREATE TABLE test2 (id INTEGER PRIMARY KEY)"),
       getter_AddRefs(stmt2));
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt1,
-      stmt2,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt1.forget(),
+      stmt2.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), true);
+  check_transaction(db, stmts, true);
 }
 
 /**
  * Test that executing a single read-only AsyncStatement doesn't create a
  * transaction.
  */
 TEST(storage_asyncStatementExecution_transaction, SingleAsyncReadStatement)
 {
   nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
 
   // -- create statements and execute them
   nsCOMPtr<mozIStorageAsyncStatement> stmt;
   db->CreateAsyncStatement(NS_LITERAL_CSTRING("SELECT * FROM sqlite_master"),
                            getter_AddRefs(stmt));
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), false);
+  check_transaction(db, stmts, false);
 }
 
 /**
  * Test that executing a single read-only Statement doesn't create a
  * transaction.
  */
 TEST(storage_asyncStatementExecution_transaction, SingleReadStatement)
 {
   nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
 
   // -- create statements and execute them
   nsCOMPtr<mozIStorageStatement> stmt;
   db->CreateStatement(NS_LITERAL_CSTRING("SELECT * FROM sqlite_master"),
                       getter_AddRefs(stmt));
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), false);
+  check_transaction(db, stmts, false);
 }
 
 /**
  * Test that executing a single AsyncStatement causing writes creates a
  * transaction.
  */
 TEST(storage_asyncStatementExecution_transaction, SingleAsyncWriteStatement)
 {
   nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
 
   // -- create statements and execute them
   nsCOMPtr<mozIStorageAsyncStatement> stmt;
   db->CreateAsyncStatement(
       NS_LITERAL_CSTRING("CREATE TABLE test (id INTEGER PRIMARY KEY)"),
       getter_AddRefs(stmt));
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), true);
+  check_transaction(db, stmts, true);
 }
 
 /**
  * Test that executing a single Statement causing writes creates a transaction.
  */
 TEST(storage_asyncStatementExecution_transaction, SingleWriteStatement)
 {
   nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
 
   // -- create statements and execute them
   nsCOMPtr<mozIStorageStatement> stmt;
   db->CreateStatement(
       NS_LITERAL_CSTRING("CREATE TABLE test (id INTEGER PRIMARY KEY)"),
       getter_AddRefs(stmt));
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), true);
+  check_transaction(db, stmts, true);
 }
 
 /**
  * Test that executing a single read-only AsyncStatement with multiple params
  * doesn't create a transaction.
  */
 TEST(storage_asyncStatementExecution_transaction,
      MultipleParamsAsyncReadStatement)
@@ -335,21 +336,21 @@ TEST(storage_asyncStatementExecution_tra
     nsCOMPtr<mozIStorageBindingParams> params;
     paramsArray->NewBindingParams(getter_AddRefs(params));
     params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
     paramsArray->AddParams(params);
   }
   stmt->BindParameters(paramsArray);
   paramsArray = nullptr;
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), false);
+  check_transaction(db, stmts, false);
 }
 
 /**
  * Test that executing a single read-only Statement with multiple params
  * doesn't create a transaction.
  */
 TEST(storage_asyncStatementExecution_transaction, MultipleParamsReadStatement)
 {
@@ -367,21 +368,21 @@ TEST(storage_asyncStatementExecution_tra
     nsCOMPtr<mozIStorageBindingParams> params;
     paramsArray->NewBindingParams(getter_AddRefs(params));
     params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
     paramsArray->AddParams(params);
   }
   stmt->BindParameters(paramsArray);
   paramsArray = nullptr;
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), false);
+  check_transaction(db, stmts, false);
 }
 
 /**
  * Test that executing a single write AsyncStatement with multiple params
  * creates a transaction.
  */
 TEST(storage_asyncStatementExecution_transaction,
      MultipleParamsAsyncWriteStatement)
@@ -409,21 +410,21 @@ TEST(storage_asyncStatementExecution_tra
     nsCOMPtr<mozIStorageBindingParams> params;
     paramsArray->NewBindingParams(getter_AddRefs(params));
     params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
     paramsArray->AddParams(params);
   }
   stmt->BindParameters(paramsArray);
   paramsArray = nullptr;
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), true);
+  check_transaction(db, stmts, true);
 }
 
 /**
  * Test that executing a single write Statement with multiple params
  * creates a transaction.
  */
 TEST(storage_asyncStatementExecution_transaction, MultipleParamsWriteStatement)
 {
@@ -449,14 +450,14 @@ TEST(storage_asyncStatementExecution_tra
     nsCOMPtr<mozIStorageBindingParams> params;
     paramsArray->NewBindingParams(getter_AddRefs(params));
     params->BindInt32ByName(NS_LITERAL_CSTRING("param"), 1);
     paramsArray->AddParams(params);
   }
   stmt->BindParameters(paramsArray);
   paramsArray = nullptr;
 
-  mozIStorageBaseStatement* stmts[] = {
-      stmt,
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      stmt.forget(),
   };
 
-  check_transaction(db, stmts, ArrayLength(stmts), true);
+  check_transaction(db, stmts, true);
 }
--- a/storage/test/unit/head_storage.js
+++ b/storage/test/unit/head_storage.js
@@ -292,17 +292,17 @@ function executeAsync(statement, onResul
         resolve(result);
       },
     });
   });
 }
 
 function executeMultipleStatementsAsync(db, statements, onResult) {
   return new Promise((resolve, reject) => {
-    db.executeAsync(statements, statements.length, {
+    db.executeAsync(statements, {
       handleError(error) {
         reject(error);
       },
       handleResult(result) {
         if (onResult) {
           onResult(result);
         }
       },
--- a/toolkit/components/places/Database.cpp
+++ b/toolkit/components/places/Database.cpp
@@ -1813,21 +1813,24 @@ nsresult Database::MigrateV32Up() {
 #undef HOSTS_PREFIX_PRIORITY_FRAGMENT
 
   nsCOMPtr<mozIStorageAsyncStatement> dropTableStmt;
   rv = mMainConn->CreateAsyncStatement(
       NS_LITERAL_CSTRING("DROP TABLE IF EXISTS moz_migrate_v32_temp"),
       getter_AddRefs(dropTableStmt));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  mozIStorageBaseStatement* stmts[] = {expireOrphansStmt, deleteHostsStmt,
-                                       updateHostsStmt, dropTableStmt};
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      expireOrphansStmt.forget(),
+      deleteHostsStmt.forget(),
+      updateHostsStmt.forget(),
+      dropTableStmt.forget(),
+  };
   nsCOMPtr<mozIStoragePendingStatement> ps;
-  rv = mMainConn->ExecuteAsync(stmts, ArrayLength(stmts), nullptr,
-                               getter_AddRefs(ps));
+  rv = mMainConn->ExecuteAsync(stmts, nullptr, getter_AddRefs(ps));
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 nsresult Database::MigrateV33Up() {
   nsresult rv = mMainConn->ExecuteSimpleSQL(
       NS_LITERAL_CSTRING("DROP INDEX IF EXISTS moz_places_url_uniqueindex"));
@@ -2961,17 +2964,17 @@ void Database::Shutdown() {
     MOZ_ASSERT(NS_SUCCEEDED(rv));
     MOZ_ASSERT(!hasResult, "Found a NULL url!");
   }
 #endif
 
   mMainThreadStatements.FinalizeStatements();
   mMainThreadAsyncStatements.FinalizeStatements();
 
-  RefPtr<FinalizeStatementCacheProxy<mozIStorageStatement> > event =
+  RefPtr<FinalizeStatementCacheProxy<mozIStorageStatement>> event =
       new FinalizeStatementCacheProxy<mozIStorageStatement>(
           mAsyncThreadStatements, NS_ISUPPORTS_CAST(nsIObserver*, this));
   DispatchToAsyncThread(event);
 
   mClosed = true;
 
   // Execute PRAGMA optimized as last step, this will ensure proper database
   // performance across restarts.
--- a/toolkit/components/places/PlacesExpiration.jsm
+++ b/toolkit/components/places/PlacesExpiration.jsm
@@ -811,17 +811,17 @@ nsPlacesExpiration.prototype = {
       let boundStatements = [];
       for (let queryType in EXPIRATION_QUERIES) {
         if (EXPIRATION_QUERIES[queryType].actions & aAction)
           boundStatements.push(this._getBoundStatement(queryType, aLimit, aAction));
       }
 
 
       // Execute statements asynchronously in a transaction.
-      this._db.executeAsync(boundStatements, boundStatements.length, this);
+      this._db.executeAsync(boundStatements, this);
     })().catch(Cu.reportError);
   },
 
   /**
    * Finalizes all of our mozIStorageStatements so we can properly close the
    * database.
    */
   _finalizeInternalStatements: function PEX__finalizeInternalStatements() {
--- a/toolkit/components/places/nsFaviconService.cpp
+++ b/toolkit/components/places/nsFaviconService.cpp
@@ -173,27 +173,28 @@ nsFaviconService::ExpireAllFavicons() {
   NS_ENSURE_STATE(removePagesStmt);
   nsCOMPtr<mozIStorageAsyncStatement> removeIconsStmt =
       mDB->GetAsyncStatement("DELETE FROM moz_icons");
   NS_ENSURE_STATE(removeIconsStmt);
   nsCOMPtr<mozIStorageAsyncStatement> unlinkIconsStmt =
       mDB->GetAsyncStatement("DELETE FROM moz_icons_to_pages");
   NS_ENSURE_STATE(unlinkIconsStmt);
 
-  mozIStorageBaseStatement* stmts[] = {
-      removePagesStmt.get(), removeIconsStmt.get(), unlinkIconsStmt.get()};
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {removePagesStmt.forget(),
+
+                                                      removeIconsStmt.forget(),
+                                                      unlinkIconsStmt.forget()};
   nsCOMPtr<mozIStorageConnection> conn = mDB->MainConn();
   if (!conn) {
     return NS_ERROR_UNEXPECTED;
   }
   nsCOMPtr<mozIStoragePendingStatement> ps;
   RefPtr<ExpireFaviconsStatementCallbackNotifier> callback =
       new ExpireFaviconsStatementCallbackNotifier();
-  return conn->ExecuteAsync(stmts, ArrayLength(stmts), callback,
-                            getter_AddRefs(ps));
+  return conn->ExecuteAsync(stmts, callback, getter_AddRefs(ps));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsITimerCallback
 
 NS_IMETHODIMP
 nsFaviconService::Notify(nsITimer* timer) {
   if (timer != mExpireUnassociatedIconsTimer.get()) {
--- a/toolkit/components/places/nsNavHistory.cpp
+++ b/toolkit/components/places/nsNavHistory.cpp
@@ -2020,17 +2020,18 @@ NS_IMETHODIMP
 nsNavHistory::RemoveObserver(nsINavHistoryObserver* aObserver) {
   NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
   NS_ENSURE_ARG(aObserver);
 
   return mObservers.RemoveWeakElement(aObserver);
 }
 
 NS_IMETHODIMP
-nsNavHistory::GetObservers(nsTArray<RefPtr<nsINavHistoryObserver>>& aObservers) {
+nsNavHistory::GetObservers(
+    nsTArray<RefPtr<nsINavHistoryObserver>>& aObservers) {
   aObservers.Clear();
 
   // Clear any cached value, cause it's very likely the consumer has made
   // changes to history and is now trying to notify them.
   mDaysOfHistory = -1;
 
   if (!mCanNotify) return NS_OK;
 
@@ -3434,21 +3435,22 @@ nsresult nsNavHistory::UpdateFrecency(in
                                          aPlaceId);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<mozIStorageConnection> conn = mDB->MainConn();
   if (!conn) {
     return NS_ERROR_UNEXPECTED;
   }
 
-  mozIStorageBaseStatement* stmts[] = {updateFrecencyStmt.get(),
-                                       updateHiddenStmt.get()};
+  nsTArray<RefPtr<mozIStorageBaseStatement>> stmts = {
+      updateFrecencyStmt.forget(),
+      updateHiddenStmt.forget(),
+  };
   nsCOMPtr<mozIStoragePendingStatement> ps;
-  rv = conn->ExecuteAsync(stmts, ArrayLength(stmts), nullptr,
-                          getter_AddRefs(ps));
+  rv = conn->ExecuteAsync(stmts, nullptr, getter_AddRefs(ps));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Trigger frecency updates for all affected origins.
   nsCOMPtr<mozIStorageAsyncStatement> updateOriginFrecenciesStmt =
       mDB->GetAsyncStatement("DELETE FROM moz_updateoriginsupdate_temp");
   NS_ENSURE_STATE(updateOriginFrecenciesStmt);
   rv = updateOriginFrecenciesStmt->ExecuteAsync(nullptr, getter_AddRefs(ps));
   NS_ENSURE_SUCCESS(rv, rv);