NS_IMETHODIMP TelemetryImpl::GetHistogramById(const nsACString &name, JSContext *cx, jsval *ret) { // Cache names // Note the histogram names are statically allocated if (!mHistogramMap.Count()) { for (PRUint32 i = 0; i < Telemetry::HistogramCount; i++) { CharPtrEntryType *entry = mHistogramMap.PutEntry(gHistograms[i].id); if (NS_UNLIKELY(!entry)) { mHistogramMap.Clear(); return NS_ERROR_OUT_OF_MEMORY; } entry->mData = (Telemetry::ID) i; } } CharPtrEntryType *entry = mHistogramMap.GetEntry(PromiseFlatCString(name).get()); if (!entry) return NS_ERROR_FAILURE; Histogram *h; nsresult rv = GetHistogramByEnumId(entry->mData, &h); if (NS_FAILED(rv)) return rv; return WrapAndReturnHistogram(h, cx, ret); }
NS_IMETHODIMP TelemetryImpl::GetHistogramSnapshots(JSContext *cx, jsval *ret) { JSObject *root_obj = JS_NewObject(cx, NULL, NULL, NULL); if (!root_obj) return NS_ERROR_FAILURE; *ret = OBJECT_TO_JSVAL(root_obj); // Ensure that all the HISTOGRAM_FLAG histograms have been created, so // that their values are snapshotted. for (size_t i = 0; i < Telemetry::HistogramCount; ++i) { if (gHistograms[i].histogramType == nsITelemetry::HISTOGRAM_FLAG) { Histogram *h; DebugOnly<nsresult> rv = GetHistogramByEnumId(Telemetry::ID(i), &h); MOZ_ASSERT(NS_SUCCEEDED(rv)); } }; StatisticsRecorder::Histograms hs; StatisticsRecorder::GetHistograms(&hs); // We identify corrupt histograms first, rather than interspersing it // in the loop below, to ensure that our corruption statistics don't // depend on histogram enumeration order. // // Of course, we hope that all of these corruption-statistics // histograms are not themselves corrupt... IdentifyCorruptHistograms(hs); // OK, now we can actually reflect things. for (HistogramIterator it = hs.begin(); it != hs.end(); ++it) { Histogram *h = *it; if (!ShouldReflectHistogram(h) || IsEmpty(h)) { continue; } JSObject *hobj = JS_NewObject(cx, NULL, NULL, NULL); if (!hobj) { return NS_ERROR_FAILURE; } JS::AutoObjectRooter root(cx, hobj); switch (ReflectHistogramSnapshot(cx, hobj, h)) { case REFLECT_CORRUPT: // We can still hit this case even if ShouldReflectHistograms // returns true. The histogram lies outside of our control // somehow; just skip it. continue; case REFLECT_FAILURE: return NS_ERROR_FAILURE; case REFLECT_OK: if (!JS_DefineProperty(cx, root_obj, h->histogram_name().c_str(), OBJECT_TO_JSVAL(hobj), NULL, NULL, JSPROP_ENUMERATE)) { return NS_ERROR_FAILURE; } } } return NS_OK; }
nsresult TelemetryImpl::GetHistogramByName(const nsACString &name, Histogram **ret) { Telemetry::ID id; nsresult rv = GetHistogramEnumId(PromiseFlatCString(name).get(), &id); if (NS_FAILED(rv)) { return rv; } rv = GetHistogramByEnumId(id, ret); if (NS_FAILED(rv)) return rv; return NS_OK; }