зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central. a=merge
This commit is contained in:
Коммит
92ba19b150
|
@ -224,7 +224,7 @@ profiledbuild::
|
|||
$(MAKE) maybe_clobber_profiledbuild
|
||||
$(call BUILDSTATUS,TIER_FINISH pgo_clobber)
|
||||
$(call BUILDSTATUS,TIER_START pgo_profile_use)
|
||||
$(MAKE) default MOZ_PROFILE_USE=1
|
||||
$(MAKE) default MOZ_PROFILE_USE=1 $(if $(CLANG_CL),MOZ_PROFILE_ORDER_FILE=$(topobjdir)/cygprofile.txt)
|
||||
$(call BUILDSTATUS,TIER_FINISH pgo_profile_use)
|
||||
|
||||
# Change default target to PGO build if PGO is enabled.
|
||||
|
@ -309,9 +309,13 @@ else
|
|||
maybe_clobber_profiledbuild:
|
||||
endif
|
||||
else
|
||||
ifdef CLANG_CL
|
||||
maybe_clobber_profiledbuild: clean
|
||||
else
|
||||
maybe_clobber_profiledbuild:
|
||||
$(RM) $(DIST)/bin/*.pgc
|
||||
find $(DIST)/$(MOZ_APP_NAME) -name '*.pgc' -exec mv {} $(DIST)/bin \;
|
||||
endif # CLANG_CL
|
||||
endif
|
||||
|
||||
.PHONY: maybe_clobber_profiledbuild
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
<binding id="toolbar">
|
||||
<implementation>
|
||||
<field name="overflowedDuringConstruction">null</field>
|
||||
|
||||
<constructor><![CDATA[
|
||||
let scope = {};
|
||||
ChromeUtils.import("resource:///modules/CustomizableUI.jsm", scope);
|
||||
|
@ -67,10 +65,6 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<property name="toolbarName"
|
||||
onget="return this.getAttribute('toolbarname');"
|
||||
onset="this.setAttribute('toolbarname', val); return val;"/>
|
||||
|
||||
<property name="customizationTarget" readonly="true">
|
||||
<getter><![CDATA[
|
||||
if (this._customizationTarget)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
. "$topsrcdir/browser/config/mozconfigs/win32/debug"
|
||||
|
||||
export CC="cl.exe"
|
||||
export CXX="cl.exe"
|
||||
export LINKER="link.exe"
|
|
@ -0,0 +1,5 @@
|
|||
. "$topsrcdir/browser/config/mozconfigs/win32/nightly"
|
||||
|
||||
export CC="cl.exe"
|
||||
export CXX="cl.exe"
|
||||
export LINKER="link.exe"
|
|
@ -0,0 +1,5 @@
|
|||
. "$topsrcdir/browser/config/mozconfigs/win64/debug"
|
||||
|
||||
export CC="cl.exe"
|
||||
export CXX="cl.exe"
|
||||
export LINKER="link.exe"
|
|
@ -0,0 +1,5 @@
|
|||
. "$topsrcdir/browser/config/mozconfigs/win64/nightly"
|
||||
|
||||
export CC="cl.exe"
|
||||
export CXX="cl.exe"
|
||||
export LINKER="link.exe"
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"llvm_revision": "333414",
|
||||
"llvm_revision": "336407",
|
||||
"stages": "3",
|
||||
"build_libcxx": false,
|
||||
"build_type": "Release",
|
||||
|
|
|
@ -157,7 +157,7 @@ endif
|
|||
# Enable profile-based feedback
|
||||
ifneq (1,$(NO_PROFILE_GUIDED_OPTIMIZE))
|
||||
ifdef MOZ_PROFILE_GENERATE
|
||||
PGO_CFLAGS += $(if $(filter $(notdir $<),$(notdir $(NO_PROFILE_GUIDED_OPTIMIZE))),,$(PROFILE_GEN_CFLAGS))
|
||||
PGO_CFLAGS += $(if $(filter $(notdir $<),$(notdir $(NO_PROFILE_GUIDED_OPTIMIZE))),,$(PROFILE_GEN_CFLAGS) $(COMPUTED_PROFILE_GEN_DYN_CFLAGS))
|
||||
PGO_LDFLAGS += $(PROFILE_GEN_LDFLAGS)
|
||||
ifeq (WINNT,$(OS_ARCH))
|
||||
AR_FLAGS += -LTCG
|
||||
|
@ -422,14 +422,14 @@ OBJ_SUFFIX := $(_OBJ_SUFFIX)
|
|||
|
||||
OBJS_VAR_SUFFIX := OBJS
|
||||
|
||||
# PGO builds with GCC build objects with instrumentation in a first pass,
|
||||
# then objects optimized, without instrumentation, in a second pass. If
|
||||
# we overwrite the objects from the first pass with those from the second,
|
||||
# we end up not getting instrumentation data for better optimization on
|
||||
# incremental builds. As a consequence, we use a different object suffix
|
||||
# for the first pass.
|
||||
# PGO builds with GCC and clang-cl build objects with instrumentation in
|
||||
# a first pass, then objects optimized, without instrumentation, in a
|
||||
# second pass. If we overwrite the objects from the first pass with
|
||||
# those from the second, we end up not getting instrumentation data for
|
||||
# better optimization on incremental builds. As a consequence, we use a
|
||||
# different object suffix for the first pass.
|
||||
ifdef MOZ_PROFILE_GENERATE
|
||||
ifdef GNU_CC
|
||||
ifneq (,$(GNU_CC)$(CLANG_CL))
|
||||
OBJS_VAR_SUFFIX := PGO_OBJS
|
||||
ifndef NO_PROFILE_GUIDED_OPTIMIZE
|
||||
OBJ_SUFFIX := i_o
|
||||
|
|
|
@ -186,6 +186,10 @@ ifndef TARGETS
|
|||
TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(HOST_SHARED_LIBRARY)
|
||||
endif
|
||||
|
||||
ifdef MOZ_PROFILE_GENERATE
|
||||
CPPSRCS := $(CPPSRCS) $(PGO_GEN_ONLY_CPPSRCS)
|
||||
endif
|
||||
|
||||
COBJS = $(notdir $(CSRCS:.c=.$(OBJ_SUFFIX)))
|
||||
SOBJS = $(notdir $(SSRCS:.S=.$(OBJ_SUFFIX)))
|
||||
# CPPSRCS can have different extensions (eg: .cpp, .cc)
|
||||
|
|
|
@ -1041,7 +1041,7 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
|||
// Step 4.
|
||||
// "If target is relatedTarget and target is not event's
|
||||
// relatedTarget, then return true."
|
||||
aVisitor.IgnoreCurrentTarget();
|
||||
aVisitor.IgnoreCurrentTargetBecauseOfShadowDOMRetargeting();
|
||||
// Old code relies on mTarget to point to the first element which
|
||||
// was not added to the event target chain because of mCanHandle
|
||||
// being false, but in Shadow DOM case mTarget really should
|
||||
|
@ -1085,7 +1085,7 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
|||
// Step 11.5
|
||||
// "Otherwise, if parent and relatedTarget are identical, then set
|
||||
// parent to null."
|
||||
aVisitor.IgnoreCurrentTarget();
|
||||
aVisitor.IgnoreCurrentTargetBecauseOfShadowDOMRetargeting();
|
||||
// Old code relies on mTarget to point to the first element which
|
||||
// was not added to the event target chain because of mCanHandle
|
||||
// being false, but in Shadow DOM case mTarget really should
|
||||
|
|
|
@ -3277,6 +3277,8 @@ nsFocusManager::GetNextTabbableContentInScope(nsIContent* aOwner,
|
|||
if (iterContent->IsInNativeAnonymousSubtree() &&
|
||||
iterContent->GetPrimaryFrame()) {
|
||||
iterContent->GetPrimaryFrame()->IsFocusable(&tabIndex);
|
||||
} else if (IsHostOrSlot(iterContent)) {
|
||||
tabIndex = HostOrSlotTabIndexValue(iterContent);
|
||||
} else {
|
||||
iterContent->IsFocusable(&tabIndex);
|
||||
}
|
||||
|
@ -3416,7 +3418,11 @@ nsFocusManager::GetNextTabbableContentInAncestorScopes(
|
|||
MOZ_ASSERT(owner, "focus navigation scope owner not in document");
|
||||
|
||||
int32_t tabIndex = 0;
|
||||
startContent->IsFocusable(&tabIndex);
|
||||
if (IsHostOrSlot(startContent)) {
|
||||
tabIndex = HostOrSlotTabIndexValue(startContent);
|
||||
} else {
|
||||
startContent->IsFocusable(&tabIndex);
|
||||
}
|
||||
nsIContent* contentToFocus =
|
||||
GetNextTabbableContentInScope(owner, startContent, aOriginalStartContent,
|
||||
aForward, tabIndex, aIgnoreTabIndex,
|
||||
|
@ -3481,7 +3487,8 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
|||
// (i.e. aStartContent is already in shadow DOM),
|
||||
// search from scope including aStartContent
|
||||
nsIContent* rootElement = aRootContent->OwnerDoc()->GetRootElement();
|
||||
if (rootElement != FindOwner(aStartContent)) {
|
||||
nsIContent* owner = FindOwner(aStartContent);
|
||||
if (owner && rootElement != owner) {
|
||||
nsIContent* contentToFocus =
|
||||
GetNextTabbableContentInAncestorScopes(&aStartContent,
|
||||
aOriginalStartContent,
|
||||
|
|
|
@ -153,12 +153,80 @@
|
|||
opener.is(lastFocusTarget, shadowAnchor, "Should have focused anchor element in shadow DOM. (2)");
|
||||
synthesizeKey("KEY_Tab", {shiftKey: true});
|
||||
opener.is(lastFocusTarget, anchor, "Should have focused anchor element. (2)");
|
||||
|
||||
host.remove();
|
||||
input.remove();
|
||||
input2.remove();
|
||||
}
|
||||
|
||||
function testTabbingThroughNestedShadowDOM() {
|
||||
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (1)");
|
||||
|
||||
var host = document.createElement("div");
|
||||
host.id = "host";
|
||||
document.body.appendChild(host);
|
||||
|
||||
var sr0 = host.attachShadow({mode: "open"});
|
||||
sr0.innerHTML = "<button id='button'>X</button><br id='br'><div id='h1'></div><div id='h2'></div>";
|
||||
var button = sr0.getElementById("button");
|
||||
button.onfocus = focusLogger;
|
||||
|
||||
var h1 = sr0.getElementById("h1");
|
||||
var sr1 = h1.attachShadow({mode: "open"});
|
||||
sr1.innerHTML = "h1 <input id='h11' placeholder='click me and press tab'><input id='h12' placeholder='and then tab again'>";
|
||||
var input11 = sr1.getElementById("h11");
|
||||
input11.onfocus = focusLogger;
|
||||
var input12 = sr1.getElementById("h12");
|
||||
input12.onfocus = focusLogger;
|
||||
|
||||
var h2 = sr0.getElementById("h2");
|
||||
var sr2 = h2.attachShadow({mode: "open"});
|
||||
sr2.innerHTML = "h2 <input id='h21'><input id='h22'>";
|
||||
var input21 = sr2.getElementById("h21");
|
||||
input21.onfocus = focusLogger;
|
||||
var input22 = sr2.getElementById("h22");
|
||||
input22.onfocus = focusLogger;
|
||||
|
||||
document.body.offsetLeft;
|
||||
|
||||
synthesizeKey("KEY_Tab");
|
||||
opener.is(lastFocusTarget, button, "[nested shadow] Should have focused button element. (1)");
|
||||
|
||||
synthesizeKey("KEY_Tab");
|
||||
opener.is(lastFocusTarget, input11, "[nested shadow] Should have focused input element. (1)");
|
||||
|
||||
synthesizeKey("KEY_Tab");
|
||||
opener.is(lastFocusTarget, input12, "[nested shadow] Should have focused input element. (2)");
|
||||
|
||||
synthesizeKey("KEY_Tab");
|
||||
opener.is(lastFocusTarget, input21, "[nested shadow] Should have focused input element. (3)");
|
||||
|
||||
synthesizeKey("KEY_Tab");
|
||||
opener.is(lastFocusTarget, input22, "[nested shadow] Should have focused input element. (4)");
|
||||
|
||||
// Backwards
|
||||
synthesizeKey("KEY_Tab", {shiftKey: true});
|
||||
opener.is(lastFocusTarget, input21, "[nested shadow] Should have focused input element. (5)");
|
||||
|
||||
synthesizeKey("KEY_Tab", {shiftKey: true});
|
||||
opener.is(lastFocusTarget, input12, "[nested shadow] Should have focused input element. (6)");
|
||||
|
||||
synthesizeKey("KEY_Tab", {shiftKey: true});
|
||||
opener.is(lastFocusTarget, input11, "[nested shadow] Should have focused input element. (7)");
|
||||
|
||||
synthesizeKey("KEY_Tab", {shiftKey: true});
|
||||
opener.is(lastFocusTarget, button, "[nested shadow] Should have focused button element. (8)");
|
||||
|
||||
// Back to beginning, outside of Shadow DOM.
|
||||
synthesizeKey("KEY_Tab", {shiftKey: true});
|
||||
opener.is(document.activeElement, document.body.firstChild, "body's first child should have focus. (2)");
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
|
||||
testTabbingThroughShadowDOMWithTabIndexes();
|
||||
testTabbingThroughSimpleShadowDOM();
|
||||
testTabbingThroughNestedShadowDOM();
|
||||
|
||||
opener.didRunTests();
|
||||
window.close();
|
||||
|
|
|
@ -773,6 +773,10 @@ MayRetargetToChromeIfCanNotHandleEvent(
|
|||
EventTargetChainItem* chromeTargetEtci =
|
||||
EventTargetChainItemForChromeTarget(aChain, aContent, aChildEtci);
|
||||
if (chromeTargetEtci) {
|
||||
// If we propagate to chrome, need to ensure we mark
|
||||
// EventTargetChainItem to be chrome handler so that event.composedPath()
|
||||
// can return the right value.
|
||||
chromeTargetEtci->SetIsChromeHandler(true);
|
||||
chromeTargetEtci->GetEventTargetParent(aPreVisitor);
|
||||
return chromeTargetEtci;
|
||||
}
|
||||
|
@ -1061,6 +1065,7 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
|||
preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget;
|
||||
topEtci = parentEtci;
|
||||
} else {
|
||||
bool ignoreBecauseOfShadowDOM = preVisitor.mIgnoreBecauseOfShadowDOM;
|
||||
nsCOMPtr<nsINode> disabledTarget = do_QueryInterface(parentTarget);
|
||||
parentEtci = MayRetargetToChromeIfCanNotHandleEvent(chain,
|
||||
preVisitor,
|
||||
|
@ -1071,7 +1076,11 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
|||
preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget;
|
||||
EventTargetChainItem* item =
|
||||
EventTargetChainItem::GetFirstCanHandleEventTarget(chain);
|
||||
item->SetNewTarget(parentTarget);
|
||||
if (!ignoreBecauseOfShadowDOM) {
|
||||
// If we ignored the target because of Shadow DOM retargeting, we
|
||||
// shouldn't treat the target to be in the event path at all.
|
||||
item->SetNewTarget(parentTarget);
|
||||
}
|
||||
topEtci = parentEtci;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@ public:
|
|||
, mParentIsSlotInClosedTree(false)
|
||||
, mParentIsChromeHandler(false)
|
||||
, mRelatedTargetRetargetedInCurrentScope(false)
|
||||
, mIgnoreBecauseOfShadowDOM(false)
|
||||
, mParentTarget(nullptr)
|
||||
, mEventTargetAtParent(nullptr)
|
||||
, mRetargetedRelatedTarget(nullptr)
|
||||
|
@ -156,6 +157,7 @@ public:
|
|||
// Note, we don't clear mRelatedTargetRetargetedInCurrentScope explicitly,
|
||||
// since it is used during event path creation to indicate whether
|
||||
// relatedTarget may need to be retargeted.
|
||||
mIgnoreBecauseOfShadowDOM = false;
|
||||
mParentTarget = nullptr;
|
||||
mEventTargetAtParent = nullptr;
|
||||
mRetargetedRelatedTarget = nullptr;
|
||||
|
@ -175,9 +177,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void IgnoreCurrentTarget()
|
||||
void IgnoreCurrentTargetBecauseOfShadowDOMRetargeting()
|
||||
{
|
||||
mCanHandle = false;
|
||||
mIgnoreBecauseOfShadowDOM = true;
|
||||
SetParentTarget(nullptr, false);
|
||||
mEventTargetAtParent = nullptr;
|
||||
}
|
||||
|
@ -262,6 +265,12 @@ public:
|
|||
* event path creation crosses shadow boundary.
|
||||
*/
|
||||
bool mRelatedTargetRetargetedInCurrentScope;
|
||||
|
||||
/**
|
||||
* True if Shadow DOM relatedTarget retargeting causes the current item
|
||||
* to not show up in the event path.
|
||||
*/
|
||||
bool mIgnoreBecauseOfShadowDOM;
|
||||
private:
|
||||
/**
|
||||
* Parent item in the event target chain.
|
||||
|
|
|
@ -4,4 +4,4 @@ support-files =
|
|||
process_error.xul
|
||||
|
||||
[test_process_error.xul]
|
||||
skip-if = !crashreporter || (verify && debug && (os == 'linux' || os == 'mac'))
|
||||
skip-if = !crashreporter
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
Services.obs.addObserver(crashObserver, 'ipc:content-shutdown');
|
||||
|
||||
BrowserTestUtils.crashBrowser(document.getElementById('thebrowser'));
|
||||
BrowserTestUtils.crashBrowser(document.getElementById('thebrowser'), true, false);
|
||||
]]></script>
|
||||
|
||||
</window>
|
||||
|
|
|
@ -194,7 +194,8 @@ public:
|
|||
{
|
||||
MOZ_ASSERT(!mDriver->ThreadRunning());
|
||||
LOG(LogLevel::Debug,
|
||||
("Starting a new system driver for graph %p", mDriver->mGraphImpl));
|
||||
("Starting a new system driver for graph %p",
|
||||
mDriver->mGraphImpl.get()));
|
||||
|
||||
RefPtr<GraphDriver> previousDriver;
|
||||
{
|
||||
|
@ -232,7 +233,8 @@ void
|
|||
ThreadedDriver::Start()
|
||||
{
|
||||
MOZ_ASSERT(!ThreadRunning());
|
||||
LOG(LogLevel::Debug, ("Starting thread for a SystemClockDriver %p", mGraphImpl));
|
||||
LOG(LogLevel::Debug,
|
||||
("Starting thread for a SystemClockDriver %p", mGraphImpl.get()));
|
||||
Unused << NS_WARN_IF(mThread);
|
||||
MOZ_ASSERT(!mThread); // Ensure we haven't already started it
|
||||
|
||||
|
@ -803,7 +805,7 @@ AudioCallbackDriver::Revive()
|
|||
} else {
|
||||
LOG(LogLevel::Debug,
|
||||
("Starting audio threads for MediaStreamGraph %p from a new thread.",
|
||||
mGraphImpl));
|
||||
mGraphImpl.get()));
|
||||
RefPtr<AsyncCubebTask> initEvent =
|
||||
new AsyncCubebTask(this, AsyncCubebOperation::INIT);
|
||||
initEvent->Dispatch();
|
||||
|
|
|
@ -219,10 +219,8 @@ protected:
|
|||
// Time of the end of this graph iteration. This must be accessed while having
|
||||
// the monitor.
|
||||
GraphTime mIterationEnd;
|
||||
// The MediaStreamGraphImpl that owns this driver. This has a lifetime longer
|
||||
// than the driver, and will never be null. Hence, it can be accesed without
|
||||
// monitor.
|
||||
MediaStreamGraphImpl* mGraphImpl;
|
||||
// The MediaStreamGraphImpl associated with this driver.
|
||||
const RefPtr<MediaStreamGraphImpl> mGraphImpl;
|
||||
|
||||
// This is used on the main thread (during initialization), and the graph
|
||||
// thread. No monitor needed because we know the graph thread does not run
|
||||
|
|
|
@ -3665,7 +3665,8 @@ MediaStreamGraphImpl::Destroy()
|
|||
// First unregister from memory reporting.
|
||||
UnregisterWeakMemoryReporter(this);
|
||||
|
||||
// Clear the self reference which will destroy this instance.
|
||||
// Clear the self reference which will destroy this instance if all
|
||||
// associated GraphDrivers are destroyed.
|
||||
mSelfRef = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -328,10 +328,9 @@ public:
|
|||
mNormal = DefaultNormal();
|
||||
}
|
||||
|
||||
void TransformToScreenSpace(const Matrix4x4Typed<Units, Units>& aTransform)
|
||||
void TransformToScreenSpace(const Matrix4x4Typed<Units, Units>& aTransform,
|
||||
const Matrix4x4Typed<Units, Units>& aInverseTransform)
|
||||
{
|
||||
MOZ_ASSERT(!aTransform.IsSingular());
|
||||
|
||||
TransformPoints(aTransform, false);
|
||||
|
||||
// Perspective projection transformation might produce points with w <= 0,
|
||||
|
@ -339,7 +338,15 @@ public:
|
|||
mPoints = ClipPointsAtInfinity(mPoints);
|
||||
|
||||
// Normal vectors should be transformed using inverse transpose.
|
||||
mNormal = aTransform.Inverse().Transpose().TransformPoint(mNormal);
|
||||
mNormal = aInverseTransform.TransposeTransform4D(mNormal);
|
||||
}
|
||||
|
||||
|
||||
void TransformToScreenSpace(const Matrix4x4Typed<Units, Units>& aTransform)
|
||||
{
|
||||
MOZ_ASSERT(!aTransform.IsSingular());
|
||||
|
||||
TransformToScreenSpace(aTransform, aTransform.Inverse());
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -35,60 +35,69 @@ namespace gfx {
|
|||
template <class T, class Sub, class Rect>
|
||||
struct BaseRectAbsolute {
|
||||
protected:
|
||||
T x1, y1, x2, y2;
|
||||
T left, top, right, bottom;
|
||||
|
||||
public:
|
||||
BaseRectAbsolute() : x1(0), y1(0), x2(0), y2(0) {}
|
||||
BaseRectAbsolute(T aX1, T aY1, T aX2, T aY2) :
|
||||
x1(aX1), y1(aY1), x2(aX2), y2(aY2) {}
|
||||
BaseRectAbsolute() : left(0), top(0), right(0), bottom(0) {}
|
||||
BaseRectAbsolute(T aLeft, T aTop, T aRight, T aBottom) :
|
||||
left(aLeft), top(aTop), right(aRight), bottom(aBottom) {}
|
||||
|
||||
MOZ_ALWAYS_INLINE T X() const { return x1; }
|
||||
MOZ_ALWAYS_INLINE T Y() const { return y1; }
|
||||
MOZ_ALWAYS_INLINE T Width() const { return x2 - x1; }
|
||||
MOZ_ALWAYS_INLINE T Height() const { return y2 - y1; }
|
||||
MOZ_ALWAYS_INLINE T XMost() const { return x2; }
|
||||
MOZ_ALWAYS_INLINE T YMost() const { return y2; }
|
||||
MOZ_ALWAYS_INLINE T X() const { return left; }
|
||||
MOZ_ALWAYS_INLINE T Y() const { return top; }
|
||||
MOZ_ALWAYS_INLINE T Width() const { return right - left; }
|
||||
MOZ_ALWAYS_INLINE T Height() const { return bottom - top; }
|
||||
MOZ_ALWAYS_INLINE T XMost() const { return right; }
|
||||
MOZ_ALWAYS_INLINE T YMost() const { return bottom; }
|
||||
MOZ_ALWAYS_INLINE const T& Left() const { return left; }
|
||||
MOZ_ALWAYS_INLINE const T& Right() const { return right; }
|
||||
MOZ_ALWAYS_INLINE const T& Top() const { return top; }
|
||||
MOZ_ALWAYS_INLINE const T& Bottom() const { return bottom; }
|
||||
MOZ_ALWAYS_INLINE T& Left() { return left; }
|
||||
MOZ_ALWAYS_INLINE T& Right() { return right; }
|
||||
MOZ_ALWAYS_INLINE T& Top() { return top; }
|
||||
MOZ_ALWAYS_INLINE T& Bottom() { return bottom; }
|
||||
|
||||
MOZ_ALWAYS_INLINE void SetBox(T aX1, T aY1, T aX2, T aY2)
|
||||
MOZ_ALWAYS_INLINE void SetBox(T aLeft, T aTop, T aRight, T aBottom)
|
||||
{
|
||||
x1 = aX1; y1 = aY1; x2 = aX2; y2 = aY2;
|
||||
left = aLeft; top = aTop; right = aRight; bottom = aBottom;
|
||||
}
|
||||
void SetLeftEdge(T aX1)
|
||||
void SetLeftEdge(T aLeft)
|
||||
{
|
||||
x1 = aX1;
|
||||
left = aLeft;
|
||||
}
|
||||
void SetRightEdge(T aX2)
|
||||
void SetRightEdge(T aRight)
|
||||
{
|
||||
x2 = aX2;
|
||||
right = aRight;
|
||||
}
|
||||
void SetTopEdge(T aY1)
|
||||
void SetTopEdge(T aTop)
|
||||
{
|
||||
y1 = aY1;
|
||||
top = aTop;
|
||||
}
|
||||
void SetBottomEdge(T aY2)
|
||||
void SetBottomEdge(T aBottom)
|
||||
{
|
||||
y2 = aY2;
|
||||
bottom = aBottom;
|
||||
}
|
||||
|
||||
static Sub FromRect(const Rect& aRect)
|
||||
{
|
||||
MOZ_ASSERT(!aRect.Overflows());
|
||||
return Sub(aRect.x, aRect.y, aRect.XMost(), aRect.YMost());
|
||||
}
|
||||
|
||||
MOZ_MUST_USE Sub Intersect(const Sub& aOther) const
|
||||
{
|
||||
Sub result;
|
||||
result.x1 = std::max<T>(x1, aOther.x1);
|
||||
result.y1 = std::max<T>(y1, aOther.y1);
|
||||
result.x2 = std::min<T>(x2, aOther.x2);
|
||||
result.y2 = std::min<T>(y2, aOther.y2);
|
||||
result.left = std::max<T>(left, aOther.left);
|
||||
result.top = std::max<T>(top, aOther.top);
|
||||
result.right = std::min<T>(right, aOther.right);
|
||||
result.bottom = std::min<T>(bottom, aOther.bottom);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsEqualEdges(const Sub& aOther) const
|
||||
{
|
||||
return x1 == aOther.x1 && y1 == aOther.y1 &&
|
||||
x2 == aOther.x2 && y2 == aOther.y2;
|
||||
return left == aOther.left && top == aOther.top &&
|
||||
right == aOther.right && bottom == aOther.bottom;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -102,8 +111,8 @@ struct IntRectAbsoluteTyped :
|
|||
typedef IntParam<int32_t> ToInt;
|
||||
|
||||
IntRectAbsoluteTyped() : Super() {}
|
||||
IntRectAbsoluteTyped(ToInt aX1, ToInt aY1, ToInt aX2, ToInt aY2) :
|
||||
Super(aX1.value, aY1.value, aX2.value, aY2.value) {}
|
||||
IntRectAbsoluteTyped(ToInt aLeft, ToInt aTop, ToInt aRight, ToInt aBottom) :
|
||||
Super(aLeft.value, aTop.value, aRight.value, aBottom.value) {}
|
||||
};
|
||||
|
||||
template <class Units>
|
||||
|
@ -115,10 +124,12 @@ struct RectAbsoluteTyped :
|
|||
typedef BaseRectAbsolute<Float, RectAbsoluteTyped<Units>, RectTyped<Units>> Super;
|
||||
|
||||
RectAbsoluteTyped() : Super() {}
|
||||
RectAbsoluteTyped(Float aX1, Float aY1, Float aX2, Float aY2) :
|
||||
Super(aX1, aY1, aX2, aY2) {}
|
||||
RectAbsoluteTyped(Float aLeft, Float aTop, Float aRight, Float aBottom) :
|
||||
Super(aLeft, aTop, aRight, aBottom) {}
|
||||
};
|
||||
|
||||
typedef IntRectAbsoluteTyped<UnknownUnits> IntRectAbsolute;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ TransformLayerGeometry(Layer* aLayer, Maybe<gfx::Polygon>& aGeometry)
|
|||
transform = transform.ProjectTo2D();
|
||||
|
||||
if (!transform.IsSingular()) {
|
||||
aGeometry->TransformToScreenSpace(transform.Inverse());
|
||||
aGeometry->TransformToScreenSpace(transform.Inverse(), transform);
|
||||
} else {
|
||||
// Discard the geometry since the result might not be correct.
|
||||
aGeometry.reset();
|
||||
|
|
|
@ -418,8 +418,8 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey
|
|||
|
||||
RefPtr<DataSourceSurface> dSurf = SharedSurfacesParent::Acquire(aExtId);
|
||||
if (dSurf) {
|
||||
bool inserted = mSharedSurfaceIds.EnsureInserted(wr::AsUint64(aExtId));
|
||||
if (!inserted) {
|
||||
auto it = mSharedSurfaceIds.emplace(wr::AsUint64(aExtId));
|
||||
if (!it.second) {
|
||||
// We already have a mapping for this image, so decrement the ownership
|
||||
// counter just increased unnecessarily. This can happen when an image is
|
||||
// slow to decode and we need to invalidate it by updating its image key.
|
||||
|
@ -477,8 +477,8 @@ WebRenderBridgeParent::AddExternalImageForTexture(wr::ExternalImageId aExtId,
|
|||
if (wrTexture) {
|
||||
wrTexture->PushResourceUpdates(aResources, TextureHost::ADD_IMAGE, keys,
|
||||
wrTexture->GetExternalImageKey());
|
||||
MOZ_ASSERT(!mTextureHosts.Get(wr::AsUint64(aKey), nullptr));
|
||||
mTextureHosts.Put(wr::AsUint64(aKey), CompositableTextureHostRef(aTexture));
|
||||
MOZ_ASSERT(mTextureHosts.find(wr::AsUint64(aKey)) == mTextureHosts.end());
|
||||
mTextureHosts.emplace(wr::AsUint64(aKey), CompositableTextureHostRef(aTexture));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1043,7 +1043,7 @@ WebRenderBridgeParent::AddPipelineIdForCompositable(const wr::PipelineId& aPipel
|
|||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mAsyncCompositables.Get(wr::AsUint64(aPipelineId)).get());
|
||||
MOZ_ASSERT(mAsyncCompositables.find(wr::AsUint64(aPipelineId)) == mAsyncCompositables.end());
|
||||
|
||||
RefPtr<CompositableHost> host;
|
||||
if (aAsync) {
|
||||
|
@ -1071,7 +1071,7 @@ WebRenderBridgeParent::AddPipelineIdForCompositable(const wr::PipelineId& aPipel
|
|||
|
||||
wrHost->SetWrBridge(this);
|
||||
wrHost->EnableUseAsyncImagePipeline();
|
||||
mAsyncCompositables.Put(wr::AsUint64(aPipelineId), wrHost);
|
||||
mAsyncCompositables.emplace(wr::AsUint64(aPipelineId), wrHost);
|
||||
mAsyncImageManager->AddAsyncImagePipeline(aPipelineId, wrHost);
|
||||
|
||||
return;
|
||||
|
@ -1085,15 +1085,16 @@ WebRenderBridgeParent::RemovePipelineIdForCompositable(const wr::PipelineId& aPi
|
|||
return;
|
||||
}
|
||||
|
||||
WebRenderImageHost* wrHost = mAsyncCompositables.Get(wr::AsUint64(aPipelineId)).get();
|
||||
if (!wrHost) {
|
||||
auto it = mAsyncCompositables.find(wr::AsUint64(aPipelineId));
|
||||
if (it == mAsyncCompositables.end()) {
|
||||
return;
|
||||
}
|
||||
RefPtr<WebRenderImageHost>& wrHost = it->second;
|
||||
|
||||
wrHost->ClearWrBridge();
|
||||
mAsyncImageManager->RemoveAsyncImagePipeline(aPipelineId, aTxn);
|
||||
aTxn.RemovePipeline(aPipelineId);
|
||||
mAsyncCompositables.Remove(wr::AsUint64(aPipelineId));
|
||||
mAsyncCompositables.erase(wr::AsUint64(aPipelineId));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1105,7 +1106,8 @@ WebRenderBridgeParent::RemoveExternalImageId(const ExternalImageId& aImageId)
|
|||
}
|
||||
|
||||
uint64_t imageId = wr::AsUint64(aImageId);
|
||||
if (mSharedSurfaceIds.EnsureRemoved(imageId)) {
|
||||
if (mSharedSurfaceIds.find(imageId) != mSharedSurfaceIds.end()) {
|
||||
mSharedSurfaceIds.erase(imageId);
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, aImageId);
|
||||
}
|
||||
}
|
||||
|
@ -1121,13 +1123,14 @@ WebRenderBridgeParent::ReleaseTextureOfImage(const wr::ImageKey& aKey)
|
|||
CompositableTextureHostRef texture;
|
||||
WebRenderTextureHost* wrTexture = nullptr;
|
||||
|
||||
if (mTextureHosts.Get(id, &texture)) {
|
||||
wrTexture = texture->AsWebRenderTextureHost();
|
||||
auto it = mTextureHosts.find(id);
|
||||
if (it != mTextureHosts.end()) {
|
||||
wrTexture = (*it).second->AsWebRenderTextureHost();
|
||||
}
|
||||
if (wrTexture) {
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, wrTexture);
|
||||
}
|
||||
mTextureHosts.Remove(id);
|
||||
mTextureHosts.erase(id);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
|
@ -1654,26 +1657,26 @@ WebRenderBridgeParent::ClearResources()
|
|||
// Schedule generate frame to clean up Pipeline
|
||||
ScheduleGenerateFrame();
|
||||
// WrFontKeys and WrImageKeys are deleted during WebRenderAPI destruction.
|
||||
for (auto iter = mTextureHosts.Iter(); !iter.Done(); iter.Next()) {
|
||||
WebRenderTextureHost* wrTexture = iter.Data()->AsWebRenderTextureHost();
|
||||
for (const auto& entry : mTextureHosts) {
|
||||
WebRenderTextureHost* wrTexture = entry.second->AsWebRenderTextureHost();
|
||||
MOZ_ASSERT(wrTexture);
|
||||
if (wrTexture) {
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, wrEpoch, wrTexture);
|
||||
}
|
||||
}
|
||||
mTextureHosts.Clear();
|
||||
for (auto iter = mAsyncCompositables.Iter(); !iter.Done(); iter.Next()) {
|
||||
wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key());
|
||||
RefPtr<WebRenderImageHost> host = iter.Data();
|
||||
mTextureHosts.clear();
|
||||
for (const auto& entry : mAsyncCompositables) {
|
||||
wr::PipelineId pipelineId = wr::AsPipelineId(entry.first);
|
||||
RefPtr<WebRenderImageHost> host = entry.second;
|
||||
host->ClearWrBridge();
|
||||
mAsyncImageManager->RemoveAsyncImagePipeline(pipelineId, txn);
|
||||
}
|
||||
mAsyncCompositables.Clear();
|
||||
for (auto iter = mSharedSurfaceIds.Iter(); !iter.Done(); iter.Next()) {
|
||||
wr::ExternalImageId id = wr::ToExternalImageId(iter.Get()->GetKey());
|
||||
mAsyncCompositables.clear();
|
||||
for (const auto& entry : mSharedSurfaceIds) {
|
||||
wr::ExternalImageId id = wr::ToExternalImageId(entry);
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, id);
|
||||
}
|
||||
mSharedSurfaceIds.Clear();
|
||||
mSharedSurfaceIds.clear();
|
||||
|
||||
mAsyncImageManager->RemovePipeline(mPipelineId, wrEpoch);
|
||||
txn.RemovePipeline(mPipelineId);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef mozilla_layers_WebRenderBridgeParent_h
|
||||
#define mozilla_layers_WebRenderBridgeParent_h
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "CompositableHost.h" // for CompositableHost, ImageCompositeNotificationInfo
|
||||
|
@ -294,9 +295,9 @@ private:
|
|||
// mActiveAnimations is used to avoid leaking animations when WebRenderBridgeParent is
|
||||
// destroyed abnormally and Tab move between different windows.
|
||||
std::unordered_set<uint64_t> mActiveAnimations;
|
||||
nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mAsyncCompositables;
|
||||
nsDataHashtable<nsUint64HashKey, CompositableTextureHostRef> mTextureHosts;
|
||||
nsTHashtable<nsUint64HashKey> mSharedSurfaceIds;
|
||||
std::unordered_map<uint64_t, RefPtr<WebRenderImageHost>> mAsyncCompositables;
|
||||
std::unordered_map<uint64_t, CompositableTextureHostRef> mTextureHosts;
|
||||
std::unordered_set<uint64_t> mSharedSurfaceIds;
|
||||
|
||||
TimeDuration mVsyncRate;
|
||||
TimeStamp mPreviousFrameTimeStamp;
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<html>
|
||||
<style>
|
||||
:root{
|
||||
transform-style:preserve-3d;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
addEventListener("DOMContentLoaded", () => {
|
||||
let s = document.createElement("fieldset")
|
||||
document.getElementsByTagName("body")[0].appendChild(s)
|
||||
s.animate([{ "transform": "matrix3d(258,8,296,626,168,58,272,151,47,-0,90,-101,116,-119,65,182) translate3d(199ch,238in,47q)" }], 1000)
|
||||
})
|
||||
</script>
|
||||
<body></body>
|
||||
</html>
|
|
@ -164,3 +164,5 @@ load 1325159-1.html
|
|||
load 1331683.html
|
||||
skip-if(Android) pref(dom.disable_open_during_load,false) load 1343666.html
|
||||
load 1408078-1.html
|
||||
load 1467847-1.html
|
||||
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// Copied from Chromium's /src/tools/cygprofile_win/cygprofile.cc.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <windows.h> // Needs to be included before the others.
|
||||
|
||||
#include <dbghelp.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// The main purpose of the order file is to optimize startup time,
|
||||
// so capturing the first N function calls is enough.
|
||||
static constexpr int kSamplesCapacity = 25 * 1024 * 1024;
|
||||
|
||||
void* samples[kSamplesCapacity];
|
||||
std::atomic_int num_samples;
|
||||
std::atomic_int done;
|
||||
|
||||
|
||||
// Symbolize the samples and write them to disk.
|
||||
void dump(void*) {
|
||||
HMODULE dbghelp = LoadLibraryA("dbghelp.dll");
|
||||
auto sym_from_addr = reinterpret_cast<decltype(::SymFromAddr)*>(
|
||||
::GetProcAddress(dbghelp, "SymFromAddr"));
|
||||
auto sym_initialize = reinterpret_cast<decltype(::SymInitialize)*>(
|
||||
::GetProcAddress(dbghelp, "SymInitialize"));
|
||||
auto sym_set_options = reinterpret_cast<decltype(::SymSetOptions)*>(
|
||||
::GetProcAddress(dbghelp, "SymSetOptions"));
|
||||
|
||||
// Path to the dump file. %s will be substituted by objdir path.
|
||||
static const char kDumpFile[] = "%s/cygprofile.txt";
|
||||
|
||||
char filename[MAX_PATH];
|
||||
const char* objdir = ::getenv("MOZ_OBJDIR");
|
||||
|
||||
if (!objdir) {
|
||||
fprintf(stderr, "ERROR: cannot determine objdir\n");
|
||||
return;
|
||||
}
|
||||
|
||||
SprintfLiteral(filename, kDumpFile, objdir);
|
||||
|
||||
FILE* f = fopen(filename, "w");
|
||||
if (!f) {
|
||||
fprintf(stderr, "ERROR: Cannot open %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
sym_initialize(::GetCurrentProcess(), NULL, TRUE);
|
||||
sym_set_options(SYMOPT_DEFERRED_LOADS | SYMOPT_PUBLICS_ONLY);
|
||||
char sym_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
|
||||
|
||||
std::unordered_set<void*> seen;
|
||||
std::unordered_set<std::string> seen_names;
|
||||
|
||||
for (void* sample : samples) {
|
||||
// Only print the first call of a function.
|
||||
if (seen.count(sample))
|
||||
continue;
|
||||
seen.insert(sample);
|
||||
|
||||
SYMBOL_INFO* symbol = reinterpret_cast<SYMBOL_INFO*>(sym_buf);
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
symbol->MaxNameLen = MAX_SYM_NAME;
|
||||
DWORD64 offset = 0;
|
||||
|
||||
if (sym_from_addr(::GetCurrentProcess(), reinterpret_cast<DWORD64>(sample),
|
||||
&offset, symbol)) {
|
||||
const char* name = symbol->Name;
|
||||
if (name[0] == '_')
|
||||
name++;
|
||||
if (seen_names.count(name))
|
||||
continue;
|
||||
seen_names.insert(name);
|
||||
|
||||
fprintf(f, "%s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
MOZ_EXPORT void
|
||||
__cyg_profile_func_enter(void* this_fn, void* call_site_unused) {
|
||||
if (done)
|
||||
return;
|
||||
|
||||
// Get our index for the samples array atomically.
|
||||
int n = num_samples++;
|
||||
|
||||
if (n < kSamplesCapacity) {
|
||||
samples[n] = this_fn;
|
||||
|
||||
if (n + 1 == kSamplesCapacity) {
|
||||
// This is the final sample; start dumping the samples to a file (on a
|
||||
// separate thread so as not to disturb the main program).
|
||||
done = 1;
|
||||
_beginthread(dump, 0, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
__cyg_profile_func_exit(void* this_fn, void* call_site) {}
|
||||
|
||||
} // extern "C"
|
|
@ -31,6 +31,10 @@ if CONFIG['OS_TARGET'] == 'WINNT':
|
|||
'user32.dll',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_PGO'] and CONFIG['CC_TYPE'] == 'clang-cl':
|
||||
SOURCES += ['cygprofile.cpp']
|
||||
SOURCES['cygprofile.cpp'].pgo_generate_only = True
|
||||
|
||||
if CONFIG['CC_TYPE'] == "msvc":
|
||||
CFLAGS += ['-guard:cf']
|
||||
CXXFLAGS += ['-guard:cf']
|
||||
|
|
|
@ -209,18 +209,27 @@ class CommonBackend(BuildBackend):
|
|||
no_pgo_objs = []
|
||||
|
||||
seen_objs = set()
|
||||
seen_pgo_gen_only_objs = set()
|
||||
seen_libs = set()
|
||||
|
||||
def add_objs(lib):
|
||||
seen_pgo_gen_only_objs.update(lib.pgo_gen_only_objs)
|
||||
|
||||
for o in lib.objs:
|
||||
if o not in seen_objs:
|
||||
seen_objs.add(o)
|
||||
objs.append(o)
|
||||
# This is slightly odd, buf for consistency with the
|
||||
# recursivemake backend we don't replace OBJ_SUFFIX if any
|
||||
# object in a library has `no_pgo` set.
|
||||
if lib.no_pgo_objs or lib.no_pgo:
|
||||
no_pgo_objs.append(o)
|
||||
if o in seen_objs:
|
||||
continue
|
||||
|
||||
# The front end should keep pgo generate-only objects and
|
||||
# normal objects separate.
|
||||
assert o not in seen_pgo_gen_only_objs
|
||||
|
||||
seen_objs.add(o)
|
||||
objs.append(o)
|
||||
# This is slightly odd, but for consistency with the
|
||||
# recursivemake backend we don't replace OBJ_SUFFIX if any
|
||||
# object in a library has `no_pgo` set.
|
||||
if lib.no_pgo_objs or lib.no_pgo:
|
||||
no_pgo_objs.append(o)
|
||||
|
||||
def expand(lib, recurse_objs, system_libs):
|
||||
if isinstance(lib, StaticLibrary):
|
||||
|
@ -262,7 +271,8 @@ class CommonBackend(BuildBackend):
|
|||
seen_libs.add(lib)
|
||||
os_libs.append(lib)
|
||||
|
||||
return objs, no_pgo_objs, shared_libs, os_libs, static_libs
|
||||
return (objs, sorted(seen_pgo_gen_only_objs), no_pgo_objs, \
|
||||
shared_libs, os_libs, static_libs)
|
||||
|
||||
def _make_list_file(self, objdir, objs, name):
|
||||
if not objs:
|
||||
|
|
|
@ -59,6 +59,7 @@ from ..frontend.data import (
|
|||
ObjdirFiles,
|
||||
ObjdirPreprocessedFiles,
|
||||
PerSourceFlag,
|
||||
PgoGenerateOnlySources,
|
||||
Program,
|
||||
RustLibrary,
|
||||
HostSharedLibrary,
|
||||
|
@ -479,6 +480,10 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
f = mozpath.relpath(f, base)
|
||||
for var in variables:
|
||||
backend_file.write('%s += %s\n' % (var, f))
|
||||
elif isinstance(obj, PgoGenerateOnlySources):
|
||||
assert obj.canonical_suffix == '.cpp'
|
||||
for f in sorted(obj.files):
|
||||
backend_file.write('PGO_GEN_ONLY_CPPSRCS += %s\n' % f)
|
||||
elif isinstance(obj, (HostSources, HostGeneratedSources)):
|
||||
suffix_map = {
|
||||
'.c': 'HOST_CSRCS',
|
||||
|
@ -1299,7 +1304,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
build_target = self._build_target_for_obj(obj)
|
||||
self._compile_graph[build_target]
|
||||
|
||||
objs, no_pgo_objs, shared_libs, os_libs, static_libs = self._expand_libs(obj)
|
||||
objs, pgo_gen_objs, no_pgo_objs, shared_libs, os_libs, static_libs = self._expand_libs(obj)
|
||||
|
||||
if obj.KIND == 'target':
|
||||
obj_target = obj.name
|
||||
|
@ -1309,13 +1314,19 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
is_unit_test = isinstance(obj, BaseProgram) and obj.is_unit_test
|
||||
profile_gen_objs = []
|
||||
|
||||
if (self.environment.substs.get('MOZ_PGO') and
|
||||
self.environment.substs.get('GNU_CC')):
|
||||
doing_pgo = self.environment.substs.get('MOZ_PGO')
|
||||
obj_suffix_change_needed = (self.environment.substs.get('GNU_CC') or
|
||||
self.environment.substs.get('CLANG_CL'))
|
||||
if doing_pgo and obj_suffix_change_needed:
|
||||
# We use a different OBJ_SUFFIX for the profile generate phase on
|
||||
# linux. These get picked up via OBJS_VAR_SUFFIX in config.mk.
|
||||
# systems where the pgo generate phase requires instrumentation
|
||||
# that can only be removed by recompiling objects. These get
|
||||
# picked up via OBJS_VAR_SUFFIX in config.mk.
|
||||
if not is_unit_test and not isinstance(obj, SimpleProgram):
|
||||
profile_gen_objs = [o if o in no_pgo_objs else '%s.%s' %
|
||||
(mozpath.splitext(o)[0], 'i_o') for o in objs]
|
||||
profile_gen_objs += ['%s.%s' % (mozpath.splitext(o)[0], 'i_o')
|
||||
for o in pgo_gen_objs]
|
||||
|
||||
def write_obj_deps(target, objs_ref, pgo_objs_ref):
|
||||
if pgo_objs_ref:
|
||||
|
|
|
@ -361,7 +361,7 @@ class TupBackend(CommonBackend):
|
|||
['-o', shlib.lib_name]
|
||||
)
|
||||
|
||||
objs, _, shared_libs, os_libs, static_libs = self._expand_libs(shlib)
|
||||
objs, _, _, shared_libs, os_libs, static_libs = self._expand_libs(shlib)
|
||||
static_libs = self._lib_paths(backend_file.objdir, static_libs)
|
||||
shared_libs = self._lib_paths(backend_file.objdir, shared_libs)
|
||||
|
||||
|
@ -416,7 +416,7 @@ class TupBackend(CommonBackend):
|
|||
|
||||
def _gen_program(self, backend_file, prog):
|
||||
cc_or_cxx = 'CXX' if prog.cxx_link else 'CC'
|
||||
objs, _, shared_libs, os_libs, static_libs = self._expand_libs(prog)
|
||||
objs, _, _, shared_libs, os_libs, static_libs = self._expand_libs(prog)
|
||||
static_libs = self._lib_paths(backend_file.objdir, static_libs)
|
||||
shared_libs = self._lib_paths(backend_file.objdir, shared_libs)
|
||||
|
||||
|
@ -476,7 +476,7 @@ class TupBackend(CommonBackend):
|
|||
|
||||
|
||||
def _gen_host_program(self, backend_file, prog):
|
||||
_, _, _, extra_libs, _ = self._expand_libs(prog)
|
||||
_, _, _, _, extra_libs, _ = self._expand_libs(prog)
|
||||
objs = prog.objs
|
||||
|
||||
if isinstance(prog, HostSimpleProgram):
|
||||
|
@ -515,7 +515,7 @@ class TupBackend(CommonBackend):
|
|||
backend_file.environment.substs['AR_FLAGS'].replace('$@', '%o')
|
||||
]
|
||||
|
||||
objs, _, shared_libs, _, static_libs = self._expand_libs(backend_file.static_lib)
|
||||
objs, _, _, shared_libs, _, static_libs = self._expand_libs(backend_file.static_lib)
|
||||
static_libs = self._lib_paths(backend_file.objdir, static_libs)
|
||||
shared_libs = self._lib_paths(backend_file.objdir, shared_libs)
|
||||
|
||||
|
|
|
@ -451,6 +451,7 @@ class CompileFlags(BaseCompileFlags):
|
|||
('DSO_PIC', context.config.substs.get('DSO_PIC_CFLAGS'),
|
||||
('CXXFLAGS', 'CFLAGS')),
|
||||
('RTL', None, ('CXXFLAGS', 'CFLAGS')),
|
||||
('PROFILE_GEN_DYN_CFLAGS', None, ('PROFILE_GEN_DYN_CFLAGS',)),
|
||||
('OS_COMPILE_CFLAGS', context.config.substs.get('OS_COMPILE_CFLAGS'),
|
||||
('CFLAGS',)),
|
||||
('OS_COMPILE_CXXFLAGS', context.config.substs.get('OS_COMPILE_CXXFLAGS'),
|
||||
|
@ -1205,7 +1206,7 @@ SUBCONTEXTS = {cls.__name__: cls for cls in SUBCONTEXTS}
|
|||
# (storage_type, input_types, docs)
|
||||
|
||||
VARIABLES = {
|
||||
'SOURCES': (ContextDerivedTypedListWithItems(Path, StrictOrderingOnAppendListWithFlagsFactory({'no_pgo': bool, 'flags': List})), list,
|
||||
'SOURCES': (ContextDerivedTypedListWithItems(Path, StrictOrderingOnAppendListWithFlagsFactory({'no_pgo': bool, 'flags': List, 'pgo_generate_only': bool})), list,
|
||||
"""Source code files.
|
||||
|
||||
This variable contains a list of source code files to compile.
|
||||
|
|
|
@ -387,6 +387,7 @@ class Linkable(ContextDerived):
|
|||
'linked_libraries',
|
||||
'linked_system_libs',
|
||||
'no_pgo_sources',
|
||||
'pgo_gen_only_sources',
|
||||
'no_pgo',
|
||||
'sources',
|
||||
)
|
||||
|
@ -399,6 +400,7 @@ class Linkable(ContextDerived):
|
|||
self.lib_defines = Defines(context, {})
|
||||
self.sources = defaultdict(list)
|
||||
self.no_pgo_sources = []
|
||||
self.pgo_gen_only_sources = set()
|
||||
self.no_pgo = False
|
||||
|
||||
def link_library(self, obj):
|
||||
|
@ -457,6 +459,10 @@ class Linkable(ContextDerived):
|
|||
def objs(self):
|
||||
return self._get_objs(self.source_files())
|
||||
|
||||
@property
|
||||
def pgo_gen_only_objs(self):
|
||||
return self._get_objs(self.pgo_gen_only_sources)
|
||||
|
||||
|
||||
class BaseProgram(Linkable):
|
||||
"""Context derived container object for programs, which is a unicode
|
||||
|
@ -951,6 +957,15 @@ class Sources(BaseSources):
|
|||
BaseSources.__init__(self, context, files, canonical_suffix)
|
||||
|
||||
|
||||
class PgoGenerateOnlySources(BaseSources):
|
||||
"""Represents files to be compiled during the build.
|
||||
|
||||
These files are only used during the PGO generation phase."""
|
||||
|
||||
def __init__(self, context, files):
|
||||
BaseSources.__init__(self, context, files, '.cpp')
|
||||
|
||||
|
||||
class GeneratedSources(BaseSources):
|
||||
"""Represents generated files to be compiled during the build."""
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ from .data import (
|
|||
ObjdirFiles,
|
||||
ObjdirPreprocessedFiles,
|
||||
PerSourceFlag,
|
||||
PgoGenerateOnlySources,
|
||||
WebIDLCollection,
|
||||
Program,
|
||||
RustLibrary,
|
||||
|
@ -842,6 +843,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
|
||||
sources = defaultdict(list)
|
||||
gen_sources = defaultdict(list)
|
||||
pgo_generate_only = set()
|
||||
all_flags = {}
|
||||
for symbol in ('SOURCES', 'HOST_SOURCES', 'UNIFIED_SOURCES'):
|
||||
srcs = sources[symbol]
|
||||
|
@ -858,6 +860,19 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
flags = context_srcs[f]
|
||||
if flags:
|
||||
all_flags[full_path] = flags
|
||||
# Files for the generation phase of PGO are unusual, so
|
||||
# it's not unreasonable to require them to be special.
|
||||
if flags.pgo_generate_only:
|
||||
if not isinstance(f, Path):
|
||||
raise SandboxValidationError('pgo_generate_only file'
|
||||
'must not be a generated file: %s' % f, context)
|
||||
if mozpath.splitext(f)[1] != '.cpp':
|
||||
raise SandboxValidationError('pgo_generate_only file'
|
||||
'must be a .cpp file: %s' % f, context)
|
||||
if flags.no_pgo:
|
||||
raise SandboxValidationError('pgo_generate_only files'
|
||||
'cannot be marked no_pgo: %s' % f, context)
|
||||
pgo_generate_only.add(f)
|
||||
|
||||
if isinstance(f, SourcePath) and not os.path.exists(full_path):
|
||||
raise SandboxValidationError('File listed in %s does not '
|
||||
|
@ -870,6 +885,8 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
no_pgo = context.get('NO_PGO')
|
||||
no_pgo_sources = [f for f, flags in all_flags.iteritems()
|
||||
if flags.no_pgo]
|
||||
pgo_gen_only_sources = set(f for f, flags in all_flags.iteritems()
|
||||
if flags.pgo_generate_only)
|
||||
if no_pgo:
|
||||
if no_pgo_sources:
|
||||
raise SandboxValidationError('NO_PGO and SOURCES[...].no_pgo '
|
||||
|
@ -932,6 +949,8 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
|
||||
for srcs, cls in ((sources[variable], klass),
|
||||
(gen_sources[variable], gen_klass)):
|
||||
if variable == 'SOURCES' and pgo_gen_only_sources:
|
||||
srcs = [s for s in srcs if s not in pgo_gen_only_sources]
|
||||
# Now sort the files to let groupby work.
|
||||
sorted_files = sorted(srcs, key=canonical_suffix_for_file)
|
||||
for canonical_suffix, files in itertools.groupby(
|
||||
|
@ -955,6 +974,8 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
for target_var in ('SOURCES', 'UNIFIED_SOURCES'):
|
||||
for suffix, srcs in ctxt_sources[target_var].items():
|
||||
linkable.sources[suffix] += srcs
|
||||
if pgo_gen_only_sources:
|
||||
linkable.pgo_gen_only_sources = pgo_gen_only_sources
|
||||
if no_pgo_sources:
|
||||
linkable.no_pgo_sources = no_pgo_sources
|
||||
elif no_pgo:
|
||||
|
@ -968,6 +989,9 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
ext = mozpath.splitext(f)[1]
|
||||
yield PerSourceFlag(context, f, flags.flags)
|
||||
|
||||
if pgo_generate_only:
|
||||
yield PgoGenerateOnlySources(context, pgo_generate_only)
|
||||
|
||||
# If there are any C++ sources, set all the linkables defined here
|
||||
# to require the C++ linker.
|
||||
for vars, linkable_items in ((('SOURCES', 'UNIFIED_SOURCES'), linkables),
|
||||
|
@ -1074,6 +1098,18 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
not context.config.substs.get('MOZ_NO_DEBUG_RTL')):
|
||||
rtl_flag += 'd'
|
||||
computed_flags.resolve_flags('RTL', [rtl_flag])
|
||||
# For PGO clang-cl builds, we generate order files in the
|
||||
# profile generate phase that are subsequently used to link the
|
||||
# final library. We need to provide flags to the compiler to
|
||||
# have it instrument functions for generating the data for the
|
||||
# order file. We'd normally put flags like these in
|
||||
# PROFILE_GEN_CFLAGS or the like, but we need to only use the
|
||||
# flags in contexts where we're compiling code for xul.
|
||||
code_for_xul = context.get('FINAL_LIBRARY', 'notxul') == 'xul'
|
||||
if context.config.substs.get('CLANG_CL') and code_for_xul:
|
||||
computed_flags.resolve_flags('PROFILE_GEN_DYN_CFLAGS',
|
||||
['-Xclang',
|
||||
'-finstrument-functions-after-inlining'])
|
||||
if not context.config.substs.get('CROSS_COMPILE'):
|
||||
computed_host_flags.resolve_flags('RTL', [rtl_flag])
|
||||
|
||||
|
|
|
@ -765,6 +765,134 @@ win32-mingw32/opt:
|
|||
- linux64-mingw32-nsis
|
||||
- linux64-mingw32-fxc2
|
||||
|
||||
win32-msvc/debug:
|
||||
description: "Win32 MSVC Debug"
|
||||
index:
|
||||
product: firefox
|
||||
job-name: win32-msvc-debug
|
||||
treeherder:
|
||||
platform: windows2012-32/debug
|
||||
symbol: Bmsvc
|
||||
tier: 2
|
||||
worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
|
||||
worker:
|
||||
max-run-time: 7200
|
||||
env:
|
||||
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/releng.manifest"
|
||||
PERFHERDER_EXTRA_OPTIONS: msvc
|
||||
run:
|
||||
using: mozharness
|
||||
options: [append-env-variables-from-configs]
|
||||
script: mozharness/scripts/fx_desktop_build.py
|
||||
config:
|
||||
- builds/releng_base_firefox.py
|
||||
- builds/taskcluster_base_windows.py
|
||||
- builds/taskcluster_base_win32.py
|
||||
- builds/taskcluster_sub_win32/debug.py
|
||||
extra-config:
|
||||
mozconfig_variant: 'debug-msvc'
|
||||
run-on-projects: ['mozilla-central']
|
||||
toolchains:
|
||||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-sccache
|
||||
|
||||
win32-msvc/opt:
|
||||
description: "Win32 MSVC Opt"
|
||||
index:
|
||||
product: firefox
|
||||
job-name: win32-msvc-opt
|
||||
treeherder:
|
||||
platform: windows2012-32/opt
|
||||
symbol: Bmsvc
|
||||
tier: 2
|
||||
worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
|
||||
worker:
|
||||
max-run-time: 7200
|
||||
env:
|
||||
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win32/releng.manifest"
|
||||
PERFHERDER_EXTRA_OPTIONS: msvc
|
||||
run:
|
||||
using: mozharness
|
||||
options: [append-env-variables-from-configs]
|
||||
script: mozharness/scripts/fx_desktop_build.py
|
||||
config:
|
||||
- builds/releng_base_firefox.py
|
||||
- builds/taskcluster_base_windows.py
|
||||
- builds/taskcluster_base_win32.py
|
||||
- builds/taskcluster_sub_win32/opt.py
|
||||
extra-config:
|
||||
mozconfig_variant: 'opt-msvc'
|
||||
run-on-projects: ['mozilla-central']
|
||||
toolchains:
|
||||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-sccache
|
||||
|
||||
win64-msvc/debug:
|
||||
description: "Win64 MSVC Debug"
|
||||
index:
|
||||
product: firefox
|
||||
job-name: win64-msvc-debug
|
||||
treeherder:
|
||||
platform: windows2012-64/debug
|
||||
symbol: Bmsvc
|
||||
tier: 2
|
||||
worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
|
||||
worker:
|
||||
max-run-time: 7200
|
||||
env:
|
||||
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
|
||||
PERFHERDER_EXTRA_OPTIONS: msvc
|
||||
run:
|
||||
using: mozharness
|
||||
options: [append-env-variables-from-configs]
|
||||
script: mozharness/scripts/fx_desktop_build.py
|
||||
config:
|
||||
- builds/releng_base_firefox.py
|
||||
- builds/taskcluster_base_windows.py
|
||||
- builds/taskcluster_base_win64.py
|
||||
- builds/taskcluster_sub_win64/debug.py
|
||||
extra-config:
|
||||
mozconfig_variant: 'debug-msvc'
|
||||
run-on-projects: ['mozilla-central']
|
||||
toolchains:
|
||||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-sccache
|
||||
|
||||
win64-msvc/opt:
|
||||
description: "Win64 MSVC Opt"
|
||||
index:
|
||||
product: firefox
|
||||
job-name: win64-msvc-opt
|
||||
treeherder:
|
||||
platform: windows2012-64/opt
|
||||
symbol: Bmsvc
|
||||
tier: 2
|
||||
worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
|
||||
worker:
|
||||
max-run-time: 7200
|
||||
env:
|
||||
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
|
||||
PERFHERDER_EXTRA_OPTIONS: msvc
|
||||
run:
|
||||
using: mozharness
|
||||
options: [append-env-variables-from-configs]
|
||||
script: mozharness/scripts/fx_desktop_build.py
|
||||
config:
|
||||
- builds/releng_base_firefox.py
|
||||
- builds/taskcluster_base_windows.py
|
||||
- builds/taskcluster_base_win64.py
|
||||
- builds/taskcluster_sub_win64/opt.py
|
||||
extra-config:
|
||||
mozconfig_variant: 'opt-msvc'
|
||||
run-on-projects: ['mozilla-central']
|
||||
toolchains:
|
||||
- win64-clang-cl
|
||||
- win64-rust
|
||||
- win64-sccache
|
||||
|
||||
win32-mingw32/debug:
|
||||
description: "Win32 MinGW Debug"
|
||||
index:
|
||||
|
|
|
@ -127,6 +127,12 @@ windows7-32/debug:
|
|||
- windows-reftest-gpu
|
||||
- windows-tests
|
||||
|
||||
windows7-32-msvc/debug:
|
||||
build-platform: win32-msvc/debug
|
||||
test-sets:
|
||||
- windows-reftest-gpu
|
||||
- windows-tests
|
||||
|
||||
windows7-32/opt:
|
||||
build-platform: win32/opt
|
||||
test-sets:
|
||||
|
@ -162,6 +168,15 @@ windows7-32-devedition/opt:
|
|||
- windows-reftest-gpu
|
||||
- windows-tests
|
||||
|
||||
windows7-32-msvc/opt:
|
||||
build-platform: win32-msvc/opt
|
||||
test-sets:
|
||||
- awsy
|
||||
- desktop-screenshot-capture
|
||||
- windows-reftest-gpu
|
||||
- windows-talos
|
||||
- windows-tests
|
||||
|
||||
# win64
|
||||
windows10-64-ccov/debug:
|
||||
build-platform: win64-ccov/debug
|
||||
|
@ -178,6 +193,12 @@ windows10-64/debug:
|
|||
- windows-tests
|
||||
- mochitest-headless
|
||||
|
||||
windows10-64-msvc/debug:
|
||||
build-platform: win64-msvc/debug
|
||||
test-sets:
|
||||
- windows-tests
|
||||
- mochitest-headless
|
||||
|
||||
windows10-64/opt:
|
||||
build-platform: win64/opt
|
||||
test-sets:
|
||||
|
@ -217,6 +238,15 @@ windows10-64-asan/opt:
|
|||
test-sets:
|
||||
- common-tests
|
||||
|
||||
windows10-64-msvc/opt:
|
||||
build-platform: win64-msvc/opt
|
||||
test-sets:
|
||||
- awsy
|
||||
- desktop-screenshot-capture
|
||||
- windows-talos
|
||||
- windows-tests
|
||||
- mochitest-headless
|
||||
|
||||
# QR builds just run a subset right now.
|
||||
windows10-64-qr/debug:
|
||||
build-platform: win64/debug
|
||||
|
|
|
@ -10,7 +10,9 @@ from taskgraph.loader.single_dep import loader as base_loader
|
|||
# patch because it required some heavy changes in single_dep.
|
||||
NON_NIGHTLY_LABELS_WHICH_SHOULD_SIGN_BUILDS = (
|
||||
'build-win32/debug', 'build-win32/opt', 'build-win32/pgo',
|
||||
'build-win32-msvc/debug', 'build-win32-msvc/opt',
|
||||
'build-win64/debug', 'build-win64/opt', 'build-win64/pgo',
|
||||
'build-win64-msvc/debug', 'build-win64-msvc/opt',
|
||||
'build-win32-devedition/opt', 'build-win64-devedition/opt',
|
||||
'build-win64-ccov/debug',
|
||||
'build-linux/opt', 'build-linux64/opt', 'build-macosx64/opt',
|
||||
|
|
|
@ -110,7 +110,6 @@ def make_task_description(config, jobs):
|
|||
treeherder = None
|
||||
if 'partner' not in config.kind and 'eme-free' not in config.kind:
|
||||
treeherder = job.get('treeherder', {})
|
||||
treeherder.setdefault('symbol', _generate_treeherder_symbol(is_nightly, config.kind))
|
||||
|
||||
dep_th_platform = dep_job.task.get('extra', {}).get(
|
||||
'treeherder', {}).get('machine', {}).get('platform', '')
|
||||
|
@ -119,8 +118,16 @@ def make_task_description(config, jobs):
|
|||
treeherder.setdefault('platform', _generate_treeherder_platform(
|
||||
dep_th_platform, build_platform, build_type
|
||||
))
|
||||
treeherder.setdefault('symbol', _generate_treeherder_symbol(
|
||||
is_nightly, build_platform
|
||||
))
|
||||
|
||||
treeherder.setdefault('tier', 1 if '-ccov' not in build_platform else 2)
|
||||
# ccov and msvc builds are tier 2, so they cannot have tier 1 tasks
|
||||
# depending on them.
|
||||
if '-ccov' in build_platform or '-msvc' in build_platform:
|
||||
treeherder.setdefault('tier', 2)
|
||||
else:
|
||||
treeherder.setdefault('tier', 1)
|
||||
treeherder.setdefault('kind', 'build')
|
||||
|
||||
label = job['label']
|
||||
|
@ -178,8 +185,8 @@ def _generate_treeherder_platform(dep_th_platform, build_platform, build_type):
|
|||
return '{}/{}'.format(dep_th_platform, actual_build_type)
|
||||
|
||||
|
||||
def _generate_treeherder_symbol(is_nightly, kind):
|
||||
if is_nightly:
|
||||
return 'Ns'
|
||||
else:
|
||||
return 'Bs'
|
||||
def _generate_treeherder_symbol(is_nightly, build_platform):
|
||||
symbol = 'Ns' if is_nightly else 'Bs'
|
||||
if '-msvc' in build_platform:
|
||||
symbol += '-msvc'
|
||||
return symbol
|
||||
|
|
|
@ -72,6 +72,11 @@ WINDOWS_WORKER_TYPES = {
|
|||
'virtual-with-gpu': 'aws-provisioner-v1/gecko-t-win7-32-gpu',
|
||||
'hardware': 'releng-hardware/gecko-t-win10-64-hw',
|
||||
},
|
||||
'windows7-32-msvc': {
|
||||
'virtual': 'aws-provisioner-v1/gecko-t-win7-32',
|
||||
'virtual-with-gpu': 'aws-provisioner-v1/gecko-t-win7-32-gpu',
|
||||
'hardware': 'releng-hardware/gecko-t-win10-64-hw',
|
||||
},
|
||||
'windows10-64': {
|
||||
'virtual': 'aws-provisioner-v1/gecko-t-win10-64',
|
||||
'virtual-with-gpu': 'aws-provisioner-v1/gecko-t-win10-64-gpu',
|
||||
|
@ -102,6 +107,11 @@ WINDOWS_WORKER_TYPES = {
|
|||
'virtual-with-gpu': 'aws-provisioner-v1/gecko-t-win10-64-gpu',
|
||||
'hardware': 'releng-hardware/gecko-t-win10-64-hw',
|
||||
},
|
||||
'windows10-64-msvc': {
|
||||
'virtual': 'aws-provisioner-v1/gecko-t-win10-64',
|
||||
'virtual-with-gpu': 'aws-provisioner-v1/gecko-t-win10-64-gpu',
|
||||
'hardware': 'releng-hardware/gecko-t-win10-64-hw',
|
||||
},
|
||||
'windows10-64-qr': {
|
||||
'virtual': 'aws-provisioner-v1/gecko-t-win10-64',
|
||||
'virtual-with-gpu': 'aws-provisioner-v1/gecko-t-win10-64-gpu',
|
||||
|
|
|
@ -32,6 +32,14 @@ PERF_SUITES = [
|
|||
{ 'name': "Images", 'node': "explicit/images/" }
|
||||
]
|
||||
|
||||
def median(values):
|
||||
sorted_ = sorted(values)
|
||||
med = int(len(sorted_) / 2)
|
||||
|
||||
if len(sorted_) % 2:
|
||||
return sorted_[med]
|
||||
return (sorted_[med - 1] + sorted_[med]) / 2
|
||||
|
||||
def update_checkpoint_paths(checkpoint_files, checkpoints):
|
||||
"""
|
||||
Updates checkpoints with memory report file fetched in data_path
|
||||
|
@ -85,15 +93,15 @@ def create_suite(name, node, data_path, checkpoints=CHECKPOINTS):
|
|||
memory_report_path = os.path.join(data_path, checkpoint['path'])
|
||||
|
||||
name_filter = checkpoint.get('name_filter', None)
|
||||
count = checkpoint.get('count', 0)
|
||||
if checkpoint.get('median'):
|
||||
process = median
|
||||
else:
|
||||
process = sum
|
||||
|
||||
if node != "resident":
|
||||
totals = parse_about_memory.calculate_memory_report_values(
|
||||
memory_report_path, node, name_filter)
|
||||
if count:
|
||||
value = sum(totals.values()[:count])
|
||||
else:
|
||||
value = sum(totals.values())
|
||||
value = process(totals.values())
|
||||
else:
|
||||
# For "resident" we really want RSS of the chrome ("Main") process
|
||||
# and USS of the child processes. We'll still call it resident
|
||||
|
|
|
@ -17,7 +17,7 @@ CHECKPOINTS = [
|
|||
'name': "After tabs open [+30s, forced GC]",
|
||||
'path': "memory-report-TabsOpenForceGC-4.json.gz",
|
||||
'name_filter': 'Web Content', # We only want the content process
|
||||
'count': 1 # We only care about the first one
|
||||
'median': True, # We want the median from all content processes
|
||||
},
|
||||
]
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
[test-003.html]
|
||||
[A_05_05_03_T01]
|
||||
expected: FAIL
|
||||
prefs: [dom.webcomponents.shadowdom.enabled:true]
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ A_05_05_03_T01.step(unit(function (ctx) {
|
|||
s.appendChild(input2);
|
||||
|
||||
input1.addEventListener('focusin', A_05_05_03_T01.step_func(function(event) {
|
||||
assert_equals(event.composed, true);
|
||||
assert_equals(event.composedPath().length, 7);
|
||||
assert_equals(event.composedPath()[0].id, 'input1');
|
||||
assert_equals(event.composedPath()[1].id, 'shadow');
|
||||
|
@ -55,6 +56,10 @@ A_05_05_03_T01.step(unit(function (ctx) {
|
|||
assert_equals(event.composedPath()[6], ctx.iframes[0].contentWindow);
|
||||
}), false);
|
||||
|
||||
input1.addEventListener('focusout', A_05_05_03_T01.step_func(function(event) {
|
||||
assert_equals(event.composed, true);
|
||||
}), false);
|
||||
|
||||
input2.addEventListener('focusin', A_05_05_03_T01.step_func(function(event) {
|
||||
assert_equals(event.composedPath().length, 2);
|
||||
assert_equals(event.composedPath()[0].id, 'input2');
|
||||
|
|
|
@ -9,3 +9,9 @@ include $(topsrcdir)/config/config.mk
|
|||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DUMP_SYMBOLS_FLAGS = --count-ctors
|
||||
|
||||
ifdef CLANG_CL
|
||||
ifdef MOZ_PROFILE_ORDER_FILE
|
||||
PGO_LDFLAGS += -ORDER:@$(MOZ_PROFILE_ORDER_FILE)
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -932,7 +932,8 @@ public:
|
|||
mFlags.mComposed = mMessage == eEditorInput;
|
||||
break;
|
||||
case eFocusEventClass:
|
||||
mFlags.mComposed = mMessage == eBlur || mMessage == eFocus;
|
||||
mFlags.mComposed = mMessage == eBlur || mMessage == eFocus ||
|
||||
mMessage == eFocusOut || mMessage == eFocusIn;
|
||||
break;
|
||||
case eKeyboardEventClass:
|
||||
mFlags.mComposed = mMessage == eKeyDown || mMessage == eKeyUp ||
|
||||
|
|
Загрузка…
Ссылка в новой задаче