Use std::string rather than String* in hprof to avoid managed-heap allocations.
Change-Id: Ia4491aa50f48ab435ca32c1d2b1825bf6553430b
diff --git a/src/hprof/hprof.h b/src/hprof/hprof.h
index 092f00d..897a996 100644
--- a/src/hprof/hprof.h
+++ b/src/hprof/hprof.h
@@ -149,11 +149,6 @@
int fd;
};
-
-/*
- * hprof_string.cc functions
- */
-
hprof_string_id hprofLookupStringId(String* string);
hprof_string_id hprofLookupStringId(const char* string);
hprof_string_id hprofLookupStringId(std::string string);
@@ -163,11 +158,6 @@
int hprofStartup_String(void);
int hprofShutdown_String(void);
-
-/*
- * hprof_class.cc functions
- */
-
hprof_class_object_id hprofLookupClassId(Class* clazz);
int hprofDumpClasses(hprof_context_t *ctx);
@@ -175,11 +165,6 @@
int hprofStartup_Class(void);
int hprofShutdown_Class(void);
-
-/*
- * hprof_heap.cc functions
- */
-
int hprofStartHeapDump(hprof_context_t *ctx);
int hprofFinishHeapDump(hprof_context_t *ctx);
@@ -190,10 +175,6 @@
int hprofDumpHeapObject(hprof_context_t *ctx, const Object *obj);
-/*
- * hprof_output.cc functions
- */
-
void hprofContextInit(hprof_context_t *ctx, char *fileName, int fd,
bool writeHeader, bool directToDdms);
@@ -223,10 +204,6 @@
#define hprofAddIdListToRecord(rec, values, numValues) \
hprofAddU4ListToRecord((rec), (const uint32_t *)(values), (numValues))
-/*
- * hprof.cc functions
- */
-
hprof_context_t* hprofStartup(const char *outputFileName, int fd,
bool directToDdms);
bool hprofShutdown(hprof_context_t *ctx);
diff --git a/src/hprof/hprof_class.cc b/src/hprof/hprof_class.cc
index d64e553..2e40ad4 100644
--- a/src/hprof/hprof_class.cc
+++ b/src/hprof/hprof_class.cc
@@ -40,8 +40,7 @@
}
static int getPrettyClassNameId(Class* clazz) {
- std::string name(PrettyClass(clazz));
- return hprofLookupStringId(name); // TODO: leaks
+ return hprofLookupStringId(PrettyClass(clazz));
}
hprof_class_object_id hprofLookupClassId(Class* clazz) {
diff --git a/src/hprof/hprof_string.cc b/src/hprof/hprof_string.cc
index 7fb4027..f498b6d 100644
--- a/src/hprof/hprof_string.cc
+++ b/src/hprof/hprof_string.cc
@@ -18,17 +18,18 @@
*/
#include "hprof.h"
#include "object.h"
-#include "unordered_set.h"
+#include "unordered_map.h"
#include "logging.h"
namespace art {
namespace hprof {
-typedef std::tr1::unordered_set<String*, StringHashCode> StringSet;
-typedef std::tr1::unordered_set<String*, StringHashCode>::iterator StringSetIterator; // TODO: equals by VALUE not REFERENCE
+size_t next_string_id_ = 200001;
+typedef std::tr1::unordered_map<std::string, size_t> StringMap;
+typedef std::tr1::unordered_map<std::string, size_t>::iterator StringMapIterator;
static Mutex strings_lock_("hprof strings");
-static StringSet strings_;
+static StringMap strings_;
int hprofStartup_String() {
return 0;
@@ -39,18 +40,19 @@
}
hprof_string_id hprofLookupStringId(String* string) {
- MutexLock mu(strings_lock_);
- std::pair<StringSetIterator, bool> result = strings_.insert(string);
- String* present = *result.first;
- return (hprof_string_id) present;
+ return hprofLookupStringId(string->ToModifiedUtf8());
}
hprof_string_id hprofLookupStringId(const char* string) {
- return hprofLookupStringId(String::AllocFromModifiedUtf8(string)); // TODO: leaks? causes GC?
+ return hprofLookupStringId(std::string(string));
}
hprof_string_id hprofLookupStringId(std::string string) {
- return hprofLookupStringId(string.c_str()); // TODO: leaks? causes GC?
+ MutexLock mu(strings_lock_);
+ if (strings_.find(string) == strings_.end()) {
+ strings_[string] = next_string_id_++;
+ }
+ return strings_[string];
}
int hprofDumpStrings(hprof_context_t *ctx) {
@@ -58,9 +60,9 @@
hprof_record_t *rec = &ctx->curRec;
- for (StringSetIterator it = strings_.begin(); it != strings_.end(); ++it) {
- String* string = *it;
- CHECK(string != NULL);
+ for (StringMapIterator it = strings_.begin(); it != strings_.end(); ++it) {
+ std::string string = (*it).first;
+ size_t id = (*it).second;
int err = hprofStartNewRecord(ctx, HPROF_TAG_STRING, HPROF_TIME);
if (err != 0) {
@@ -75,11 +77,11 @@
*
* We use the address of the string data as its ID.
*/
- err = hprofAddU4ToRecord(rec, (uint32_t) string);
+ err = hprofAddU4ToRecord(rec, id);
if (err != 0) {
return err;
}
- err = hprofAddUtf8StringToRecord(rec, string->ToModifiedUtf8().c_str()); // TODO: leak?
+ err = hprofAddUtf8StringToRecord(rec, string.c_str());
if (err != 0) {
return err;
}