зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1425909) for mochitest C3 failures on test_memoryReporters.xul. on a CLOSED TREE
Backed out changeset 6bcaae60c82e (bug 1425909) Backed out changeset 0b5d96b317c3 (bug 1425909)
This commit is contained in:
Родитель
54a5db7d0a
Коммит
b709f2768b
|
@ -23,16 +23,14 @@ struct BaseScalarInfo {
|
|||
uint32_t dataset;
|
||||
mozilla::Telemetry::Common::RecordedProcessType record_in_processes;
|
||||
bool keyed;
|
||||
bool builtin;
|
||||
|
||||
BaseScalarInfo(uint32_t aKind, uint32_t aDataset,
|
||||
mozilla::Telemetry::Common::RecordedProcessType aRecordInProcess,
|
||||
bool aKeyed, bool aBuiltin = true)
|
||||
bool aKeyed)
|
||||
: kind(aKind)
|
||||
, dataset(aDataset)
|
||||
, record_in_processes(aRecordInProcess)
|
||||
, keyed(aKeyed)
|
||||
, builtin(aBuiltin)
|
||||
{}
|
||||
virtual ~BaseScalarInfo() {}
|
||||
|
||||
|
|
|
@ -1727,15 +1727,7 @@ TelemetryImpl::RegisterScalars(const nsACString& aCategoryName,
|
|||
JS::Handle<JS::Value> aScalarData,
|
||||
JSContext* cx)
|
||||
{
|
||||
return TelemetryScalar::RegisterScalars(aCategoryName, aScalarData, false, cx);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelemetryImpl::RegisterBuiltinScalars(const nsACString& aCategoryName,
|
||||
JS::Handle<JS::Value> aScalarData,
|
||||
JSContext* cx)
|
||||
{
|
||||
return TelemetryScalar::RegisterScalars(aCategoryName, aScalarData, true, cx);
|
||||
return TelemetryScalar::RegisterScalars(aCategoryName, aScalarData, cx);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -67,7 +67,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
TelemetryModules: "resource://gre/modules/TelemetryModules.jsm",
|
||||
UpdatePing: "resource://gre/modules/UpdatePing.jsm",
|
||||
TelemetryHealthPing: "resource://gre/modules/TelemetryHealthPing.jsm",
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -157,13 +156,6 @@ this.TelemetryController = Object.freeze({
|
|||
return Impl.setupContentTelemetry(true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Used only for testing purposes.
|
||||
*/
|
||||
testPromiseJsProbeRegistration() {
|
||||
return Promise.resolve(Impl._probeRegistrationPromise);
|
||||
},
|
||||
|
||||
/**
|
||||
* Send a notification.
|
||||
*/
|
||||
|
@ -330,8 +322,6 @@ var Impl = {
|
|||
_testMode: false,
|
||||
// The task performing the delayed sending of the "new-profile" ping.
|
||||
_delayedNewPingTask: null,
|
||||
// The promise used to wait for the JS probe registration (dynamic builtin).
|
||||
_probeRegistrationPromise: null,
|
||||
|
||||
get _log() {
|
||||
if (!this._logger) {
|
||||
|
@ -689,11 +679,6 @@ var Impl = {
|
|||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Enable adding scalars in artifact builds and build faster modes.
|
||||
// The function is async: we intentionally don't wait for it to complete
|
||||
// as we don't want to delay startup.
|
||||
this._probeRegistrationPromise = this.registerJsProbes();
|
||||
|
||||
// This will trigger displaying the datachoices infobar.
|
||||
TelemetryReportingPolicy.setup();
|
||||
|
||||
|
@ -1053,64 +1038,4 @@ var Impl = {
|
|||
.then(() => TelemetrySession.markNewProfilePingSent(),
|
||||
e => this._log.error("sendNewProfilePing - failed to submit new-profile ping", e));
|
||||
},
|
||||
|
||||
/**
|
||||
* Register 'dynamic builtin' probes from the JSON definition files.
|
||||
* This is needed to support adding new probes in developer builds
|
||||
* without rebuilding the whole codebase.
|
||||
*
|
||||
* This is not meant to be used outside of local developer builds.
|
||||
*/
|
||||
async registerJsProbes() {
|
||||
// We don't support this outside of developer builds.
|
||||
if (AppConstants.MOZILLA_OFFICIAL && !this._testMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._log.trace("registerJsProbes - registering builtin JS probes");
|
||||
|
||||
// Load the scalar probes JSON file.
|
||||
const scalarProbeFilename = "ScalarArtifactDefinitions.json";
|
||||
let scalarProbeFile = Services.dirsvc.get("GreBinD", Ci.nsIFile);
|
||||
scalarProbeFile.append(scalarProbeFilename);
|
||||
if (!scalarProbeFile.exists()) {
|
||||
this._log.trace("registerJsProbes - no scalar builtin JS probes");
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the file off the disk.
|
||||
let scalarJSProbes = {};
|
||||
try {
|
||||
let fileContent = await OS.File.read(scalarProbeFile.path, { encoding: "utf-8" });
|
||||
scalarJSProbes = JSON.parse(fileContent, (property, value) => {
|
||||
// Fixup the "kind" property: it's a string, and we need the constant
|
||||
// coming from nsITelemetry.
|
||||
if (property !== "kind" || typeof value != "string") {
|
||||
return value;
|
||||
}
|
||||
|
||||
let newValue;
|
||||
switch (value) {
|
||||
case "nsITelemetry::SCALAR_TYPE_COUNT":
|
||||
newValue = Telemetry.SCALAR_TYPE_COUNT;
|
||||
break;
|
||||
case "nsITelemetry::SCALAR_TYPE_BOOLEAN":
|
||||
newValue = Telemetry.SCALAR_TYPE_BOOLEAN;
|
||||
break;
|
||||
case "nsITelemetry::SCALAR_TYPE_STRING":
|
||||
newValue = Telemetry.SCALAR_TYPE_STRING;
|
||||
break;
|
||||
}
|
||||
return newValue;
|
||||
});
|
||||
} catch (ex) {
|
||||
this._log.error(`registerJsProbes - there was an error loading {$scalarProbeFilename}`,
|
||||
ex);
|
||||
}
|
||||
|
||||
// Register the builtin probes.
|
||||
for (let category in scalarJSProbes) {
|
||||
Telemetry.registerBuiltinScalars(category, scalarJSProbes[category]);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -137,14 +137,13 @@ struct DynamicScalarInfo : BaseScalarInfo {
|
|||
|
||||
DynamicScalarInfo(uint32_t aKind, bool aRecordOnRelease,
|
||||
bool aExpired, const nsACString& aName,
|
||||
bool aKeyed, bool aBuiltin)
|
||||
bool aKeyed)
|
||||
: BaseScalarInfo(aKind,
|
||||
aRecordOnRelease ?
|
||||
nsITelemetry::DATASET_RELEASE_CHANNEL_OPTOUT :
|
||||
nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN,
|
||||
RecordedProcessType::All,
|
||||
aKeyed,
|
||||
aBuiltin)
|
||||
aKeyed)
|
||||
, mDynamicName(aName)
|
||||
, mDynamicExpiration(aExpired)
|
||||
{}
|
||||
|
@ -855,10 +854,6 @@ ScalarMapType gScalarNameIDMap(kScalarCount);
|
|||
ProcessesScalarsMapType gScalarStorageMap;
|
||||
// As above, for the keyed scalars.
|
||||
ProcessesKeyedScalarsMapType gKeyedScalarStorageMap;
|
||||
// Provide separate storage for "dynamic builtin" plain and keyed scalars,
|
||||
// needed to support "build faster" in local developer builds.
|
||||
ProcessesScalarsMapType gDynamicBuiltinScalarStorageMap;
|
||||
ProcessesKeyedScalarsMapType gDynamicBuiltinKeyedScalarStorageMap;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -1105,11 +1100,8 @@ internal_GetScalarByEnum(const StaticMutexAutoLock& lock,
|
|||
|
||||
const BaseScalarInfo &info = internal_GetScalarInfo(lock, aId);
|
||||
|
||||
// Dynamic scalars fixup: they are always stored in the "dynamic" process,
|
||||
// unless they are part of the "builtin" Firefox probes. Please note that
|
||||
// "dynamic builtin" probes are meant to support "artifact" and "build faster"
|
||||
// builds.
|
||||
if (aId.dynamic && !info.builtin) {
|
||||
// Dynamic scalars fixup: they are always stored in the "dynamic" process.
|
||||
if (aId.dynamic) {
|
||||
aProcessStorage = ProcessID::Dynamic;
|
||||
}
|
||||
|
||||
|
@ -1119,16 +1111,11 @@ internal_GetScalarByEnum(const StaticMutexAutoLock& lock,
|
|||
// set to the child storage if needed.
|
||||
uint32_t storageId = static_cast<uint32_t>(aProcessStorage);
|
||||
|
||||
// Put dynamic-builtin scalars (used to support "build faster") in a
|
||||
// separate storage.
|
||||
ProcessesScalarsMapType& processStorage =
|
||||
(aId.dynamic && info.builtin) ? gDynamicBuiltinScalarStorageMap : gScalarStorageMap;
|
||||
|
||||
// Get the process-specific storage or create one if it's not
|
||||
// available.
|
||||
if (!processStorage.Get(storageId, &scalarStorage)) {
|
||||
if (!gScalarStorageMap.Get(storageId, &scalarStorage)) {
|
||||
scalarStorage = new ScalarStorageMapType();
|
||||
processStorage.Put(storageId, scalarStorage);
|
||||
gScalarStorageMap.Put(storageId, scalarStorage);
|
||||
}
|
||||
|
||||
// Check if the scalar is already allocated in the parent or in the child storage.
|
||||
|
@ -1270,11 +1257,8 @@ internal_GetKeyedScalarByEnum(const StaticMutexAutoLock& lock,
|
|||
|
||||
const BaseScalarInfo &info = internal_GetScalarInfo(lock, aId);
|
||||
|
||||
// Dynamic scalars fixup: they are always stored in the "dynamic" process,
|
||||
// unless they are part of the "builtin" Firefox probes. Please note that
|
||||
// "dynamic builtin" probes are meant to support "artifact" and "build faster"
|
||||
// builds.
|
||||
if (aId.dynamic && !info.builtin) {
|
||||
// Dynamic scalars fixup: they are always stored in the "dynamic" process.
|
||||
if (aId.dynamic) {
|
||||
aProcessStorage = ProcessID::Dynamic;
|
||||
}
|
||||
|
||||
|
@ -1284,16 +1268,11 @@ internal_GetKeyedScalarByEnum(const StaticMutexAutoLock& lock,
|
|||
// set to the child storage if needed.
|
||||
uint32_t storageId = static_cast<uint32_t>(aProcessStorage);
|
||||
|
||||
// Put dynamic-builtin scalars (used to support "build faster") in a
|
||||
// separate storage.
|
||||
ProcessesKeyedScalarsMapType& processStorage =
|
||||
(aId.dynamic && info.builtin) ? gDynamicBuiltinKeyedScalarStorageMap : gKeyedScalarStorageMap;
|
||||
|
||||
// Get the process-specific storage or create one if it's not
|
||||
// available.
|
||||
if (!processStorage.Get(storageId, &scalarStorage)) {
|
||||
if (!gKeyedScalarStorageMap.Get(storageId, &scalarStorage)) {
|
||||
scalarStorage = new KeyedScalarStorageMapType();
|
||||
processStorage.Put(storageId, scalarStorage);
|
||||
gKeyedScalarStorageMap.Put(storageId, scalarStorage);
|
||||
}
|
||||
|
||||
if (scalarStorage->Get(aId.id, &scalar)) {
|
||||
|
@ -1446,7 +1425,7 @@ internal_RegisterScalars(const StaticMutexAutoLock& lock,
|
|||
CharPtrEntryType *existingKey = gScalarNameIDMap.GetEntry(scalarInfo.name());
|
||||
if (existingKey) {
|
||||
// Change the scalar to expired if needed.
|
||||
if (scalarInfo.mDynamicExpiration && !scalarInfo.builtin) {
|
||||
if (scalarInfo.mDynamicExpiration) {
|
||||
DynamicScalarInfo& scalarData = (*gDynamicScalarInfo)[existingKey->mData.id];
|
||||
scalarData.mDynamicExpiration = true;
|
||||
}
|
||||
|
@ -1509,8 +1488,6 @@ TelemetryScalar::DeInitializeGlobalState()
|
|||
gScalarNameIDMap.Clear();
|
||||
gScalarStorageMap.Clear();
|
||||
gKeyedScalarStorageMap.Clear();
|
||||
gDynamicBuiltinScalarStorageMap.Clear();
|
||||
gDynamicBuiltinKeyedScalarStorageMap.Clear();
|
||||
gDynamicScalarInfo = nullptr;
|
||||
gInitDone = false;
|
||||
}
|
||||
|
@ -2156,63 +2133,41 @@ TelemetryScalar::CreateSnapshots(unsigned int aDataset, bool aClearScalars, JSCo
|
|||
nsDataHashtable<ProcessIDHashKey, ScalarArray> scalarsToReflect;
|
||||
{
|
||||
StaticMutexAutoLock locker(gTelemetryScalarsMutex);
|
||||
// Iterate the scalars in gScalarStorageMap. The storage may contain empty or yet to be
|
||||
// initialized scalars from all the supported processes.
|
||||
for (auto iter = gScalarStorageMap.Iter(); !iter.Done(); iter.Next()) {
|
||||
ScalarStorageMapType* scalarStorage = static_cast<ScalarStorageMapType*>(iter.Data());
|
||||
ScalarArray& processScalars = scalarsToReflect.GetOrInsert(iter.Key());
|
||||
|
||||
// The snapshotting function is the same for both static and dynamic builtin scalars.
|
||||
// We can use the same function and store the scalars in the same output storage.
|
||||
auto snapshotter = [aDataset, &locker, &scalarsToReflect]
|
||||
(ProcessesScalarsMapType& aProcessStorage, bool aIsBuiltinDynamic)
|
||||
-> nsresult
|
||||
{
|
||||
// Iterate the scalars in aProcessStorage. The storage may contain empty or yet to be
|
||||
// initialized scalars from all the supported processes.
|
||||
for (auto iter = aProcessStorage.Iter(); !iter.Done(); iter.Next()) {
|
||||
ScalarStorageMapType* scalarStorage = static_cast<ScalarStorageMapType*>(iter.Data());
|
||||
ScalarArray& processScalars = scalarsToReflect.GetOrInsert(iter.Key());
|
||||
// Are we in the "Dynamic" process?
|
||||
bool isDynamicProcess = ProcessID::Dynamic == static_cast<ProcessID>(iter.Key());
|
||||
|
||||
// Are we in the "Dynamic" process?
|
||||
bool isDynamicProcess = ProcessID::Dynamic == static_cast<ProcessID>(iter.Key());
|
||||
// Iterate each available child storage.
|
||||
for (auto childIter = scalarStorage->Iter(); !childIter.Done(); childIter.Next()) {
|
||||
ScalarBase* scalar = static_cast<ScalarBase*>(childIter.Data());
|
||||
|
||||
// Iterate each available child storage.
|
||||
for (auto childIter = scalarStorage->Iter(); !childIter.Done(); childIter.Next()) {
|
||||
ScalarBase* scalar = static_cast<ScalarBase*>(childIter.Data());
|
||||
// Get the informations for this scalar.
|
||||
const BaseScalarInfo& info =
|
||||
internal_GetScalarInfo(locker, ScalarKey{childIter.Key(),
|
||||
isDynamicProcess});
|
||||
|
||||
// Get the informations for this scalar.
|
||||
const BaseScalarInfo& info =
|
||||
internal_GetScalarInfo(locker, ScalarKey{childIter.Key(),
|
||||
aIsBuiltinDynamic ? true : isDynamicProcess});
|
||||
|
||||
// Serialize the scalar if it's in the desired dataset.
|
||||
if (IsInDataset(info.dataset, aDataset)) {
|
||||
// Get the scalar value.
|
||||
nsCOMPtr<nsIVariant> scalarValue;
|
||||
nsresult rv = scalar->GetValue(scalarValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
// Append it to our list.
|
||||
processScalars.AppendElement(mozilla::MakePair(info.name(), scalarValue));
|
||||
// Serialize the scalar if it's in the desired dataset.
|
||||
if (IsInDataset(info.dataset, aDataset)) {
|
||||
// Get the scalar value.
|
||||
nsCOMPtr<nsIVariant> scalarValue;
|
||||
nsresult rv = scalar->GetValue(scalarValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
// Append it to our list.
|
||||
processScalars.AppendElement(mozilla::MakePair(info.name(), scalarValue));
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
};
|
||||
|
||||
// Take a snapshot of the scalars.
|
||||
nsresult rv = snapshotter(gScalarStorageMap, false);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// And a snapshot of the dynamic builtin ones.
|
||||
rv = snapshotter(gDynamicBuiltinScalarStorageMap, true);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aClearScalars) {
|
||||
// The map already takes care of freeing the allocated memory.
|
||||
gScalarStorageMap.Clear();
|
||||
gDynamicBuiltinScalarStorageMap.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2286,61 +2241,41 @@ TelemetryScalar::CreateKeyedSnapshots(unsigned int aDataset, bool aClearScalars,
|
|||
nsDataHashtable<ProcessIDHashKey, ScalarArray> scalarsToReflect;
|
||||
{
|
||||
StaticMutexAutoLock locker(gTelemetryScalarsMutex);
|
||||
// Iterate the scalars in gKeyedScalarStorageMap. The storage may contain empty or yet
|
||||
// to be initialized scalars from all the supported processes.
|
||||
for (auto iter = gKeyedScalarStorageMap.Iter(); !iter.Done(); iter.Next()) {
|
||||
KeyedScalarStorageMapType* scalarStorage =
|
||||
static_cast<KeyedScalarStorageMapType*>(iter.Data());
|
||||
ScalarArray& processScalars = scalarsToReflect.GetOrInsert(iter.Key());
|
||||
|
||||
auto snapshotter = [aDataset, &locker, &scalarsToReflect]
|
||||
(ProcessesKeyedScalarsMapType& aProcessStorage,
|
||||
bool aIsBuiltinDynamic) -> nsresult
|
||||
{
|
||||
// Iterate the scalars in aProcessStorage. The storage may contain empty or yet
|
||||
// to be initialized scalars from all the supported processes.
|
||||
for (auto iter = aProcessStorage.Iter(); !iter.Done(); iter.Next()) {
|
||||
KeyedScalarStorageMapType* scalarStorage =
|
||||
static_cast<KeyedScalarStorageMapType*>(iter.Data());
|
||||
ScalarArray& processScalars = scalarsToReflect.GetOrInsert(iter.Key());
|
||||
// Are we in the "Dynamic" process?
|
||||
bool isDynamicProcess = ProcessID::Dynamic == static_cast<ProcessID>(iter.Key());
|
||||
|
||||
// Are we in the "Dynamic" process?
|
||||
bool isDynamicProcess = ProcessID::Dynamic == static_cast<ProcessID>(iter.Key());
|
||||
for (auto childIter = scalarStorage->Iter(); !childIter.Done(); childIter.Next()) {
|
||||
KeyedScalar* scalar = static_cast<KeyedScalar*>(childIter.Data());
|
||||
|
||||
for (auto childIter = scalarStorage->Iter(); !childIter.Done(); childIter.Next()) {
|
||||
KeyedScalar* scalar = static_cast<KeyedScalar*>(childIter.Data());
|
||||
// Get the informations for this scalar.
|
||||
const BaseScalarInfo& info =
|
||||
internal_GetScalarInfo(locker, ScalarKey{childIter.Key(),
|
||||
isDynamicProcess});
|
||||
|
||||
// Get the informations for this scalar.
|
||||
const BaseScalarInfo& info =
|
||||
internal_GetScalarInfo(locker, ScalarKey{childIter.Key(),
|
||||
aIsBuiltinDynamic ? true : isDynamicProcess});
|
||||
|
||||
// Serialize the scalar if it's in the desired dataset.
|
||||
if (IsInDataset(info.dataset, aDataset)) {
|
||||
// Get the keys for this scalar.
|
||||
nsTArray<KeyedScalar::KeyValuePair> scalarKeyedData;
|
||||
nsresult rv = scalar->GetValue(scalarKeyedData);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
// Append it to our list.
|
||||
processScalars.AppendElement(mozilla::MakePair(info.name(), scalarKeyedData));
|
||||
// Serialize the scalar if it's in the desired dataset.
|
||||
if (IsInDataset(info.dataset, aDataset)) {
|
||||
// Get the keys for this scalar.
|
||||
nsTArray<KeyedScalar::KeyValuePair> scalarKeyedData;
|
||||
nsresult rv = scalar->GetValue(scalarKeyedData);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
// Append it to our list.
|
||||
processScalars.AppendElement(mozilla::MakePair(info.name(), scalarKeyedData));
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
};
|
||||
|
||||
// Take a snapshot of the scalars.
|
||||
nsresult rv = snapshotter(gKeyedScalarStorageMap, false);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// And a snapshot of the dynamic builtin ones.
|
||||
rv = snapshotter(gDynamicBuiltinKeyedScalarStorageMap, true);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aClearScalars) {
|
||||
// The map already takes care of freeing the allocated memory.
|
||||
gKeyedScalarStorageMap.Clear();
|
||||
gDynamicBuiltinKeyedScalarStorageMap.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2398,7 +2333,6 @@ TelemetryScalar::CreateKeyedSnapshots(unsigned int aDataset, bool aClearScalars,
|
|||
nsresult
|
||||
TelemetryScalar::RegisterScalars(const nsACString& aCategoryName,
|
||||
JS::Handle<JS::Value> aScalarData,
|
||||
bool aBuiltin,
|
||||
JSContext* cx)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess(),
|
||||
|
@ -2497,7 +2431,7 @@ TelemetryScalar::RegisterScalars(const nsACString& aCategoryName,
|
|||
// We defer the actual registration here in case any other event description is invalid.
|
||||
// In that case we don't need to roll back any partial registration.
|
||||
newScalarInfos.AppendElement(DynamicScalarInfo{
|
||||
kind, recordOnRelease, expired, fullName, keyed, aBuiltin
|
||||
kind, recordOnRelease, expired, fullName, keyed
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2527,8 +2461,6 @@ TelemetryScalar::ClearScalars()
|
|||
StaticMutexAutoLock locker(gTelemetryScalarsMutex);
|
||||
gScalarStorageMap.Clear();
|
||||
gKeyedScalarStorageMap.Clear();
|
||||
gDynamicBuiltinScalarStorageMap.Clear();
|
||||
gDynamicBuiltinKeyedScalarStorageMap.Clear();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -2543,26 +2475,23 @@ TelemetryScalar::GetScalarSizesOfIncludingThis(mozilla::MallocSizeOf aMallocSize
|
|||
{
|
||||
StaticMutexAutoLock locker(gTelemetryScalarsMutex);
|
||||
size_t n = 0;
|
||||
|
||||
auto getSizeOf = [aMallocSizeOf](auto &storageMap)
|
||||
{
|
||||
size_t partial = 0;
|
||||
for (auto iter = storageMap.Iter(); !iter.Done(); iter.Next()) {
|
||||
auto scalarStorage = iter.Data();
|
||||
for (auto childIter = scalarStorage->Iter(); !childIter.Done(); childIter.Next()) {
|
||||
auto scalar = childIter.Data();
|
||||
partial += scalar->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
// Account for scalar data coming from parent and child processes.
|
||||
for (auto iter = gScalarStorageMap.Iter(); !iter.Done(); iter.Next()) {
|
||||
ScalarStorageMapType* scalarStorage = static_cast<ScalarStorageMapType*>(iter.Data());
|
||||
for (auto childIter = scalarStorage->Iter(); !childIter.Done(); childIter.Next()) {
|
||||
ScalarBase* scalar = static_cast<ScalarBase*>(childIter.Data());
|
||||
n += scalar->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
return partial;
|
||||
};
|
||||
|
||||
// Account for all the storage used for the different scalar types.
|
||||
n += getSizeOf(gScalarStorageMap);
|
||||
n += getSizeOf(gKeyedScalarStorageMap);
|
||||
n += getSizeOf(gDynamicBuiltinScalarStorageMap);
|
||||
n += getSizeOf(gDynamicBuiltinKeyedScalarStorageMap);
|
||||
|
||||
}
|
||||
// Also account for keyed scalar data coming from parent and child processes.
|
||||
for (auto iter = gKeyedScalarStorageMap.Iter(); !iter.Done(); iter.Next()) {
|
||||
KeyedScalarStorageMapType* scalarStorage =
|
||||
static_cast<KeyedScalarStorageMapType*>(iter.Data());
|
||||
for (auto childIter = scalarStorage->Iter(); !childIter.Done(); childIter.Next()) {
|
||||
KeyedScalar* scalar = static_cast<KeyedScalar*>(childIter.Data());
|
||||
n += scalar->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -2837,8 +2766,7 @@ TelemetryScalar::AddDynamicScalarDefinitions(
|
|||
recordOnRelease,
|
||||
def.expired,
|
||||
def.name,
|
||||
def.keyed,
|
||||
false /* builtin */});
|
||||
def.keyed});
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -56,7 +56,7 @@ void Set(mozilla::Telemetry::ScalarID aId, const nsAString& aKey, bool aValue);
|
|||
void SetMaximum(mozilla::Telemetry::ScalarID aId, const nsAString& aKey, uint32_t aValue);
|
||||
|
||||
nsresult RegisterScalars(const nsACString& aCategoryName, JS::Handle<JS::Value> aScalarData,
|
||||
bool aBuiltin, JSContext* cx);
|
||||
JSContext* cx);
|
||||
|
||||
// Only to be used for testing.
|
||||
void ClearScalars();
|
||||
|
|
|
@ -5,7 +5,7 @@ Scalars
|
|||
Historically we started to overload our histogram mechanism to also collect scalar data,
|
||||
such as flag values, counts, labels and others.
|
||||
The scalar measurement types are the suggested way to collect that kind of scalar data.
|
||||
The serialized scalar data is submitted with the :doc:`main pings <../data/main-ping>`. Adding scalars is supported in artifact builds and build faster workflows.
|
||||
The serialized scalar data is submitted with the :doc:`main pings <../data/main-ping>`.
|
||||
|
||||
.. important::
|
||||
|
||||
|
@ -290,5 +290,3 @@ Version History
|
|||
|
||||
- Added support for recording new scalars from add-ons (`bug 1393801 <bug https://bugzilla.mozilla.org/show_bug.cgi?id=1393801>`_).
|
||||
- Ignore re-registering existing scalars for a category instead of failing (`bug 1409323 <https://bugzilla.mozilla.org/show_bug.cgi?id=1409323>`_).
|
||||
|
||||
- Firefox 60: Enabled support for adding scalars in artifact builds and build-faster workflows (`bug 1425909 <https://bugzilla.mozilla.org/show_bug.cgi?id=1425909`_).
|
||||
|
|
|
@ -6,10 +6,8 @@
|
|||
# in a file provided as a command-line argument.
|
||||
|
||||
from __future__ import print_function
|
||||
from collections import OrderedDict
|
||||
from shared_telemetry_utils import StringTable, static_assert, ParserError
|
||||
|
||||
import json
|
||||
import parse_scalars
|
||||
import sys
|
||||
|
||||
|
@ -80,49 +78,17 @@ def write_scalar_tables(scalars, output):
|
|||
"index overflow")
|
||||
|
||||
|
||||
def parse_scalar_definitions(filenames):
|
||||
def main(output, *filenames):
|
||||
# Load the scalars first.
|
||||
if len(filenames) > 1:
|
||||
raise Exception('We don\'t support loading from more than one file.')
|
||||
|
||||
try:
|
||||
return parse_scalars.load_scalars(filenames[0])
|
||||
scalars = parse_scalars.load_scalars(filenames[0])
|
||||
except ParserError as ex:
|
||||
print("\nError processing scalars:\n" + str(ex) + "\n")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def generate_JSON_definitions(output, *filenames):
|
||||
""" Write the scalar definitions to a JSON file.
|
||||
|
||||
:param output: the file to write the content to.
|
||||
:param filenames: a list of filenames provided by the build system.
|
||||
We only support a single file.
|
||||
"""
|
||||
scalars = parse_scalar_definitions(filenames)
|
||||
|
||||
scalar_definitions = OrderedDict()
|
||||
for scalar in scalars:
|
||||
category = scalar.category
|
||||
|
||||
if category not in scalar_definitions:
|
||||
scalar_definitions[category] = OrderedDict()
|
||||
|
||||
scalar_definitions[category][scalar.name] = OrderedDict({
|
||||
'kind': scalar.nsITelemetry_kind,
|
||||
'keyed': scalar.keyed,
|
||||
'record_on_release': True if scalar.dataset == 'opt-out' else False,
|
||||
# We don't expire dynamic-builtin scalars: they're only meant for
|
||||
# use in local developer builds anyway. They will expire when rebuilding.
|
||||
'expired': False,
|
||||
})
|
||||
|
||||
json.dump(scalar_definitions, output)
|
||||
|
||||
|
||||
def main(output, *filenames):
|
||||
# Load the scalars first.
|
||||
scalars = parse_scalar_definitions(filenames)
|
||||
|
||||
# Write the scalar data file.
|
||||
print(banner, file=output)
|
||||
print(file_header, file=output)
|
||||
|
|
|
@ -110,7 +110,6 @@ PYTHON_UNITTEST_MANIFESTS += [
|
|||
]
|
||||
|
||||
GENERATED_FILES = [
|
||||
'ScalarArtifactDefinitions.json',
|
||||
'TelemetryEventData.h',
|
||||
'TelemetryEventEnums.h',
|
||||
'TelemetryHistogramData.inc',
|
||||
|
@ -149,15 +148,6 @@ scalar_enums = GENERATED_FILES['TelemetryScalarEnums.h']
|
|||
scalar_enums.script = 'gen_scalar_enum.py'
|
||||
scalar_enums.inputs = scalar_files
|
||||
|
||||
# Generate the JSON scalar definitions. They will only be
|
||||
# used in artifact or "build faster" builds.
|
||||
scalar_json_data = GENERATED_FILES['ScalarArtifactDefinitions.json']
|
||||
scalar_json_data.script = 'gen_scalar_data.py:generate_JSON_definitions'
|
||||
scalar_json_data.inputs = scalar_files
|
||||
|
||||
# Move the scalars JSON file to the directory where the Firefox binary is.
|
||||
FINAL_TARGET_FILES += ['!ScalarArtifactDefinitions.json']
|
||||
|
||||
# Generate event files.
|
||||
event_files = [
|
||||
'Events.yaml',
|
||||
|
|
|
@ -541,17 +541,6 @@ interface nsITelemetry : nsISupports
|
|||
[implicit_jscontext]
|
||||
void registerScalars(in ACString aCategoryName, in jsval aScalarData);
|
||||
|
||||
/**
|
||||
* Parent process only. Register dynamic builtin scalars. The parameters
|
||||
* have the same meaning as the usual |registerScalars| function.
|
||||
*
|
||||
* This function is only meant to be used to support the "artifact build"/
|
||||
* "built faster" developers by allowing to add new scalars without rebuilding
|
||||
* the C++ components including the headers files.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
void registerBuiltinScalars(in ACString aCategoryName, in jsval aScalarData);
|
||||
|
||||
/**
|
||||
* Resets all the stored events. This is intended to be only used in tests.
|
||||
*/
|
||||
|
|
|
@ -198,11 +198,6 @@ class ScalarType:
|
|||
raise ParserError('{} - invalid expires: {}.\nSee: {}#required-fields'
|
||||
.format(self._name, expires, BASE_DOC_URL))
|
||||
|
||||
@property
|
||||
def category(self):
|
||||
"""Get the category name"""
|
||||
return self._category_name
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Get the scalar name"""
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const UINT_SCALAR = "telemetry.test.unsigned_int_kind";
|
||||
const STRING_SCALAR = "telemetry.test.string_kind";
|
||||
const BOOLEAN_SCALAR = "telemetry.test.boolean_kind";
|
||||
const KEYED_UINT_SCALAR = "telemetry.test.keyed_unsigned_int";
|
||||
|
||||
ChromeUtils.import("resource://services-common/utils.js");
|
||||
|
||||
/**
|
||||
* Return the path to the definitions file for the scalars.
|
||||
*/
|
||||
function getDefinitionsPath() {
|
||||
// Write the scalar definition to the spec file in the binary directory.
|
||||
let definitionFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
definitionFile = Services.dirsvc.get("GreBinD", Ci.nsIFile);
|
||||
definitionFile.append("ScalarArtifactDefinitions.json");
|
||||
return definitionFile.path;
|
||||
}
|
||||
|
||||
add_task(async function test_setup() {
|
||||
do_get_profile();
|
||||
});
|
||||
|
||||
add_task({
|
||||
// The test needs to write a file, and that fails in tests on Android.
|
||||
// We don't really need the Android coverage, so skip on Android.
|
||||
skip_if: () => AppConstants.platform == "android"
|
||||
}, async function test_invalidJSON() {
|
||||
const INVALID_JSON = "{ invalid,JSON { {1}";
|
||||
const FILE_PATH = getDefinitionsPath();
|
||||
|
||||
// Write a corrupted JSON file.
|
||||
await OS.File.writeAtomic(FILE_PATH, INVALID_JSON, { encoding: "utf-8", noOverwrite: false });
|
||||
|
||||
// Simulate Firefox startup. This should not throw!
|
||||
await TelemetryController.testSetup();
|
||||
await TelemetryController.testPromiseJsProbeRegistration();
|
||||
|
||||
// Cleanup.
|
||||
await TelemetryController.testShutdown();
|
||||
await OS.File.remove(FILE_PATH);
|
||||
});
|
||||
|
||||
add_task({
|
||||
// The test needs to write a file, and that fails in tests on Android.
|
||||
// We don't really need the Android coverage, so skip on Android.
|
||||
skip_if: () => AppConstants.platform == "android"
|
||||
}, async function test_dynamicBuiltin() {
|
||||
const DYNAMIC_SCALAR_SPEC = {
|
||||
"telemetry.test": {
|
||||
"builtin_dynamic": {
|
||||
"kind": "nsITelemetry::SCALAR_TYPE_COUNT",
|
||||
"expired": false,
|
||||
"record_on_release": false,
|
||||
"keyed": false
|
||||
},
|
||||
"builtin_dynamic_other": {
|
||||
"kind": "nsITelemetry::SCALAR_TYPE_BOOLEAN",
|
||||
"expired": false,
|
||||
"record_on_release": false,
|
||||
"keyed": false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Telemetry.clearScalars();
|
||||
|
||||
// Let's write to the definition file to also cover the file
|
||||
// loading part.
|
||||
const FILE_PATH = getDefinitionsPath();
|
||||
await CommonUtils.writeJSON(DYNAMIC_SCALAR_SPEC, FILE_PATH);
|
||||
|
||||
// Start TelemetryController to trigger loading the specs.
|
||||
await TelemetryController.testReset();
|
||||
await TelemetryController.testPromiseJsProbeRegistration();
|
||||
|
||||
// Store to that scalar.
|
||||
const TEST_SCALAR1 = "telemetry.test.builtin_dynamic";
|
||||
const TEST_SCALAR2 = "telemetry.test.builtin_dynamic_other";
|
||||
Telemetry.scalarSet(TEST_SCALAR1, 3785);
|
||||
Telemetry.scalarSet(TEST_SCALAR2, true);
|
||||
|
||||
// Check the values we tried to store.
|
||||
const scalars =
|
||||
Telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false).parent;
|
||||
|
||||
// Check that they are serialized to the correct format.
|
||||
Assert.equal(typeof(scalars[TEST_SCALAR1]), "number",
|
||||
TEST_SCALAR1 + " must be serialized to the correct format.");
|
||||
Assert.ok(Number.isInteger(scalars[TEST_SCALAR1]),
|
||||
TEST_SCALAR1 + " must be a finite integer.");
|
||||
Assert.equal(scalars[TEST_SCALAR1], 3785,
|
||||
TEST_SCALAR1 + " must have the correct value.");
|
||||
Assert.equal(typeof(scalars[TEST_SCALAR2]), "boolean",
|
||||
TEST_SCALAR2 + " must be serialized to the correct format.");
|
||||
Assert.equal(scalars[TEST_SCALAR2], true,
|
||||
TEST_SCALAR2 + " must have the correct value.");
|
||||
|
||||
// Clean up.
|
||||
await TelemetryController.testShutdown();
|
||||
await OS.File.remove(FILE_PATH);
|
||||
});
|
||||
|
||||
add_task(async function test_keyedDynamicBuiltin() {
|
||||
Telemetry.clearScalars();
|
||||
|
||||
// Register the built-in scalars (let's not take the I/O hit).
|
||||
Telemetry.registerBuiltinScalars("telemetry.test", {
|
||||
"builtin_dynamic_keyed": {
|
||||
"kind": Ci.nsITelemetry.SCALAR_TYPE_COUNT,
|
||||
"expired": false,
|
||||
"record_on_release": false,
|
||||
"keyed": true
|
||||
}
|
||||
});
|
||||
|
||||
// Store to that scalar.
|
||||
const TEST_SCALAR1 = "telemetry.test.builtin_dynamic_keyed";
|
||||
Telemetry.keyedScalarSet(TEST_SCALAR1, "test-key", 3785);
|
||||
|
||||
// Check the values we tried to store.
|
||||
const scalars =
|
||||
Telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false).parent;
|
||||
|
||||
// Check that they are serialized to the correct format.
|
||||
Assert.equal(typeof(scalars[TEST_SCALAR1]), "object",
|
||||
TEST_SCALAR1 + " must be a keyed scalar.");
|
||||
Assert.equal(typeof(scalars[TEST_SCALAR1]["test-key"]), "number",
|
||||
TEST_SCALAR1 + " must be serialized to the correct format.");
|
||||
Assert.ok(Number.isInteger(scalars[TEST_SCALAR1]["test-key"]),
|
||||
TEST_SCALAR1 + " must be a finite integer.");
|
||||
Assert.equal(scalars[TEST_SCALAR1]["test-key"], 3785,
|
||||
TEST_SCALAR1 + " must have the correct value.");
|
||||
});
|
|
@ -64,7 +64,6 @@ skip-if = os == "android" # Disabled due to crashes (see bug 1331366)
|
|||
skip-if = os == "android" # Disabled due to crashes (see bug 1367762)
|
||||
tags = addons
|
||||
[test_TelemetryScalars.js]
|
||||
[test_TelemetryScalars_buildFaster.js]
|
||||
[test_TelemetryTimestamps.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_TelemetryCaptureStack.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче