зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1608556 - Expose to privileged JS an API to add markers with a start time and an associated text, r=gerald,mconley,baku.
Differential Revision: https://phabricator.services.mozilla.com/D68784 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
e4c3013b95
Коммит
d10cae0789
|
@ -2293,13 +2293,13 @@ BrowserGlue.prototype = {
|
|||
ChromeUtils.idleDispatch(
|
||||
() => {
|
||||
if (!Services.startup.shuttingDown) {
|
||||
if (Services.profiler) {
|
||||
Services.profiler.AddMarker("startupIdleTask");
|
||||
}
|
||||
let startTime = Cu.now();
|
||||
try {
|
||||
task.task();
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
} finally {
|
||||
ChromeUtils.addProfilerMarker("startupIdleTask", startTime);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2372,13 +2372,13 @@ BrowserGlue.prototype = {
|
|||
for (let task of idleTasks) {
|
||||
ChromeUtils.idleDispatch(() => {
|
||||
if (!Services.startup.shuttingDown) {
|
||||
if (Services.profiler) {
|
||||
Services.profiler.AddMarker("startupLateIdleTask");
|
||||
}
|
||||
let startTime = Cu.now();
|
||||
try {
|
||||
task();
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
} finally {
|
||||
ChromeUtils.addProfilerMarker("startupLateIdleTask", startTime);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "mozilla/dom/MediaControlService.h"
|
||||
#include "mozilla/dom/MediaMetadata.h"
|
||||
#include "mozilla/dom/MediaSessionBinding.h"
|
||||
#include "mozilla/dom/Performance.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/ReportingHeader.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
|
@ -44,6 +45,9 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "mozJSComponentLoader.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
# include "ProfilerMarkerPayload.h"
|
||||
#endif
|
||||
#include "nsIException.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -184,6 +188,57 @@ void ChromeUtils::ReleaseAssert(GlobalObject& aGlobal, bool aCondition,
|
|||
messageUtf8.get(), filenameUtf8.get(), lineNo);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ChromeUtils::AddProfilerMarker(
|
||||
GlobalObject& aGlobal, const nsACString& aName,
|
||||
const Optional<DOMHighResTimeStamp>& aStartTime,
|
||||
const Optional<nsACString>& aText) {
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
const nsCString& name = PromiseFlatCString(aName);
|
||||
|
||||
if (!aText.WasPassed() && !aStartTime.WasPassed()) {
|
||||
profiler_add_js_marker(name.get());
|
||||
return;
|
||||
}
|
||||
|
||||
TimeStamp now = mozilla::TimeStamp::NowUnfuzzed();
|
||||
TimeStamp startTime = now;
|
||||
if (aStartTime.WasPassed()) {
|
||||
RefPtr<Performance> performance;
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsPIDOMWindowInner> ownerWindow =
|
||||
do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (ownerWindow) {
|
||||
performance = ownerWindow->GetPerformance();
|
||||
}
|
||||
} else {
|
||||
JSContext* cx = aGlobal.Context();
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
|
||||
if (workerPrivate) {
|
||||
performance = workerPrivate->GlobalScope()->GetPerformance();
|
||||
}
|
||||
}
|
||||
|
||||
if (performance) {
|
||||
startTime = performance->CreationTimeStamp() +
|
||||
TimeDuration::FromMilliseconds(aStartTime.Value());
|
||||
} else {
|
||||
startTime = TimeStamp::ProcessCreation() +
|
||||
TimeDuration::FromMilliseconds(aStartTime.Value());
|
||||
}
|
||||
}
|
||||
|
||||
if (aText.WasPassed()) {
|
||||
profiler_add_text_marker(name.get(), aText.Value(),
|
||||
JS::ProfilingCategoryPair::JS, startTime, now);
|
||||
} else {
|
||||
profiler_add_marker(name.get(), JS::ProfilingCategoryPair::JS,
|
||||
TimingMarkerPayload(startTime, now));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ChromeUtils::WaiveXrays(GlobalObject& aGlobal, JS::HandleValue aVal,
|
||||
JS::MutableHandleValue aRetval, ErrorResult& aRv) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/ChromeUtilsBinding.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "nsDOMNavigationTiming.h" // for DOMHighResTimeStamp
|
||||
#include "nsIContentChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -78,6 +79,10 @@ class ChromeUtils {
|
|||
static void ReleaseAssert(GlobalObject& aGlobal, bool aCondition,
|
||||
const nsAString& aMessage);
|
||||
|
||||
static void AddProfilerMarker(GlobalObject& aGlobal, const nsACString& aName,
|
||||
const Optional<DOMHighResTimeStamp>& aStartTime,
|
||||
const Optional<nsACString>& text);
|
||||
|
||||
static void OriginAttributesToSuffix(
|
||||
GlobalObject& aGlobal, const dom::OriginAttributesDictionary& aAttrs,
|
||||
nsCString& aSuffix);
|
||||
|
|
|
@ -157,6 +157,22 @@ namespace ChromeUtils {
|
|||
void clearRecentJSDevError();
|
||||
#endif // NIGHTLY_BUILD
|
||||
|
||||
/**
|
||||
* If the profiler is currently running and recording the current thread,
|
||||
* add a marker for the current thread. No-op otherwise.
|
||||
*
|
||||
* @param name The name of the marker.
|
||||
* @param startTime The timestamp to use as the start of the marker.
|
||||
* If omitted, the marker will have no duration.
|
||||
* In window and ChromeWorker contexts, use a
|
||||
* timestamp from `performance.now()`.
|
||||
* In JS modules, use `Cu.now()` to get a timestamp.
|
||||
* @param text Text to associate with the marker.
|
||||
*/
|
||||
void addProfilerMarker(UTF8String name,
|
||||
optional DOMHighResTimeStamp startTime,
|
||||
optional UTF8String text);
|
||||
|
||||
/**
|
||||
* IF YOU ADD NEW METHODS HERE, MAKE SURE THEY ARE THREAD-SAFE.
|
||||
*/
|
||||
|
|
|
@ -29,22 +29,21 @@ if (this.Components) {
|
|||
|
||||
let worker = new PromiseWorker.AbstractWorker();
|
||||
worker.dispatch = function(method, args = []) {
|
||||
let prefix = "OS.File " + method;
|
||||
performance.mark(prefix + "-start");
|
||||
let startTime = performance.now();
|
||||
try {
|
||||
return Agent[method](...args);
|
||||
} finally {
|
||||
let name = prefix;
|
||||
let text = method;
|
||||
if (args.length && args[0] instanceof Object && args[0].string) {
|
||||
// Including the path in the marker name here means it will be part of
|
||||
// Including the path in the marker text here means it will be part of
|
||||
// profiles. It's fine to include personally identifiable information
|
||||
// in profiles, because when a profile is captured only the user will
|
||||
// see it, and before uploading it a sanitization step will be offered.
|
||||
// The 'OS.File ' prefix will help the profiler know that these marker
|
||||
// names should be sanitized.
|
||||
name += " — " + args[0].string;
|
||||
// The 'OS.File' name will help the profiler know that these markers
|
||||
// should be sanitized.
|
||||
text += " — " + args[0].string;
|
||||
}
|
||||
performance.measure(name, prefix + "-start");
|
||||
ChromeUtils.addProfilerMarker("OS.File", startTime, text);
|
||||
}
|
||||
};
|
||||
worker.log = LOG;
|
||||
|
|
|
@ -300,6 +300,32 @@ void UserTimingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
|||
}
|
||||
}
|
||||
|
||||
ProfileBufferEntryWriter::Length TimingMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes();
|
||||
}
|
||||
|
||||
void TimingMarkerPayload::SerializeTagAndPayload(
|
||||
ProfileBufferEntryWriter& aEntryWriter) const {
|
||||
static const DeserializerTag tag = TagForDeserializer(Deserialize);
|
||||
SerializeTagAndCommonProps(tag, aEntryWriter);
|
||||
}
|
||||
|
||||
// static
|
||||
UniquePtr<ProfilerMarkerPayload> TimingMarkerPayload::Deserialize(
|
||||
ProfileBufferEntryReader& aEntryReader) {
|
||||
ProfilerMarkerPayload::CommonProps props =
|
||||
DeserializeCommonProps(aEntryReader);
|
||||
return UniquePtr<ProfilerMarkerPayload>(
|
||||
new TimingMarkerPayload(std::move(props)));
|
||||
}
|
||||
|
||||
void TimingMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) const {
|
||||
StreamCommonProps("Timing", aWriter, aProcessStartTime, aUniqueStacks);
|
||||
}
|
||||
|
||||
ProfileBufferEntryWriter::Length TextMarkerPayload::TagAndSerializationBytes()
|
||||
const {
|
||||
return CommonPropsTagAndSerializationBytes() +
|
||||
|
|
|
@ -578,6 +578,19 @@ class LongTaskMarkerPayload : public ProfilerMarkerPayload {
|
|||
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
||||
};
|
||||
|
||||
class TimingMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
TimingMarkerPayload(const mozilla::TimeStamp& aStartTime,
|
||||
const mozilla::TimeStamp& aEndTime)
|
||||
: ProfilerMarkerPayload(aStartTime, aEndTime) {}
|
||||
|
||||
DECL_STREAM_PAYLOAD
|
||||
|
||||
private:
|
||||
TimingMarkerPayload(CommonProps&& aCommonProps)
|
||||
: ProfilerMarkerPayload(std::move(aCommonProps)) {}
|
||||
};
|
||||
|
||||
class TextMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
TextMarkerPayload(const nsACString& aText,
|
||||
|
|
Загрузка…
Ссылка в новой задаче