Merge mozilla-central to mozilla-inbound. CLOSED TREE

This commit is contained in:
Csoregi Natalia 2019-02-17 00:14:07 +02:00
Родитель 020b13e585 ee40541496
Коммит 952908fda0
99 изменённых файлов: 1266 добавлений и 814 удалений

Просмотреть файл

@ -189,9 +189,6 @@ dom/media/webspeech/**
dom/messagechannel/**
dom/midi/**
dom/network/**
dom/notification/Notification*.*
dom/notification/test/browser/**
dom/notification/test/mochitest/**
dom/payments/**
dom/performance/**
dom/permission/**

Просмотреть файл

@ -811,8 +811,7 @@ nsresult Accessible::HandleAccEvent(AccEvent* aEvent) {
nsAutoCString strMarker;
strMarker.AppendLiteral("A11y Event - ");
strMarker.Append(strEventType);
profiler_add_marker(strMarker.get(),
js::ProfilingStackFrame::Category::OTHER);
profiler_add_marker(strMarker.get(), JS::ProfilingCategoryPair::OTHER);
}
#endif

Просмотреть файл

@ -28,7 +28,6 @@ browser.jar:
skin/classic/browser/places/editBookmark.css (places/editBookmark.css)
* skin/classic/browser/places/sidebar.css (places/sidebar.css)
skin/classic/browser/places/organizer.css (places/organizer.css)
skin/classic/browser/places/organizer.xml (places/organizer.xml)
skin/classic/browser/places/toolbarDropMarker.png (places/toolbarDropMarker.png)
skin/classic/browser/preferences/alwaysAsk.png (preferences/alwaysAsk.png)
skin/classic/browser/preferences/preferences.css (preferences/preferences.css)

Просмотреть файл

@ -61,7 +61,6 @@
/* Menu */
#placesMenu > menu {
padding-inline-start: 4px;
-moz-binding: url("chrome://browser/skin/places/organizer.xml#toolbarbutton-dropdown");
-moz-appearance: toolbarbutton;
}
@ -71,7 +70,9 @@
color: ButtonText;
}
#placesMenu > menu > .menubar-right {
#placesMenu > menu::after {
content: "";
display: -moz-box;
-moz-appearance: toolbarbutton-dropdown;
width: 12px;
height: 12px;

Просмотреть файл

@ -1,21 +0,0 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<bindings id="organizerBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="toolbarbutton-dropdown"
extends="chrome://global/content/bindings/menu.xml#menu-base">
<content>
<xul:image class="menubar-left" xbl:inherits="src=image"/>
<xul:label class="menubar-text" xbl:inherits="value=label,accesskey,crop" crop="right"/>
<xul:hbox class="menubar-right"/>
<children includes="menupopup"/>
</content>
</binding>
</bindings>

Просмотреть файл

@ -7,7 +7,7 @@ const { L10N } = require("devtools/client/performance/modules/global");
/**
* Details about each label stack frame category.
* To be kept in sync with the js::ProfilingStackFrame::Category in ProfilingStack.h
* To be kept in sync with the JS::ProfilingCategory enum in ProfilingCategory.h
*/
const CATEGORIES = [{
color: "#d99b28",

Просмотреть файл

@ -138,7 +138,7 @@ CustomizedReload.prototype = {
if (this.injectedScript) {
// Listen to the newly created document elements only if there is an
// injectedScript to evaluate.
Services.obs.addObserver(this, "document-element-inserted");
Services.obs.addObserver(this, "initial-document-element-inserted");
}
// Watch the loading progress and clear the current CustomizedReload once the
@ -159,7 +159,7 @@ CustomizedReload.prototype = {
},
observe(subject, topic, data) {
if (topic !== "document-element-inserted") {
if (topic !== "initial-document-element-inserted") {
return;
}
@ -232,7 +232,7 @@ CustomizedReload.prototype = {
this.docShell.removeProgressListener(this);
if (this.injectedScript) {
Services.obs.removeObserver(this, "document-element-inserted");
Services.obs.removeObserver(this, "initial-document-element-inserted");
}
// Reset the customized user agent.

Просмотреть файл

@ -9363,6 +9363,7 @@ class UnblockParsingPromiseHandler final : public PromiseNativeHandler {
mParser = do_GetWeakReference(parser);
mDocument = aDocument;
mDocument->BlockOnload();
mDocument->BlockDOMContentLoaded();
}
}
@ -9396,9 +9397,17 @@ class UnblockParsingPromiseHandler final : public PromiseNativeHandler {
if (parser == docParser) {
parser->UnblockParser();
parser->ContinueInterruptedParsingAsync();
mDocument->UnblockOnload(false);
}
}
if (mDocument) {
// We blocked DOMContentLoaded and load events on this document. Unblock
// them. Note that we want to do that no matter what's going on with the
// parser state for this document. Maybe someone caused it to stop being
// parsed, so CreatorParserOrNull() is returning null, but we still want
// to unblock these.
mDocument->UnblockDOMContentLoaded();
mDocument->UnblockOnload(false);
}
mParser = nullptr;
mDocument = nullptr;
}

Просмотреть файл

@ -973,6 +973,31 @@ int32_t Element::ScrollWidth() {
}
nsRect Element::GetClientAreaRect() {
Document* doc = OwnerDoc();
nsPresContext* presContext = doc->GetPresContext();
// We can avoid a layout flush if this is the scrolling element of the
// document, we have overlay scrollbars, and we aren't embedded in another
// document
bool overlayScrollbars =
LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0;
bool rootContentDocument =
presContext && presContext->IsRootContentDocument();
if (overlayScrollbars && rootContentDocument &&
doc->IsScrollingElement(this)) {
// We will always have a pres shell if we have a pres context, and we will
// only get here if we have a pres context from the root content document
// check
nsIPresShell* presShell = doc->GetShell();
// Ensure up to date dimensions, but don't reflow
RefPtr<nsViewManager> viewManager = presShell->GetViewManager();
if (viewManager) {
viewManager->FlushDelayedResize(false);
}
return nsRect(nsPoint(), presContext->GetVisibleArea().Size());
}
nsIFrame* frame;
nsIScrollableFrame* sf = GetScrollFrame(&frame);

Просмотреть файл

@ -174,7 +174,7 @@ void TimeoutManager::MoveIdleToActive() {
int(delta.ToMilliseconds()));
// don't have end before start...
profiler_add_marker(
"setTimeout deferred release", js::ProfilingStackFrame::Category::DOM,
"setTimeout deferred release", JS::ProfilingCategoryPair::DOM,
MakeUnique<TextMarkerPayload>(
marker, delta.ToMilliseconds() >= 0 ? timeout->When() : now,
now));
@ -960,7 +960,7 @@ void TimeoutManager::RunTimeout(const TimeStamp& aNow,
int(delta.ToMilliseconds()), int(runtime.ToMilliseconds()));
// don't have end before start...
profiler_add_marker(
"setTimeout", js::ProfilingStackFrame::Category::DOM,
"setTimeout", JS::ProfilingCategoryPair::DOM,
MakeUnique<TextMarkerPayload>(
marker, delta.ToMilliseconds() >= 0 ? timeout->When() : now,
now));

Просмотреть файл

@ -29,6 +29,7 @@
#include "nsViewManager.h"
#include "nsAtom.h"
#include "nsGkAtoms.h"
#include "nsGlobalWindowInner.h"
#include "nsNetCID.h"
#include "nsIOfflineCacheUpdate.h"
#include "nsIApplicationCache.h"
@ -1553,10 +1554,20 @@ void nsContentSink::NotifyDocElementCreated(Document* aDoc) {
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
observerService->NotifyObservers(
ToSupports(aDoc), "document-element-inserted", EmptyString().get());
MOZ_ASSERT(observerService);
auto* win = nsGlobalWindowInner::Cast(aDoc->GetInnerWindow());
bool fireInitialInsertion = !win || !win->DidFireDocElemInserted();
if (win) {
win->SetDidFireDocElemInserted();
}
if (fireInitialInsertion) {
observerService->NotifyObservers(ToSupports(aDoc),
"initial-document-element-inserted",
EmptyString().get());
}
observerService->NotifyObservers(
ToSupports(aDoc), "document-element-inserted", EmptyString().get());
nsContentUtils::DispatchChromeEvent(
aDoc, ToSupports(aDoc), NS_LITERAL_STRING("DOMDocElementInserted"),

Просмотреть файл

@ -162,7 +162,7 @@ void nsDOMNavigationTiming::NotifyLoadEventEnd() {
DECLARE_DOCSHELL_AND_HISTORY_ID(mDocShell);
PAGELOAD_LOG(("%s", marker.get()));
profiler_add_marker(
"DocumentLoad", js::ProfilingStackFrame::Category::DOM,
"DocumentLoad", JS::ProfilingCategoryPair::DOM,
MakeUnique<TextMarkerPayload>(marker, mNavigationStart, mLoadEventEnd,
docShellId, docShellHistoryId));
}
@ -357,7 +357,7 @@ void nsDOMNavigationTiming::TTITimeout(nsITimer* aTimer) {
DECLARE_DOCSHELL_AND_HISTORY_ID(mDocShell);
profiler_add_marker(
"TTFI", js::ProfilingStackFrame::Category::DOM,
"TTFI", JS::ProfilingCategoryPair::DOM,
MakeUnique<TextMarkerPayload>(marker, mNavigationStart, mTTFI,
docShellId, docShellHistoryId));
}
@ -392,7 +392,7 @@ void nsDOMNavigationTiming::NotifyNonBlankPaintForRootContentDocument() {
PAGELOAD_LOG(("%s", marker.get()));
DECLARE_DOCSHELL_AND_HISTORY_ID(mDocShell);
profiler_add_marker(
"FirstNonBlankPaint", js::ProfilingStackFrame::Category::DOM,
"FirstNonBlankPaint", JS::ProfilingCategoryPair::DOM,
MakeUnique<TextMarkerPayload>(marker, mNavigationStart, mNonBlankPaint,
docShellId, docShellHistoryId));
}
@ -441,11 +441,10 @@ void nsDOMNavigationTiming::NotifyContentfulPaintForRootContentDocument(
"and first non-blank paint");
DECLARE_DOCSHELL_AND_HISTORY_ID(mDocShell);
PAGELOAD_LOG(("%s", marker.get()));
profiler_add_marker(
"FirstContentfulPaint", js::ProfilingStackFrame::Category::DOM,
MakeUnique<TextMarkerPayload>(marker, mNavigationStart,
mContentfulPaint, docShellId,
docShellHistoryId));
profiler_add_marker("FirstContentfulPaint", JS::ProfilingCategoryPair::DOM,
MakeUnique<TextMarkerPayload>(
marker, mNavigationStart, mContentfulPaint,
docShellId, docShellHistoryId));
}
#endif
@ -492,11 +491,10 @@ void nsDOMNavigationTiming::NotifyDOMContentFlushedForRootContentDocument() {
"and DOMContentFlushed");
DECLARE_DOCSHELL_AND_HISTORY_ID(mDocShell);
PAGELOAD_LOG(("%s", marker.get()));
profiler_add_marker(
"DOMContentFlushed", js::ProfilingStackFrame::Category::DOM,
MakeUnique<TextMarkerPayload>(marker, mNavigationStart,
mDOMContentFlushed, docShellId,
docShellHistoryId));
profiler_add_marker("DOMContentFlushed", JS::ProfilingCategoryPair::DOM,
MakeUnique<TextMarkerPayload>(
marker, mNavigationStart, mDOMContentFlushed,
docShellId, docShellHistoryId));
}
#endif
}

Просмотреть файл

@ -856,6 +856,7 @@ nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow)
mHasFocus(false),
mShowFocusRingForContent(false),
mFocusByKeyOccurred(false),
mDidFireDocElemInserted(false),
mHasGamepad(false),
mHasVREvents(false),
mHasVRDisplayActivateEvents(false),

Просмотреть файл

@ -863,6 +863,9 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
bool ShouldResistFingerprinting();
bool DidFireDocElemInserted() const { return mDidFireDocElemInserted; }
void SetDidFireDocElemInserted() { mDidFireDocElemInserted = true; }
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> OpenDialog(
JSContext* aCx, const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions,
@ -1317,6 +1320,10 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
// should be displayed.
bool mFocusByKeyOccurred : 1;
// True if we have notified document-element-inserted observers for this
// document.
bool mDidFireDocElemInserted : 1;
// Indicates whether this window wants gamepad input events
bool mHasGamepad : 1;

Просмотреть файл

@ -2585,8 +2585,8 @@ inline static Element* FindMatchingElementWithId(
Element* nsINode::QuerySelector(const nsAString& aSelector,
ErrorResult& aResult) {
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING("nsINode::QuerySelector", DOM,
aSelector);
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING("nsINode::QuerySelector",
LAYOUT_SelectorQuery, aSelector);
const RawServoSelectorList* list = ParseSelectorList(aSelector, aResult);
if (!list) {
@ -2599,8 +2599,8 @@ Element* nsINode::QuerySelector(const nsAString& aSelector,
already_AddRefed<nsINodeList> nsINode::QuerySelectorAll(
const nsAString& aSelector, ErrorResult& aResult) {
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING("nsINode::QuerySelectorAll", DOM,
aSelector);
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING("nsINode::QuerySelectorAll",
LAYOUT_SelectorQuery, aSelector);
RefPtr<nsSimpleContentList> contentList = new nsSimpleContentList(this);
const RawServoSelectorList* list = ParseSelectorList(aSelector, aResult);

Просмотреть файл

@ -118,7 +118,7 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
#ifdef MOZ_GECKO_PROFILER
mAutoProfilerLabel("nsJSUtils::ExecutionContext",
/* dynamicStr */ nullptr,
js::ProfilingStackFrame::Category::JS),
JS::ProfilingCategoryPair::JS),
#endif
mCx(aCx),
mRealm(aCx, aGlobal),

Просмотреть файл

@ -1025,7 +1025,7 @@ static bool ShouldClearTargets(WidgetEvent* aEvent) {
docShell = nsContentUtils::GetDocShellForEventTarget(aEvent->mTarget);
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell);
profiler_add_marker(
"DOMEvent", js::ProfilingStackFrame::Category::DOM,
"DOMEvent", JS::ProfilingCategoryPair::DOM,
MakeUnique<DOMEventMarkerPayload>(
typeStr, aEvent->mTimeStamp, "DOMEvent",
TRACING_INTERVAL_START, docShellId, docShellHistoryId));
@ -1034,7 +1034,7 @@ static bool ShouldClearTargets(WidgetEvent* aEvent) {
aCallback, cd);
profiler_add_marker(
"DOMEvent", js::ProfilingStackFrame::Category::DOM,
"DOMEvent", JS::ProfilingCategoryPair::DOM,
MakeUnique<DOMEventMarkerPayload>(
typeStr, aEvent->mTimeStamp, "DOMEvent", TRACING_INTERVAL_END,
docShellId, docShellHistoryId));

Просмотреть файл

@ -41,6 +41,7 @@
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsDocElementCreatedNotificationRunner.h"
#include "nsGkAtoms.h"
#include "nsContentUtils.h"
#include "nsIChannel.h"
@ -905,6 +906,9 @@ void HTMLContentSink::NotifyRootInsertion() {
// contexts, since we just inserted the root and notified on
// our whole tree
UpdateChildCounts();
nsContentUtils::AddScriptRunner(
new nsDocElementCreatedNotificationRunner(mDocument));
}
void HTMLContentSink::UpdateChildCounts() {

Просмотреть файл

@ -9,16 +9,11 @@ var EXPORTED_SYMBOLS = [];
const DEBUG = false;
function debug(s) { dump("-*- NotificationDB component: " + s + "\n"); }
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "notificationStorage",
"@mozilla.org/notificationStorage;1",
"nsINotificationStorage");
const NOTIFICATION_STORE_DIR = OS.Constants.Path.profileDir;
const NOTIFICATION_STORE_PATH =
OS.Path.join(NOTIFICATION_STORE_DIR, "notificationstore.json");
@ -26,7 +21,7 @@ const NOTIFICATION_STORE_PATH =
const kMessages = [
"Notification:Save",
"Notification:Delete",
"Notification:GetAll"
"Notification:GetAll",
];
var NotificationDB = {
@ -34,7 +29,7 @@ var NotificationDB = {
// Ensure we won't call init() while xpcom-shutdown is performed
_shutdownInProgress: false,
init: function() {
init() {
if (this._shutdownInProgress) {
return;
}
@ -50,19 +45,19 @@ var NotificationDB = {
this.registerListeners();
},
registerListeners: function() {
registerListeners() {
for (let message of kMessages) {
Services.ppmm.addMessageListener(message, this);
}
},
unregisterListeners: function() {
unregisterListeners() {
for (let message of kMessages) {
Services.ppmm.removeMessageListener(message, this);
}
},
observe: function(aSubject, aTopic, aData) {
observe(aSubject, aTopic, aData) {
if (DEBUG) debug("Topic: " + aTopic);
if (aTopic == "xpcom-shutdown") {
this._shutdownInProgress = true;
@ -71,7 +66,7 @@ var NotificationDB = {
}
},
filterNonAppNotifications: function(notifications) {
filterNonAppNotifications(notifications) {
for (let origin in notifications) {
let persistentNotificationCount = 0;
for (let id in notifications[origin]) {
@ -91,7 +86,7 @@ var NotificationDB = {
},
// Attempt to read notification file, if it's not there we will create it.
load: function() {
load() {
var promise = OS.File.read(NOTIFICATION_STORE_PATH, { encoding: "utf-8"});
return promise.then(
data => {
@ -126,9 +121,9 @@ var NotificationDB = {
},
// Creates the notification directory.
createStore: function() {
createStore() {
var promise = OS.File.makeDir(NOTIFICATION_STORE_DIR, {
ignoreExisting: true
ignoreExisting: true,
});
return promise.then(
this.createFile.bind(this)
@ -136,26 +131,25 @@ var NotificationDB = {
},
// Creates the notification file once the directory is created.
createFile: function() {
createFile() {
return OS.File.writeAtomic(NOTIFICATION_STORE_PATH, "");
},
// Save current notifications to the file.
save: function() {
save() {
var data = JSON.stringify(this.notifications);
return OS.File.writeAtomic(NOTIFICATION_STORE_PATH, data, { encoding: "utf-8"});
},
// Helper function: promise will be resolved once file exists and/or is loaded.
ensureLoaded: function() {
ensureLoaded() {
if (!this.loaded) {
return this.load();
} else {
return Promise.resolve();
}
return Promise.resolve();
},
receiveMessage: function(message) {
receiveMessage(message) {
if (DEBUG) { debug("Received message:" + message.name); }
// sendAsyncMessage can fail if the child process exits during a
@ -174,13 +168,13 @@ var NotificationDB = {
returnMessage("Notification:GetAll:Return:OK", {
requestID: message.data.requestID,
origin: message.data.origin,
notifications: notifications
notifications,
});
}).catch(function(error) {
returnMessage("Notification:GetAll:Return:KO", {
requestID: message.data.requestID,
origin: message.data.origin,
errorMsg: error
errorMsg: error,
});
});
break;
@ -188,12 +182,12 @@ var NotificationDB = {
case "Notification:Save":
this.queueTask("save", message.data).then(function() {
returnMessage("Notification:Save:Return:OK", {
requestID: message.data.requestID
requestID: message.data.requestID,
});
}).catch(function(error) {
returnMessage("Notification:Save:Return:KO", {
requestID: message.data.requestID,
errorMsg: error
errorMsg: error,
});
});
break;
@ -201,12 +195,12 @@ var NotificationDB = {
case "Notification:Delete":
this.queueTask("delete", message.data).then(function() {
returnMessage("Notification:Delete:Return:OK", {
requestID: message.data.requestID
requestID: message.data.requestID,
});
}).catch(function(error) {
returnMessage("Notification:Delete:Return:KO", {
requestID: message.data.requestID,
errorMsg: error
errorMsg: error,
});
});
break;
@ -218,15 +212,15 @@ var NotificationDB = {
// We need to make sure any read/write operations are atomic,
// so use a queue to run each operation sequentially.
queueTask: function(operation, data) {
queueTask(operation, data) {
if (DEBUG) { debug("Queueing task: " + operation); }
var defer = {};
this.tasks.push({
operation: operation,
data: data,
defer: defer
operation,
data,
defer,
});
var promise = new Promise(function(resolve, reject) {
@ -243,7 +237,7 @@ var NotificationDB = {
return promise;
},
runNextTask: function() {
runNextTask() {
if (this.tasks.length === 0) {
if (DEBUG) { debug("No more tasks to run, queue depleted"); }
this.runningTask = null;
@ -259,17 +253,17 @@ var NotificationDB = {
switch (task.operation) {
case "getall":
return this.taskGetAll(task.data);
break;
case "save":
return this.taskSave(task.data);
break;
case "delete":
return this.taskDelete(task.data);
break;
}
default:
return Promise.reject(
new Error(`Found a task with unknown operation ${task.operation}`));
}
})
.then(payload => {
if (DEBUG) {
@ -281,14 +275,14 @@ var NotificationDB = {
if (DEBUG) {
debug("Error while running " + this.runningTask.operation + ": " + err);
}
this.runningTask.defer.reject(new String(err));
this.runningTask.defer.reject(err);
})
.then(() => {
this.runNextTask();
});
},
taskGetAll: function(data) {
taskGetAll(data) {
if (DEBUG) { debug("Task, getting all"); }
var origin = data.origin;
var notifications = [];
@ -308,7 +302,7 @@ var NotificationDB = {
return Promise.resolve(notifications);
},
taskSave: function(data) {
taskSave(data) {
if (DEBUG) { debug("Task, saving"); }
var origin = data.origin;
var notification = data.notification;
@ -331,7 +325,7 @@ var NotificationDB = {
return this.save();
},
taskDelete: function(data) {
taskDelete(data) {
if (DEBUG) { debug("Task, deleting"); }
var origin = data.origin;
var id = data.id;
@ -352,7 +346,7 @@ var NotificationDB = {
}
delete this.notifications[origin][id];
return this.save();
}
},
};
NotificationDB.init();

Просмотреть файл

@ -19,7 +19,7 @@ const kMessages = [
kMessageNotificationGetAllOk,
kMessageNotificationGetAllKo,
kMessageNotificationSaveKo,
kMessageNotificationDeleteKo
kMessageNotificationDeleteKo,
];
function NotificationStorage() {
@ -34,19 +34,19 @@ function NotificationStorage() {
NotificationStorage.prototype = {
registerListeners: function() {
registerListeners() {
for (let message of kMessages) {
Services.cpmm.addMessageListener(message, this);
}
},
unregisterListeners: function() {
unregisterListeners() {
for (let message of kMessages) {
Services.cpmm.removeMessageListener(message, this);
}
},
observe: function(aSubject, aTopic, aData) {
observe(aSubject, aTopic, aData) {
if (DEBUG) debug("Topic: " + aTopic);
if (aTopic === "xpcom-shutdown") {
Services.obs.removeObserver(this, "xpcom-shutdown");
@ -54,37 +54,37 @@ NotificationStorage.prototype = {
}
},
put: function(origin, id, title, dir, lang, body, tag, icon, alertName,
put(origin, id, title, dir, lang, body, tag, icon, alertName,
data, behavior, serviceWorkerRegistrationScope) {
if (DEBUG) { debug("PUT: " + origin + " " + id + ": " + title); }
var notification = {
id: id,
title: title,
dir: dir,
lang: lang,
body: body,
tag: tag,
icon: icon,
alertName: alertName,
id,
title,
dir,
lang,
body,
tag,
icon,
alertName,
timestamp: new Date().getTime(),
origin: origin,
data: data,
origin,
data,
mozbehavior: behavior,
serviceWorkerRegistrationScope: serviceWorkerRegistrationScope,
serviceWorkerRegistrationScope,
};
Services.cpmm.sendAsyncMessage("Notification:Save", {
origin: origin,
notification: notification
origin,
notification,
});
},
get: function(origin, tag, callback) {
get(origin, tag, callback) {
if (DEBUG) { debug("GET: " + origin + " " + tag); }
this._fetchFromDB(origin, tag, callback);
},
getByID: function(origin, id, callback) {
getByID(origin, id, callback) {
if (DEBUG) { debug("GETBYID: " + origin + " " + id); }
var GetByIDProxyCallback = function(id, originalCallback) {
this.searchID = id;
@ -103,15 +103,15 @@ NotificationStorage.prototype = {
return this.get(origin, "", new GetByIDProxyCallback(id, callback));
},
delete: function(origin, id) {
delete(origin, id) {
if (DEBUG) { debug("DELETE: " + id); }
Services.cpmm.sendAsyncMessage("Notification:Delete", {
origin: origin,
id: id
origin,
id,
});
},
receiveMessage: function(message) {
receiveMessage(message) {
var request = this._requests[message.data.requestID];
switch (message.name) {
@ -142,7 +142,7 @@ NotificationStorage.prototype = {
}
},
_fetchFromDB: function(origin, tag, callback) {
_fetchFromDB(origin, tag, callback) {
var request = {
origin,
tag,
@ -157,7 +157,7 @@ NotificationStorage.prototype = {
});
},
_returnNotifications: function(notifications, origin, tag, callback) {
_returnNotifications(notifications, origin, tag, callback) {
// Pass each notification back separately.
// The callback is called asynchronously to match the behaviour when
// fetching from the database.

Просмотреть файл

@ -51,7 +51,7 @@ function tabWithRequest(task, permission) {
url: TEST_URL,
}, async function(browser) {
let requestPromise = ContentTask.spawn(browser, {
permission
permission,
}, async function({permission}) {
function requestCallback(perm) {
is(perm, permission,

Просмотреть файл

@ -1,4 +1,5 @@
var MockServices = (function () {
/* eslint-disable mozilla/use-chromeutils-generateqi */
var MockServices = (function() {
"use strict";
const MOCK_ALERTS_CID = SpecialPowers.wrap(SpecialPowers.Components)
@ -16,7 +17,7 @@ var MockServices = (function () {
var activeAppNotifications = Object.create(null);
window.addEventListener('mock-notification-close-event', function(e) {
window.addEventListener("mock-notification-close-event", function(e) {
for (var alertName in activeAlertNotifications) {
var notif = activeAlertNotifications[alertName];
if (notif.title === e.detail.title) {
@ -29,39 +30,39 @@ var MockServices = (function () {
});
var mockAlertsService = {
showPersistentNotification: function(persistentData, alert, alertListener) {
showPersistentNotification(persistentData, alert, alertListener) {
this.showAlert(alert, alertListener);
},
showAlert: function(alert, alertListener) {
showAlert(alert, alertListener) {
var listener = SpecialPowers.wrap(alertListener);
activeAlertNotifications[alert.name] = {
listener: listener,
listener,
cookie: alert.cookie,
title: alert.title
title: alert.title,
};
// fake async alert show event
if (listener) {
setTimeout(function () {
setTimeout(function() {
listener.observe(null, "alertshow", alert.cookie);
}, 100);
setTimeout(function () {
setTimeout(function() {
listener.observe(null, "alertclickcallback", alert.cookie);
}, 100);
}
},
showAlertNotification: function(imageUrl, title, text, textClickable,
showAlertNotification(imageUrl, title, text, textClickable,
cookie, alertListener, name) {
this.showAlert({
name: name,
cookie: cookie,
title: title
name,
cookie,
title,
}, alertListener);
},
closeAlert: function(name) {
closeAlert(name) {
var alertNotification = activeAlertNotifications[name];
if (alertNotification) {
if (alertNotification.listener) {
@ -76,7 +77,7 @@ var MockServices = (function () {
}
},
QueryInterface: function(aIID) {
QueryInterface(aIID) {
if (SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsISupports) ||
SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAlertsService)) {
return this;
@ -84,18 +85,18 @@ var MockServices = (function () {
throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function(aOuter, aIID) {
createInstance(aOuter, aIID) {
if (aOuter != null) {
throw SpecialPowers.Components.results.NS_ERROR_NO_AGGREGATION;
}
return this.QueryInterface(aIID);
}
},
};
mockAlertsService = SpecialPowers.wrapCallbackObject(mockAlertsService);
// MockServices API
return {
register: function () {
register() {
registrar.registerFactory(MOCK_ALERTS_CID, "alerts service",
ALERTS_SERVICE_CONTRACT_ID,
mockAlertsService);
@ -105,13 +106,13 @@ var MockServices = (function () {
mockAlertsService);
},
unregister: function () {
unregister() {
registrar.unregisterFactory(MOCK_ALERTS_CID, mockAlertsService);
registrar.unregisterFactory(MOCK_SYSTEM_ALERTS_CID, mockAlertsService);
},
activeAlertNotifications: activeAlertNotifications,
activeAlertNotifications,
activeAppNotifications: activeAppNotifications,
activeAppNotifications,
};
})();

Просмотреть файл

@ -1,4 +1,4 @@
var NotificationTest = (function () {
var NotificationTest = (function() {
"use strict";
function info(msg, name) {
@ -22,7 +22,8 @@ var NotificationTest = (function () {
(function executeRemainingTests(remainingTests) {
if (!remainingTests.length) {
return callback();
callback();
return;
}
var nextTest = remainingTests.shift();
@ -43,9 +44,9 @@ var NotificationTest = (function () {
})(tests);
}
var fakeCustomData = (function () {
var fakeCustomData = (function() {
var buffer = new ArrayBuffer(2);
var dv = new DataView(buffer).setInt16(0, 42, true);
new DataView(buffer).setInt16(0, 42, true);
var canvas = document.createElement("canvas");
canvas.width = canvas.height = 100;
var context = canvas.getContext("2d");
@ -60,53 +61,53 @@ var NotificationTest = (function () {
a: 123,
b: "test",
c: true,
d: [1, 2, 3]
d: [1, 2, 3],
},
date: new Date(2013, 2, 1, 1, 10),
regexp: new RegExp("[^.]+"),
arrayBuffer: buffer,
imageData: context.createImageData(100, 100),
map: map,
set: set
map,
set,
};
})();
// NotificationTest API
return {
run: function (tests, callback) {
run(tests, callback) {
setup_testing_env();
addLoadEvent(function () {
executeTests(tests, function () {
addLoadEvent(function() {
executeTests(tests, function() {
teardown_testing_env();
callback && callback();
});
});
},
allowNotifications: function () {
allowNotifications() {
SpecialPowers.setBoolPref("notification.prompt.testing.allow", true);
},
denyNotifications: function () {
denyNotifications() {
SpecialPowers.setBoolPref("notification.prompt.testing.allow", false);
},
clickNotification: function (notification) {
clickNotification(notification) {
// TODO: how??
},
fireCloseEvent: function (title) {
fireCloseEvent(title) {
window.dispatchEvent(new CustomEvent("mock-notification-close-event", {
detail: {
title: title
}
title,
},
}));
},
info: info,
info,
customDataMatches: function(dataObj) {
customDataMatches(dataObj) {
var url = "http://www.domain.com";
try {
return (JSON.stringify(dataObj.primitives) ===
@ -119,7 +120,7 @@ var NotificationTest = (function () {
JSON.stringify(fakeCustomData.imageData.data)) &&
(dataObj.map.get("test") == 42) &&
(dataObj.set.has(4) && dataObj.set.has(2));
} catch(e) {
} catch (e) {
return false;
}
},
@ -130,7 +131,7 @@ var NotificationTest = (function () {
icon: "icon.jpg",
lang: "en-US",
dir: "ltr",
data: fakeCustomData
}
data: fakeCustomData,
},
};
})();

Просмотреть файл

@ -19,7 +19,7 @@
SimpleTest.requestFlakyTimeout("untriaged");
var steps = [
function () {
function() {
info("Test notification spec");
ok(Notification, "Notification constructor exists");
ok(Notification.permission, "Notification.permission exists");
@ -27,12 +27,12 @@
ok(Notification.get, "Notification.get exists");
},
function () {
function() {
info("Test requestPermission without callback");
Notification.requestPermission();
},
function (done) {
function(done) {
info("Test requestPermission deny");
function assertPermissionDenied(perm) {
is(perm, "denied", "Permission should be denied.");
@ -48,7 +48,7 @@
.then(done);
},
function (done) {
function(done) {
info("Test requestPermission grant");
function assertPermissionGranted(perm) {
is(perm, "granted", "Permission should be granted.");
@ -64,7 +64,7 @@
.then(done);
},
function (done) {
function(done) {
info("Test invalid requestPermission");
Notification.requestPermission({})
.then(_ => {
@ -75,7 +75,7 @@
.then(done);
},
function (done) {
function(done) {
info("Test create notification");
options = NotificationTest.payload;
@ -101,27 +101,27 @@
// store notification in test context
this.notification = notification;
notification.onshow = function () {
notification.onshow = function() {
ok(true, "onshow handler should be called");
done();
};
},
function (done) {
function(done) {
info("Test closing a notification");
var notification = this.notification;
notification.onclose = function () {
notification.onclose = function() {
ok(true, "onclose handler should be called");
done();
};
notification.close();
}
},
];
MockServices.register();
NotificationTest.run(steps, function () {
NotificationTest.run(steps, function() {
MockServices.unregister();
});
</script>

Просмотреть файл

@ -2,8 +2,8 @@
<html>
<head>
<title>Notification Basics</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="MockServices.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="NotificationTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
@ -17,7 +17,7 @@
function deleteAllNotifications(done) {
var promise = Notification.get();
promise.then(function (notifications) {
promise.then(function(notifications) {
notifications.forEach(function(notification) {
notification.close();
});
@ -28,16 +28,16 @@
var info = NotificationTest.info;
var steps = [
function (done) {
function(done) {
info("Test that Notifcation.get fulfills the promise");
var promise = Notification.get();
ok(promise.then, "should return a promise");
// Create a new notification to make sure
// Notification.get() works while creating
var notification = new Notification("this is a test");
new Notification("this is a test");
promise.then(function () {
promise.then(function() {
ok(true, "promise should be fulfilled");
done();
});
@ -45,28 +45,28 @@
deleteAllNotifications,
function (done) {
function(done) {
info("Test adding a notification, and making sure get returns it");
NotificationTest.allowNotifications();
var options = NotificationTest.payload;
var notification = new Notification("This is a title", options);
var promise = Notification.get();
promise.then(function (notifications) {
promise.then(function(notifications) {
ok(notifications.length, "should return notifications");
for (var i = 0; i < notifications.length; i++) {
var notification = notifications[i];
if (notification.tag === options.tag) {
var currentNotification = notifications[i];
if (currentNotification.tag === options.tag) {
ok(true, "should contain newly created notification");
for (var key in options) {
if (key === "data") {
ok(NotificationTest.customDataMatches(notification.data),
ok(NotificationTest.customDataMatches(currentNotification.data),
"data property should match");
continue;
}
is(notification[key], options[key], key + " property should match");
is(currentNotification[key], options[key], key + " property should match");
}
notification.close();
currentNotification.close();
return;
}
}
@ -76,19 +76,19 @@
notification.onclose = done;
},
function (done) {
function(done) {
info("Testing fetching notification by tag filter");
var n1 = new Notification("title1", {tag: "tag1"});
var n2 = new Notification("title2", {tag: "tag2"});
var n3 = new Notification("title3", {tag: "tag3"});
var promise = Notification.get({tag: "tag3"});
promise.then(function (notifications) {
promise.then(function(notifications) {
var notification = notifications[0];
is(notifications.length, 1, "should return 1 notification");
is(notifications[0].title, "title3", "titles should match");
is(notifications[0].tag, "tag3", "tags should match");
is(notification.title, "title3", "titles should match");
is(notification.tag, "tag3", "tags should match");
var closeCount = 0;
var waitForAll = function () {
var waitForAll = function() {
if (++closeCount >= 3) {
done();
}
@ -104,22 +104,22 @@
deleteAllNotifications,
function (done) {
function(done) {
info("Testing fetching no notifications");
var promise = Notification.get();
promise.then(function (notifications) {
promise.then(function(notifications) {
is(notifications.length, 0, "should return 0 notifications");
done();
});
},
function (done) {
function(done) {
info("Testing fetching multiple notifications");
var n1 = new Notification("title1");
var n2 = new Notification("title2");
var n3 = new Notification("title3");
var promise = Notification.get();
promise.then(function (notifications) {
promise.then(function(notifications) {
is(notifications.length, 3, "should return 3 notifications");
n1.close();
n2.close();
@ -130,7 +130,7 @@
deleteAllNotifications,
function (done) {
function(done) {
info("Testing 'alertfinished' removes the notification from DB");
var n = new Notification("test-title" + Math.random());
n.onclose = function() {
@ -146,11 +146,11 @@
NotificationTest.fireCloseEvent(n.title);
}, 100);
};
}
},
];
MockServices.register();
NotificationTest.run(steps, function () {
NotificationTest.run(steps, function() {
MockServices.unregister();
});
</script>

Просмотреть файл

@ -19,24 +19,25 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=782211
<pre id="test">
</pre>
<script type="text/javascript">
/* eslint-disable mozilla/use-chromeutils-generateqi */
const MOCK_CID = SpecialPowers.wrap(SpecialPowers.Components).ID("{dbe37e64-d9a3-402c-8d8a-0826c619f7ad}");
const ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/alerts-service;1";
var mockAlertsService = {
showAlert: function(alert, alertListener) {
showAlert(alert, alertListener) {
notificationsCreated.push(alert.name);
if (notificationsCreated.length == 3) {
checkNotifications();
}
},
showAlertNotification: function(imageUrl, title, text, textClickable,
cookie, alertListener, name, dir,
lang, data) {
this.showAlert({ name: name });
showAlertNotification(imageUrl, title, text, textClickable,
cookie, alertListener, name, dir,
lang, data) {
this.showAlert({ name });
},
QueryInterface: function(aIID) {
QueryInterface(aIID) {
if (SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsISupports) ||
SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAlertsService)) {
return this;
@ -44,12 +45,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=782211
throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function(aOuter, aIID) {
createInstance(aOuter, aIID) {
if (aOuter != null) {
throw SpecialPowers.Components.results.NS_ERROR_NO_AGGREGATION;
}
return this.QueryInterface(aIID);
}
},
};
mockAlertsService = SpecialPowers.wrapCallbackObject(mockAlertsService);
@ -91,14 +92,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=782211
// Load two frames with the same origin that create notification with the same tag.
// Both pages should generate notifications with the same name, and thus the second
// notification should replace the first.
frames["sameDomain"].location.href = "http://test1.example.org:80/tests/dom/notification/test/mochitest/create_notification.html";
frames["anotherSameDomain"].location.href = "http://test1.example.org:80/tests/dom/notification/test/mochitest/create_notification.html";
frames.sameDomain.location.href = "http://test1.example.org:80/tests/dom/notification/test/mochitest/create_notification.html";
frames.anotherSameDomain.location.href = "http://test1.example.org:80/tests/dom/notification/test/mochitest/create_notification.html";
// Load a frame with a different origin that creates a notification with the same tag.
// The notification name should be different and thus no notifications should be replaced.
frames["crossDomain"].location.href = "http://test2.example.org:80/tests/dom/notification/test/mochitest/create_notification.html";
frames.crossDomain.location.href = "http://test2.example.org:80/tests/dom/notification/test/mochitest/create_notification.html";
}
SpecialPowers.pushPrefEnv({'set': [["notification.prompt.testing", true],
SpecialPowers.pushPrefEnv({"set": [["notification.prompt.testing", true],
["notification.prompt.testing.allow", true]]},
showNotifications);
} else {

Просмотреть файл

@ -225,7 +225,7 @@ void Performance::Mark(const nsAString& aName, ErrorResult& aRv) {
nsContentUtils::GetDocShellForEventTarget(et);
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell);
profiler_add_marker(
"UserTiming", js::ProfilingStackFrame::Category::DOM,
"UserTiming", JS::ProfilingCategoryPair::DOM,
MakeUnique<UserTimingMarkerPayload>(aName, TimeStamp::Now(), docShellId,
docShellHistoryId));
}
@ -321,7 +321,7 @@ void Performance::Measure(const nsAString& aName,
nsCOMPtr<nsIDocShell> docShell =
nsContentUtils::GetDocShellForEventTarget(et);
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell);
profiler_add_marker("UserTiming", js::ProfilingStackFrame::Category::DOM,
profiler_add_marker("UserTiming", JS::ProfilingCategoryPair::DOM,
MakeUnique<UserTimingMarkerPayload>(
aName, startMark, endMark, startTimeStamp,
endTimeStamp, docShellId, docShellHistoryId));

Просмотреть файл

@ -567,7 +567,7 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
#ifdef MOZ_GECKO_PROFILER
,
mAutoProfilerLabel(
"", aReason, js::ProfilingStackFrame::Category::JS,
"", aReason, JS::ProfilingCategoryPair::JS,
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS))
#endif
{

Просмотреть файл

@ -164,8 +164,7 @@ void LayerManager::PayloadPresented() {
"Payload Presented, type: %d latency: %dms\n",
int32_t(payload.mType),
int32_t((presented - payload.mTimeStamp).ToMilliseconds()));
profiler_add_marker(marker.get(),
js::ProfilingStackFrame::Category::GRAPHICS);
profiler_add_marker(marker.get(), JS::ProfilingCategoryPair::GRAPHICS);
}
#endif

Просмотреть файл

@ -105,7 +105,7 @@ void ProfilerScreenshots::SubmitScreenshot(
if (NS_SUCCEEDED(rv)) {
// Add a marker with the data URL.
profiler_add_marker_for_thread(
sourceThread, js::ProfilingStackFrame::Category::GRAPHICS,
sourceThread, JS::ProfilingCategoryPair::GRAPHICS,
"CompositorScreenshot",
MakeUnique<ScreenshotPayload>(timeStamp, std::move(dataURL),
originalSize, windowIdentifier));

Просмотреть файл

@ -434,7 +434,7 @@ CompositorBridgeChild* ClientLayerManager::GetCompositorBridgeChild() {
}
void ClientLayerManager::FlushAsyncPaints() {
AUTO_PROFILER_LABEL("ClientLayerManager::FlushAsyncPaints", GRAPHICS);
AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_FlushingAsyncPaints);
CompositorBridgeChild* cbc = GetCompositorBridgeChild();
if (cbc) {

Просмотреть файл

@ -307,8 +307,6 @@ bool ClientMultiTiledLayerBuffer::ValidateTile(TileClient& aTile,
const nsIntPoint& aTileOrigin,
nsIntRegion& aDirtyRegion,
TilePaintFlags aFlags) {
AUTO_PROFILER_LABEL("ClientMultiTiledLayerBuffer::ValidateTile", GRAPHICS);
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
if (aDirtyRegion.IsComplex()) {
printf_stderr("Complex region\n");

Просмотреть файл

@ -578,6 +578,7 @@ Maybe<AcquiredBackBuffer> TileClient::AcquireBackBuffer(
CompositableClient& aCompositable, const nsIntRegion& aDirtyRegion,
const nsIntRegion& aVisibleRegion, gfxContentType aContent,
SurfaceMode aMode, TilePaintFlags aFlags) {
AUTO_PROFILER_LABEL("TileClient::AcquireBackBuffer", GRAPHICS_TileAllocation);
if (!mAllocator) {
gfxCriticalError() << "[TileClient] Missing TextureClientAllocator.";
return Nothing();

Просмотреть файл

@ -88,7 +88,7 @@ void CompositorScreenshotGrabber::MaybeProcessQueue() {
void CompositorScreenshotGrabber::NotifyEmptyFrame() {
#ifdef MOZ_GECKO_PROFILER
profiler_add_marker("NoCompositorScreenshot because nothing changed",
js::ProfilingStackFrame::Category::GRAPHICS);
JS::ProfilingCategoryPair::GRAPHICS);
#endif
}

Просмотреть файл

@ -100,8 +100,7 @@ static void PrintUniformityInfo(Layer* aLayer) {
}
Point translation = transform.As2D().GetTranslation();
profiler_add_marker("LayerTranslation",
js::ProfilingStackFrame::Category::GRAPHICS,
profiler_add_marker("LayerTranslation", JS::ProfilingCategoryPair::GRAPHICS,
MakeUnique<LayerTranslationMarkerPayload>(
aLayer, translation, TimeStamp::Now()));
#endif

Просмотреть файл

@ -1908,8 +1908,7 @@ CompositorBridgeParent::GetAPZCTreeManager(LayersId aLayersId) {
static void InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
if (profiler_thread_is_being_profiled()) {
profiler_add_marker("VsyncTimestamp",
js::ProfilingStackFrame::Category::GRAPHICS,
profiler_add_marker("VsyncTimestamp", JS::ProfilingCategoryPair::GRAPHICS,
MakeUnique<VsyncMarkerPayload>(aVsyncTimestamp));
}
}
@ -2452,8 +2451,8 @@ int32_t RecordContentFrameTime(
}
};
profiler_add_marker_for_thread(
profiler_current_thread_id(),
js::ProfilingStackFrame::Category::GRAPHICS, "CONTENT_FRAME_TIME",
profiler_current_thread_id(), JS::ProfilingCategoryPair::GRAPHICS,
"CONTENT_FRAME_TIME",
MakeUnique<ContentFramePayload>(aTxnStart, aCompositeEnd));
}
#endif

Просмотреть файл

@ -380,8 +380,8 @@ void CrossProcessCompositorBridgeParent::ShadowLayersUpdated(
}
};
profiler_add_marker_for_thread(
profiler_current_thread_id(),
js::ProfilingStackFrame::Category::GRAPHICS, "CONTENT_FULL_PAINT_TIME",
profiler_current_thread_id(), JS::ProfilingCategoryPair::GRAPHICS,
"CONTENT_FULL_PAINT_TIME",
MakeUnique<ContentBuildPayload>(aInfo.transactionStart(), endTime));
}
#endif

Просмотреть файл

@ -104,7 +104,7 @@ void MLGPUScreenshotGrabber::MaybeProcessQueue() {
void MLGPUScreenshotGrabber::NotifyEmptyFrame() {
#ifdef MOZ_GECKO_PROFILER
profiler_add_marker("NoCompositorScreenshot because nothing changed",
js::ProfilingStackFrame::Category::GRAPHICS);
JS::ProfilingCategoryPair::GRAPHICS);
#endif
}

Просмотреть файл

@ -52,16 +52,14 @@ bool is_in_render_thread() {
void gecko_profiler_start_marker(const char* name) {
#ifdef MOZ_GECKO_PROFILER
profiler_tracing("WebRender", name,
js::ProfilingStackFrame::Category::GRAPHICS,
profiler_tracing("WebRender", name, JS::ProfilingCategoryPair::GRAPHICS,
TRACING_INTERVAL_START);
#endif
}
void gecko_profiler_end_marker(const char* name) {
#ifdef MOZ_GECKO_PROFILER
profiler_tracing("WebRender", name,
js::ProfilingStackFrame::Category::GRAPHICS,
profiler_tracing("WebRender", name, JS::ProfilingCategoryPair::GRAPHICS,
TRACING_INTERVAL_END);
#endif
}
@ -206,8 +204,7 @@ class SceneBuiltNotification : public wr::NotificationHandler {
profiler_add_marker_for_thread(
profiler_current_thread_id(),
js::ProfilingStackFrame::Category::GRAPHICS,
"CONTENT_FULL_PAINT_TIME",
JS::ProfilingCategoryPair::GRAPHICS, "CONTENT_FULL_PAINT_TIME",
MakeUnique<ContentFullPaintPayload>(startTime, endTime));
}
#endif

Просмотреть файл

@ -1426,6 +1426,8 @@ void WebRenderCommandBuilder::BuildWebRenderCommands(
wr::IpcResourceUpdateQueue& aResourceUpdates, nsDisplayList* aDisplayList,
nsDisplayListBuilder* aDisplayListBuilder, WebRenderScrollData& aScrollData,
wr::LayoutSize& aContentSize, nsTArray<wr::FilterOp>&& aFilters) {
AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_WRDisplayList);
StackingContextHelper sc;
aScrollData = WebRenderScrollData(mManager);
MOZ_ASSERT(mLayerScrollData.empty());

Просмотреть файл

@ -119,7 +119,7 @@ LexerResult Decoder::Decode(IResumable* aOnResume /* = nullptr */) {
LexerResult lexerResult(TerminalState::FAILURE);
{
AUTO_PROFILER_LABEL("Decoder::Decode", GRAPHICS);
AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_ImageDecoding);
AutoRecordDecoderTelemetry telemetry(this);
lexerResult = DoDecode(*mIterator, aOnResume);

Просмотреть файл

@ -0,0 +1,120 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef js_ProfilingCategory_h
#define js_ProfilingCategory_h
#include "jstypes.h" // JS_FRIEND_API
// clang-format off
// This higher-order macro lists all categories with their subcategories.
//
// PROFILING_CATEGORY_LIST(BEGIN_CATEGORY, SUBCATEGORY, END_CATEGORY)
// BEGIN_CATEGORY(name, labelAsString, colorAsString)
// SUBCATEGORY(category, name, labelAsString)
// END_CATEGORY
//
// The list of available color names for categories is:
// transparent, grey, purple, yellow, orange, lightblue, green, blue, magenta
//
// Categories and subcategories are used for stack-based instrumentation. They
// are specified in label frames in the profiling stack, see ProfilingStack.h.
// At any point, the category pair of the topmost profiler label frame in the
// label stack determines the category pair of that stack.
// Each category describes a type of workload that the CPU can be busy with.
// Categories should be non-overlapping: the list of categories should be
// chosen in such a way that every possible stack can be mapped to a single
// category unambiguously.
#define PROFILING_CATEGORY_LIST(BEGIN_CATEGORY, SUBCATEGORY, END_CATEGORY) \
BEGIN_CATEGORY(IDLE, "Idle", "transparent") \
SUBCATEGORY(IDLE, IDLE, "Other") \
END_CATEGORY \
BEGIN_CATEGORY(OTHER, "Other", "grey") \
SUBCATEGORY(OTHER, OTHER, "Other") \
END_CATEGORY \
BEGIN_CATEGORY(LAYOUT, "Layout", "purple") \
SUBCATEGORY(LAYOUT, LAYOUT, "Other") \
SUBCATEGORY(LAYOUT, LAYOUT_FrameConstruction, "Frame construction") \
SUBCATEGORY(LAYOUT, LAYOUT_Reflow, "Reflow") \
SUBCATEGORY(LAYOUT, LAYOUT_CSSParsing, "CSS parsing") \
SUBCATEGORY(LAYOUT, LAYOUT_SelectorQuery, "Selector query") \
SUBCATEGORY(LAYOUT, LAYOUT_StyleComputation, "Style computation") \
END_CATEGORY \
BEGIN_CATEGORY(JS, "JavaScript", "yellow") \
SUBCATEGORY(JS, JS, "Other") \
END_CATEGORY \
BEGIN_CATEGORY(GCCC, "GC / CC", "orange") \
SUBCATEGORY(GCCC, GCCC, "Other") \
END_CATEGORY \
BEGIN_CATEGORY(NETWORK, "Network", "lightblue") \
SUBCATEGORY(NETWORK, NETWORK, "Other") \
END_CATEGORY \
BEGIN_CATEGORY(GRAPHICS, "Graphics", "green") \
SUBCATEGORY(GRAPHICS, GRAPHICS, "Other") \
SUBCATEGORY(GRAPHICS, GRAPHICS_DisplayListBuilding, "DisplayList building") \
SUBCATEGORY(GRAPHICS, GRAPHICS_DisplayListMerging, "DisplayList merging") \
SUBCATEGORY(GRAPHICS, GRAPHICS_LayerBuilding, "Layer building") \
SUBCATEGORY(GRAPHICS, GRAPHICS_TileAllocation, "Tile allocation") \
SUBCATEGORY(GRAPHICS, GRAPHICS_WRDisplayList, "WebRender display list") \
SUBCATEGORY(GRAPHICS, GRAPHICS_Rasterization, "Rasterization") \
SUBCATEGORY(GRAPHICS, GRAPHICS_FlushingAsyncPaints, "Flushing async paints") \
SUBCATEGORY(GRAPHICS, GRAPHICS_ImageDecoding, "Image decoding") \
END_CATEGORY \
BEGIN_CATEGORY(DOM, "DOM", "blue") \
SUBCATEGORY(DOM, DOM, "Other") \
END_CATEGORY
namespace JS {
// An enum that lists all possible category pairs in one list.
// This is the enum that is used in profiler stack labels. Having one list that
// includes subcategories from all categories in one list allows assigning the
// category pair to a stack label with just one number.
#define CATEGORY_ENUM_BEGIN_CATEGORY(name, labelAsString, color)
#define CATEGORY_ENUM_SUBCATEGORY(supercategory, name, labelAsString) name,
#define CATEGORY_ENUM_END_CATEGORY
enum class ProfilingCategoryPair : uint32_t {
PROFILING_CATEGORY_LIST(CATEGORY_ENUM_BEGIN_CATEGORY,
CATEGORY_ENUM_SUBCATEGORY,
CATEGORY_ENUM_END_CATEGORY)
COUNT,
LAST = COUNT - 1,
};
#undef CATEGORY_ENUM_BEGIN_CATEGORY
#undef CATEGORY_ENUM_SUBCATEGORY
#undef CATEGORY_ENUM_END_CATEGORY
// An enum that lists just the categories without their subcategories.
#define SUPERCATEGORY_ENUM_BEGIN_CATEGORY(name, labelAsString, color) name,
#define SUPERCATEGORY_ENUM_SUBCATEGORY(supercategory, name, labelAsString)
#define SUPERCATEGORY_ENUM_END_CATEGORY
enum class ProfilingCategory : uint32_t {
PROFILING_CATEGORY_LIST(SUPERCATEGORY_ENUM_BEGIN_CATEGORY,
SUPERCATEGORY_ENUM_SUBCATEGORY,
SUPERCATEGORY_ENUM_END_CATEGORY)
COUNT,
LAST = COUNT - 1,
};
#undef SUPERCATEGORY_ENUM_BEGIN_CATEGORY
#undef SUPERCATEGORY_ENUM_SUBCATEGORY
#undef SUPERCATEGORY_ENUM_END_CATEGORY
// clang-format on
struct ProfilingCategoryPairInfo {
ProfilingCategory mCategory;
uint32_t mSubcategoryIndex;
const char* mLabel;
};
JS_FRIEND_API const ProfilingCategoryPairInfo& GetProfilingCategoryPairInfo(
ProfilingCategoryPair aCategoryPair);
} // namespace JS
#endif /* js_ProfilingCategory_h */

Просмотреть файл

@ -12,6 +12,7 @@
#include "jstypes.h"
#include "js/ProfilingCategory.h"
#include "js/TypeDecls.h"
#include "js/Utility.h"
@ -156,10 +157,10 @@ class ProfilingStackFrame {
mozilla::recordreplay::Behavior::DontPreserve>
pcOffsetIfJS_;
// Bits 0...7 hold the Flags. Bits 8...31 hold the category.
// Bits 0...8 hold the Flags. Bits 9...31 hold the category pair.
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire,
mozilla::recordreplay::Behavior::DontPreserve>
flagsAndCategory_;
flagsAndCategoryPair_;
static int32_t pcToOffset(JSScript* aScript, jsbytecode* aPc);
@ -172,13 +173,13 @@ class ProfilingStackFrame {
spOrScript = spScript;
int32_t offsetIfJS = other.pcOffsetIfJS_;
pcOffsetIfJS_ = offsetIfJS;
uint32_t flagsAndCategory = other.flagsAndCategory_;
flagsAndCategory_ = flagsAndCategory;
uint32_t flagsAndCategory = other.flagsAndCategoryPair_;
flagsAndCategoryPair_ = flagsAndCategory;
return *this;
}
// 8 bits for the flags.
// That leaves 32 - 8 = 25 bits for the category.
// 9 bits for the flags.
// That leaves 32 - 9 = 23 bits for the category pair.
enum class Flags : uint32_t {
// The first three flags describe the kind of the frame and are
// mutually exclusive. (We still give them individual bits for
@ -216,69 +217,70 @@ class ProfilingStackFrame {
// tree view.
RELEVANT_FOR_JS = 1 << 7,
FLAGS_BITCOUNT = 8,
// If set, causes the label on this ProfilingStackFrame to be ignored
// and to be replaced by the subcategory's label.
LABEL_DETERMINED_BY_CATEGORY_PAIR = 1 << 8,
FLAGS_BITCOUNT = 9,
FLAGS_MASK = (1 << FLAGS_BITCOUNT) - 1
};
// Keep these in sync with devtools/client/performance/modules/categories.js
enum class Category : uint32_t {
IDLE,
OTHER,
LAYOUT,
JS,
GCCC,
NETWORK,
GRAPHICS,
DOM,
FIRST = OTHER,
LAST = DOM,
};
static_assert(uint32_t(Category::LAST) <=
(UINT32_MAX >> uint32_t(Flags::FLAGS_BITCOUNT)),
"Too many categories to fit into u32 with together with the "
"reserved bits for the flags");
static_assert(
uint32_t(JS::ProfilingCategoryPair::LAST) <=
(UINT32_MAX >> uint32_t(Flags::FLAGS_BITCOUNT)),
"Too many category pairs to fit into u32 with together with the "
"reserved bits for the flags");
bool isLabelFrame() const {
return uint32_t(flagsAndCategory_) & uint32_t(Flags::IS_LABEL_FRAME);
return uint32_t(flagsAndCategoryPair_) & uint32_t(Flags::IS_LABEL_FRAME);
}
bool isSpMarkerFrame() const {
return uint32_t(flagsAndCategory_) & uint32_t(Flags::IS_SP_MARKER_FRAME);
return uint32_t(flagsAndCategoryPair_) &
uint32_t(Flags::IS_SP_MARKER_FRAME);
}
bool isJsFrame() const {
return uint32_t(flagsAndCategory_) & uint32_t(Flags::IS_JS_FRAME);
return uint32_t(flagsAndCategoryPair_) & uint32_t(Flags::IS_JS_FRAME);
}
bool isOSRFrame() const {
return uint32_t(flagsAndCategory_) & uint32_t(Flags::JS_OSR);
return uint32_t(flagsAndCategoryPair_) & uint32_t(Flags::JS_OSR);
}
void setIsOSRFrame(bool isOSR) {
if (isOSR) {
flagsAndCategory_ = uint32_t(flagsAndCategory_) | uint32_t(Flags::JS_OSR);
flagsAndCategoryPair_ =
uint32_t(flagsAndCategoryPair_) | uint32_t(Flags::JS_OSR);
} else {
flagsAndCategory_ =
uint32_t(flagsAndCategory_) & ~uint32_t(Flags::JS_OSR);
flagsAndCategoryPair_ =
uint32_t(flagsAndCategoryPair_) & ~uint32_t(Flags::JS_OSR);
}
}
void setLabel(const char* aLabel) { label_ = aLabel; }
const char* label() const { return label_; }
const char* label() const {
uint32_t flagsAndCategoryPair = flagsAndCategoryPair_;
if (flagsAndCategoryPair &
uint32_t(Flags::LABEL_DETERMINED_BY_CATEGORY_PAIR)) {
auto categoryPair = JS::ProfilingCategoryPair(
flagsAndCategoryPair >> uint32_t(Flags::FLAGS_BITCOUNT));
return JS::GetProfilingCategoryPairInfo(categoryPair).mLabel;
}
return label_;
}
const char* dynamicString() const { return dynamicString_; }
void initLabelFrame(const char* aLabel, const char* aDynamicString, void* sp,
Category aCategory, uint32_t aFlags) {
JS::ProfilingCategoryPair aCategoryPair,
uint32_t aFlags) {
label_ = aLabel;
dynamicString_ = aDynamicString;
spOrScript = sp;
// pcOffsetIfJS_ is not set and must not be used on label frames.
flagsAndCategory_ =
flagsAndCategoryPair_ =
uint32_t(Flags::IS_LABEL_FRAME) |
(uint32_t(aCategory) << uint32_t(Flags::FLAGS_BITCOUNT)) | aFlags;
(uint32_t(aCategoryPair) << uint32_t(Flags::FLAGS_BITCOUNT)) | aFlags;
MOZ_ASSERT(isLabelFrame());
}
@ -287,9 +289,9 @@ class ProfilingStackFrame {
dynamicString_ = nullptr;
spOrScript = sp;
// pcOffsetIfJS_ is not set and must not be used on sp marker frames.
flagsAndCategory_ =
uint32_t(Flags::IS_SP_MARKER_FRAME) |
(uint32_t(Category::OTHER) << uint32_t(Flags::FLAGS_BITCOUNT));
flagsAndCategoryPair_ = uint32_t(Flags::IS_SP_MARKER_FRAME) |
(uint32_t(JS::ProfilingCategoryPair::OTHER)
<< uint32_t(Flags::FLAGS_BITCOUNT));
MOZ_ASSERT(isSpMarkerFrame());
}
@ -299,18 +301,19 @@ class ProfilingStackFrame {
dynamicString_ = aDynamicString;
spOrScript = aScript;
pcOffsetIfJS_ = pcToOffset(aScript, aPc);
flagsAndCategory_ =
uint32_t(Flags::IS_JS_FRAME) |
(uint32_t(Category::JS) << uint32_t(Flags::FLAGS_BITCOUNT));
flagsAndCategoryPair_ =
uint32_t(Flags::IS_JS_FRAME) | (uint32_t(JS::ProfilingCategoryPair::JS)
<< uint32_t(Flags::FLAGS_BITCOUNT));
MOZ_ASSERT(isJsFrame());
}
uint32_t flags() const {
return uint32_t(flagsAndCategory_) & uint32_t(Flags::FLAGS_MASK);
return uint32_t(flagsAndCategoryPair_) & uint32_t(Flags::FLAGS_MASK);
}
Category category() const {
return Category(flagsAndCategory_ >> uint32_t(Flags::FLAGS_BITCOUNT));
JS::ProfilingCategoryPair categoryPair() const {
return JS::ProfilingCategoryPair(flagsAndCategoryPair_ >>
uint32_t(Flags::FLAGS_BITCOUNT));
}
void* stackAddress() const {
@ -390,7 +393,7 @@ class ProfilingStack final {
~ProfilingStack();
void pushLabelFrame(const char* label, const char* dynamicString, void* sp,
js::ProfilingStackFrame::Category category,
JS::ProfilingCategoryPair categoryPair,
uint32_t flags = 0) {
// This thread is the only one that ever changes the value of
// stackPointer.
@ -402,8 +405,8 @@ class ProfilingStack final {
if (MOZ_UNLIKELY(stackPointerVal >= capacity)) {
ensureCapacitySlow();
}
frames[stackPointerVal].initLabelFrame(label, dynamicString, sp, category,
flags);
frames[stackPointerVal].initLabelFrame(label, dynamicString, sp,
categoryPair, flags);
// This must happen at the end! The compiler will not reorder this
// update because stackPointer is Atomic<..., ReleaseAcquire>, so any

Просмотреть файл

@ -1382,7 +1382,7 @@ bool js::array_join(JSContext* cx, unsigned argc, Value* vp) {
}
AutoGeckoProfilerEntry pseudoFrame(
cx, "Array.prototype.join", ProfilingStackFrame::Category::JS,
cx, "Array.prototype.join", JS::ProfilingCategoryPair::JS,
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
CallArgs args = CallArgsFromVp(argc, vp);
@ -1657,7 +1657,7 @@ static DenseElementResult ArrayReverseDenseKernel(JSContext* cx,
// 22.1.3.21 Array.prototype.reverse ( )
bool js::array_reverse(JSContext* cx, unsigned argc, Value* vp) {
AutoGeckoProfilerEntry pseudoFrame(
cx, "Array.prototype.reverse", ProfilingStackFrame::Category::JS,
cx, "Array.prototype.reverse", JS::ProfilingCategoryPair::JS,
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
CallArgs args = CallArgsFromVp(argc, vp);
@ -2381,7 +2381,7 @@ bool js::NewbornArrayPush(JSContext* cx, HandleObject obj, const Value& v) {
// 22.1.3.18 Array.prototype.push ( ...items )
bool js::array_push(JSContext* cx, unsigned argc, Value* vp) {
AutoGeckoProfilerEntry pseudoFrame(
cx, "Array.prototype.push", ProfilingStackFrame::Category::JS,
cx, "Array.prototype.push", JS::ProfilingCategoryPair::JS,
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
CallArgs args = CallArgsFromVp(argc, vp);
@ -2442,7 +2442,7 @@ bool js::array_push(JSContext* cx, unsigned argc, Value* vp) {
// 22.1.3.17 Array.prototype.pop ( )
bool js::array_pop(JSContext* cx, unsigned argc, Value* vp) {
AutoGeckoProfilerEntry pseudoFrame(
cx, "Array.prototype.pop", ProfilingStackFrame::Category::JS,
cx, "Array.prototype.pop", JS::ProfilingCategoryPair::JS,
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
CallArgs args = CallArgsFromVp(argc, vp);
@ -2562,7 +2562,7 @@ static DenseElementResult ArrayShiftDenseKernel(JSContext* cx, HandleObject obj,
// 22.1.3.22 Array.prototype.shift ( )
bool js::array_shift(JSContext* cx, unsigned argc, Value* vp) {
AutoGeckoProfilerEntry pseudoFrame(
cx, "Array.prototype.shift", ProfilingStackFrame::Category::JS,
cx, "Array.prototype.shift", JS::ProfilingCategoryPair::JS,
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
CallArgs args = CallArgsFromVp(argc, vp);
@ -2648,7 +2648,7 @@ bool js::array_shift(JSContext* cx, unsigned argc, Value* vp) {
// 22.1.3.29 Array.prototype.unshift ( ...items )
bool js::array_unshift(JSContext* cx, unsigned argc, Value* vp) {
AutoGeckoProfilerEntry pseudoFrame(
cx, "Array.prototype.unshift", ProfilingStackFrame::Category::JS,
cx, "Array.prototype.unshift", JS::ProfilingCategoryPair::JS,
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
CallArgs args = CallArgsFromVp(argc, vp);
@ -2908,7 +2908,7 @@ static bool CopyArrayElements(JSContext* cx, HandleObject obj, uint64_t begin,
static bool array_splice_impl(JSContext* cx, unsigned argc, Value* vp,
bool returnValueIsUsed) {
AutoGeckoProfilerEntry pseudoFrame(
cx, "Array.prototype.splice", ProfilingStackFrame::Category::JS,
cx, "Array.prototype.splice", JS::ProfilingCategoryPair::JS,
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
CallArgs args = CallArgsFromVp(argc, vp);
@ -3504,7 +3504,7 @@ static bool ArraySliceOrdinary(JSContext* cx, HandleObject obj, uint64_t begin,
/* ES 2016 draft Mar 25, 2016 22.1.3.23. */
bool js::array_slice(JSContext* cx, unsigned argc, Value* vp) {
AutoGeckoProfilerEntry pseudoFrame(
cx, "Array.prototype.slice", ProfilingStackFrame::Category::JS,
cx, "Array.prototype.slice", JS::ProfilingCategoryPair::JS,
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
CallArgs args = CallArgsFromVp(argc, vp);

Просмотреть файл

@ -6711,7 +6711,7 @@ AutoHeapSession::AutoHeapSession(JSRuntime* rt, JS::HeapState heapState)
prevState(rt->heapState_),
profilingStackFrame(rt->mainContextFromOwnThread(),
HeapStateToLabel(heapState),
ProfilingStackFrame::Category::GCCC) {
JS::ProfilingCategoryPair::GCCC) {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
MOZ_ASSERT(prevState == JS::HeapState::Idle);
MOZ_ASSERT(heapState != JS::HeapState::Idle);

Просмотреть файл

@ -3590,9 +3590,9 @@ static bool UnmarkGrayGCThing(JSRuntime* rt, JS::GCCellPtr thing) {
// replay, so disallow recorded events from occurring in the tracer.
mozilla::recordreplay::AutoDisallowThreadEvents d;
AutoGeckoProfilerEntry profilingStackFrame(
rt->mainContextFromOwnThread(), "UnmarkGrayGCThing",
ProfilingStackFrame::Category::GCCC);
AutoGeckoProfilerEntry profilingStackFrame(rt->mainContextFromOwnThread(),
"UnmarkGrayGCThing",
JS::ProfilingCategoryPair::GCCC);
UnmarkGrayTracer unmarker(rt);
gcstats::AutoPhase innerPhase(rt->gc.stats(),

Просмотреть файл

@ -67,7 +67,7 @@ class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler {
bool makesGCCalls() const { return makesGCCalls_; }
private:
#define DEFINE_OP(op) MOZ_MUST_USE bool emit##op();
#define DEFINE_OP(op, ...) MOZ_MUST_USE bool emit##op();
CACHE_IR_OPS(DEFINE_OP)
#undef DEFINE_OP
@ -192,7 +192,7 @@ JitCode* BaselineCacheIRCompiler::compile() {
do {
switch (reader.readOp()) {
#define DEFINE_OP(op) \
#define DEFINE_OP(op, ...) \
case CacheOp::op: \
if (!emit##op()) return nullptr; \
break;
@ -202,7 +202,9 @@ JitCode* BaselineCacheIRCompiler::compile() {
default:
MOZ_CRASH("Invalid op");
}
#ifdef DEBUG
assertAllArgumentsConsumed();
#endif
allocator.nextOp();
} while (reader.more());

Просмотреть файл

@ -34,6 +34,45 @@ const char* const js::jit::CacheKindNames[] = {
#undef DEFINE_KIND
};
// We need to enter the namespace here so that the definition of
// CacheIROpFormat::OpLengths can see CacheIROpFormat::ArgType
// (without defining None/Id/Field/etc everywhere else in this file.)
namespace js {
namespace jit {
namespace CacheIROpFormat {
static constexpr uint32_t CacheIROpLength(ArgType arg) {
switch (arg) {
case None:
return 0;
case Id:
return sizeof(uint8_t);
case Field:
return sizeof(uint8_t);
case Byte:
return sizeof(uint8_t);
case Int32:
case UInt32:
return sizeof(uint32_t);
case Word:
return sizeof(uintptr_t);
}
}
template <typename... Args>
static constexpr uint32_t CacheIROpLength(ArgType arg, Args... args) {
return CacheIROpLength(arg) + CacheIROpLength(args...);
}
const uint32_t OpLengths[] = {
#define OPLENGTH(op, ...) 1 + CacheIROpLength(__VA_ARGS__),
CACHE_IR_OPS(OPLENGTH)
#undef OPLENGTH
};
} // namespace CacheIROpFormat
} // namespace jit
} // namespace js
void CacheIRWriter::assertSameCompartment(JSObject* obj) {
cx_->debugOnlyCheck(obj);
}

Просмотреть файл

@ -173,192 +173,216 @@ enum class CacheKind : uint8_t {
extern const char* const CacheKindNames[];
#define CACHE_IR_OPS(_) \
_(GuardIsObject) \
_(GuardIsObjectOrNull) \
_(GuardIsNullOrUndefined) \
_(GuardIsNotNullOrUndefined) \
_(GuardIsNull) \
_(GuardIsUndefined) \
_(GuardIsBoolean) \
_(GuardIsString) \
_(GuardIsSymbol) \
_(GuardIsBigInt) \
_(GuardIsNumber) \
_(GuardIsInt32) \
_(GuardIsInt32Index) \
_(GuardType) \
_(GuardShape) \
_(GuardGroup) \
_(GuardProto) \
_(GuardClass) /* Guard an object class, per GuardClassKind */ \
_(GuardAnyClass) /* Guard an arbitrary class for an object */ \
_(GuardCompartment) \
_(GuardIsExtensible) \
_(GuardIsNativeFunction) \
_(GuardIsNativeObject) \
_(GuardIsProxy) \
_(GuardHasProxyHandler) \
_(GuardNotDOMProxy) \
_(GuardSpecificObject) \
_(GuardSpecificAtom) \
_(GuardSpecificSymbol) \
_(GuardSpecificInt32Immediate) \
_(GuardNoDetachedTypedObjects) \
_(GuardMagicValue) \
_(GuardFrameHasNoArgumentsObject) \
_(GuardNoDenseElements) \
_(GuardNoUnboxedExpando) \
_(GuardAndLoadUnboxedExpando) \
_(GuardAndGetIndexFromString) \
_(GuardAndGetNumberFromString) \
_(GuardAndGetIterator) \
_(GuardHasGetterSetter) \
_(GuardGroupHasUnanalyzedNewScript) \
_(GuardIndexIsNonNegative) \
_(GuardIndexGreaterThanDenseCapacity) \
_(GuardIndexGreaterThanArrayLength) \
_(GuardIndexIsValidUpdateOrAdd) \
_(GuardIndexGreaterThanDenseInitLength) \
_(GuardTagNotEqual) \
_(GuardXrayExpandoShapeAndDefaultProto) \
_(GuardFunctionPrototype) \
_(GuardNoAllocationMetadataBuilder) \
_(GuardObjectGroupNotPretenured) \
_(LoadStackValue) \
_(LoadObject) \
_(LoadProto) \
_(LoadEnclosingEnvironment) \
_(LoadWrapperTarget) \
_(LoadValueTag) \
\
_(TruncateDoubleToUInt32) \
\
_(MegamorphicLoadSlotResult) \
_(MegamorphicLoadSlotByValueResult) \
_(MegamorphicStoreSlot) \
_(MegamorphicSetElement) \
_(MegamorphicHasPropResult) \
\
/* See CacheIR.cpp 'DOM proxies' comment. */ \
_(LoadDOMExpandoValue) \
_(LoadDOMExpandoValueGuardGeneration) \
_(LoadDOMExpandoValueIgnoreGeneration) \
_(GuardDOMExpandoMissingOrGuardShape) \
\
_(StoreFixedSlot) \
_(StoreDynamicSlot) \
_(AddAndStoreFixedSlot) \
_(AddAndStoreDynamicSlot) \
_(AllocateAndStoreDynamicSlot) \
_(StoreTypedObjectReferenceProperty) \
_(StoreTypedObjectScalarProperty) \
_(StoreUnboxedProperty) \
_(StoreDenseElement) \
_(StoreDenseElementHole) \
_(ArrayPush) \
_(ArrayJoinResult) \
_(StoreTypedElement) \
_(CallNativeSetter) \
_(CallScriptedSetter) \
_(CallSetArrayLength) \
_(CallProxySet) \
_(CallProxySetByValue) \
_(CallAddOrUpdateSparseElementHelper) \
_(CallInt32ToString) \
_(CallNumberToString) \
\
/* The *Result ops load a value into the cache's result register. */ \
_(LoadFixedSlotResult) \
_(LoadDynamicSlotResult) \
_(LoadUnboxedPropertyResult) \
_(LoadTypedObjectResult) \
_(LoadDenseElementResult) \
_(LoadDenseElementHoleResult) \
_(CallGetSparseElementResult) \
_(LoadDenseElementExistsResult) \
_(LoadTypedElementExistsResult) \
_(LoadDenseElementHoleExistsResult) \
_(LoadTypedElementResult) \
_(LoadInt32ArrayLengthResult) \
_(LoadArgumentsObjectArgResult) \
_(LoadArgumentsObjectLengthResult) \
_(LoadFunctionLengthResult) \
_(LoadStringCharResult) \
_(LoadStringLengthResult) \
_(LoadFrameCalleeResult) \
_(LoadFrameNumActualArgsResult) \
_(LoadFrameArgumentResult) \
_(LoadEnvironmentFixedSlotResult) \
_(LoadEnvironmentDynamicSlotResult) \
_(LoadObjectResult) \
_(CallScriptedGetterResult) \
_(CallNativeGetterResult) \
_(CallProxyGetResult) \
_(CallProxyGetByValueResult) \
_(CallProxyHasPropResult) \
_(CallObjectHasSparseElementResult) \
_(CallNativeGetElementResult) \
_(LoadUndefinedResult) \
_(LoadBooleanResult) \
_(LoadStringResult) \
_(LoadInstanceOfObjectResult) \
_(LoadTypeOfObjectResult) \
_(DoubleAddResult) \
_(DoubleSubResult) \
_(DoubleMulResult) \
_(DoubleDivResult) \
_(DoubleModResult) \
_(Int32AddResult) \
_(Int32SubResult) \
_(Int32MulResult) \
_(Int32DivResult) \
_(Int32ModResult) \
_(Int32BitOrResult) \
_(Int32BitXorResult) \
_(Int32BitAndResult) \
_(Int32LeftShiftResult) \
_(Int32RightShiftResult) \
_(Int32URightShiftResult) \
_(Int32NotResult) \
_(Int32NegationResult) \
_(DoubleNegationResult) \
_(Int32IncResult) \
_(Int32DecResult) \
_(DoubleIncResult) \
_(DoubleDecResult) \
_(LoadInt32TruthyResult) \
_(LoadDoubleTruthyResult) \
_(LoadStringTruthyResult) \
_(LoadObjectTruthyResult) \
_(LoadValueResult) \
_(LoadNewObjectFromTemplateResult) \
\
_(CallStringSplitResult) \
_(CallStringConcatResult) \
_(CallStringObjectConcatResult) \
_(CallIsSuspendedGeneratorResult) \
\
_(CompareStringResult) \
_(CompareObjectResult) \
_(CompareSymbolResult) \
_(CompareInt32Result) \
_(CompareDoubleResult) \
_(CompareObjectUndefinedNullResult) \
\
_(CallPrintString) \
_(Breakpoint) \
\
_(TypeMonitorResult) \
_(ReturnFromIC) \
_(WrapResult)
// This namespace exists to make it possible to use unqualified
// argument types in CACHE_IR_OPS without letting the symbols escape
// into the global namespace. Any code that consumes the argument
// information must have CacheIROpFormat in scope.
namespace CacheIROpFormat {
enum ArgType {
None,
Id,
Field,
Byte,
Int32,
UInt32,
Word,
};
extern const uint32_t OpLengths[];
} // namespace CacheIROpFormat
#define CACHE_IR_OPS(_) \
_(GuardIsObject, Id) \
_(GuardIsObjectOrNull, Id) \
_(GuardIsNullOrUndefined, Id) \
_(GuardIsNotNullOrUndefined, Id) \
_(GuardIsNull, Id) \
_(GuardIsUndefined, Id) \
_(GuardIsBoolean, Id, Id) \
_(GuardIsString, Id) \
_(GuardIsSymbol, Id) \
_(GuardIsBigInt, Id) \
_(GuardIsNumber, Id) \
_(GuardIsInt32, Id, Id) \
_(GuardIsInt32Index, Id, Id) \
_(GuardType, Id, Byte) \
_(GuardShape, Id, Field) \
_(GuardGroup, Id, Field) \
_(GuardProto, Id, Field) \
_(GuardClass, Id, Byte) /* Guard per GuardClassKind */ \
_(GuardAnyClass, Id, Field) /* Guard an arbitrary class */ \
_(GuardCompartment, Id, Field, Field) \
_(GuardIsExtensible, Id) \
_(GuardIsNativeFunction, Id, Word) \
_(GuardIsNativeObject, Id) \
_(GuardIsProxy, Id) \
_(GuardHasProxyHandler, Id, Field) \
_(GuardNotDOMProxy, Id) \
_(GuardSpecificObject, Id, Field) \
_(GuardSpecificAtom, Id, Field) \
_(GuardSpecificSymbol, Id, Field) \
_(GuardSpecificInt32Immediate, Id, Int32, Byte) \
_(GuardNoDetachedTypedObjects, None) \
_(GuardMagicValue, Id, Byte) \
_(GuardFrameHasNoArgumentsObject, None) \
_(GuardNoDenseElements, Id) \
_(GuardNoUnboxedExpando, Id) \
_(GuardAndLoadUnboxedExpando, Id, Id) \
_(GuardAndGetIndexFromString, Id, Id) \
_(GuardAndGetNumberFromString, Id, Id) \
_(GuardAndGetIterator, Id, Id, Field, Field) \
_(GuardHasGetterSetter, Id, Field) \
_(GuardGroupHasUnanalyzedNewScript, Field) \
_(GuardIndexIsNonNegative, Id) \
_(GuardIndexGreaterThanDenseCapacity, Id, Id) \
_(GuardIndexGreaterThanArrayLength, Id, Id) \
_(GuardIndexIsValidUpdateOrAdd, Id, Id) \
_(GuardIndexGreaterThanDenseInitLength, Id, Id) \
_(GuardTagNotEqual, Id, Id) \
_(GuardXrayExpandoShapeAndDefaultProto, Id, Byte, Field) \
_(GuardFunctionPrototype, Id, Id, Field) \
_(GuardNoAllocationMetadataBuilder, None) \
_(GuardObjectGroupNotPretenured, Field) \
_(LoadStackValue, Id, UInt32) \
_(LoadObject, Id, Field) \
_(LoadProto, Id, Id) \
_(LoadEnclosingEnvironment, Id, Id) \
_(LoadWrapperTarget, Id, Id) \
_(LoadValueTag, Id, Id) \
\
_(TruncateDoubleToUInt32, Id, Id) \
\
_(MegamorphicLoadSlotResult, Id, Field, Byte) \
_(MegamorphicLoadSlotByValueResult, Id, Id, Byte) \
_(MegamorphicStoreSlot, Id, Field, Id, Byte) \
_(MegamorphicSetElement, Id, Id, Id, Byte) \
_(MegamorphicHasPropResult, Id, Id, Byte) \
\
/* See CacheIR.cpp 'DOM proxies' comment. */ \
_(LoadDOMExpandoValue, Id, Id) \
_(LoadDOMExpandoValueGuardGeneration, Id, Field, Field, Id) \
_(LoadDOMExpandoValueIgnoreGeneration, Id, Id) \
_(GuardDOMExpandoMissingOrGuardShape, Id, Field) \
\
_(StoreFixedSlot, Id, Field, Id) \
_(StoreDynamicSlot, Id, Field, Id) \
_(AddAndStoreFixedSlot, Id, Field, Id, Byte, Field, Field) \
_(AddAndStoreDynamicSlot, Id, Field, Id, Byte, Field, Field) \
_(AllocateAndStoreDynamicSlot, Id, Field, Id, Byte, Field, Field, Field) \
_(StoreTypedObjectReferenceProperty, Id, Field, Byte, Byte, Id) \
_(StoreTypedObjectScalarProperty, Id, Field, Byte, Byte, Id) \
_(StoreUnboxedProperty, Id, Byte, Field, Id) \
_(StoreDenseElement, Id, Id, Id) \
_(StoreDenseElementHole, Id, Id, Id, Byte) \
_(ArrayPush, Id, Id) \
_(ArrayJoinResult, Id) \
_(StoreTypedElement, Id, Id, Id, Byte, Byte, Byte) \
_(CallNativeSetter, Id, Id, Field) \
_(CallScriptedSetter, Id, Field, Id, Byte) \
_(CallSetArrayLength, Id, Byte, Id) \
_(CallProxySet, Id, Id, Field, Byte) \
_(CallProxySetByValue, Id, Id, Id, Byte) \
_(CallAddOrUpdateSparseElementHelper, Id, Id, Id, Byte) \
_(CallInt32ToString, Id, Id) \
_(CallNumberToString, Id, Id) \
\
/* The *Result ops load a value into the cache's result register. */ \
_(LoadFixedSlotResult, Id, Field) \
_(LoadDynamicSlotResult, Id, Field) \
_(LoadUnboxedPropertyResult, Id, Byte, Field) \
_(LoadTypedObjectResult, Id, Byte, Byte, Field) \
_(LoadDenseElementResult, Id, Id) \
_(LoadDenseElementHoleResult, Id, Id) \
_(CallGetSparseElementResult, Id, Id) \
_(LoadDenseElementExistsResult, Id, Id) \
_(LoadTypedElementExistsResult, Id, Id, Byte) \
_(LoadDenseElementHoleExistsResult, Id, Id) \
_(LoadTypedElementResult, Id, Id, Byte, Byte) \
_(LoadInt32ArrayLengthResult, Id) \
_(LoadArgumentsObjectArgResult, Id, Id) \
_(LoadArgumentsObjectLengthResult, Id) \
_(LoadFunctionLengthResult, Id) \
_(LoadStringCharResult, Id, Id) \
_(LoadStringLengthResult, Id) \
_(LoadFrameCalleeResult, None) \
_(LoadFrameNumActualArgsResult, None) \
_(LoadFrameArgumentResult, Id) \
_(LoadEnvironmentFixedSlotResult, Id, Field) \
_(LoadEnvironmentDynamicSlotResult, Id, Field) \
_(LoadObjectResult, Id) \
_(CallScriptedGetterResult, Id, Field, Byte) \
_(CallNativeGetterResult, Id, Field) \
_(CallProxyGetResult, Id, Field) \
_(CallProxyGetByValueResult, Id, Id) \
_(CallProxyHasPropResult, Id, Id, Byte) \
_(CallObjectHasSparseElementResult, Id, Id) \
_(CallNativeGetElementResult, Id, Id) \
_(LoadUndefinedResult, None) \
_(LoadBooleanResult, Byte) \
_(LoadStringResult, Field) \
_(LoadInstanceOfObjectResult, Id, Id) \
_(LoadTypeOfObjectResult, Id) \
_(DoubleAddResult, Id, Id) \
_(DoubleSubResult, Id, Id) \
_(DoubleMulResult, Id, Id) \
_(DoubleDivResult, Id, Id) \
_(DoubleModResult, Id, Id) \
_(Int32AddResult, Id, Id) \
_(Int32SubResult, Id, Id) \
_(Int32MulResult, Id, Id) \
_(Int32DivResult, Id, Id) \
_(Int32ModResult, Id, Id) \
_(Int32BitOrResult, Id, Id) \
_(Int32BitXorResult, Id, Id) \
_(Int32BitAndResult, Id, Id) \
_(Int32LeftShiftResult, Id, Id) \
_(Int32RightShiftResult, Id, Id) \
_(Int32URightShiftResult, Id, Id, Byte) \
_(Int32NotResult, Id) \
_(Int32NegationResult, Id) \
_(DoubleNegationResult, Id) \
_(Int32IncResult, Id) \
_(Int32DecResult, Id) \
_(DoubleIncResult, Id) \
_(DoubleDecResult, Id) \
_(LoadInt32TruthyResult, Id) \
_(LoadDoubleTruthyResult, Id) \
_(LoadStringTruthyResult, Id) \
_(LoadObjectTruthyResult, Id) \
_(LoadValueResult, Field) \
_(LoadNewObjectFromTemplateResult, Field, UInt32, UInt32) \
\
_(CallStringSplitResult, Id, Id, Field) \
_(CallStringConcatResult, Id, Id) \
_(CallStringObjectConcatResult, Id, Id) \
_(CallIsSuspendedGeneratorResult, Id) \
\
_(CompareStringResult, Id, Id, Byte) \
_(CompareObjectResult, Id, Id, Byte) \
_(CompareSymbolResult, Id, Id, Byte) \
_(CompareInt32Result, Id, Id, Byte) \
_(CompareDoubleResult, Id, Id, Byte) \
_(CompareObjectUndefinedNullResult, Id, Byte) \
\
_(CallPrintString, Word) \
_(Breakpoint, None) \
\
_(TypeMonitorResult, None) \
_(ReturnFromIC, None) \
_(WrapResult, None)
enum class CacheOp {
#define DEFINE_OP(op) op,
#define DEFINE_OP(op, ...) op,
CACHE_IR_OPS(DEFINE_OP)
#undef DEFINE_OP
};
const char* const CacheIrOpNames[] = {
#define OPNAME(op, ...) #op,
CACHE_IR_OPS(OPNAME)
#undef OPNAME
};
class StubField {
public:
enum class Type : uint8_t {
@ -500,8 +524,8 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter {
operandLastUsed_[opId.id()] = nextInstructionId_ - 1;
}
void writeInt32Immediate(int32_t i32) { buffer_.writeSigned(i32); }
void writeUint32Immediate(uint32_t u32) { buffer_.writeUnsigned(u32); }
void writeInt32Immediate(int32_t i32) { buffer_.writeFixedUint32_t(i32); }
void writeUint32Immediate(uint32_t u32) { buffer_.writeFixedUint32_t(u32); }
void writePointer(void* ptr) { buffer_.writeRawPointer(ptr); }
void writeOpWithOperandId(CacheOp op, OperandId opId) {
@ -757,8 +781,7 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter {
void guardSpecificInt32Immediate(
Int32OperandId operand, int32_t expected,
Assembler::Condition cond = Assembler::Equal) {
writeOp(CacheOp::GuardSpecificInt32Immediate);
writeOperandId(operand);
writeOpWithOperandId(CacheOp::GuardSpecificInt32Immediate, operand);
writeInt32Immediate(expected);
buffer_.writeByte(uint32_t(cond));
}
@ -1344,8 +1367,7 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter {
}
void loadInstanceOfObjectResult(ValOperandId lhs, ObjOperandId protoId,
uint32_t slot) {
writeOp(CacheOp::LoadInstanceOfObjectResult);
writeOperandId(lhs);
writeOpWithOperandId(CacheOp::LoadInstanceOfObjectResult, lhs);
writeOperandId(protoId);
}
void loadTypeOfObjectResult(ObjOperandId obj) {
@ -1387,8 +1409,7 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter {
}
void callStringSplitResult(StringOperandId str, StringOperandId sep,
ObjectGroup* group) {
writeOp(CacheOp::CallStringSplitResult);
writeOperandId(str);
writeOpWithOperandId(CacheOp::CallStringSplitResult, str);
writeOperandId(sep);
addStubField(uintptr_t(group), StubField::Type::ObjectGroup);
}
@ -1482,8 +1503,8 @@ class MOZ_RAII CacheIRReader {
uint32_t typeDescrKey() { return buffer_.readByte(); }
JSWhyMagic whyMagic() { return JSWhyMagic(buffer_.readByte()); }
JSOp jsop() { return JSOp(buffer_.readByte()); }
int32_t int32Immediate() { return buffer_.readSigned(); }
uint32_t uint32Immediate() { return buffer_.readUnsigned(); }
int32_t int32Immediate() { return int32_t(buffer_.readFixedUint32_t()); }
uint32_t uint32Immediate() { return buffer_.readFixedUint32_t(); }
void* pointer() { return buffer_.readRawPointer(); }
ReferenceType referenceTypeDescrType() {
@ -1522,6 +1543,7 @@ class MOZ_RAII CacheIRReader {
buffer_.seek(pos, 0);
return false;
}
const uint8_t* currentPosition() const { return buffer_.currentPosition(); }
};
class MOZ_RAII IRGenerator {

Просмотреть файл

@ -727,6 +727,23 @@ class MOZ_RAII CacheIRCompiler {
StubFieldPolicy stubFieldPolicy_;
#ifdef DEBUG
const uint8_t* currentVerificationPosition_;
// Verify that the number of bytes consumed by the compiler matches
// up with the opcode signature in CACHE_IR_OPS.
void assertAllArgumentsConsumed() {
CacheOp prevOp = CacheOp(*currentVerificationPosition_);
uint32_t expectedLength = CacheIROpFormat::OpLengths[uint8_t(prevOp)];
const uint8_t* newPosition = reader.currentPosition();
MOZ_ASSERT(newPosition > currentVerificationPosition_);
uint32_t actualLength = newPosition - currentVerificationPosition_;
MOZ_ASSERT(actualLength == expectedLength);
currentVerificationPosition_ = newPosition;
};
#endif
CacheIRCompiler(JSContext* cx, const CacheIRWriter& writer,
uint32_t stubDataOffset, Mode mode, StubFieldPolicy policy)
: cx_(cx),
@ -738,6 +755,9 @@ class MOZ_RAII CacheIRCompiler {
stubDataOffset_(stubDataOffset),
stubFieldPolicy_(policy) {
MOZ_ASSERT(!writer.failed());
#ifdef DEBUG
currentVerificationPosition_ = reader.currentPosition();
#endif
}
MOZ_MUST_USE bool addFailurePath(FailurePath** failure);

Просмотреть файл

@ -192,6 +192,72 @@ void CacheIRSpewer::opcodeProperty(const char* name, const JSOp op) {
j.endStringProperty();
}
void CacheIRSpewer::CacheIRArgs(JSONPrinter& j, CacheIRReader& r,
CacheIROpFormat::ArgType arg) {
j.beginObject();
switch (arg) {
case CacheIROpFormat::None:
break;
case CacheIROpFormat::Id:
j.property("Id", r.readByte());
break;
case CacheIROpFormat::Field:
j.property("Field", r.readByte());
break;
case CacheIROpFormat::Byte:
j.property("Byte", r.readByte());
break;
case CacheIROpFormat::Int32:
j.property("Int32", r.int32Immediate());
break;
case CacheIROpFormat::UInt32:
j.property("Uint32", r.uint32Immediate());
break;
case CacheIROpFormat::Word:
j.property("Word", uintptr_t(r.pointer()));
break;
}
j.endObject();
}
template <typename... Args>
void CacheIRSpewer::CacheIRArgs(JSONPrinter& j, CacheIRReader& r,
CacheIROpFormat::ArgType arg, Args... args) {
using namespace js::jit::CacheIROpFormat;
CacheIRArgs(j, r, arg);
CacheIRArgs(j, r, args...);
}
void CacheIRSpewer::cacheIRSequence(CacheIRReader& reader) {
using namespace js::jit::CacheIROpFormat;
MOZ_ASSERT(enabled());
JSONPrinter& j = json_.ref();
j.beginListProperty("cacheIR");
while (reader.more()) {
j.beginObject();
CacheOp op = reader.readOp();
j.property("op", CacheIrOpNames[uint32_t(op)]);
j.beginListProperty("args");
switch (op) {
# define DEFINE_OP(op, ...) \
case CacheOp::op: \
CacheIRArgs(j, reader, __VA_ARGS__); \
break;
CACHE_IR_OPS(DEFINE_OP)
# undef DEFINE_OP
default:
MOZ_CRASH("unreachable");
}
j.endList();
j.endObject();
}
j.endList();
}
void CacheIRSpewer::attached(const char* name) {
MOZ_ASSERT(enabled());
json_.ref().property("attached", name);

Просмотреть файл

@ -50,6 +50,12 @@ class CacheIRSpewer {
void beginCache(const IRGenerator& generator);
void valueProperty(const char* name, const Value& v);
void opcodeProperty(const char* name, const JSOp op);
void cacheIRSequence(CacheIRReader& reader);
void CacheIRArgs(JSONPrinter& j, CacheIRReader& r,
CacheIROpFormat::ArgType arg);
template <typename... Args>
void CacheIRArgs(JSONPrinter& j, CacheIRReader& r,
CacheIROpFormat::ArgType arg, Args... args);
void attached(const char* name);
void endCache();
@ -73,6 +79,10 @@ class CacheIRSpewer {
~Guard() {
if (sp_.enabled()) {
if (gen_.writerRef().codeLength() > 0) {
CacheIRReader reader(gen_.writerRef());
sp_.cacheIRSequence(reader);
}
if (name_ != nullptr) {
sp_.attached(name_);
}

Просмотреть файл

@ -115,7 +115,7 @@ class MOZ_RAII IonCacheIRCompiler : public CacheIRCompiler {
stubJitCodeOffset_.emplace(masm.PushWithPatch(ImmPtr((void*)-1)));
}
#define DEFINE_OP(op) MOZ_MUST_USE bool emit##op();
#define DEFINE_OP(op, ...) MOZ_MUST_USE bool emit##op();
CACHE_IR_OPS(DEFINE_OP)
#undef DEFINE_OP
};
@ -588,7 +588,7 @@ JitCode* IonCacheIRCompiler::compile() {
do {
switch (reader.readOp()) {
#define DEFINE_OP(op) \
#define DEFINE_OP(op, ...) \
case CacheOp::op: \
if (!emit##op()) return nullptr; \
break;
@ -598,7 +598,9 @@ JitCode* IonCacheIRCompiler::compile() {
default:
MOZ_CRASH("Invalid op");
}
#ifdef DEBUG
assertAllArgumentsConsumed();
#endif
allocator.nextOp();
} while (reader.more());

Просмотреть файл

@ -147,6 +147,7 @@ EXPORTS.js += [
'../public/OffThreadScriptCompilation.h',
'../public/Principals.h',
'../public/Printf.h',
'../public/ProfilingCategory.h',
'../public/ProfilingFrameIterator.h',
'../public/ProfilingStack.h',
'../public/Promise.h',

Просмотреть файл

@ -79,7 +79,7 @@ GeckoProfilerEntryMarker::~GeckoProfilerEntryMarker() {
MOZ_ALWAYS_INLINE
AutoGeckoProfilerEntry::AutoGeckoProfilerEntry(
JSContext* cx, const char* label, ProfilingStackFrame::Category category,
JSContext* cx, const char* label, JS::ProfilingCategoryPair categoryPair,
uint32_t flags MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
: profiler_(&cx->geckoProfiler()) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
@ -92,7 +92,8 @@ AutoGeckoProfilerEntry::AutoGeckoProfilerEntry(
#endif
profiler_->profilingStack_->pushLabelFrame(label,
/* dynamicString = */ nullptr,
/* sp = */ this, category, flags);
/* sp = */ this, categoryPair,
flags);
}
MOZ_ALWAYS_INLINE

Просмотреть файл

@ -6,6 +6,7 @@
#include "vm/GeckoProfiler-inl.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/DebugOnly.h"
#include "jsnum.h"
@ -476,3 +477,60 @@ AutoSuppressProfilerSampling::~AutoSuppressProfilerSampling() {
cx_->enableProfilerSampling();
}
}
namespace JS {
// clang-format off
// ProfilingSubcategory_X:
// One enum for each category X, listing that category's subcategories. This
// allows the sProfilingCategoryInfo macro construction below to look up a
// per-category index for a subcategory.
#define SUBCATEGORY_ENUMS_BEGIN_CATEGORY(name, labelAsString, color) \
enum class ProfilingSubcategory_##name : uint32_t {
#define SUBCATEGORY_ENUMS_SUBCATEGORY(category, name, labelAsString) \
name,
#define SUBCATEGORY_ENUMS_END_CATEGORY \
};
PROFILING_CATEGORY_LIST(SUBCATEGORY_ENUMS_BEGIN_CATEGORY,
SUBCATEGORY_ENUMS_SUBCATEGORY,
SUBCATEGORY_ENUMS_END_CATEGORY)
#undef SUBCATEGORY_ENUMS_BEGIN_CATEGORY
#undef SUBCATEGORY_ENUMS_SUBCATEGORY
#undef SUBCATEGORY_ENUMS_END_CATEGORY
// sProfilingCategoryPairInfo:
// A list of ProfilingCategoryPairInfos with the same order as
// ProfilingCategoryPair, which can be used to map a ProfilingCategoryPair to
// its information.
#define CATEGORY_INFO_BEGIN_CATEGORY(name, labelAsString, color)
#define CATEGORY_INFO_SUBCATEGORY(category, name, labelAsString) \
{ProfilingCategory::category, \
uint32_t(ProfilingSubcategory_##category::name), labelAsString},
#define CATEGORY_INFO_END_CATEGORY
const ProfilingCategoryPairInfo sProfilingCategoryPairInfo[] = {
PROFILING_CATEGORY_LIST(CATEGORY_INFO_BEGIN_CATEGORY,
CATEGORY_INFO_SUBCATEGORY,
CATEGORY_INFO_END_CATEGORY)
};
#undef CATEGORY_INFO_BEGIN_CATEGORY
#undef CATEGORY_INFO_SUBCATEGORY
#undef CATEGORY_INFO_END_CATEGORY
// clang-format on
JS_FRIEND_API const ProfilingCategoryPairInfo& GetProfilingCategoryPairInfo(
ProfilingCategoryPair aCategoryPair) {
static_assert(
MOZ_ARRAY_LENGTH(sProfilingCategoryPairInfo) ==
uint32_t(ProfilingCategoryPair::COUNT),
"sProfilingCategoryPairInfo and ProfilingCategory need to have the "
"same order and the same length");
uint32_t categoryPairIndex = uint32_t(aCategoryPair);
MOZ_RELEASE_ASSERT(categoryPairIndex <=
uint32_t(ProfilingCategoryPair::LAST));
return sProfilingCategoryPairInfo[categoryPairIndex];
}
} // namespace JS

Просмотреть файл

@ -177,8 +177,7 @@ class MOZ_NONHEAP_CLASS AutoGeckoProfilerEntry {
public:
explicit MOZ_ALWAYS_INLINE AutoGeckoProfilerEntry(
JSContext* cx, const char* label,
ProfilingStackFrame::Category category =
ProfilingStackFrame::Category::JS,
JS::ProfilingCategoryPair categoryPair = JS::ProfilingCategoryPair::JS,
uint32_t flags = 0 MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
MOZ_ALWAYS_INLINE ~AutoGeckoProfilerEntry();

Просмотреть файл

@ -57,9 +57,9 @@ GlobalHelperThreadState* gHelperThreadState = nullptr;
#define PROFILER_RAII_PASTE(id, line) id##line
#define PROFILER_RAII_EXPAND(id, line) PROFILER_RAII_PASTE(id, line)
#define PROFILER_RAII PROFILER_RAII_EXPAND(raiiObject, __LINE__)
#define AUTO_PROFILER_LABEL(label, category) \
#define AUTO_PROFILER_LABEL(label, categoryPair) \
HelperThread::AutoProfilerLabel PROFILER_RAII( \
this, label, js::ProfilingStackFrame::Category::category)
this, label, JS::ProfilingCategoryPair::categoryPair)
bool js::CreateHelperThreadsState() {
MOZ_ASSERT(!gHelperThreadState);
@ -2410,10 +2410,10 @@ const HelperThread::TaskSpec HelperThread::taskSpecs[] = {
HelperThread::AutoProfilerLabel::AutoProfilerLabel(
HelperThread* helperThread, const char* label,
ProfilingStackFrame::Category category)
JS::ProfilingCategoryPair categoryPair)
: profilingStack(helperThread->profilingStack) {
if (profilingStack) {
profilingStack->pushLabelFrame(label, nullptr, this, category);
profilingStack->pushLabelFrame(label, nullptr, this, categoryPair);
}
}

Просмотреть файл

@ -426,7 +426,7 @@ struct HelperThread {
private:
struct AutoProfilerLabel {
AutoProfilerLabel(HelperThread* helperThread, const char* label,
ProfilingStackFrame::Category category);
JS::ProfilingCategoryPair categoryPair);
~AutoProfilerLabel();
private:

Просмотреть файл

@ -39,7 +39,7 @@ class MOZ_RAII AutoProfilerStyleMarker {
return;
}
ServoTraversalStatistics::sActive = false;
profiler_add_marker("Styles", js::ProfilingStackFrame::Category::LAYOUT,
profiler_add_marker("Styles", JS::ProfilingCategoryPair::LAYOUT,
MakeUnique<StyleMarkerPayload>(
mStartTime, TimeStamp::Now(), std::move(mCause),
ServoTraversalStatistics::sSingleton, mDocShellId,

Просмотреть файл

@ -8850,7 +8850,7 @@ bool nsIPresShell::DoReflow(nsIFrame* target, bool aInterruptible,
#ifdef MOZ_GECKO_PROFILER
nsIURI* uri = mDocument->GetDocumentURI();
AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(
"PresShell::DoReflow", LAYOUT,
"Reflow", LAYOUT_Reflow,
uri ? uri->GetSpecOrDefault() : NS_LITERAL_CSTRING("N/A"));
#endif
@ -8881,7 +8881,7 @@ bool nsIPresShell::DoReflow(nsIFrame* target, bool aInterruptible,
#ifdef MOZ_GECKO_PROFILER
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell);
AutoProfilerTracing tracingLayoutFlush(
"Paint", "Reflow", js::ProfilingStackFrame::Category::LAYOUT,
"Paint", "Reflow", JS::ProfilingCategoryPair::LAYOUT,
std::move(mReflowCause), docShellId, docShellHistoryId);
mReflowCause = nullptr;
#endif

Просмотреть файл

@ -2508,7 +2508,8 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame(
}
nsIFrame* nsCSSFrameConstructor::ConstructRootFrame() {
AUTO_PROFILER_LABEL("nsCSSFrameConstructor::ConstructRootFrame", LAYOUT);
AUTO_PROFILER_LABEL("nsCSSFrameConstructor::ConstructRootFrame",
LAYOUT_FrameConstruction);
AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);
ServoStyleSet* styleSet = mPresShell->StyleSet();
@ -6616,7 +6617,8 @@ void nsCSSFrameConstructor::ContentAppended(nsIContent* aFirstNewContent,
MOZ_ASSERT(aInsertionKind == InsertionKind::Sync ||
!RestyleManager()->IsInStyleRefresh());
AUTO_PROFILER_LABEL("nsCSSFrameConstructor::ContentAppended", LAYOUT);
AUTO_PROFILER_LABEL("nsCSSFrameConstructor::ContentAppended",
LAYOUT_FrameConstruction);
AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);
#ifdef DEBUG
@ -6914,7 +6916,8 @@ void nsCSSFrameConstructor::ContentRangeInserted(
MOZ_ASSERT(aInsertionKind == InsertionKind::Sync ||
!RestyleManager()->IsInStyleRefresh());
AUTO_PROFILER_LABEL("nsCSSFrameConstructor::ContentRangeInserted", LAYOUT);
AUTO_PROFILER_LABEL("nsCSSFrameConstructor::ContentRangeInserted",
LAYOUT_FrameConstruction);
AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);
MOZ_ASSERT(aStartChild, "must always pass a child");
@ -7363,7 +7366,8 @@ bool nsCSSFrameConstructor::ContentRemoved(nsIContent* aChild,
MOZ_ASSERT(aChild);
MOZ_ASSERT(!aChild->IsRootOfAnonymousSubtree() || !aOldNextSibling,
"Anonymous roots don't have siblings");
AUTO_PROFILER_LABEL("nsCSSFrameConstructor::ContentRemoved", LAYOUT);
AUTO_PROFILER_LABEL("nsCSSFrameConstructor::ContentRemoved",
LAYOUT_FrameConstruction);
AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);
nsPresContext* presContext = mPresShell->GetPresContext();
MOZ_ASSERT(presContext, "Our presShell should have a valid presContext");
@ -7753,7 +7757,8 @@ bool nsCSSFrameConstructor::EnsureFrameForTextNodeIsCreatedAfterFlush(
void nsCSSFrameConstructor::CharacterDataChanged(
nsIContent* aContent, const CharacterDataChangeInfo& aInfo) {
AUTO_PROFILER_LABEL("nsCSSFrameConstructor::CharacterDataChanged", LAYOUT);
AUTO_PROFILER_LABEL("nsCSSFrameConstructor::CharacterDataChanged",
LAYOUT_FrameConstruction);
AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);
if ((aContent->HasFlag(NS_CREATE_FRAME_IF_NON_WHITESPACE) &&

Просмотреть файл

@ -3534,7 +3534,7 @@ nsresult nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext,
PartialUpdateResult updateState = PartialUpdateResult::Failed;
{
AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame:BuildDisplayList", GRAPHICS);
AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_DisplayListBuilding);
AUTO_PROFILER_TRACING("Paint", "DisplayList", GRAPHICS);
PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::DisplayList);
@ -6761,7 +6761,8 @@ static ImgDrawResult DrawImageInternal(
SamplingFilter aSamplingFilter, const nsRect& aDest, const nsRect& aFill,
const nsSize& aRepeatSize, const nsPoint& aAnchor, const nsRect& aDirty,
uint32_t aImageFlags, ExtendMode aExtendMode, float aOpacity) {
AUTO_PROFILER_LABEL("nsLayoutUtils::DrawBackgroundImage", GRAPHICS);
AUTO_PROFILER_LABEL("nsLayoutUtils::DrawBackgroundImage",
GRAPHICS_Rasterization);
Maybe<SVGImageContext> svgContext(Some(SVGImageContext(Some(aImageSize))));
SVGImageContext::MaybeStoreContextPaint(svgContext, aForFrame, aImage);

Просмотреть файл

@ -51,7 +51,8 @@ void ViewportFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
void ViewportFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) {
AUTO_PROFILER_LABEL("ViewportFrame::BuildDisplayList", GRAPHICS);
AUTO_PROFILER_LABEL("ViewportFrame::BuildDisplayList",
GRAPHICS_DisplayListBuilding);
if (nsIFrame* kid = mFrames.FirstChild()) {
// make the kid's BorderBackground our own. This ensures that the canvas

Просмотреть файл

@ -5574,21 +5574,35 @@ void ScrollFrameHelper::UpdateMinimumScaleSize(
}
nsViewportInfo viewportInfo = doc->GetViewportInfo(displaySize);
nsSize maximumPossibleSize =
CSSSize::ToAppUnits(ScreenSize(displaySize) / viewportInfo.GetMinZoom());
mMinimumScaleSize =
Min(maximumPossibleSize,
nsSize(aScrollableOverflow.XMost(), aScrollableOverflow.YMost()));
mMinimumScaleSize = Max(aICBSize, mMinimumScaleSize);
// The intrinsic minimum scale is the scale that fits the entire content
// width into the visual viewport.
CSSToScreenScale intrinsicMinScale(
displaySize.width / CSSRect::FromAppUnits(aScrollableOverflow).XMost());
// Chrome doesn't allow overflow-y:hidden region reachable if there is no
// overflow-x:hidden region.
// The scale used to compute the minimum-scale size is the larger of the
// intrinsic minimum and the min-scale from the meta viewport tag.
CSSToScreenScale minScale =
std::max(intrinsicMinScale, viewportInfo.GetMinZoom());
// The minimum-scale size is the size of the visual viewport when zoomed
// to be the minimum scale.
mMinimumScaleSize = CSSSize::ToAppUnits(ScreenSize(displaySize) / minScale);
// Clamp the min-scale size so it's not taller than the content height.
// TODO: Bug 1508177: We can drop this condition once after we shrink the
// content even if no content area gets visible.
if (mMinimumScaleSize.width != aICBSize.width) {
mIsUsingMinimumScaleSize = true;
}
mMinimumScaleSize =
Min(mMinimumScaleSize,
nsSize(aScrollableOverflow.XMost(), aScrollableOverflow.YMost()));
// Ensure the minimum-scale size is never smaller than the ICB size.
// That could happen if a page has a meta viewport tag with large explicitly
// specified viewport dimensions (making the ICB large) and also a large
// minimum scale (making the min-scale size small).
mMinimumScaleSize = Max(aICBSize, mMinimumScaleSize);
mIsUsingMinimumScaleSize = true;
}
bool ScrollFrameHelper::ReflowFinished() {

Просмотреть файл

@ -4393,7 +4393,8 @@ static void ProcessDisplayItemMarker(DisplayItemEntryType aMarker,
* of ContainerState::Finish.
*/
void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
AUTO_PROFILER_LABEL("ContainerState::ProcessDisplayItems", GRAPHICS);
AUTO_PROFILER_LABEL("ContainerState::ProcessDisplayItems",
GRAPHICS_LayerBuilding);
nsPoint topLeft(0, 0);
@ -6941,10 +6942,11 @@ void FrameLayerBuilder::PaintItems(std::vector<AssignedDisplayItem>& aItems,
}
#ifdef MOZ_DUMP_PAINTING
AUTO_PROFILER_LABEL_DYNAMIC_CSTR("FrameLayerBuilder::PaintItems", GRAPHICS,
item->Name());
AUTO_PROFILER_LABEL_DYNAMIC_CSTR("FrameLayerBuilder::PaintItems",
GRAPHICS_Rasterization, item->Name());
#else
AUTO_PROFILER_LABEL("FrameLayerBuilder::PaintItems", GRAPHICS);
AUTO_PROFILER_LABEL("FrameLayerBuilder::PaintItems",
GRAPHICS_Rasterization);
#endif
MOZ_ASSERT((opacityLevel == 0 && !cdi.mHasOpacity) ||
@ -7117,7 +7119,8 @@ static void DrawForcedBackgroundColor(DrawTarget& aDrawTarget,
void* aCallbackData) {
DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
AUTO_PROFILER_LABEL("FrameLayerBuilder::DrawPaintedLayer", GRAPHICS);
AUTO_PROFILER_LABEL("FrameLayerBuilder::DrawPaintedLayer",
GRAPHICS_Rasterization);
nsDisplayListBuilder* builder =
static_cast<nsDisplayListBuilder*>(aCallbackData);

Просмотреть файл

@ -658,6 +658,8 @@ bool RetainedDisplayListBuilder::MergeDisplayLists(
RetainedDisplayList* aOutList,
mozilla::Maybe<const mozilla::ActiveScrolledRoot*>& aOutContainerASR,
nsDisplayItem* aOuterItem) {
AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_DisplayListMerging);
MergeState merge(this, *aOldList,
aOuterItem ? aOuterItem->GetPerFrameKey() : 0);

Просмотреть файл

@ -2466,6 +2466,7 @@ FrameLayerBuilder* nsDisplayList::BuildLayers(nsDisplayListBuilder* aBuilder,
RefPtr<ContainerLayer> root;
{
AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_LayerBuilding);
#ifdef MOZ_GECKO_PROFILER
nsCOMPtr<nsIDocShell> docShell = presContext->GetDocShell();
AUTO_PROFILER_TRACING_DOCSHELL("Paint", "LayerBuilding", GRAPHICS,

Просмотреть файл

@ -0,0 +1,41 @@
<html class="reftest-wait">
<meta name="viewport" content="width=device-width minimum-scale=0.25 initial-scale=1.0">
<style>
html, body {
margin: 0;
width: 100%;
height: 100%;
scrollbar-width: none;
}
div {
position: absolute;
}
.B {
width: 200%;
height: 400%;
background: white;
}
.C {
width: 200%;
height: 200%;
background: green;
}
</style>
<div class="B"></div>
<div class="C"></div>
<script>
document.addEventListener('MozReftestInvalidate', () => {
// The page here is twice the width of the ICB, and four times the height.
// We want the layout viewport to be expanded to be twice the width and
// height of the ICB (to maintain aspect ratio), rather than four times the
// height.
// To test this, scroll to the end of the layout scroll range.
// If the layout viewport is expanded too much, we have no layout scroll
// range, so nothing will happen, and a green area will remain in view.
// If the layout viewport is expanded to the desired size, a white area
// will be scrolled into view, matching the reference page.
window.scrollTo(window.scrollMaxX, window.scrollMaxY);
document.documentElement.classList.remove('reftest-wait');
});
</script>
</html>

Просмотреть файл

@ -22,3 +22,4 @@ skip-if(winWidget||webrender) == vertical-overflow-hidden-region.html about:blan
skip-if(winWidget||webrender) == scroll-to-unreachable-area.html scroll-to-unreachable-area-ref.html
skip-if(winWidget||webrender) == wrapped-text-at-icb.html wrapped-text-at-icb-ref.html
skip-if(winWidget||webrender) == not-able-to-scrollTo.html about:blank
skip-if(winWidget||webrender) == min-scale-aspect-ratio.html about:blank

Просмотреть файл

@ -1578,7 +1578,7 @@ Loader::Completed Loader::ParseSheet(const nsACString& aBytes,
SheetLoadData* aLoadData,
AllowAsyncParse aAllowAsync) {
LOG(("css::Loader::ParseSheet"));
AUTO_PROFILER_LABEL("css::Loader::ParseSheet", LAYOUT);
AUTO_PROFILER_LABEL("css::Loader::ParseSheet", LAYOUT_CSSParsing);
MOZ_ASSERT(aLoadData);
aLoadData->mIsBeingParsed = true;

Просмотреть файл

@ -860,6 +860,7 @@ already_AddRefed<ComputedStyle> ServoStyleSet::ProbePseudoElementStyle(
}
bool ServoStyleSet::StyleDocument(ServoTraversalFlags aFlags) {
AUTO_PROFILER_LABEL_CATEGORY_PAIR(LAYOUT_StyleComputation);
MOZ_ASSERT(GetPresContext(), "Styling a document without a shell?");
if (!mDocument->GetServoRestyleRoot()) {

Просмотреть файл

@ -272,6 +272,8 @@ nsresult nsDOMCSSDeclaration::ModifyDeclaration(
nsresult nsDOMCSSDeclaration::ParsePropertyValue(
const nsCSSPropertyID aPropID, const nsAString& aPropValue,
bool aIsImportant, nsIPrincipal* aSubjectPrincipal) {
AUTO_PROFILER_LABEL_CATEGORY_PAIR(LAYOUT_CSSParsing);
DeclarationBlockMutationClosure closure = {};
MutationClosureData closureData;
GetPropertyChangeClosure(&closure, &closureData);

Просмотреть файл

@ -20,9 +20,9 @@
//
// Note that this class is slightly slower than the other AutoProfilerLabel,
// and it lacks the macro wrappers. It also is effectively hardwired to use
// js::ProfilingStackFrame::Category::OTHER as the category, because that's what
// the callbacks provided by the profiler use. (Specifying the category in
// this file would require #including ProfilingStack.h in mozglue, which we
// JS::ProfilingCategory::OTHER as the category pair, because that's what
// the callbacks provided by the profiler use. (Specifying the categories in
// this file would require #including ProfilingCategory.h in mozglue, which we
// don't want to do.)
class ProfilingStack;

Просмотреть файл

@ -267,7 +267,7 @@ browser.Context = class {
* Retrieves the current tabmodal UI object. According to the browser
* associated with the currently selected tab.
*/
getTabModalUI() {
getTabModal() {
let br = this.contentBrowser;
if (!br.hasAttribute("tabmodalPromptShowing")) {
return null;
@ -278,7 +278,7 @@ browser.Context = class {
let modalElements = br.parentNode.getElementsByTagNameNS(
XUL_NS, "tabmodalprompt");
return br.tabModalPromptBox.prompts.get(modalElements[0]).ui;
return br.tabModalPromptBox.prompts.get(modalElements[0]);
}
/**

Просмотреть файл

@ -37,6 +37,7 @@ const {
WebElement,
} = ChromeUtils.import("chrome://marionette/content/element.js");
const {
ElementNotInteractableError,
InsecureCertificateError,
InvalidArgumentError,
InvalidCookieDomainError,
@ -3225,12 +3226,24 @@ GeckoDriver.prototype.sendKeysToDialog = async function(cmd) {
assert.open(this.getCurrentWindow());
this._checkIfAlertIsPresent();
let text = assert.string(cmd.parameters.text);
let promptType = this.dialog.args.promptType;
switch (promptType) {
case "alert":
case "confirm":
throw new ElementNotInteractableError(
`User prompt of type ${promptType} is not interactable`);
case "prompt":
break;
default:
throw new UnsupportedOperationError(
`User prompt of type ${promptType} is not supported`);
}
// see toolkit/components/prompts/content/commonDialog.js
let {loginTextbox} = this.dialog.ui;
loginTextbox.value = "";
await interaction.sendKeysToElement(
loginTextbox, cmd.parameters.text, this.a11yChecks);
loginTextbox.value = text;
};
GeckoDriver.prototype._checkIfAlertIsPresent = function() {

Просмотреть файл

@ -143,11 +143,19 @@ modal.Dialog = class {
return null;
}
get ui() {
get tabModal() {
let win = this.window;
if (win) {
return win.Dialog.ui;
return win.Dialog;
}
return this.curBrowser_.getTabModalUI();
return this.curBrowser_.getTabModal();
}
get args() {
return this.tabModal.args;
}
get ui() {
return this.tabModal.ui;
}
};

Просмотреть файл

@ -356,7 +356,7 @@ class UserPrompt(object):
@text.setter
@command
def text(self, value):
body = {"value": list(value)}
body = {"text": value}
self.session.send_session_command("POST", "alert/text", body=body)

Просмотреть файл

@ -3,6 +3,7 @@ import pytest
from webdriver.transport import Response
from tests.support.asserts import assert_error, assert_success
from tests.support.authentication import basic_authentication
from tests.support.inline import inline
@ -55,7 +56,14 @@ def test_alert_element_not_interactable(session, dialog_type):
assert_error(response, "element not interactable")
@pytest.mark.parametrize("text", ["", "Federer", " Fed erer "])
def test_alert_unsupported_operation(session):
session.url = basic_authentication()
response = send_alert_text(session, "Federer")
assert_error(response, "unsupported operation")
@pytest.mark.parametrize("text", ["", "Federer", " Fed erer ", "Fed\terer"])
def test_send_alert_text(session, page, text):
send_response = send_alert_text(session, text)
assert_success(send_response)

Просмотреть файл

@ -0,0 +1,28 @@
import urllib
def basic_authentication(username=None, password=None, protocol="http"):
from .fixtures import server_config, url
build_url = url(server_config())
query = {}
return build_url("/webdriver/tests/support/authentication.py",
query=urllib.urlencode(query),
protocol=protocol)
def main(request, response):
user = request.auth.username
password = request.auth.password
if user == "user" and password == "password":
return "Authentication done"
realm = "test"
if "realm" in request.GET:
realm = request.GET.first("realm")
return ((401, "Unauthorized"),
[("WWW-Authenticate", 'Basic realm="' + realm + '"')],
"Please login with credentials 'user' and 'password'")

Просмотреть файл

@ -498,7 +498,7 @@ void BackgroundHangThread::ReportHang(TimeDuration aHangTime) {
TimeStamp endTime = TimeStamp::Now();
TimeStamp startTime = endTime - aHangTime;
profiler_add_marker_for_thread(
mStackHelper.GetThreadId(), js::ProfilingStackFrame::Category::OTHER,
mStackHelper.GetThreadId(), JS::ProfilingCategoryPair::OTHER,
"BHR-detected hang", MakeUnique<HangMarkerPayload>(startTime, endTime));
}
#endif

Просмотреть файл

@ -373,7 +373,7 @@ ExtensionPageChild = {
},
/**
* Create a privileged context at document-element-inserted.
* Create a privileged context at initial-document-element-inserted.
*
* @param {BrowserExtensionContent} extension
* The extension for which the context should be created.

Просмотреть файл

@ -55,6 +55,8 @@ using dom::Promise;
#define OBS_TOPIC_PRELOAD_SCRIPT "web-extension-preload-content-script"
#define OBS_TOPIC_LOAD_SCRIPT "web-extension-load-content-script"
static const char kDocElementInserted[] = "initial-document-element-inserted";
static mozIExtensionProcessScript& ProcessScript() {
static nsCOMPtr<mozIExtensionProcessScript> sProcessScript;
@ -235,8 +237,7 @@ ExtensionPolicyService::CollectReports(nsIHandleReportCallback* aHandleReport,
*****************************************************************************/
void ExtensionPolicyService::RegisterObservers() {
mObs->AddObserver(this, "content-document-global-created", false);
mObs->AddObserver(this, "document-element-inserted", false);
mObs->AddObserver(this, kDocElementInserted, false);
mObs->AddObserver(this, "tab-content-frameloader-created", false);
if (XRE_IsContentProcess()) {
mObs->AddObserver(this, "http-on-opening-request", false);
@ -244,8 +245,7 @@ void ExtensionPolicyService::RegisterObservers() {
}
void ExtensionPolicyService::UnregisterObservers() {
mObs->RemoveObserver(this, "content-document-global-created");
mObs->RemoveObserver(this, "document-element-inserted");
mObs->RemoveObserver(this, kDocElementInserted);
mObs->RemoveObserver(this, "tab-content-frameloader-created");
if (XRE_IsContentProcess()) {
mObs->RemoveObserver(this, "http-on-opening-request");
@ -255,12 +255,7 @@ void ExtensionPolicyService::UnregisterObservers() {
nsresult ExtensionPolicyService::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData) {
if (!strcmp(aTopic, "content-document-global-created")) {
nsCOMPtr<nsPIDOMWindowOuter> win = do_QueryInterface(aSubject);
if (win) {
CheckWindow(win);
}
} else if (!strcmp(aTopic, "document-element-inserted")) {
if (!strcmp(aTopic, kDocElementInserted)) {
nsCOMPtr<Document> doc = do_QueryInterface(aSubject);
if (doc) {
CheckDocument(doc);
@ -478,34 +473,6 @@ void ExtensionPolicyService::CheckDocument(Document* aDocument) {
}
}
// Checks for loads of about:blank into new window globals, and loads any
// matching content scripts. about:blank loads do not trigger document element
// inserted events, so they're the only load type that are special cased this
// way.
void ExtensionPolicyService::CheckWindow(nsPIDOMWindowOuter* aWindow) {
// We only care about non-initial document loads here. The initial
// about:blank document will usually be re-used to load another document.
RefPtr<Document> doc = aWindow->GetExtantDoc();
if (!doc || doc->IsInitialDocument() ||
doc->GetReadyStateEnum() == Document::READYSTATE_UNINITIALIZED) {
return;
}
nsCOMPtr<nsIURI> docUri = doc->GetDocumentURI();
nsCOMPtr<nsIURI> uri;
if (!docUri || NS_FAILED(NS_GetURIWithoutRef(docUri, getter_AddRefs(uri))) ||
!NS_IsAboutBlank(uri)) {
return;
}
nsIDocShell* docShell = aWindow->GetDocShell();
if (RefPtr<ContentFrameMessageManager> mm = docShell->GetMessageManager()) {
if (mMessageManagers.Contains(mm)) {
CheckContentScripts(aWindow, false);
}
}
}
void ExtensionPolicyService::CheckContentScripts(const DocInfo& aDocInfo,
bool aIsPreload) {
nsCOMPtr<nsPIDOMWindowInner> win;

Просмотреть файл

@ -103,7 +103,6 @@ class ExtensionPolicyService final : public nsIAddonPolicyService,
void CheckRequest(nsIChannel* aChannel);
void CheckDocument(dom::Document* aDocument);
void CheckWindow(nsPIDOMWindowOuter* aWindow);
void CheckContentScripts(const DocInfo& aDocInfo, bool aIsPreload);

Просмотреть файл

@ -76,6 +76,7 @@ subsuite = clipboard
[browser_passwordmgr_switchtab.js]
[browser_passwordmgrdlg.js]
[browser_private_window.js]
skip-if = os == "linux" #Bug 1526614
support-files =
subtst_privbrowsing_1.html
subtst_privbrowsing_2.html

Просмотреть файл

@ -58,7 +58,7 @@ void ProfileBuffer::AddStoredMarker(ProfilerMarker* aStoredMarker) {
void ProfileBuffer::CollectCodeLocation(
const char* aLabel, const char* aStr, uint32_t aFrameFlags,
const Maybe<uint32_t>& aLineNumber, const Maybe<uint32_t>& aColumnNumber,
const Maybe<js::ProfilingStackFrame::Category>& aCategory) {
const Maybe<JS::ProfilingCategoryPair>& aCategoryPair) {
AddEntry(ProfileBufferEntry::Label(aLabel));
AddEntry(ProfileBufferEntry::FrameFlags(uint64_t(aFrameFlags)));
@ -87,8 +87,8 @@ void ProfileBuffer::CollectCodeLocation(
AddEntry(ProfileBufferEntry::ColumnNumber(*aColumnNumber));
}
if (aCategory.isSome()) {
AddEntry(ProfileBufferEntry::Category(int(*aCategory)));
if (aCategoryPair.isSome()) {
AddEntry(ProfileBufferEntry::CategoryPair(int(*aCategoryPair)));
}
}
@ -186,5 +186,5 @@ void ProfileBufferCollector::CollectProfilingStackFrame(
}
mBuf.CollectCodeLocation(label, dynamicString, aFrame.flags(), line, column,
Some(aFrame.category()));
Some(aFrame.categoryPair()));
}

Просмотреть файл

@ -44,7 +44,7 @@ class ProfileBuffer final {
const char* aLabel, const char* aStr, uint32_t aFrameFlags,
const mozilla::Maybe<uint32_t>& aLineNumber,
const mozilla::Maybe<uint32_t>& aColumnNumber,
const mozilla::Maybe<js::ProfilingStackFrame::Category>& aCategory);
const mozilla::Maybe<JS::ProfilingCategoryPair>& aCategoryPair);
// Maximum size of a frameKey string that we'll handle.
static const size_t kMaxFrameKeyLength = 512;

Просмотреть файл

@ -357,7 +357,7 @@ bool UniqueStacks::FrameKey::NormalFrameData::operator==(
const NormalFrameData& aOther) const {
return mLocation == aOther.mLocation &&
mRelevantForJS == aOther.mRelevantForJS && mLine == aOther.mLine &&
mColumn == aOther.mColumn && mCategory == aOther.mCategory;
mColumn == aOther.mColumn && mCategoryPair == aOther.mCategoryPair;
}
bool UniqueStacks::FrameKey::JITFrameData::operator==(
@ -380,8 +380,8 @@ uint32_t UniqueStacks::FrameKey::Hash() const {
if (data.mColumn.isSome()) {
hash = AddToHash(hash, *data.mColumn);
}
if (data.mCategory.isSome()) {
hash = AddToHash(hash, *data.mCategory);
if (data.mCategoryPair.isSome()) {
hash = AddToHash(hash, uint32_t(*data.mCategoryPair));
}
} else {
const JITFrameData& data = mData.as<JITFrameData>();
@ -527,8 +527,10 @@ void UniqueStacks::StreamNonJITFrame(const FrameKey& aFrame) {
if (data.mColumn.isSome()) {
writer.IntElement(COLUMN, *data.mColumn);
}
if (data.mCategory.isSome()) {
writer.IntElement(CATEGORY, *data.mCategory);
if (data.mCategoryPair.isSome()) {
const JS::ProfilingCategoryPairInfo& info =
JS::GetProfilingCategoryPairInfo(*data.mCategoryPair);
writer.IntElement(CATEGORY, uint32_t(info.mCategory));
}
}
@ -785,7 +787,7 @@ class EntryGetter {
// ThreadId
// Time
// ( NativeLeafAddr
// | Label FrameFlags? DynamicStringFragment* LineNumber? Category?
// | Label FrameFlags? DynamicStringFragment* LineNumber? CategoryPair?
// | JitReturnAddr
// )+
// Marker*
@ -821,15 +823,15 @@ class EntryGetter {
// - ProfilingStack frames without a dynamic string:
//
// Label("js::RunScript")
// Category(ProfilingStackFrame::Category::JS)
// CategoryPair(JS::ProfilingCategoryPair::JS)
//
// Label("XREMain::XRE_main")
// LineNumber(4660)
// Category(ProfilingStackFrame::Category::OTHER)
// CategoryPair(JS::ProfilingCategoryPair::OTHER)
//
// Label("ElementRestyler::ComputeStyleChangeFor")
// LineNumber(3003)
// Category(ProfilingStackFrame::Category::CSS)
// CategoryPair(JS::ProfilingCategoryPair::CSS)
//
// - ProfilingStack frames with a dynamic string:
//
@ -838,7 +840,7 @@ class EntryGetter {
// DynamicStringFragment("domwindo")
// DynamicStringFragment("wopened")
// LineNumber(291)
// Category(ProfilingStackFrame::Category::OTHER)
// CategoryPair(JS::ProfilingCategoryPair::OTHER)
//
// Label("")
// FrameFlags(uint64_t(ProfilingStackFrame::Flags::IS_JS_FRAME))
@ -851,7 +853,7 @@ class EntryGetter {
// DynamicStringFragment("ay.js:5)")
// DynamicStringFragment("") # this string holds the closing '\0'
// LineNumber(25)
// Category(ProfilingStackFrame::Category::JS)
// CategoryPair(JS::ProfilingCategoryPair::JS)
//
// Label("")
// FrameFlags(uint64_t(ProfilingStackFrame::Flags::IS_JS_FRAME))
@ -859,7 +861,7 @@ class EntryGetter {
// DynamicStringFragment("elf-host")
// DynamicStringFragment("ed:914)")
// LineNumber(945)
// Category(ProfilingStackFrame::Category::JS)
// CategoryPair(JS::ProfilingCategoryPair::JS)
//
// - A profiling stack frame with a dynamic string, but with privacy enabled:
//
@ -868,7 +870,7 @@ class EntryGetter {
// DynamicStringFragment("(private")
// DynamicStringFragment(")")
// LineNumber(291)
// Category(ProfilingStackFrame::Category::OTHER)
// CategoryPair(JS::ProfilingCategoryPair::OTHER)
//
// - A profiling stack frame with an overly long dynamic string:
//
@ -877,7 +879,7 @@ class EntryGetter {
// DynamicStringFragment("(too lon")
// DynamicStringFragment("g)")
// LineNumber(100)
// Category(ProfilingStackFrame::Category::NETWORK)
// CategoryPair(JS::ProfilingCategoryPair::NETWORK)
//
// - A wasm JIT frame:
//
@ -1062,15 +1064,16 @@ void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter,
e.Next();
}
Maybe<unsigned> category;
if (e.Has() && e.Get().IsCategory()) {
category = Some(unsigned(e.Get().GetInt()));
Maybe<JS::ProfilingCategoryPair> categoryPair;
if (e.Has() && e.Get().IsCategoryPair()) {
categoryPair =
Some(JS::ProfilingCategoryPair(uint32_t(e.Get().GetInt())));
e.Next();
}
stack = aUniqueStacks.AppendFrame(
stack, UniqueStacks::FrameKey(std::move(frameLabel), relevantForJS,
line, column, category));
line, column, categoryPair));
} else if (e.Get().IsJitReturnAddr()) {
numFrames++;

Просмотреть файл

@ -10,6 +10,7 @@
#include "ProfileJSONWriter.h"
#include "gtest/MozGtestFriend.h"
#include "js/ProfilingCategory.h"
#include "js/ProfilingFrameIterator.h"
#include "js/TrackedOptimizationInfo.h"
#include "mozilla/HashFunctions.h"
@ -27,7 +28,7 @@ class ProfilerMarker;
// NOTE! If you add entries, you need to verify if they need to be added to the
// switch statement in DuplicateLastSample!
#define FOR_EACH_PROFILE_BUFFER_ENTRY_KIND(MACRO) \
MACRO(Category, int) \
MACRO(CategoryPair, int) \
MACRO(CollectionStart, double) \
MACRO(CollectionEnd, double) \
MACRO(Label, const char*) \
@ -224,9 +225,9 @@ class UniqueStacks {
FrameKey(nsCString&& aLocation, bool aRelevantForJS,
const mozilla::Maybe<unsigned>& aLine,
const mozilla::Maybe<unsigned>& aColumn,
const mozilla::Maybe<unsigned>& aCategory)
const mozilla::Maybe<JS::ProfilingCategoryPair>& aCategoryPair)
: mData(NormalFrameData{aLocation, aRelevantForJS, aLine, aColumn,
aCategory}) {}
aCategoryPair}) {}
FrameKey(void* aJITAddress, uint32_t aJITDepth, uint32_t aRangeIndex)
: mData(JITFrameData{aJITAddress, aJITDepth, aRangeIndex}) {}
@ -245,7 +246,7 @@ class UniqueStacks {
bool mRelevantForJS;
mozilla::Maybe<unsigned> mLine;
mozilla::Maybe<unsigned> mColumn;
mozilla::Maybe<unsigned> mCategory;
mozilla::Maybe<JS::ProfilingCategoryPair> mCategoryPair;
};
struct JITFrameData {
bool operator==(const JITFrameData& aOther) const;

Просмотреть файл

@ -21,7 +21,7 @@ class ProfilerMarker {
public:
explicit ProfilerMarker(
const char* aMarkerName, js::ProfilingStackFrame::Category aCategory,
const char* aMarkerName, JS::ProfilingCategoryPair aCategoryPair,
int aThreadId,
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload = nullptr,
double aTime = 0)
@ -31,7 +31,7 @@ class ProfilerMarker {
mTime(aTime),
mPositionInBuffer{0},
mThreadId{aThreadId},
mCategory{aCategory} {}
mCategoryPair{aCategoryPair} {}
void SetPositionInBuffer(uint64_t aPosition) {
mPositionInBuffer = aPosition;
@ -55,7 +55,9 @@ class ProfilerMarker {
{
aUniqueStacks.mUniqueStrings->WriteElement(aWriter, mMarkerName.get());
aWriter.DoubleElement(mTime);
aWriter.IntElement(unsigned(mCategory));
const JS::ProfilingCategoryPairInfo& info =
JS::GetProfilingCategoryPairInfo(mCategoryPair);
aWriter.IntElement(unsigned(info.mCategory));
// TODO: Store the callsite for this marker if available:
// if have location data
// b.NameValue(marker, "location", ...);
@ -75,7 +77,7 @@ class ProfilerMarker {
double mTime;
uint64_t mPositionInBuffer;
int mThreadId;
js::ProfilingStackFrame::Category mCategory;
JS::ProfilingCategoryPair mCategoryPair;
};
template <typename T>

Просмотреть файл

@ -38,13 +38,13 @@ class RacyRegisteredThread final {
bool IsBeingProfiled() const { return mIsBeingProfiled; }
void AddPendingMarker(const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload,
double aTime) {
// Note: We don't assert on mIsBeingProfiled, because it could have changed
// between the check in the caller and now.
ProfilerMarker* marker = new ProfilerMarker(
aMarkerName, aCategory, mThreadId, std::move(aPayload), aTime);
aMarkerName, aCategoryPair, mThreadId, std::move(aPayload), aTime);
mPendingMarkers.insert(marker);
}

Просмотреть файл

@ -1708,41 +1708,21 @@ static void StreamTaskTracer(PSLockRef aLock, SpliceableJSONWriter& aWriter) {
}
static void StreamCategories(SpliceableJSONWriter& aWriter) {
// Same order as ProfilingStackFrame::Category.
// The list of available color names is:
// transparent, grey, purple, yellow, orange, lightblue, green, blue, magenta
aWriter.Start();
aWriter.StringProperty("name", "Idle");
aWriter.StringProperty("color", "transparent");
aWriter.EndObject();
aWriter.Start();
aWriter.StringProperty("name", "Other");
aWriter.StringProperty("color", "grey");
aWriter.EndObject();
aWriter.Start();
aWriter.StringProperty("name", "Layout");
aWriter.StringProperty("color", "purple");
aWriter.EndObject();
aWriter.Start();
aWriter.StringProperty("name", "JavaScript");
aWriter.StringProperty("color", "yellow");
aWriter.EndObject();
aWriter.Start();
aWriter.StringProperty("name", "GC / CC");
aWriter.StringProperty("color", "orange");
aWriter.EndObject();
aWriter.Start();
aWriter.StringProperty("name", "Network");
aWriter.StringProperty("color", "lightblue");
aWriter.EndObject();
aWriter.Start();
aWriter.StringProperty("name", "Graphics");
aWriter.StringProperty("color", "green");
aWriter.EndObject();
aWriter.Start();
aWriter.StringProperty("name", "DOM");
aWriter.StringProperty("color", "blue");
aWriter.EndObject();
// Same order as ProfilingCategory.
#define CATEGORY_JSON_BEGIN_CATEGORY(name, labelAsString, color) \
aWriter.Start(); \
aWriter.StringProperty("name", labelAsString); \
aWriter.StringProperty("color", color);
#define CATEGORY_JSON_SUBCATEGORY(category, name, labelAsString)
#define CATEGORY_JSON_END_CATEGORY aWriter.EndObject();
PROFILING_CATEGORY_LIST(CATEGORY_JSON_BEGIN_CATEGORY,
CATEGORY_JSON_SUBCATEGORY, CATEGORY_JSON_END_CATEGORY)
#undef CATEGORY_JSON_BEGIN_CATEGORY
#undef CATEGORY_JSON_SUBCATEGORY
#undef CATEGORY_JSON_END_CATEGORY
}
static void StreamMetaJSCustomObject(PSLockRef aLock,
@ -1936,22 +1916,22 @@ static UniquePtr<ProfileBuffer> CollectJavaThreadProfileData() {
}
nsCString frameNameString = frameName->ToCString();
// Compute a category for the frame:
// Compute a category pair for the frame:
// - IDLE for the wait function android.os.MessageQueue.nativePollOnce()
// - OTHER for any function that's directly called by that wait function
// - no category on everything else
Maybe<js::ProfilingStackFrame::Category> category;
Maybe<JS::ProfilingCategoryPair> categoryPair;
if (frameNameString.EqualsLiteral(
"android.os.MessageQueue.nativePollOnce()")) {
category = Some(js::ProfilingStackFrame::Category::IDLE);
categoryPair = Some(JS::ProfilingCategoryPair::IDLE);
parentFrameWasIdleFrame = true;
} else if (parentFrameWasIdleFrame) {
category = Some(js::ProfilingStackFrame::Category::OTHER);
categoryPair = Some(JS::ProfilingCategoryPair::OTHER);
parentFrameWasIdleFrame = false;
}
buffer->CollectCodeLocation("", frameNameString.get(), 0, Nothing(),
Nothing(), category);
Nothing(), categoryPair);
}
sampleId++;
}
@ -2635,7 +2615,7 @@ ProfilingStack* MozGlueLabelEnter(const char* aLabel,
ProfilingStack* profilingStack = AutoProfilerLabel::sProfilingStack.get();
if (profilingStack) {
profilingStack->pushLabelFrame(aLabel, aDynamicString, aSp,
js::ProfilingStackFrame::Category::OTHER);
JS::ProfilingCategoryPair::OTHER);
}
return profilingStack;
}
@ -3685,7 +3665,7 @@ void ProfilerBacktraceDestructor::operator()(ProfilerBacktrace* aBacktrace) {
}
static void racy_profiler_add_marker(
const char* aMarkerName, js::ProfilingStackFrame::Category aCategory,
const char* aMarkerName, JS::ProfilingCategoryPair aCategoryPair,
UniquePtr<ProfilerMarkerPayload> aPayload) {
MOZ_RELEASE_ASSERT(CorePS::Exists());
@ -3707,11 +3687,11 @@ static void racy_profiler_add_marker(
: TimeStamp::Now();
TimeDuration delta = origin - CorePS::ProcessStartTime();
racyRegisteredThread->AddPendingMarker(
aMarkerName, aCategory, std::move(aPayload), delta.ToMilliseconds());
aMarkerName, aCategoryPair, std::move(aPayload), delta.ToMilliseconds());
}
void profiler_add_marker(const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
UniquePtr<ProfilerMarkerPayload> aPayload) {
MOZ_RELEASE_ASSERT(CorePS::Exists());
@ -3720,19 +3700,18 @@ void profiler_add_marker(const char* aMarkerName,
return;
}
racy_profiler_add_marker(aMarkerName, aCategory, std::move(aPayload));
racy_profiler_add_marker(aMarkerName, aCategoryPair, std::move(aPayload));
}
void profiler_add_marker(const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory) {
profiler_add_marker(aMarkerName, aCategory, nullptr);
JS::ProfilingCategoryPair aCategoryPair) {
profiler_add_marker(aMarkerName, aCategoryPair, nullptr);
}
// This is a simplified version of profiler_add_marker that can be easily passed
// into the JS engine.
void profiler_add_js_marker(const char* aMarkerName) {
profiler_add_marker(aMarkerName, js::ProfilingStackFrame::Category::JS,
nullptr);
profiler_add_marker(aMarkerName, JS::ProfilingCategoryPair::JS, nullptr);
}
void profiler_add_network_marker(
@ -3757,7 +3736,7 @@ void profiler_add_network_marker(
char name[2048];
SprintfLiteral(name, "Load %d: %s", id, PromiseFlatCString(spec).get());
profiler_add_marker(
name, js::ProfilingStackFrame::Category::NETWORK,
name, JS::ProfilingCategoryPair::NETWORK,
MakeUnique<NetworkMarkerPayload>(
static_cast<int64_t>(aChannelId), PromiseFlatCString(spec).get(),
aType, aStart, aEnd, aPriority, aCount, aCacheDisposition, aTimings,
@ -3767,7 +3746,7 @@ void profiler_add_network_marker(
// This logic needs to add a marker for a different thread, so we actually need
// to lock here.
void profiler_add_marker_for_thread(int aThreadId,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
const char* aMarkerName,
UniquePtr<ProfilerMarkerPayload> aPayload) {
MOZ_RELEASE_ASSERT(CorePS::Exists());
@ -3783,8 +3762,8 @@ void profiler_add_marker_for_thread(int aThreadId,
: TimeStamp::Now();
TimeDuration delta = origin - CorePS::ProcessStartTime();
ProfilerMarker* marker =
new ProfilerMarker(aMarkerName, aCategory, aThreadId, std::move(aPayload),
delta.ToMilliseconds());
new ProfilerMarker(aMarkerName, aCategoryPair, aThreadId,
std::move(aPayload), delta.ToMilliseconds());
#ifdef DEBUG
// Assert that our thread ID makes sense
@ -3808,7 +3787,7 @@ void profiler_add_marker_for_thread(int aThreadId,
}
void profiler_tracing(const char* aCategoryString, const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
TracingKind aKind, const Maybe<nsID>& aDocShellId,
const Maybe<uint32_t>& aDocShellHistoryId) {
MOZ_RELEASE_ASSERT(CorePS::Exists());
@ -3822,11 +3801,11 @@ void profiler_tracing(const char* aCategoryString, const char* aMarkerName,
auto payload = MakeUnique<TracingMarkerPayload>(
aCategoryString, aKind, aDocShellId, aDocShellHistoryId);
racy_profiler_add_marker(aMarkerName, aCategory, std::move(payload));
racy_profiler_add_marker(aMarkerName, aCategoryPair, std::move(payload));
}
void profiler_tracing(const char* aCategoryString, const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
TracingKind aKind, UniqueProfilerBacktrace aCause,
const Maybe<nsID>& aDocShellId,
const Maybe<uint32_t>& aDocShellHistoryId) {
@ -3842,18 +3821,18 @@ void profiler_tracing(const char* aCategoryString, const char* aMarkerName,
auto payload =
MakeUnique<TracingMarkerPayload>(aCategoryString, aKind, aDocShellId,
aDocShellHistoryId, std::move(aCause));
racy_profiler_add_marker(aMarkerName, aCategory, std::move(payload));
racy_profiler_add_marker(aMarkerName, aCategoryPair, std::move(payload));
}
void profiler_add_text_marker(
const char* aMarkerName, const nsACString& aText,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime,
const mozilla::Maybe<nsID>& aDocShellId,
const mozilla::Maybe<uint32_t>& aDocShellHistoryId,
UniqueProfilerBacktrace aCause) {
profiler_add_marker(
aMarkerName, aCategory,
aMarkerName, aCategoryPair,
MakeUnique<TextMarkerPayload>(aText, aStartTime, aEndTime, aDocShellId,
aDocShellHistoryId, std::move(aCause)));
}

Просмотреть файл

@ -19,7 +19,7 @@ void ProfilerIOInterposeObserver::Observe(Observation& aObservation) {
nsString filename;
aObservation.Filename(filename);
profiler_add_marker(
"DiskIO", js::ProfilingStackFrame::Category::OTHER,
"DiskIO", JS::ProfilingCategoryPair::OTHER,
MakeUnique<DiskIOMarkerPayload>(
aObservation.ObservedOperationString(), aObservation.Reference(),
NS_ConvertUTF16toUTF8(filename).get(), aObservation.Start(),

Просмотреть файл

@ -157,7 +157,7 @@ nsProfiler::ResumeSampling() {
NS_IMETHODIMP
nsProfiler::AddMarker(const char* aMarker) {
profiler_add_marker(aMarker, js::ProfilingStackFrame::Category::OTHER);
profiler_add_marker(aMarker, JS::ProfilingCategoryPair::OTHER);
return NS_OK;
}

Просмотреть файл

@ -41,30 +41,31 @@
# define PROFILER_SET_JS_CONTEXT(cx)
# define PROFILER_CLEAR_JS_CONTEXT()
# define AUTO_PROFILER_LABEL(label, category)
# define AUTO_PROFILER_LABEL_DYNAMIC_CSTR(label, category, cStr)
# define AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(label, category, nsCStr)
# define AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(label, category, nsStr)
# define AUTO_PROFILER_LABEL_FAST(label, category, ctx)
# define AUTO_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, category, \
# define AUTO_PROFILER_LABEL(label, categoryPair)
# define AUTO_PROFILER_LABEL_CATEGORY_PAIR(categoryPair)
# define AUTO_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr)
# define AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(label, categoryPair, nsCStr)
# define AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(label, categoryPair, nsStr)
# define AUTO_PROFILER_LABEL_FAST(label, categoryPair, ctx)
# define AUTO_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, categoryPair, \
ctx, flags)
# define PROFILER_ADD_MARKER(markerName, category)
# define PROFILER_ADD_MARKER(markerName, categoryPair)
# define PROFILER_ADD_NETWORK_MARKER(uri, pri, channel, type, start, end, \
count, cache, timings, redirect)
# define DECLARE_DOCSHELL_AND_HISTORY_ID(docShell)
# define PROFILER_TRACING(categoryString, markerName, category, kind)
# define PROFILER_TRACING_DOCSHELL(categoryString, markerName, category, \
# define PROFILER_TRACING(categoryString, markerName, categoryPair, kind)
# define PROFILER_TRACING_DOCSHELL(categoryString, markerName, categoryPair, \
kind, docshell)
# define AUTO_PROFILER_TRACING(categoryString, markerName, category)
# define AUTO_PROFILER_TRACING_DOCSHELL(categoryString, markerName, category, \
docShell)
# define AUTO_PROFILER_TEXT_MARKER_CAUSE(markerName, text, category, cause)
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL(markerName, text, category, \
# define AUTO_PROFILER_TRACING(categoryString, markerName, categoryPair)
# define AUTO_PROFILER_TRACING_DOCSHELL(categoryString, markerName, \
categoryPair, docShell)
# define AUTO_PROFILER_TEXT_MARKER_CAUSE(markerName, text, categoryPair, cause)
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL(markerName, text, categoryPair, \
docShell)
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL_CAUSE(markerName, text, category, \
docShell, cause)
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL_CAUSE( \
markerName, text, categoryPair, docShell, cause)
#else // !MOZ_GECKO_PROFILER
@ -518,9 +519,19 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
//
// Use AUTO_PROFILER_LABEL_DYNAMIC_* if you want to add additional / dynamic
// information to the label stack frame.
# define AUTO_PROFILER_LABEL(label, category) \
mozilla::AutoProfilerLabel PROFILER_RAII( \
label, nullptr, js::ProfilingStackFrame::Category::category)
# define AUTO_PROFILER_LABEL(label, categoryPair) \
mozilla::AutoProfilerLabel PROFILER_RAII( \
label, nullptr, JS::ProfilingCategoryPair::categoryPair)
// Similar to AUTO_PROFILER_LABEL, but with only one argument: the category
// pair. The label string is taken from the category pair. This is convenient
// for labels like AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_LayerBuilding)
// which would otherwise just repeat the string.
# define AUTO_PROFILER_LABEL_CATEGORY_PAIR(categoryPair) \
mozilla::AutoProfilerLabel PROFILER_RAII( \
"", nullptr, JS::ProfilingCategoryPair::categoryPair, \
uint32_t(js::ProfilingStackFrame::Flags:: \
LABEL_DETERMINED_BY_CATEGORY_PAIR))
// Similar to AUTO_PROFILER_LABEL, but with an additional string. The inserted
// RAII object stores the cStr pointer in a field; it does not copy the string.
@ -541,9 +552,9 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
// profile buffer can just store the raw pointers to the literal strings.
// Consequently, AUTO_PROFILER_LABEL frames take up considerably less space in
// the profile buffer than AUTO_PROFILER_LABEL_DYNAMIC_* frames.
# define AUTO_PROFILER_LABEL_DYNAMIC_CSTR(label, category, cStr) \
mozilla::AutoProfilerLabel PROFILER_RAII( \
label, cStr, js::ProfilingStackFrame::Category::category)
# define AUTO_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr) \
mozilla::AutoProfilerLabel PROFILER_RAII( \
label, cStr, JS::ProfilingCategoryPair::categoryPair)
// Similar to AUTO_PROFILER_LABEL_DYNAMIC_CSTR, but takes an nsACString.
//
@ -552,14 +563,13 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
// cost of the string assignment unless the profiler is active. Therefore,
// unlike AUTO_PROFILER_LABEL and AUTO_PROFILER_LABEL_DYNAMIC_CSTR, this macro
// doesn't push/pop a label when the profiler is inactive.
# define AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(label, category, nsCStr) \
mozilla::Maybe<nsAutoCString> autoCStr; \
mozilla::Maybe<AutoProfilerLabel> raiiObjectNsCString; \
if (profiler_is_active()) { \
autoCStr.emplace(nsCStr); \
raiiObjectNsCString.emplace( \
label, autoCStr->get(), \
js::ProfilingStackFrame::Category::category); \
# define AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(label, categoryPair, nsCStr) \
mozilla::Maybe<nsAutoCString> autoCStr; \
mozilla::Maybe<AutoProfilerLabel> raiiObjectNsCString; \
if (profiler_is_active()) { \
autoCStr.emplace(nsCStr); \
raiiObjectNsCString.emplace(label, autoCStr->get(), \
JS::ProfilingCategoryPair::categoryPair); \
}
// Similar to AUTO_PROFILER_LABEL_DYNAMIC_CSTR, but takes an nsString that is
@ -570,14 +580,14 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
// the runtime cost of the string conversion unless the profiler is active.
// Therefore, unlike AUTO_PROFILER_LABEL and AUTO_PROFILER_LABEL_DYNAMIC_CSTR,
// this macro doesn't push/pop a label when the profiler is inactive.
# define AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(label, category, nsStr) \
mozilla::Maybe<NS_LossyConvertUTF16toASCII> asciiStr; \
mozilla::Maybe<AutoProfilerLabel> raiiObjectLossyNsString; \
if (profiler_is_active()) { \
asciiStr.emplace(nsStr); \
raiiObjectLossyNsString.emplace( \
label, asciiStr->get(), \
js::ProfilingStackFrame::Category::category); \
# define AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(label, categoryPair, \
nsStr) \
mozilla::Maybe<NS_LossyConvertUTF16toASCII> asciiStr; \
mozilla::Maybe<AutoProfilerLabel> raiiObjectLossyNsString; \
if (profiler_is_active()) { \
asciiStr.emplace(nsStr); \
raiiObjectLossyNsString.emplace( \
label, asciiStr->get(), JS::ProfilingCategoryPair::categoryPair); \
}
// Similar to AUTO_PROFILER_LABEL, but accepting a JSContext* parameter, and a
@ -586,18 +596,18 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
// noticeable. It avoids overhead from the TLS lookup because it can get the
// ProfilingStack from the JS context, and avoids almost all overhead in the
// case where the profiler is disabled.
# define AUTO_PROFILER_LABEL_FAST(label, category, ctx) \
mozilla::AutoProfilerLabel PROFILER_RAII( \
ctx, label, nullptr, js::ProfilingStackFrame::Category::category)
# define AUTO_PROFILER_LABEL_FAST(label, categoryPair, ctx) \
mozilla::AutoProfilerLabel PROFILER_RAII( \
ctx, label, nullptr, JS::ProfilingCategoryPair::categoryPair)
// Similar to AUTO_PROFILER_LABEL_FAST, but also takes an extra string and an
// additional set of flags. The flags parameter should carry values from the
// js::ProfilingStackFrame::Flags enum.
# define AUTO_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, category, \
ctx, flags) \
mozilla::AutoProfilerLabel PROFILER_RAII( \
ctx, label, dynamicString, \
js::ProfilingStackFrame::Category::category, flags)
# define AUTO_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, categoryPair, \
ctx, flags) \
mozilla::AutoProfilerLabel PROFILER_RAII( \
ctx, label, dynamicString, JS::ProfilingCategoryPair::categoryPair, \
flags)
// Insert a marker in the profile timeline. This is useful to delimit something
// important happening such as the first paint. Unlike labels, which are only
@ -607,19 +617,19 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
// certain length of time. A no-op if the profiler is inactive or in privacy
// mode.
# define PROFILER_ADD_MARKER(markerName, category) \
profiler_add_marker(markerName, js::ProfilingStackFrame::Category::category)
# define PROFILER_ADD_MARKER(markerName, categoryPair) \
profiler_add_marker(markerName, JS::ProfilingCategoryPair::categoryPair)
void profiler_add_marker(const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory);
JS::ProfilingCategoryPair aCategoryPair);
void profiler_add_marker(const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload);
void profiler_add_js_marker(const char* aMarkerName);
// Insert a marker in the profile timeline for a specified thread.
void profiler_add_marker_for_thread(
int aThreadId, js::ProfilingStackFrame::Category aCategory,
int aThreadId, JS::ProfilingCategoryPair aCategoryPair,
const char* aMarkerName,
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload);
@ -664,41 +674,39 @@ enum TracingKind {
// Adds a tracing marker to the profile. A no-op if the profiler is inactive or
// in privacy mode.
# define PROFILER_TRACING(categoryString, markerName, category, kind) \
profiler_tracing(categoryString, markerName, \
js::ProfilingStackFrame::Category::category, kind)
# define PROFILER_TRACING_DOCSHELL(categoryString, markerName, category, \
kind, docShell) \
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
profiler_tracing(categoryString, markerName, \
js::ProfilingStackFrame::Category::category, kind, \
# define PROFILER_TRACING(categoryString, markerName, categoryPair, kind) \
profiler_tracing(categoryString, markerName, \
JS::ProfilingCategoryPair::categoryPair, kind)
# define PROFILER_TRACING_DOCSHELL(categoryString, markerName, categoryPair, \
kind, docShell) \
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
profiler_tracing(categoryString, markerName, \
JS::ProfilingCategoryPair::categoryPair, kind, \
docShellId, docShellHistoryId)
void profiler_tracing(
const char* aCategoryString, const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory, TracingKind aKind,
JS::ProfilingCategoryPair aCategoryPair, TracingKind aKind,
const mozilla::Maybe<nsID>& aDocShellId = mozilla::Nothing(),
const mozilla::Maybe<uint32_t>& aDocShellHistoryId = mozilla::Nothing());
void profiler_tracing(
const char* aCategoryString, const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory, TracingKind aKind,
JS::ProfilingCategoryPair aCategoryPair, TracingKind aKind,
UniqueProfilerBacktrace aCause,
const mozilla::Maybe<nsID>& aDocShellId = mozilla::Nothing(),
const mozilla::Maybe<uint32_t>& aDocShellHistoryId = mozilla::Nothing());
// Adds a START/END pair of tracing markers.
# define AUTO_PROFILER_TRACING(categoryString, markerName, category) \
mozilla::AutoProfilerTracing PROFILER_RAII( \
categoryString, markerName, \
js::ProfilingStackFrame::Category::category, mozilla::Nothing(), \
mozilla::Nothing())
# define AUTO_PROFILER_TRACING_DOCSHELL(categoryString, markerName, category, \
docShell) \
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
mozilla::AutoProfilerTracing PROFILER_RAII( \
categoryString, markerName, \
js::ProfilingStackFrame::Category::category, docShellId, \
docShellHistoryId)
# define AUTO_PROFILER_TRACING(categoryString, markerName, categoryPair) \
mozilla::AutoProfilerTracing PROFILER_RAII( \
categoryString, markerName, JS::ProfilingCategoryPair::categoryPair, \
mozilla::Nothing(), mozilla::Nothing())
# define AUTO_PROFILER_TRACING_DOCSHELL(categoryString, markerName, \
categoryPair, docShell) \
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
mozilla::AutoProfilerTracing PROFILER_RAII( \
categoryString, markerName, JS::ProfilingCategoryPair::categoryPair, \
docShellId, docShellHistoryId)
// Add a text marker. Text markers are similar to tracing markers, with the
// difference that text markers have their "text" separate from the marker name;
@ -708,7 +716,7 @@ void profiler_tracing(
// into one marker.
void profiler_add_text_marker(
const char* aMarkerName, const nsACString& aText,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime,
const mozilla::Maybe<nsID>& aDocShellId = mozilla::Nothing(),
const mozilla::Maybe<uint32_t>& aDocShellHistoryId = mozilla::Nothing(),
@ -717,14 +725,14 @@ void profiler_add_text_marker(
class MOZ_RAII AutoProfilerTextMarker {
public:
AutoProfilerTextMarker(const char* aMarkerName, const nsACString& aText,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
const mozilla::Maybe<nsID>& aDocShellId,
const mozilla::Maybe<uint32_t>& aDocShellHistoryId,
UniqueProfilerBacktrace&& aCause =
nullptr MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mMarkerName(aMarkerName),
mText(aText),
mCategory(aCategory),
mCategoryPair(aCategoryPair),
mStartTime(mozilla::TimeStamp::Now()),
mCause(std::move(aCause)),
mDocShellId(aDocShellId),
@ -733,9 +741,8 @@ class MOZ_RAII AutoProfilerTextMarker {
}
~AutoProfilerTextMarker() {
profiler_add_text_marker(mMarkerName, mText,
js::ProfilingStackFrame::Category::LAYOUT,
mStartTime, mozilla::TimeStamp::Now(), mDocShellId,
profiler_add_text_marker(mMarkerName, mText, mCategoryPair, mStartTime,
mozilla::TimeStamp::Now(), mDocShellId,
mDocShellHistoryId, std::move(mCause));
}
@ -743,31 +750,32 @@ class MOZ_RAII AutoProfilerTextMarker {
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
const char* mMarkerName;
nsCString mText;
const js::ProfilingStackFrame::Category mCategory;
const JS::ProfilingCategoryPair mCategoryPair;
mozilla::TimeStamp mStartTime;
UniqueProfilerBacktrace mCause;
const mozilla::Maybe<nsID> mDocShellId;
const mozilla::Maybe<uint32_t> mDocShellHistoryId;
};
# define AUTO_PROFILER_TEXT_MARKER_CAUSE(markerName, text, category, cause) \
AutoProfilerTextMarker PROFILER_RAII( \
markerName, text, js::ProfilingStackFrame::Category::category, \
Nothing(), Nothing(), cause)
# define AUTO_PROFILER_TEXT_MARKER_CAUSE(markerName, text, categoryPair, \
cause) \
AutoProfilerTextMarker PROFILER_RAII( \
markerName, text, JS::ProfilingCategoryPair::categoryPair, Nothing(), \
Nothing(), cause)
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL(markerName, text, category, \
docShell) \
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
AutoProfilerTextMarker PROFILER_RAII( \
markerName, text, js::ProfilingStackFrame::Category::category, \
docShellId, docShellHistoryId)
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL_CAUSE(markerName, text, category, \
docShell, cause) \
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL(markerName, text, categoryPair, \
docShell) \
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
AutoProfilerTextMarker PROFILER_RAII( \
markerName, text, js::ProfilingStackFrame::Category::category, \
docShellId, docShellHistoryId, cause)
markerName, text, JS::ProfilingCategoryPair::categoryPair, docShellId, \
docShellHistoryId)
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL_CAUSE( \
markerName, text, categoryPair, docShell, cause) \
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
AutoProfilerTextMarker PROFILER_RAII( \
markerName, text, JS::ProfilingCategoryPair::categoryPair, docShellId, \
docShellHistoryId, cause)
//---------------------------------------------------------------------------
// Output profiles
@ -882,12 +890,12 @@ class MOZ_RAII AutoProfilerLabel {
public:
// This is the AUTO_PROFILER_LABEL and AUTO_PROFILER_LABEL_DYNAMIC variant.
AutoProfilerLabel(const char* aLabel, const char* aDynamicString,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
uint32_t aFlags = 0 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
// Get the ProfilingStack from TLS.
Push(sProfilingStack.get(), aLabel, aDynamicString, aCategory, aFlags);
Push(sProfilingStack.get(), aLabel, aDynamicString, aCategoryPair, aFlags);
}
// This is the AUTO_PROFILER_LABEL_FAST variant. It retrieves the
@ -895,22 +903,22 @@ class MOZ_RAII AutoProfilerLabel {
// inactive.
AutoProfilerLabel(JSContext* aJSContext, const char* aLabel,
const char* aDynamicString,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
uint32_t aFlags MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
Push(js::GetContextProfilingStackIfEnabled(aJSContext), aLabel,
aDynamicString, aCategory, aFlags);
aDynamicString, aCategoryPair, aFlags);
}
void Push(ProfilingStack* aProfilingStack, const char* aLabel,
const char* aDynamicString,
js::ProfilingStackFrame::Category aCategory, uint32_t aFlags = 0) {
const char* aDynamicString, JS::ProfilingCategoryPair aCategoryPair,
uint32_t aFlags = 0) {
// This function runs both on and off the main thread.
mProfilingStack = aProfilingStack;
if (mProfilingStack) {
mProfilingStack->pushLabelFrame(aLabel, aDynamicString, this, aCategory,
aFlags);
mProfilingStack->pushLabelFrame(aLabel, aDynamicString, this,
aCategoryPair, aFlags);
}
}
@ -937,39 +945,39 @@ class MOZ_RAII AutoProfilerLabel {
class MOZ_RAII AutoProfilerTracing {
public:
AutoProfilerTracing(const char* aCategoryString, const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
const mozilla::Maybe<nsID>& aDocShellId,
const mozilla::Maybe<uint32_t>& aDocShellHistoryId
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mCategoryString(aCategoryString),
mMarkerName(aMarkerName),
mCategory(aCategory),
mCategoryPair(aCategoryPair),
mDocShellId(aDocShellId),
mDocShellHistoryId(aDocShellHistoryId) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
profiler_tracing(mCategoryString, mMarkerName, aCategory,
profiler_tracing(mCategoryString, mMarkerName, aCategoryPair,
TRACING_INTERVAL_START, mDocShellId, mDocShellHistoryId);
}
AutoProfilerTracing(const char* aCategoryString, const char* aMarkerName,
js::ProfilingStackFrame::Category aCategory,
JS::ProfilingCategoryPair aCategoryPair,
UniqueProfilerBacktrace aBacktrace,
const mozilla::Maybe<nsID>& aDocShellId,
const mozilla::Maybe<uint32_t>& aDocShellHistoryId
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mCategoryString(aCategoryString),
mMarkerName(aMarkerName),
mCategory(aCategory),
mCategoryPair(aCategoryPair),
mDocShellId(aDocShellId),
mDocShellHistoryId(aDocShellHistoryId) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
profiler_tracing(mCategoryString, mMarkerName, aCategory,
profiler_tracing(mCategoryString, mMarkerName, aCategoryPair,
TRACING_INTERVAL_START, std::move(aBacktrace), mDocShellId,
mDocShellHistoryId);
}
~AutoProfilerTracing() {
profiler_tracing(mCategoryString, mMarkerName, mCategory,
profiler_tracing(mCategoryString, mMarkerName, mCategoryPair,
TRACING_INTERVAL_END, mDocShellId, mDocShellHistoryId);
}
@ -977,7 +985,7 @@ class MOZ_RAII AutoProfilerTracing {
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
const char* mCategoryString;
const char* mMarkerName;
const js::ProfilingStackFrame::Category mCategory;
const JS::ProfilingCategoryPair mCategoryPair;
const mozilla::Maybe<nsID> mDocShellId;
const mozilla::Maybe<uint32_t> mDocShellHistoryId;
};

Просмотреть файл

@ -459,28 +459,27 @@ TEST(GeckoProfiler, Markers) {
profiler_start(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL, features,
filters, MOZ_ARRAY_LENGTH(filters));
profiler_tracing("A", "B", js::ProfilingStackFrame::Category::OTHER,
TRACING_EVENT);
profiler_tracing("A", "B", JS::ProfilingCategoryPair::OTHER, TRACING_EVENT);
PROFILER_TRACING("A", "C", OTHER, TRACING_INTERVAL_START);
PROFILER_TRACING("A", "C", OTHER, TRACING_INTERVAL_END);
UniqueProfilerBacktrace bt = profiler_get_backtrace();
profiler_tracing("B", "A", js::ProfilingStackFrame::Category::OTHER,
TRACING_EVENT, std::move(bt));
profiler_tracing("B", "A", JS::ProfilingCategoryPair::OTHER, TRACING_EVENT,
std::move(bt));
{ AUTO_PROFILER_TRACING("C", "A", OTHER); }
profiler_add_marker("M1", js::ProfilingStackFrame::Category::OTHER);
profiler_add_marker("M2", js::ProfilingStackFrame::Category::OTHER,
profiler_add_marker("M1", JS::ProfilingCategoryPair::OTHER);
profiler_add_marker("M2", JS::ProfilingCategoryPair::OTHER,
MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT));
PROFILER_ADD_MARKER("M3", OTHER);
profiler_add_marker("M4", js::ProfilingStackFrame::Category::OTHER,
profiler_add_marker("M4", JS::ProfilingCategoryPair::OTHER,
MakeUnique<TracingMarkerPayload>(
"C", TRACING_EVENT, mozilla::Nothing(),
mozilla::Nothing(), profiler_get_backtrace()));
for (int i = 0; i < 10; i++) {
profiler_add_marker("M5", js::ProfilingStackFrame::Category::OTHER,
profiler_add_marker("M5", JS::ProfilingCategoryPair::OTHER,
MakeUnique<GTestMarkerPayload>(i));
}
@ -539,7 +538,7 @@ TEST(GeckoProfiler, Markers) {
ASSERT_TRUE(GTestMarkerPayload::sNumDestroyed == 10);
for (int i = 0; i < 10; i++) {
profiler_add_marker("M5", js::ProfilingStackFrame::Category::OTHER,
profiler_add_marker("M5", JS::ProfilingCategoryPair::OTHER,
MakeUnique<GTestMarkerPayload>(i));
}
@ -569,10 +568,10 @@ TEST(GeckoProfiler, DurationLimit) {
GTestMarkerPayload::sNumStreamed = 0;
GTestMarkerPayload::sNumDestroyed = 0;
profiler_add_marker("M1", js::ProfilingStackFrame::Category::OTHER,
profiler_add_marker("M1", JS::ProfilingCategoryPair::OTHER,
MakeUnique<GTestMarkerPayload>(1));
PR_Sleep(PR_MillisecondsToInterval(1100));
profiler_add_marker("M2", js::ProfilingStackFrame::Category::OTHER,
profiler_add_marker("M2", JS::ProfilingCategoryPair::OTHER,
MakeUnique<GTestMarkerPayload>(2));
PR_Sleep(PR_MillisecondsToInterval(500));
@ -785,10 +784,9 @@ TEST(GeckoProfiler, ProfilingStack) {
ASSERT_TRUE(profiler_get_backtrace());
}
AutoProfilerLabel label1("A", nullptr,
js::ProfilingStackFrame::Category::DOM);
AutoProfilerLabel label1("A", nullptr, JS::ProfilingCategoryPair::DOM);
AutoProfilerLabel label2("A", dynamic.get(),
js::ProfilingStackFrame::Category::NETWORK);
JS::ProfilingCategoryPair::NETWORK);
ASSERT_TRUE(profiler_get_backtrace());
profiler_stop();

Просмотреть файл

@ -798,13 +798,13 @@ void CycleCollectedJSRuntime::TraverseNativeRoots(
if (profiler_thread_is_being_profiled()) {
if (aProgress == JS::GC_CYCLE_END) {
profiler_add_marker(
"GCMajor", js::ProfilingStackFrame::Category::GCCC,
"GCMajor", JS::ProfilingCategoryPair::GCCC,
MakeUnique<GCMajorMarkerPayload>(aDesc.startTime(aContext),
aDesc.endTime(aContext),
aDesc.formatJSONProfiler(aContext)));
} else if (aProgress == JS::GC_SLICE_END) {
profiler_add_marker(
"GCSlice", js::ProfilingStackFrame::Category::GCCC,
"GCSlice", JS::ProfilingCategoryPair::GCCC,
MakeUnique<GCSliceMarkerPayload>(
aDesc.lastSliceStart(aContext), aDesc.lastSliceEnd(aContext),
aDesc.sliceToJSONProfiler(aContext)));
@ -885,7 +885,7 @@ class MinorGCMarker : public TimelineMarker {
#ifdef MOZ_GECKO_PROFILER
else if (aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_END &&
profiler_thread_is_being_profiled()) {
profiler_add_marker("GCMinor", js::ProfilingStackFrame::Category::GCCC,
profiler_add_marker("GCMinor", JS::ProfilingCategoryPair::GCCC,
MakeUnique<GCMinorMarkerPayload>(
self->mLatestNurseryCollectionStart,
TimeStamp::Now(), JS::MinorGcToJSON(aContext)));

Просмотреть файл

@ -412,7 +412,7 @@ class LogModuleManager {
#ifdef MOZ_GECKO_PROFILER
if (mAddProfilerMarker && profiler_is_active()) {
profiler_add_marker(
"LogMessages", js::ProfilingStackFrame::Category::OTHER,
"LogMessages", JS::ProfilingCategoryPair::OTHER,
MakeUnique<LogMarkerPayload>(aName, buffToWrite, TimeStamp::Now()));
}
#endif

Просмотреть файл

@ -1177,7 +1177,7 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult) {
profiler_add_marker(
(priority != EventQueuePriority::Idle) ? "LongTask"
: "LongIdleTask",
js::ProfilingStackFrame::Category::OTHER,
JS::ProfilingCategoryPair::OTHER,
MakeUnique<LongTaskMarkerPayload>(mCurrentEventStart, now));
}
#endif