mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1329111 - Change the nsIProfiler shared library information API. r=njn
API before this change: - nsIProfiler::getSharedLibraryInformation() returns a string containing a JSON array of libraries. - The profile format is at version 3. - Every profile has a "libs" field that contains the same JSON string as the return value of nsIProfiler::getSharedLibraryInformation. - The array of libraries is not sorted. - Each library has a "name" field that contains: - The module's debug name on Windows - The full path to the binary on Mac + Linux API after this change: - nsIProfiler::getSharedLibraryInformation() is removed. - nsIProfiler has a readonly property called sharedLibraries. - The profile format is at version 4. - Every profile has a "libs" field that contains the same array as nsIProfiler.sharedLibraries, no longer as a JSON string but as a regular array. - The array of libraries is sorted by start address. - Each library has a "name" field that contains the binary file's basename, on all platforms. - Each library has a "path" field that contains the full path to the binary, on all platforms. - Each library has a "debugName" field that contains the library's debug name, on all platforms. On Windows, the debug name is the filename (basename) of the pdb file for that binary. On other platforms, debugName is the same as |name|. - Each library has a "debugPath" field that contains the absolute path library's pdb file on Windows; on non-Windows, debugPath and path are the same. - Each library has an "arch" field that is either an empty string (Linux + Windows) or the library's architecture; it'll differentiate between the architectures "x86_64" and "x86_64h". (x86_64h is used for binaries that contain instructions that are specific to the Intel Haswell microarchitecture.) MozReview-Commit-ID: 8Nrs4dyHhDS --HG-- extra : rebase_source : 4039926ae4d776bf53ea71df5fe3f8200d3e2784 extra : source : 4e282aa03422de5b8d51e1aaeb3e53ee547293dd
This commit is contained in:
parent
e552737d0a
commit
5c5945bfa0
@ -1048,23 +1048,23 @@ AddSharedLibraryInfoToStream(JSONWriter& aWriter, const SharedLibrary& aLib)
|
||||
aWriter.IntProperty("start", SafeJSInteger(aLib.GetStart()));
|
||||
aWriter.IntProperty("end", SafeJSInteger(aLib.GetEnd()));
|
||||
aWriter.IntProperty("offset", SafeJSInteger(aLib.GetOffset()));
|
||||
aWriter.StringProperty("name", aLib.GetNativeDebugPath().c_str());
|
||||
aWriter.StringProperty("name", NS_ConvertUTF16toUTF8(aLib.GetModuleName()).get());
|
||||
aWriter.StringProperty("path", NS_ConvertUTF16toUTF8(aLib.GetModulePath()).get());
|
||||
aWriter.StringProperty("debugName", NS_ConvertUTF16toUTF8(aLib.GetDebugName()).get());
|
||||
aWriter.StringProperty("debugPath", NS_ConvertUTF16toUTF8(aLib.GetDebugPath()).get());
|
||||
aWriter.StringProperty("breakpadId", aLib.GetBreakpadId().c_str());
|
||||
aWriter.StringProperty("arch", aLib.GetArch().c_str());
|
||||
aWriter.EndObject();
|
||||
}
|
||||
|
||||
static std::string
|
||||
GetSharedLibraryInfoStringInternal()
|
||||
void
|
||||
AppendSharedLibraries(JSONWriter& aWriter)
|
||||
{
|
||||
SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf();
|
||||
std::ostringstream os;
|
||||
JSONWriter w(MakeUnique<OStreamJSONWriteFunc>(os));
|
||||
w.StartArrayElement();
|
||||
info.SortByAddress();
|
||||
for (size_t i = 0; i < info.GetSize(); i++) {
|
||||
AddSharedLibraryInfoToStream(w, info.GetEntry(i));
|
||||
AddSharedLibraryInfoToStream(aWriter, info.GetEntry(i));
|
||||
}
|
||||
w.EndArray();
|
||||
return os.str();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1112,7 +1112,7 @@ StreamMetaJSCustomObject(PS::LockRef aLock, SpliceableJSONWriter& aWriter)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
|
||||
aWriter.IntProperty("version", 3);
|
||||
aWriter.IntProperty("version", 4);
|
||||
aWriter.DoubleProperty("interval", gPS->Interval(aLock));
|
||||
aWriter.IntProperty("stackwalk", gPS->FeatureStackWalk(aLock));
|
||||
|
||||
@ -1267,8 +1267,9 @@ StreamJSON(PS::LockRef aLock, SpliceableJSONWriter& aWriter, double aSinceTime)
|
||||
aWriter.Start(SpliceableJSONWriter::SingleLineStyle);
|
||||
{
|
||||
// Put shared library info
|
||||
aWriter.StringProperty("libs",
|
||||
GetSharedLibraryInfoStringInternal().c_str());
|
||||
aWriter.StartArrayProperty("libs");
|
||||
AppendSharedLibraries(aWriter);
|
||||
aWriter.EndArray();
|
||||
|
||||
// Put meta data
|
||||
aWriter.StartObjectProperty("meta");
|
||||
|
@ -167,4 +167,9 @@ UniquePlatformData AllocPlatformData(int aThreadId);
|
||||
mozilla::UniquePtr<char[]>
|
||||
ToJSON(PSLockRef aLock, double aSinceTime);
|
||||
|
||||
namespace mozilla {
|
||||
class JSONWriter;
|
||||
}
|
||||
void AppendSharedLibraries(mozilla::JSONWriter& aWriter);
|
||||
|
||||
#endif /* ndef TOOLS_PLATFORM_H_ */
|
||||
|
@ -77,16 +77,28 @@ interface nsIProfiler : nsISupports
|
||||
double getElapsedTime();
|
||||
|
||||
/**
|
||||
* Returns a JSON string of an array of shared library objects.
|
||||
* Every object has three properties: start, end, and name.
|
||||
* start and end are integers describing the address range that the library
|
||||
* occupies in memory. name is the path of the library as a string.
|
||||
*
|
||||
* On Windows profiling builds, the shared library objects will have
|
||||
* additional pdbSignature and pdbAge properties for uniquely identifying
|
||||
* shared library versions for stack symbolication.
|
||||
* Contains an array of shared library objects.
|
||||
* Every object has the properties:
|
||||
* - start: The start address of the memory region occupied by this library.
|
||||
* - end: The end address of the memory region occupied by this library.
|
||||
* - offset: Usually zero, except on Android if the region was mapped from
|
||||
* a file (using mmap), then this is the offset in the file where
|
||||
* the mapping begins.
|
||||
* - name: The name (file basename) of the binary.
|
||||
* - path: The full absolute path to the binary.
|
||||
* - debugName: On Windows, the name of the pdb file for the binary. On other
|
||||
* platforms, the same as |name|.
|
||||
* - debugPath: On Windows, the full absolute path of the pdb file for the
|
||||
* binary. On other platforms, the same as |path|.
|
||||
* - arch: On Mac, the name of the architecture that identifies the right
|
||||
* binary image of a fat binary. Example values are "i386", "x86_64",
|
||||
* and "x86_64h". (x86_64h is used for binaries that contain
|
||||
* instructions that are specific to the Intel Haswell microarchitecture.)
|
||||
* On non-Mac platforms, arch is "".
|
||||
* - breakpadId: A unique identifier string for this library, as used by breakpad.
|
||||
*/
|
||||
AString getSharedLibraryInformation();
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval sharedLibraries;
|
||||
|
||||
/**
|
||||
* Dump the collected profile to a file.
|
||||
|
@ -144,18 +144,38 @@ nsProfiler::GetProfile(double aSinceTime, char** aProfile)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
std::string GetSharedLibraryInfoStringInternal();
|
||||
namespace {
|
||||
struct StringWriteFunc : public JSONWriteFunc
|
||||
{
|
||||
nsAString& mBuffer; // This struct must not outlive this buffer
|
||||
explicit StringWriteFunc(nsAString& buffer) : mBuffer(buffer) {}
|
||||
|
||||
std::string
|
||||
GetSharedLibraryInfoString()
|
||||
{
|
||||
return GetSharedLibraryInfoStringInternal();
|
||||
void Write(const char* aStr)
|
||||
{
|
||||
mBuffer.Append(NS_ConvertUTF8toUTF16(aStr));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsProfiler::GetSharedLibraryInformation(nsAString& aOutString)
|
||||
nsProfiler::GetSharedLibraries(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aResult)
|
||||
{
|
||||
aOutString.Assign(NS_ConvertUTF8toUTF16(GetSharedLibraryInfoString().c_str()));
|
||||
JS::RootedValue val(aCx);
|
||||
{
|
||||
nsString buffer;
|
||||
JSONWriter w(MakeUnique<StringWriteFunc>(buffer));
|
||||
w.StartArrayElement();
|
||||
AppendSharedLibraries(w);
|
||||
w.EndArray();
|
||||
MOZ_ALWAYS_TRUE(JS_ParseJSON(aCx, static_cast<const char16_t*>(buffer.get()),
|
||||
buffer.Length(), &val));
|
||||
}
|
||||
JS::RootedObject obj(aCx, &val.toObject());
|
||||
if (!obj) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aResult.setObject(*obj);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,19 @@ function run_test() {
|
||||
if (!profiler)
|
||||
return;
|
||||
|
||||
var sharedStr = profiler.getSharedLibraryInformation();
|
||||
sharedStr = sharedStr.toLowerCase();
|
||||
var libs = profiler.sharedLibraries;
|
||||
|
||||
// Let's not hardcode anything too specific
|
||||
// just some sanity checks.
|
||||
do_check_neq(sharedStr, null);
|
||||
do_check_neq(sharedStr, "");
|
||||
do_check_eq(typeof libs, "object");
|
||||
do_check_true(Array.isArray(libs));
|
||||
do_check_eq(typeof libs, "object");
|
||||
do_check_true(libs.length >= 1);
|
||||
do_check_eq(typeof libs[0], "object");
|
||||
do_check_eq(typeof libs[0].name, "string");
|
||||
do_check_eq(typeof libs[0].path, "string");
|
||||
do_check_eq(typeof libs[0].debugName, "string");
|
||||
do_check_eq(typeof libs[0].debugPath, "string");
|
||||
do_check_eq(typeof libs[0].arch, "string");
|
||||
do_check_eq(typeof libs[0].start, "number");
|
||||
do_check_eq(typeof libs[0].end, "number");
|
||||
do_check_true(libs[0].start <= libs[0].end);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user