Bug 730495 - guarantee that sqlite3_config is called before any other SQLite function. r=glandium draft
authorKan-Ru Chen <kanru@kanru.info>
Thu, 10 Mar 2016 16:41:20 +0800
changeset 338997 a9fe584c11259213514896e2f3f3a537195389f5
parent 338094 7a6ad98de34e7374188231aec6a50eff87781913
child 515900 fc6884ca0206e1707e8b3d03f7f5838eba046c6d
push id12628
push userbmo:kchen@mozilla.com
push dateThu, 10 Mar 2016 10:28:24 +0000
reviewersglandium
bugs730495
milestone48.0a1
Bug 730495 - guarantee that sqlite3_config is called before any other SQLite function. r=glandium This does not enable us to use jemalloc on Android because the malloc functions are still in libxul. They has to be in libxul because the customized DMD reporting. MozReview-Commit-ID: 7uCQEOIpDwx
db/sqlite3/src/moz.build
db/sqlite3/src/sqlite_jemalloc.c
storage/mozStorageService.cpp
storage/mozStorageService.h
--- a/db/sqlite3/src/moz.build
+++ b/db/sqlite3/src/moz.build
@@ -83,8 +83,18 @@ if CONFIG['SOLARIS_SUNPRO_CC']:
     NO_PGO = True
 
 # Suppress warnings in third-party code.
 if CONFIG['GNU_CC']:
     CFLAGS += [
         '-Wno-sign-compare',
         '-Wno-type-limits',
     ]
+
+# Config malloc function as early as possible when building with
+# jemalloc. See bug 730495.
+if CONFIG['MOZ_MEMORY']:
+    CFLAGS += [
+        '-DSQLITE_EXTRA_INIT=sqlite3_config_jemalloc',
+    ]
+    SOURCES += [
+        'sqlite_jemalloc.c',
+    ]
new file mode 100644
--- /dev/null
+++ b/db/sqlite3/src/sqlite_jemalloc.c
@@ -0,0 +1,17 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "sqlite3.h"
+
+__attribute__((weak)) void sqlite3_really_config_jemalloc();
+
+int sqlite3_config_jemalloc(char* unused)
+{
+  if (sqlite3_really_config_jemalloc) {
+    sqlite3_really_config_jemalloc();
+  }
+  return SQLITE_OK;
+}
--- a/storage/mozStorageService.cpp
+++ b/storage/mozStorageService.cpp
@@ -506,37 +506,41 @@ const sqlite3_mem_methods memMethods = {
   &sqliteMemRoundup,
   &sqliteMemInit,
   &sqliteMemShutdown,
   nullptr
 };
 
 } // namespace
 
+// Called by SQLite on init
+void sqlite3_really_config_jemalloc()
+{
+  int rc;
+  rc = ::sqlite3_config(SQLITE_CONFIG_MALLOC, &memMethods);
+  if (rc != SQLITE_OK) {
+    MOZ_CRASH("Unable to config sqlite3 to use jemalloc as allocator.");
+  }
+}
+
 #endif  // MOZ_STORAGE_MEMORY
 
 static const char* sObserverTopics[] = {
   "memory-pressure",
   "xpcom-shutdown",
   "xpcom-shutdown-threads"
 };
 
 nsresult
 Service::initialize()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Must be initialized on the main thread");
 
   int rc;
 
-#ifdef MOZ_STORAGE_MEMORY
-  rc = ::sqlite3_config(SQLITE_CONFIG_MALLOC, &memMethods);
-  if (rc != SQLITE_OK)
-    return convertResultCode(rc);
-#endif
-
   // TODO (bug 1191405): do not preallocate the connections caches until we
   // have figured the impact on our consumers and memory.
   sqlite3_config(SQLITE_CONFIG_PAGECACHE, NULL, 0, 0);
 
   // Explicitly initialize sqlite3.  Although this is implicitly called by
   // various sqlite3 functions (and the sqlite3_open calls in our case),
   // the documentation suggests calling this directly.  So we do.
   rc = ::sqlite3_initialize();
--- a/storage/mozStorageService.h
+++ b/storage/mozStorageService.h
@@ -16,16 +16,20 @@
 #include "mozilla/Mutex.h"
 
 #include "mozIStorageService.h"
 
 class nsIMemoryReporter;
 class nsIXPConnect;
 struct sqlite3_vfs;
 
+#ifdef MOZ_STORAGE_MEMORY
+extern "C" void sqlite3_really_config_jemalloc();
+#endif
+
 namespace mozilla {
 namespace storage {
 
 class Connection;
 class Service : public mozIStorageService
               , public nsIObserver
               , public nsIMemoryReporter
 {