Backed out changeset 712073c4f0b4 (bug 1213780) for causing rooting hazard failures on a CLOSED TREE

This commit is contained in:
Carsten "Tomcat" Book 2015-10-23 14:38:29 +02:00
parent a627be1cb7
commit de948d2239

View File

@ -10,7 +10,6 @@
#include <prio.h>
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Likely.h"
@ -221,27 +220,6 @@ CombinedStacks::SizeOfExcludingThis() const {
return n;
}
// This utility function generates a string key that is used to index the annotations
// in a hash map from |HangReports::AddHang|.
nsresult
ComputeAnnotationsKey(const HangAnnotationsPtr& aAnnotations, nsAString& aKeyOut)
{
UniquePtr<HangAnnotations::Enumerator> annotationsEnum = aAnnotations->GetEnumerator();
if (!annotationsEnum) {
return NS_ERROR_FAILURE;
}
// Append all the attributes to the key, to uniquely identify this annotation.
nsAutoString key;
nsAutoString value;
while (annotationsEnum->Next(key, value)) {
aKeyOut.Append(key);
aKeyOut.Append(value);
}
return NS_OK;
}
class HangReports {
public:
/**
@ -251,24 +229,21 @@ public:
struct AnnotationInfo {
AnnotationInfo(uint32_t aHangIndex,
HangAnnotationsPtr aAnnotations)
: mAnnotations(Move(aAnnotations))
{
mHangIndices.AppendElement(aHangIndex);
}
: mHangIndex(aHangIndex)
, mAnnotations(Move(aAnnotations))
{}
AnnotationInfo(AnnotationInfo&& aOther)
: mHangIndices(aOther.mHangIndices)
: mHangIndex(aOther.mHangIndex)
, mAnnotations(Move(aOther.mAnnotations))
{}
~AnnotationInfo() {}
AnnotationInfo& operator=(AnnotationInfo&& aOther)
{
mHangIndices = aOther.mHangIndices;
mHangIndex = aOther.mHangIndex;
mAnnotations = Move(aOther.mAnnotations);
return *this;
}
// To save memory, a single AnnotationInfo can be associated to multiple chrome
// hangs. The following array holds the index of each related chrome hang.
nsTArray<uint32_t> mHangIndices;
uint32_t mHangIndex;
HangAnnotationsPtr mAnnotations;
private:
@ -283,7 +258,7 @@ public:
uint32_t GetDuration(unsigned aIndex) const;
int32_t GetSystemUptime(unsigned aIndex) const;
int32_t GetFirefoxUptime(unsigned aIndex) const;
const nsClassHashtable<nsStringHashKey, AnnotationInfo>& GetAnnotationInfo() const;
const nsTArray<AnnotationInfo>& GetAnnotationInfo() const;
const CombinedStacks& GetStacks() const;
private:
/**
@ -299,7 +274,7 @@ private:
int32_t mFirefoxUptime;
};
std::vector<HangInfo> mHangInfo;
nsClassHashtable<nsStringHashKey, AnnotationInfo> mAnnotationInfo;
nsTArray<AnnotationInfo> mAnnotationInfo;
CombinedStacks mStacks;
};
@ -311,31 +286,12 @@ HangReports::AddHang(const Telemetry::ProcessedStack& aStack,
HangAnnotationsPtr aAnnotations) {
HangInfo info = { aDuration, aSystemUptime, aFirefoxUptime };
mHangInfo.push_back(info);
if (aAnnotations) {
AnnotationInfo ainfo(static_cast<uint32_t>(mHangInfo.size() - 1),
Move(aAnnotations));
mAnnotationInfo.AppendElement(Move(ainfo));
}
mStacks.AddStack(aStack);
if (!aAnnotations) {
return;
}
nsAutoString annotationsKey;
uint32_t hangIndex = static_cast<uint32_t>(mHangInfo.size() - 1);
// Generate a key to index aAnnotations in the hash map.
nsresult rv = ComputeAnnotationsKey(aAnnotations, annotationsKey);
if (NS_FAILED(rv)) {
return;
}
AnnotationInfo* annotationsEntry = mAnnotationInfo.Get(annotationsKey);
if (annotationsEntry) {
// If the key is already in the hash map, append the index of the chrome hang
// to its indices.
annotationsEntry->mHangIndices.AppendElement(hangIndex);
return;
}
// If the key was not found, add the annotations to the hash map.
mAnnotationInfo.Put(annotationsKey, new AnnotationInfo(hangIndex, Move(aAnnotations)));
}
size_t
@ -345,11 +301,9 @@ HangReports::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
// This is a crude approximation. See comment on
// CombinedStacks::SizeOfExcludingThis.
n += mHangInfo.capacity() * sizeof(HangInfo);
n += mAnnotationInfo.ShallowSizeOfExcludingThis(aMallocSizeOf);
n += mAnnotationInfo.Count() * sizeof(AnnotationInfo);
for (auto iter = mAnnotationInfo.ConstIter(); !iter.Done(); iter.Next()) {
n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
n += iter.Data()->mAnnotations->SizeOfIncludingThis(aMallocSizeOf);
n += mAnnotationInfo.Capacity() * sizeof(AnnotationInfo);
for (int32_t i = 0, l = mAnnotationInfo.Length(); i < l; ++i) {
n += mAnnotationInfo[i].mAnnotations->SizeOfIncludingThis(aMallocSizeOf);
}
return n;
}
@ -374,7 +328,7 @@ HangReports::GetFirefoxUptime(unsigned aIndex) const {
return mHangInfo[aIndex].mFirefoxUptime;
}
const nsClassHashtable<nsStringHashKey, HangReports::AnnotationInfo>&
const nsTArray<HangReports::AnnotationInfo>&
HangReports::GetAnnotationInfo() const {
return mAnnotationInfo;
}
@ -2582,46 +2536,30 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle<JS::Value> ret)
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
size_t annotationIndex = 0;
const nsClassHashtable<nsStringHashKey, HangReports::AnnotationInfo>& annotationInfo =
mHangReports.GetAnnotationInfo();
for (auto iter = annotationInfo.ConstIter(); !iter.Done(); iter.Next()) {
const HangReports::AnnotationInfo* info = iter.Data();
const nsTArray<HangReports::AnnotationInfo>& annotationInfo =
mHangReports.GetAnnotationInfo();
for (uint32_t iterIndex = 0, arrayLen = annotationInfo.Length();
iterIndex < arrayLen; ++iterIndex) {
JS::Rooted<JSObject*> keyValueArray(cx, JS_NewArrayObject(cx, 0));
if (!keyValueArray) {
return NS_ERROR_FAILURE;
}
// Create an array containing all the indices of the chrome hangs relative to this
// annotation.
JS::Rooted<JS::Value> indicesArray(cx);
if (!mozilla::dom::ToJSValue(cx, info->mHangIndices, &indicesArray)) {
return NS_ERROR_OUT_OF_MEMORY;
}
// We're saving the annotation as [[indices], {annotation-data}], so add the indices
// array as the first element of that structure.
if (!JS_DefineElement(cx, keyValueArray, 0, indicesArray, JSPROP_ENUMERATE)) {
JS::RootedValue indexValue(cx);
indexValue.setNumber(annotationInfo[iterIndex].mHangIndex);
if (!JS_DefineElement(cx, keyValueArray, 0, indexValue, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
// Create the annotations object...
JS::Rooted<JSObject*> jsAnnotation(cx, JS_NewPlainObject(cx));
if (!jsAnnotation) {
return NS_ERROR_FAILURE;
}
UniquePtr<HangAnnotations::Enumerator> annotationsEnum =
info->mAnnotations->GetEnumerator();
annotationInfo[iterIndex].mAnnotations->GetEnumerator();
if (!annotationsEnum) {
return NS_ERROR_FAILURE;
}
// ... fill it with key:value pairs...
nsAutoString key;
nsAutoString value;
nsAutoString key;
nsAutoString value;
while (annotationsEnum->Next(key, value)) {
JS::RootedValue jsValue(cx);
jsValue.setString(JS_NewUCStringCopyN(cx, value.get(), value.Length()));
@ -2630,12 +2568,10 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle<JS::Value> ret)
return NS_ERROR_FAILURE;
}
}
// ... and append it after the indices array.
if (!JS_DefineElement(cx, keyValueArray, 1, jsAnnotation, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
if (!JS_DefineElement(cx, annotationsArray, annotationIndex++,
if (!JS_DefineElement(cx, annotationsArray, iterIndex,
keyValueArray, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}