summaryrefslogtreecommitdiffstats
path: root/sql
diff options
context:
space:
mode:
authorssid <ssid@chromium.org>2015-10-12 10:49:03 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-12 17:49:46 +0000
commit9f8022f2aadfd86989231e6d367c2c2b9a53ae4b (patch)
tree7566cfd6b24a6087a535cc47d498114fba990669 /sql
parent55e0b3620524432d77cd3f707acd6ed470c2f1c9 (diff)
downloadchromium_src-9f8022f2aadfd86989231e6d367c2c2b9a53ae4b.zip
chromium_src-9f8022f2aadfd86989231e6d367c2c2b9a53ae4b.tar.gz
chromium_src-9f8022f2aadfd86989231e6d367c2c2b9a53ae4b.tar.bz2
[tracing] Add sqlite memory statistics to tracing.
The process-wide memory usage statistics of sqlite library is added to chrome://tracing. The memory usage of sqlite library is mainly through sqlite_malloc. The total usage of the process is recorded by sqlite3_memory_used() api. This CL also adds per-connection memory usage to tracing. Each connection uses memory for cache, schema and statement, and these usages are recorded. sqlit3_malloc uses malloc internally to allocate memory. So, thie memory is traced as sub-allocation from system_allocator(malloc). This CL lets us keep track of sqlite memory usage in chrome telemetry. BUG=466141 Review URL: https://codereview.chromium.org/1327063002 Cr-Commit-Position: refs/heads/master@{#353549}
Diffstat (limited to 'sql')
-rw-r--r--sql/BUILD.gn3
-rw-r--r--sql/connection.cc44
-rw-r--r--sql/connection.h10
-rw-r--r--sql/connection_unittest.cc9
-rw-r--r--sql/sql.gyp3
-rw-r--r--sql/sql_memory_dump_provider.cc62
-rw-r--r--sql/sql_memory_dump_provider.h36
-rw-r--r--sql/sql_memory_dump_provider_unittest.cc22
8 files changed, 187 insertions, 2 deletions
diff --git a/sql/BUILD.gn b/sql/BUILD.gn
index 57f1b38..8d071a3 100644
--- a/sql/BUILD.gn
+++ b/sql/BUILD.gn
@@ -15,6 +15,8 @@ component("sql") {
"meta_table.h",
"recovery.cc",
"recovery.h",
+ "sql_memory_dump_provider.cc",
+ "sql_memory_dump_provider.h",
"statement.cc",
"statement.h",
"transaction.cc",
@@ -77,6 +79,7 @@ test("sql_unittests") {
"connection_unittest.cc",
"meta_table_unittest.cc",
"recovery_unittest.cc",
+ "sql_memory_dump_provider_unittest.cc",
"sqlite_features_unittest.cc",
"statement_unittest.cc",
"test/paths.cc",
diff --git a/sql/connection.cc b/sql/connection.cc
index 20f0f07..61aebbe 100644
--- a/sql/connection.cc
+++ b/sql/connection.cc
@@ -19,6 +19,8 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
+#include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/process_memory_dump.h"
#include "sql/statement.h"
#include "third_party/sqlite/sqlite3.h"
@@ -217,6 +219,44 @@ bool Connection::ShouldIgnoreSqliteError(int error) {
return current_ignorer_cb_->Run(error);
}
+bool Connection::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
+ base::trace_event::ProcessMemoryDump* pmd) {
+ if (args.level_of_detail ==
+ base::trace_event::MemoryDumpLevelOfDetail::LIGHT ||
+ !db_) {
+ return true;
+ }
+
+ // The high water mark is not tracked for the following usages.
+ int cache_size, dummy_int;
+ sqlite3_db_status(db_, SQLITE_DBSTATUS_CACHE_USED, &cache_size, &dummy_int,
+ 0 /* resetFlag */);
+ int schema_size;
+ sqlite3_db_status(db_, SQLITE_DBSTATUS_SCHEMA_USED, &schema_size, &dummy_int,
+ 0 /* resetFlag */);
+ int statement_size;
+ sqlite3_db_status(db_, SQLITE_DBSTATUS_STMT_USED, &statement_size, &dummy_int,
+ 0 /* resetFlag */);
+
+ std::string name = base::StringPrintf(
+ "sqlite/%s_connection/%p",
+ histogram_tag_.empty() ? "Unknown" : histogram_tag_.c_str(), this);
+ base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(name);
+ dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ cache_size + schema_size + statement_size);
+ dump->AddScalar("cache_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ cache_size);
+ dump->AddScalar("schema_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ schema_size);
+ dump->AddScalar("statement_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ statement_size);
+ return true;
+}
+
// static
void Connection::SetErrorIgnorer(Connection::ErrorIgnorerCallback* cb) {
CHECK(current_ignorer_cb_ == NULL);
@@ -291,9 +331,13 @@ Connection::Connection()
update_time_histogram_(NULL),
query_time_histogram_(NULL),
clock_(new TimeSource()) {
+ base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+ this);
}
Connection::~Connection() {
+ base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
+ this);
Close();
}
diff --git a/sql/connection.h b/sql/connection.h
index d456b6c..7d2ab6a 100644
--- a/sql/connection.h
+++ b/sql/connection.h
@@ -18,6 +18,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
+#include "base/trace_event/memory_dump_provider.h"
#include "sql/sql_export.h"
struct sqlite3;
@@ -102,7 +103,7 @@ class SQL_EXPORT TimeSource {
DISALLOW_COPY_AND_ASSIGN(TimeSource);
};
-class SQL_EXPORT Connection {
+class SQL_EXPORT Connection : public base::trace_event::MemoryDumpProvider {
private:
class StatementRef; // Forward declaration, see real one below.
@@ -110,7 +111,7 @@ class SQL_EXPORT Connection {
// The database is opened by calling Open[InMemory](). Any uncommitted
// transactions will be rolled back when this object is deleted.
Connection();
- ~Connection();
+ ~Connection() override;
// Pre-init configuration ----------------------------------------------------
@@ -464,6 +465,11 @@ class SQL_EXPORT Connection {
// tests.
static bool ShouldIgnoreSqliteError(int error);
+ // base::trace_event::MemoryDumpProvider implementation.
+ bool OnMemoryDump(
+ const base::trace_event::MemoryDumpArgs& args,
+ base::trace_event::ProcessMemoryDump* process_memory_dump) override;
+
private:
// For recovery module.
friend class Recovery;
diff --git a/sql/connection_unittest.cc b/sql/connection_unittest.cc
index 0038a1d..d933a6d 100644
--- a/sql/connection_unittest.cc
+++ b/sql/connection_unittest.cc
@@ -11,6 +11,7 @@
#include "base/metrics/statistics_recorder.h"
#include "base/strings/stringprintf.h"
#include "base/test/histogram_tester.h"
+#include "base/trace_event/process_memory_dump.h"
#include "sql/connection.h"
#include "sql/correct_sql_test_base.h"
#include "sql/meta_table.h"
@@ -1378,4 +1379,12 @@ TEST_F(SQLConnectionTest, MmapTest) {
}
#endif
+TEST_F(SQLConnectionTest, OnMemoryDump) {
+ base::trace_event::ProcessMemoryDump pmd(nullptr);
+ base::trace_event::MemoryDumpArgs args = {
+ base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
+ ASSERT_TRUE(db().OnMemoryDump(args, &pmd));
+ EXPECT_GE(pmd.allocator_dumps().size(), 1u);
+}
+
} // namespace
diff --git a/sql/sql.gyp b/sql/sql.gyp
index 115a93b..362597e 100644
--- a/sql/sql.gyp
+++ b/sql/sql.gyp
@@ -29,6 +29,8 @@
'meta_table.h',
'recovery.cc',
'recovery.h',
+ 'sql_memory_dump_provider.cc',
+ 'sql_memory_dump_provider.h',
'statement.cc',
'statement.h',
'transaction.cc',
@@ -89,6 +91,7 @@
'connection_unittest.cc',
'meta_table_unittest.cc',
'recovery_unittest.cc',
+ 'sql_memory_dump_provider_unittest.cc',
'sqlite_features_unittest.cc',
'statement_unittest.cc',
'test/paths.cc',
diff --git a/sql/sql_memory_dump_provider.cc b/sql/sql_memory_dump_provider.cc
new file mode 100644
index 0000000..bb6d813
--- /dev/null
+++ b/sql/sql_memory_dump_provider.cc
@@ -0,0 +1,62 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sql/sql_memory_dump_provider.h"
+
+#include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/process_memory_dump.h"
+#include "third_party/sqlite/sqlite3.h"
+
+namespace sql {
+
+// static
+SqlMemoryDumpProvider* SqlMemoryDumpProvider::GetInstance() {
+ return base::Singleton<
+ SqlMemoryDumpProvider,
+ base::LeakySingletonTraits<SqlMemoryDumpProvider>>::get();
+}
+
+SqlMemoryDumpProvider::SqlMemoryDumpProvider() {}
+
+SqlMemoryDumpProvider::~SqlMemoryDumpProvider() {}
+
+bool SqlMemoryDumpProvider::OnMemoryDump(
+ const base::trace_event::MemoryDumpArgs& args,
+ base::trace_event::ProcessMemoryDump* pmd) {
+ int memory_used = 0;
+ int memory_high_water = 0;
+ int status = sqlite3_status(SQLITE_STATUS_MEMORY_USED, &memory_used,
+ &memory_high_water, 1 /*resetFlag */);
+ if (status != SQLITE_OK)
+ return false;
+
+ base::trace_event::MemoryAllocatorDump* dump =
+ pmd->CreateAllocatorDump("sqlite");
+ dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ memory_used);
+ dump->AddScalar("malloc_high_wmark_size",
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ memory_high_water);
+
+ int dummy_high_water = -1;
+ int malloc_count = -1;
+ status = sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &malloc_count,
+ &dummy_high_water, 0 /* resetFlag */);
+ if (status == SQLITE_OK) {
+ dump->AddScalar("malloc_count",
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ malloc_count);
+ }
+
+ const char* system_allocator_name =
+ base::trace_event::MemoryDumpManager::GetInstance()
+ ->system_allocator_pool_name();
+ if (system_allocator_name) {
+ pmd->AddSuballocation(dump->guid(), system_allocator_name);
+ }
+ return true;
+}
+
+} // namespace sql
diff --git a/sql/sql_memory_dump_provider.h b/sql/sql_memory_dump_provider.h
new file mode 100644
index 0000000..051755f
--- /dev/null
+++ b/sql/sql_memory_dump_provider.h
@@ -0,0 +1,36 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SQL_PROCESS_MEMORY_DUMP_PROVIDER_H
+#define SQL_PROCESS_MEMORY_DUMP_PROVIDER_H
+
+#include "base/memory/singleton.h"
+#include "base/trace_event/memory_dump_provider.h"
+#include "sql/sql_export.h"
+
+namespace sql {
+
+// Adds process-wide memory usage statistics about sqlite to chrome://tracing.
+// sql::Connection::OnMemoryDump adds per-connection memory statistics.
+class SQL_EXPORT SqlMemoryDumpProvider
+ : public base::trace_event::MemoryDumpProvider {
+ public:
+ static SqlMemoryDumpProvider* GetInstance();
+
+ // MemoryDumpProvider implementation.
+ bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
+ base::trace_event::ProcessMemoryDump* pmd) override;
+
+ private:
+ friend struct base::DefaultSingletonTraits<SqlMemoryDumpProvider>;
+
+ SqlMemoryDumpProvider();
+ ~SqlMemoryDumpProvider() override;
+
+ DISALLOW_COPY_AND_ASSIGN(SqlMemoryDumpProvider);
+};
+
+} // namespace sql
+
+#endif // SQL_PROCESS_MEMORY_DUMP_PROVIDER_H
diff --git a/sql/sql_memory_dump_provider_unittest.cc b/sql/sql_memory_dump_provider_unittest.cc
new file mode 100644
index 0000000..1f1dcf9
--- /dev/null
+++ b/sql/sql_memory_dump_provider_unittest.cc
@@ -0,0 +1,22 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sql/sql_memory_dump_provider.h"
+
+#include "base/trace_event/process_memory_dump.h"
+#include "sql/test/sql_test_base.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+using SQLMemoryDumpProviderTest = sql::SQLTestBase;
+}
+
+TEST_F(SQLMemoryDumpProviderTest, OnMemoryDump) {
+ base::trace_event::ProcessMemoryDump pmd(nullptr);
+ base::trace_event::MemoryDumpArgs args = {
+ base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
+ ASSERT_TRUE(
+ sql::SqlMemoryDumpProvider::GetInstance()->OnMemoryDump(args, &pmd));
+ ASSERT_TRUE(pmd.GetAllocatorDump("sqlite"));
+}