Bug 615978 - Add SQLITE_DBSTATUS_* memory usage to memory reporter

Adds some finer-grained memory reporting about SQLite usage.
r=asuth
This commit is contained in:
Doug Turner ext:(%2C%20Shawn%20Wilsher%20%3Cme%40shawnwilsher.com%3E) 2011-03-31 10:19:30 -07:00
parent 126342234e
commit e32a08f431
3 changed files with 124 additions and 0 deletions

View File

@ -84,6 +84,7 @@ EXPORTS
sqlite3_data_count
sqlite3_db_handle
sqlite3_db_mutex
sqlite3_db_status
sqlite3_declare_vtab
sqlite3_enable_load_extension
sqlite3_enable_shared_cache

View File

@ -48,6 +48,7 @@
#include "nsHashSets.h"
#include "nsAutoPtr.h"
#include "nsIFile.h"
#include "nsIMemoryReporter.h"
#include "nsThreadUtils.h"
#include "nsAutoLock.h"
@ -326,6 +327,100 @@ private:
} // anonymous namespace
////////////////////////////////////////////////////////////////////////////////
//// Memory Reporting
class StorageMemoryReporter : public nsIMemoryReporter
{
public:
NS_DECL_ISUPPORTS
enum ReporterType {
LookAside_Used,
Cache_Used,
Schema_Used,
Stmt_Used
};
StorageMemoryReporter(Connection &aDBConn,
ReporterType aType)
: mDBConn(aDBConn)
, mType(aType)
{
}
NS_IMETHOD GetPath(char **memoryPath)
{
nsCString path;
path.AppendLiteral("storage/");
path.Append(mDBConn.getFilename());
if (mType == LookAside_Used) {
path.AppendLiteral("/LookAside_Used");
}
else if (mType == Cache_Used) {
path.AppendLiteral("/Cache_Used");
}
else if (mType == Schema_Used) {
path.AppendLiteral("/Schema_Used");
}
else if (mType == Stmt_Used) {
path.AppendLiteral("/Stmt_Used");
}
*memoryPath = ::ToNewCString(path);
return NS_OK;
}
NS_IMETHOD GetDescription(char **desc)
{
if (mType == LookAside_Used) {
*desc = ::strdup("Number of lookaside memory slots currently checked out");
}
else if (mType == Cache_Used) {
*desc = ::strdup("Approximate number of bytes of heap memory used by all pager caches");
}
else if (mType == Schema_Used) {
*desc = ::strdup("Approximate number of bytes of heap memory used to store the schema for all databases associated with the connection");
}
else if (mType == Stmt_Used) {
*desc = ::strdup("Approximate number of bytes of heap and lookaside memory used by all prepared statements");
}
return NS_OK;
}
NS_IMETHOD GetMemoryUsed(PRInt64 *memoryUsed)
{
int type = 0;
if (mType == LookAside_Used) {
type = SQLITE_DBSTATUS_LOOKASIDE_USED;
}
else if (mType == Cache_Used) {
type = SQLITE_DBSTATUS_CACHE_USED;
}
else if (mType == Schema_Used) {
type = SQLITE_DBSTATUS_SCHEMA_USED;
}
else if (mType == Stmt_Used) {
type = SQLITE_DBSTATUS_STMT_USED;
}
int cur=0, max=0;
int rc = ::sqlite3_db_status(mDBConn, type, &cur, &max, 0);
*memoryUsed = cur;
return convertResultCode(rc);
}
Connection &mDBConn;
nsCString mFileName;
ReporterType mType;
};
NS_IMPL_THREADSAFE_ISUPPORTS1(
StorageMemoryReporter
, nsIMemoryReporter
)
////////////////////////////////////////////////////////////////////////////////
//// Connection
@ -481,6 +576,26 @@ Connection::initialize(nsIFile *aDatabaseFile,
break;
}
nsRefPtr<nsIMemoryReporter> reporter;
reporter =
new StorageMemoryReporter(*this, StorageMemoryReporter::LookAside_Used);
mMemoryReporters.AppendElement(reporter);
reporter =
new StorageMemoryReporter(*this, StorageMemoryReporter::Cache_Used);
mMemoryReporters.AppendElement(reporter);
reporter =
new StorageMemoryReporter(*this, StorageMemoryReporter::Schema_Used);
mMemoryReporters.AppendElement(reporter);
reporter = new StorageMemoryReporter(*this, StorageMemoryReporter::Stmt_Used);
mMemoryReporters.AppendElement(reporter);
for (PRUint32 i = 0; i < mMemoryReporters.Length(); i++) {
(void)::NS_RegisterMemoryReporter(mMemoryReporters[i]);
}
return NS_OK;
}
@ -617,6 +732,10 @@ Connection::internalClose()
}
#endif
for (PRUint32 i = 0; i < mMemoryReporters.Length(); i++) {
(void)::NS_UnregisterMemoryReporter(mMemoryReporters[i]);
}
int srv = ::sqlite3_close(mDBConn);
NS_ASSERTION(srv == SQLITE_OK,
"sqlite3_close failed. There are probably outstanding statements that are listed above!");

View File

@ -61,6 +61,7 @@ struct PRLock;
class nsIFile;
class nsIEventTarget;
class nsIThread;
class nsIMemoryReporter;
namespace mozilla {
namespace storage {
@ -112,6 +113,7 @@ public:
// fetch the native handle
sqlite3 *GetNativeConnection() { return mDBConn; }
operator sqlite3 *() const { return mDBConn; }
/**
* Lazily creates and returns a background execution thread. In the future,
@ -201,6 +203,8 @@ private:
sqlite3 *mDBConn;
nsCOMPtr<nsIFile> mDatabaseFile;
nsTArray<nsCOMPtr<nsIMemoryReporter> > mMemoryReporters;
/**
* Lazily created thread for asynchronous statement execution. Consumers
* should use getAsyncExecutionTarget rather than directly accessing this