Bug 1166492 - Return UniquePtr<char[]> from profiler_get_profile to avoid double copying. (r=mstange)

This commit is contained in:
Shu-yu Guo 2015-05-26 22:58:40 -07:00
parent 58d880c1fb
commit 95302871f0
10 changed files with 26 additions and 23 deletions

View File

@ -2655,10 +2655,9 @@ ContentChild::RecvStopProfiler()
bool
ContentChild::RecvGetProfile(nsCString* aProfile)
{
char* profile = profiler_get_profile();
UniquePtr<char[]> profile = profiler_get_profile();
if (profile) {
*aProfile = nsCString(profile, strlen(profile));
free(profile);
*aProfile = nsCString(profile.get(), strlen(profile.get()));
} else {
*aProfile = EmptyCString();
}

View File

@ -2566,10 +2566,9 @@ PluginModuleChild::RecvStopProfiler()
bool
PluginModuleChild::AnswerGetProfile(nsCString* aProfile)
{
char* profile = profiler_get_profile();
UniquePtr<char[]> profile = profiler_get_profile();
if (profile != nullptr) {
*aProfile = nsCString(profile, strlen(profile));
free(profile);
*aProfile = nsCString(profile.get(), strlen(profile.get()));
} else {
*aProfile = nsCString("", 0);
}

View File

@ -50,6 +50,7 @@
#define SAMPLER_H
#include "js/TypeDecls.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
class TimeStamp;
@ -159,7 +160,9 @@ static inline void profiler_responsiveness(const mozilla::TimeStamp& aTime) {}
static inline void profiler_set_frame_number(int frameNumber) {}
// Get the profile encoded as a JSON string.
static inline char* profiler_get_profile(float aSinceTime = 0) { return nullptr; }
static inline mozilla::UniquePtr<char[]> profiler_get_profile(float aSinceTime = 0) {
return nullptr;
}
// Get the profile encoded as a JSON object.
static inline JSObject* profiler_get_profile_jsobject(JSContext* aCx,

View File

@ -8,6 +8,7 @@
#include "js/TypeDecls.h"
#include "js/ProfilingStack.h"
#include "mozilla/UniquePtr.h"
#include <stdint.h>
namespace mozilla {
@ -53,7 +54,7 @@ const double* mozilla_sampler_get_responsiveness();
void mozilla_sampler_save();
char* mozilla_sampler_get_profile(float aSinceTime);
mozilla::UniquePtr<char[]> mozilla_sampler_get_profile(float aSinceTime);
JSObject *mozilla_sampler_get_profile_data(JSContext *aCx, float aSinceTime);

View File

@ -144,7 +144,7 @@ void profiler_set_frame_number(int frameNumber)
}
static inline
char* profiler_get_profile(float aSinceTime = 0)
mozilla::UniquePtr<char[]> profiler_get_profile(float aSinceTime = 0)
{
return mozilla_sampler_get_profile(aSinceTime);
}

View File

@ -218,9 +218,7 @@ JSObject* TableTicker::ToJSObject(JSContext *aCx, float aSinceTime)
{
JS::RootedValue val(aCx);
{
SpliceableChunkedJSONWriter b;
StreamJSON(b, aSinceTime);
UniquePtr<char[]> buf = b.WriteFunc()->CopyData();
UniquePtr<char[]> buf = ToJSON(aSinceTime);
NS_ConvertUTF8toUTF16 js_string(nsDependentCString(buf.get()));
MOZ_ALWAYS_TRUE(JS_ParseJSON(aCx, static_cast<const char16_t*>(js_string.get()),
js_string.Length(), &val));
@ -228,6 +226,13 @@ JSObject* TableTicker::ToJSObject(JSContext *aCx, float aSinceTime)
return &val.toObject();
}
UniquePtr<char[]> TableTicker::ToJSON(float aSinceTime)
{
SpliceableChunkedJSONWriter b;
StreamJSON(b, aSinceTime);
return b.WriteFunc()->CopyData();
}
struct SubprocessClosure {
explicit SubprocessClosure(SpliceableJSONWriter *aWriter)
: mWriter(aWriter)

View File

@ -194,6 +194,7 @@ class TableTicker: public Sampler {
void ToStreamAsJSON(std::ostream& stream, float aSinceTime = 0);
virtual JSObject *ToJSObject(JSContext *aCx, float aSinceTime = 0);
mozilla::UniquePtr<char[]> ToJSON(float aSinceTime = 0);
void StreamMetaJSCustomObject(SpliceableJSONWriter& aWriter);
void StreamTaskTracer(SpliceableJSONWriter& aWriter);
void FlushOnJSShutdown(JSRuntime* aRuntime);

View File

@ -119,14 +119,13 @@ nsProfiler::AddMarker(const char *aMarker)
NS_IMETHODIMP
nsProfiler::GetProfile(float aSinceTime, char **aProfile)
{
char *profile = profiler_get_profile(aSinceTime);
mozilla::UniquePtr<char[]> profile = profiler_get_profile(aSinceTime);
if (profile) {
size_t len = strlen(profile);
size_t len = strlen(profile.get());
char *profileStr = static_cast<char *>
(nsMemory::Clone(profile, (len + 1) * sizeof(char)));
(nsMemory::Clone(profile.get(), (len + 1) * sizeof(char)));
profileStr[len] = '\0';
*aProfile = profileStr;
free(profile);
}
return NS_OK;
}

View File

@ -561,17 +561,14 @@ void mozilla_sampler_save()
t->HandleSaveRequest();
}
char* mozilla_sampler_get_profile(float aSinceTime)
mozilla::UniquePtr<char[]> mozilla_sampler_get_profile(float aSinceTime)
{
TableTicker *t = tlsTicker.get();
if (!t) {
return nullptr;
}
std::stringstream stream;
t->ToStreamAsJSON(stream, aSinceTime);
char* profile = strdup(stream.str().c_str());
return profile;
return t->ToJSON(aSinceTime);
}
JSObject *mozilla_sampler_get_profile_data(JSContext *aCx, float aSinceTime)

View File

@ -1012,9 +1012,8 @@ Java_org_mozilla_gecko_ANRReporter_getNativeStack(JNIEnv* jenv, jclass)
const PRIntervalTime timeout = PR_SecondsToInterval(5);
const PRIntervalTime startTime = PR_IntervalNow();
typedef struct { void operator()(void* p) { free(p); } } ProfilePtrPolicy;
// Pointer to a profile JSON string
typedef mozilla::UniquePtr<char, ProfilePtrPolicy> ProfilePtr;
typedef mozilla::UniquePtr<char[]> ProfilePtr;
ProfilePtr profile(profiler_get_profile());