diff --git a/browser/base/content/urlbarBindings.xml b/browser/base/content/urlbarBindings.xml --- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -668,20 +668,20 @@ if (selectedOneOff && !selectedOneOff.engine) { selectedOneOff.doCommand(); return; } - BrowserUsageTelemetry.recordUrlbarSelectedResultMethod( - event, this.userSelectionBehavior); - let where = openUILinkWhere || this._whereToOpen(event); let url = this.value; if (!url) { return; } + BrowserUsageTelemetry.recordUrlbarSelectedResultMethod( + event, this.userSelectionBehavior); + let mayInheritPrincipal = false; let postData = null; let browser = gBrowser.selectedBrowser; let action = this._parseActionUrl(url); diff --git a/browser/components/customizableui/content/panelUI.js b/browser/components/customizableui/content/panelUI.js --- a/browser/components/customizableui/content/panelUI.js +++ b/browser/components/customizableui/content/panelUI.js @@ -698,11 +698,16 @@ notifications.filter(n => !n.dismissed && !n.options.badgeOnly); if (this.panel.state == "showing" || this.panel.state == "open") { // If the menu is already showing, then we need to dismiss all notifications // since we don't want their doorhangers competing for attention - doorhangers.forEach(n => { n.dismissed = true; }); + doorhangers.forEach(n => { + n.dismissed = true; + if (n.options.onDismissed) { + n.options.onDismissed(); + } + }); this._hidePopup(); this._clearBadge(); if (!notifications[0].options.badgeOnly) { this._showBannerItem(notifications[0]); } diff --git a/browser/modules/ExtensionsUI.jsm b/browser/modules/ExtensionsUI.jsm --- a/browser/modules/ExtensionsUI.jsm +++ b/browser/modules/ExtensionsUI.jsm @@ -421,11 +421,14 @@ "chrome://browser/skin/addons/addon-install-installed.svg"; let options = { name: addon.name, message, popupIconURL: icon, - onDismissed: resolve, + onDismissed: () => { + AppMenuNotifications.removeNotification("addon-installed"); + resolve(); + }, }; AppMenuNotifications.showNotification("addon-installed", action, null, options); }); }, diff --git a/dom/locales/en-US/chrome/dom/dom.properties b/dom/locales/en-US/chrome/dom/dom.properties --- a/dom/locales/en-US/chrome/dom/dom.properties +++ b/dom/locales/en-US/chrome/dom/dom.properties @@ -322,14 +322,10 @@ GeolocationInsecureRequestIsForbidden=A Geolocation request can only be fulfilled in a secure context. # LOCALIZATION NOTE: Do not translate "Large-Allocation", as it is a literal header name. LargeAllocationNonWin32=This page would be loaded in a new process due to a Large-Allocation header, however Large-Allocation process creation is disabled on non-Win32 platforms. # LOCALIZATION NOTE: Do not translate URL.createObjectURL(MediaStream). URLCreateObjectURL_MediaStreamWarning=URL.createObjectURL(MediaStream) is deprecated and will be removed soon. -# LOCALIZATION NOTE: Do not translate MozAutoGainControl or autoGainControl. -MozAutoGainControlWarning=mozAutoGainControl is deprecated. Use autoGainControl instead. -# LOCALIZATION NOTE: Do not translate mozNoiseSuppression or noiseSuppression. -MozNoiseSuppressionWarning=mozNoiseSuppression is deprecated. Use noiseSuppression instead. # LOCALIZATION NOTE: Do not translate xml:base. XMLBaseAttributeWarning=Use of xml:base attribute is deprecated and will be removed soon. Please remove any use of it. # LOCALIZATION NOTE: Do not translate "content", "Window", and "window.top" WindowContentUntrustedWarning=The ‘content’ attribute of Window objects is deprecated. Please use ‘window.top’ instead. # LOCALIZATION NOTE: The first %S is the tag name of the element that starts the loop, the second %S is the element's ID. diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -2793,18 +2793,10 @@ (uint32_t) videoType); } if (c.mAudio.IsMediaTrackConstraints()) { auto& ac = c.mAudio.GetAsMediaTrackConstraints(); - MediaConstraintsHelper::ConvertOldWithWarning(ac.mMozAutoGainControl, - ac.mAutoGainControl, - "MozAutoGainControlWarning", - aWindow); - MediaConstraintsHelper::ConvertOldWithWarning(ac.mMozNoiseSuppression, - ac.mNoiseSuppression, - "MozNoiseSuppressionWarning", - aWindow); audioType = StringToEnum(dom::MediaSourceEnumValues::strings, ac.mMediaSource, MediaSourceEnum::Other); // Work around WebIDL default since spec uses same dictionary w/audio & video. if (audioType == MediaSourceEnum::Camera) { @@ -4769,11 +4761,11 @@ RefPtr SourceListener::ApplyConstraintsToTrack( nsPIDOMWindowInner* aWindow, TrackID aTrackID, - const MediaTrackConstraints& aConstraintsPassedIn, + const MediaTrackConstraints& aConstraints, dom::CallerType aCallerType) { MOZ_ASSERT(NS_IsMainThread()); DeviceState& state = GetDeviceStateFor(aTrackID); @@ -4781,41 +4773,31 @@ LOG(("gUM %s track %d applyConstraints, but source is stopped", aTrackID == kAudioTrack ? "audio" : "video", aTrackID)); return ApplyConstraintsPromise::CreateAndResolve(false, __func__); } - MediaTrackConstraints c(aConstraintsPassedIn); // use a modifiable copy - MediaConstraintsHelper::ConvertOldWithWarning(c.mMozAutoGainControl, - c.mAutoGainControl, - "MozAutoGainControlWarning", - aWindow); - MediaConstraintsHelper::ConvertOldWithWarning(c.mMozNoiseSuppression, - c.mNoiseSuppression, - "MozNoiseSuppressionWarning", - aWindow); - MediaManager* mgr = MediaManager::GetIfExists(); if (!mgr) { return ApplyConstraintsPromise::CreateAndResolve(false, __func__); } return MediaManager::PostTask(__func__, - [device = state.mDevice, c, + [device = state.mDevice, aConstraints, isChrome = aCallerType == dom::CallerType::System] (MozPromiseHolder& aHolder) mutable { MOZ_ASSERT(MediaManager::IsInMediaThread()); MediaManager* mgr = MediaManager::GetIfExists(); MOZ_RELEASE_ASSERT(mgr); // Must exist while media thread is alive const char* badConstraint = nullptr; - nsresult rv = device->Reconfigure(c, mgr->mPrefs, &badConstraint); + nsresult rv = device->Reconfigure(aConstraints, mgr->mPrefs, &badConstraint); if (rv == NS_ERROR_INVALID_ARG) { // Reconfigure failed due to constraints if (!badConstraint) { nsTArray> devices; devices.AppendElement(device); badConstraint = MediaConstraintsHelper::SelectSettings( - NormalizedConstraints(c), devices, isChrome); + NormalizedConstraints(aConstraints), devices, isChrome); } aHolder.Reject(Some(NS_ConvertASCIItoUTF16(badConstraint)), __func__); return; } diff --git a/dom/media/webrtc/MediaEngineDefault.cpp b/dom/media/webrtc/MediaEngineDefault.cpp --- a/dom/media/webrtc/MediaEngineDefault.cpp +++ b/dom/media/webrtc/MediaEngineDefault.cpp @@ -422,12 +422,13 @@ AssertIsOnOwningThread(); MOZ_ASSERT(mState == kReleased); // Mock failure for automated tests. - if (aConstraints.mDeviceId.IsString() && - aConstraints.mDeviceId.GetAsString().EqualsASCII("bad device")) { + if (aConstraints.mDeviceId.WasPassed() && + aConstraints.mDeviceId.Value().IsString() && + aConstraints.mDeviceId.Value().GetAsString().EqualsASCII("bad device")) { return NS_ERROR_FAILURE; } mFreq = aPrefs.mFreq ? aPrefs.mFreq : 1000; *aOutHandle = nullptr; diff --git a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp --- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp +++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp @@ -989,13 +989,13 @@ // Any remaining multiples all have the same distance. A common case of this // occurs when no ideal is specified. Lean toward defaults. uint32_t sameDistance = candidateSet[0].mDistance; { MediaTrackConstraintSet prefs; - prefs.mWidth.SetAsLong() = aPrefs.GetWidth(); - prefs.mHeight.SetAsLong() = aPrefs.GetHeight(); - prefs.mFrameRate.SetAsDouble() = aPrefs.mFPS; + prefs.mWidth.Construct().SetAsLong() = aPrefs.GetWidth(); + prefs.mHeight.Construct().SetAsLong() = aPrefs.GetHeight(); + prefs.mFrameRate.Construct().SetAsDouble() = aPrefs.mFPS; NormalizedConstraintSet normPrefs(prefs, false); for (auto& candidate : candidateSet) { candidate.mDistance = GetDistance(candidate.mCapability, normPrefs, aDeviceId, aCalculate); diff --git a/dom/media/webrtc/MediaTrackConstraints.h b/dom/media/webrtc/MediaTrackConstraints.h --- a/dom/media/webrtc/MediaTrackConstraints.h +++ b/dom/media/webrtc/MediaTrackConstraints.h @@ -148,11 +148,12 @@ struct LongRange : public Range { typedef LongRange NormalizedConstraintSet::* LongPtrType; LongRange(LongPtrType aMemberPtr, const char* aName, - const dom::OwningLongOrConstrainLongRange& aOther, bool advanced, + const dom::Optional& aOther, + bool advanced, nsTArray* aList); }; struct LongLongRange : public Range { @@ -167,21 +168,21 @@ { typedef DoubleRange NormalizedConstraintSet::* DoublePtrType; DoubleRange(DoublePtrType aMemberPtr, const char* aName, - const dom::OwningDoubleOrConstrainDoubleRange& aOther, + const dom::Optional& aOther, bool advanced, nsTArray* aList); }; struct BooleanRange : public Range { typedef BooleanRange NormalizedConstraintSet::* BooleanPtrType; BooleanRange(BooleanPtrType aMemberPtr, const char* aName, - const dom::OwningBooleanOrConstrainBooleanParameters& aOther, + const dom::Optional& aOther, bool advanced, nsTArray* aList); BooleanRange(BooleanPtrType aMemberPtr, const char* aName, const bool& aOther, nsTArray* aList) @@ -196,11 +197,11 @@ ValueType mExact, mIdeal; typedef StringRange NormalizedConstraintSet::* StringPtrType; StringRange(StringPtrType aMemberPtr, const char* aName, - const dom::OwningStringOrStringSequenceOrConstrainDOMStringParameters& aOther, + const dom::Optional& aOther, bool advanced, nsTArray* aList); StringRange(StringPtrType aMemberPtr, const char* aName, const nsString& aOther, nsTArray* aList) @@ -335,18 +336,10 @@ static const char* FindBadConstraint(const NormalizedConstraints& aConstraints, const RefPtr& aMediaEngineSource, const nsString& aDeviceId); - // Warn on and convert use of deprecated constraints to new ones - static void - ConvertOldWithWarning( - const dom::OwningBooleanOrConstrainBooleanParameters& old, - dom::OwningBooleanOrConstrainBooleanParameters& to, - const char* aMessageName, - nsPIDOMWindowInner* aWindow); - static void LogConstraints(const NormalizedConstraintSet& aConstraints); }; } // namespace mozilla diff --git a/dom/media/webrtc/MediaTrackConstraints.cpp b/dom/media/webrtc/MediaTrackConstraints.cpp --- a/dom/media/webrtc/MediaTrackConstraints.cpp +++ b/dom/media/webrtc/MediaTrackConstraints.cpp @@ -19,11 +19,10 @@ #define LOG(msg, ...) MOZ_LOG(GetMediaManagerLog(), mozilla::LogLevel::Debug, (msg, ##__VA_ARGS__)) namespace mozilla { using dom::ConstrainBooleanParameters; -using dom::OwningLongOrConstrainLongRange; template template void NormalizedConstraintSet::Range::SetFrom(const ConstrainRange& aOther) @@ -89,25 +88,29 @@ } NormalizedConstraintSet::LongRange::LongRange( LongPtrType aMemberPtr, const char* aName, - const dom::OwningLongOrConstrainLongRange& aOther, + const dom::Optional& aOther, bool advanced, nsTArray* aList) : Range((MemberPtrType)aMemberPtr, aName, 1 + INT32_MIN, INT32_MAX, // +1 avoids Windows compiler bug aList) { - if (aOther.IsLong()) { + if (!aOther.WasPassed()) { + return; + } + auto& other = aOther.Value(); + if (other.IsLong()) { if (advanced) { - mMin = mMax = aOther.GetAsLong(); + mMin = mMax = other.GetAsLong(); } else { - mIdeal.emplace(aOther.GetAsLong()); + mIdeal.emplace(other.GetAsLong()); } } else { - SetFrom(aOther.GetAsConstrainLongRange()); + SetFrom(other.GetAsConstrainLongRange()); } } NormalizedConstraintSet::LongLongRange::LongLongRange( LongLongPtrType aMemberPtr, @@ -122,43 +125,52 @@ } NormalizedConstraintSet::DoubleRange::DoubleRange( DoublePtrType aMemberPtr, const char* aName, - const dom::OwningDoubleOrConstrainDoubleRange& aOther, bool advanced, + const dom::Optional& aOther, + bool advanced, nsTArray* aList) : Range((MemberPtrType)aMemberPtr, aName, -std::numeric_limits::infinity(), std::numeric_limits::infinity(), aList) { - if (aOther.IsDouble()) { + if (!aOther.WasPassed()) { + return; + } + auto& other = aOther.Value(); + if (other.IsDouble()) { if (advanced) { - mMin = mMax = aOther.GetAsDouble(); + mMin = mMax = other.GetAsDouble(); } else { - mIdeal.emplace(aOther.GetAsDouble()); + mIdeal.emplace(other.GetAsDouble()); } } else { - SetFrom(aOther.GetAsConstrainDoubleRange()); + SetFrom(other.GetAsConstrainDoubleRange()); } } NormalizedConstraintSet::BooleanRange::BooleanRange( BooleanPtrType aMemberPtr, const char* aName, - const dom::OwningBooleanOrConstrainBooleanParameters& aOther, + const dom::Optional& aOther, bool advanced, nsTArray* aList) : Range((MemberPtrType)aMemberPtr, aName, false, true, aList) { - if (aOther.IsBoolean()) { + if (!aOther.WasPassed()) { + return; + } + auto& other = aOther.Value(); + if (other.IsBoolean()) { if (advanced) { - mMin = mMax = aOther.GetAsBoolean(); + mMin = mMax = other.GetAsBoolean(); } else { - mIdeal.emplace(aOther.GetAsBoolean()); + mIdeal.emplace(other.GetAsBoolean()); } } else { - const dom::ConstrainBooleanParameters& r = aOther.GetAsConstrainBooleanParameters(); + auto& r = other.GetAsConstrainBooleanParameters(); if (r.mIdeal.WasPassed()) { mIdeal.emplace(r.mIdeal.Value()); } if (r.mExact.WasPassed()) { mMin = r.mExact.Value(); @@ -168,35 +180,39 @@ } NormalizedConstraintSet::StringRange::StringRange( StringPtrType aMemberPtr, const char* aName, - const dom::OwningStringOrStringSequenceOrConstrainDOMStringParameters& aOther, + const dom::Optional& aOther, bool advanced, nsTArray* aList) : BaseRange((MemberPtrType)aMemberPtr, aName, aList) { - if (aOther.IsString()) { + if (!aOther.WasPassed()) { + return; + } + auto& other = aOther.Value(); + if (other.IsString()) { if (advanced) { - mExact.insert(aOther.GetAsString()); + mExact.insert(other.GetAsString()); } else { - mIdeal.insert(aOther.GetAsString()); + mIdeal.insert(other.GetAsString()); } - } else if (aOther.IsStringSequence()) { + } else if (other.IsStringSequence()) { if (advanced) { mExact.clear(); - for (auto& str : aOther.GetAsStringSequence()) { + for (auto& str : other.GetAsStringSequence()) { mExact.insert(str); } } else { mIdeal.clear(); - for (auto& str : aOther.GetAsStringSequence()) { + for (auto& str : other.GetAsStringSequence()) { mIdeal.insert(str); } } } else { - SetFrom(aOther.GetAsConstrainDOMStringParameters()); + SetFrom(other.GetAsConstrainDOMStringParameters()); } } void NormalizedConstraintSet::StringRange::SetFrom( @@ -606,37 +622,10 @@ aMediaEngineSource->GetName(), aDeviceId)); return FindBadConstraint(aConstraints, devices); } -/* static */ void -MediaConstraintsHelper::ConvertOldWithWarning( - const dom::OwningBooleanOrConstrainBooleanParameters& old, - dom::OwningBooleanOrConstrainBooleanParameters& to, - const char* aMessageName, - nsPIDOMWindowInner* aWindow) { - if ((old.IsBoolean() || - old.GetAsConstrainBooleanParameters().mExact.WasPassed() || - old.GetAsConstrainBooleanParameters().mIdeal.WasPassed()) && - !(to.IsBoolean() || - to.GetAsConstrainBooleanParameters().mExact.WasPassed() || - to.GetAsConstrainBooleanParameters().mIdeal.WasPassed())) { - nsCOMPtr doc = aWindow->GetDoc(); - if (doc) { - nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, - NS_LITERAL_CSTRING("DOM"), doc, - nsContentUtils::eDOM_PROPERTIES, - aMessageName); - } - if (old.IsBoolean()) { - to.SetAsBoolean() = old.GetAsBoolean(); - } else { - to.SetAsConstrainBooleanParameters() = old.GetAsConstrainBooleanParameters(); - } - } -} - static void LogConstraintStringRange(const NormalizedConstraintSet::StringRange& aRange) { if (aRange.mExact.size() <= 1 && aRange.mIdeal.size() <= 1) { LOG(" %s: { exact: [%s], ideal: [%s] }", diff --git a/dom/webidl/MediaStreamTrack.webidl b/dom/webidl/MediaStreamTrack.webidl --- a/dom/webidl/MediaStreamTrack.webidl +++ b/dom/webidl/MediaStreamTrack.webidl @@ -40,45 +40,26 @@ // Note: When adding new constraints, remember to update the SelectSettings() // function in MediaManager.cpp to make OverconstrainedError's constraint work! dictionary MediaTrackConstraintSet { - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainLong width = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainLong height = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainDouble frameRate = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainDOMString facingMode = null; + ConstrainLong width; + ConstrainLong height; + ConstrainDouble frameRate; + ConstrainDOMString facingMode; DOMString mediaSource = "camera"; long long browserWindow; boolean scrollWithPage; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainDOMString deviceId = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainLong viewportOffsetX = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainLong viewportOffsetY = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainLong viewportWidth = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainLong viewportHeight = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainBoolean echoCancellation = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainBoolean noiseSuppression = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainBoolean autoGainControl = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainLong channelCount = null; - - // Deprecated with warnings: - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainBoolean mozNoiseSuppression = null; - // FIXME: bug 1493860 or bug 1493798: should this "= null" be here? - ConstrainBoolean mozAutoGainControl = null; + ConstrainDOMString deviceId; + ConstrainLong viewportOffsetX; + ConstrainLong viewportOffsetY; + ConstrainLong viewportWidth; + ConstrainLong viewportHeight; + ConstrainBoolean echoCancellation; + ConstrainBoolean noiseSuppression; + ConstrainBoolean autoGainControl; + ConstrainLong channelCount; }; dictionary MediaTrackConstraints : MediaTrackConstraintSet { sequence advanced; }; diff --git a/js/src/jit-test/tests/ion/bug913749.js b/js/src/jit-test/tests/ion/bug913749.js --- a/js/src/jit-test/tests/ion/bug913749.js +++ b/js/src/jit-test/tests/ion/bug913749.js @@ -14,8 +14,8 @@ try { x.toString(); assertEq(0, 1); } catch (e) { assertEq(e.message === `y is undefined; can't access its "length" property` || - e.message === "undefined has no properties", true); + e.message === `can't access property "length" of undefined`, true); } } diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -1795,25 +1795,18 @@ explicit ICGetElem_Fallback(JitCode* stubCode) : ICMonitoredFallbackStub(ICStub::GetElem_Fallback, stubCode) { } static const uint16_t EXTRA_NEGATIVE_INDEX = 0x1; - static const uint16_t EXTRA_UNOPTIMIZABLE_ACCESS = 0x2; public: void noteNegativeIndex() { extra_ |= EXTRA_NEGATIVE_INDEX; } bool hasNegativeIndex() const { return extra_ & EXTRA_NEGATIVE_INDEX; } - void noteUnoptimizableAccess() { - extra_ |= EXTRA_UNOPTIMIZABLE_ACCESS; - } - bool hadUnoptimizableAccess() const { - return extra_ & EXTRA_UNOPTIMIZABLE_ACCESS; - } // Compiler for this stub kind. class Compiler : public ICStubCompiler { protected: bool hasReceiver_; @@ -1936,19 +1929,10 @@ explicit ICGetName_Fallback(JitCode* stubCode) : ICMonitoredFallbackStub(ICStub::GetName_Fallback, stubCode) { } public: - static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0; - - void noteUnoptimizableAccess() { - extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT); - } - bool hadUnoptimizableAccess() const { - return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT); - } - class Compiler : public ICStubCompiler { protected: MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override; public: @@ -2025,20 +2009,12 @@ explicit ICGetProp_Fallback(JitCode* stubCode) : ICMonitoredFallbackStub(ICStub::GetProp_Fallback, stubCode) { } public: - static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0; static const size_t ACCESSED_GETTER_BIT = 1; - void noteUnoptimizableAccess() { - extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT); - } - bool hadUnoptimizableAccess() const { - return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT); - } - void noteAccessedGetter() { extra_ |= (1u << ACCESSED_GETTER_BIT); } bool hasAccessedGetter() const { return extra_ & (1u << ACCESSED_GETTER_BIT); @@ -2082,18 +2058,10 @@ explicit ICSetProp_Fallback(JitCode* stubCode) : ICFallbackStub(ICStub::SetProp_Fallback, stubCode) { } public: - static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0; - void noteUnoptimizableAccess() { - extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT); - } - bool hadUnoptimizableAccess() const { - return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT); - } - class Compiler : public ICStubCompiler { protected: CodeOffset bailoutReturnOffset_; MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override; void postGenerateStubCode(MacroAssembler& masm, Handle code) override; @@ -2147,27 +2115,18 @@ class ICCall_Fallback : public ICMonitoredFallbackStub { friend class ICStubSpace; public: - static const unsigned UNOPTIMIZABLE_CALL_FLAG = 0x1; - static const uint32_t MAX_OPTIMIZED_STUBS = 16; private: explicit ICCall_Fallback(JitCode* stubCode) : ICMonitoredFallbackStub(ICStub::Call_Fallback, stubCode) {} public: - void noteUnoptimizableCall() { - extra_ |= UNOPTIMIZABLE_CALL_FLAG; - } - bool hadUnoptimizableCall() const { - return extra_ & UNOPTIMIZABLE_CALL_FLAG; - } - bool scriptedStubsAreGeneralized() const { return hasStub(Call_AnyScripted); } bool nativeStubsAreGeneralized() const { // Return hasStub(Call_AnyNative) after Call_AnyNative stub is added. @@ -2854,21 +2813,11 @@ explicit ICInstanceOf_Fallback(JitCode* stubCode) : ICFallbackStub(ICStub::InstanceOf_Fallback, stubCode) { } - static const uint16_t UNOPTIMIZABLE_ACCESS_BIT = 0x1; - public: - - void noteUnoptimizableAccess() { - extra_ |= UNOPTIMIZABLE_ACCESS_BIT; - } - bool hadUnoptimizableAccess() const { - return extra_ & UNOPTIMIZABLE_ACCESS_BIT; - } - class Compiler : public ICStubCompiler { protected: MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override; public: @@ -3069,20 +3018,10 @@ explicit ICCompare_Fallback(JitCode* stubCode) : ICFallbackStub(ICStub::Compare_Fallback, stubCode) {} public: - static const uint32_t MAX_OPTIMIZED_STUBS = 8; - - static const size_t UNOPTIMIZABLE_ACCESS_BIT = 0; - void noteUnoptimizableAccess() { - extra_ |= (1u << UNOPTIMIZABLE_ACCESS_BIT); - } - bool hadUnoptimizableAccess() const { - return extra_ & (1u << UNOPTIMIZABLE_ACCESS_BIT); - } - // Compiler for this stub kind. class Compiler : public ICStubCompiler { protected: MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override; @@ -3111,27 +3050,20 @@ { extra_ = 0; } static const uint16_t SAW_DOUBLE_RESULT_BIT = 0x1; - static const uint16_t UNOPTIMIZABLE_OPERANDS_BIT = 0x2; public: static const uint32_t MAX_OPTIMIZED_STUBS = 8; bool sawDoubleResult() const { return extra_ & SAW_DOUBLE_RESULT_BIT; } void setSawDoubleResult() { extra_ |= SAW_DOUBLE_RESULT_BIT; } - bool hadUnoptimizableOperands() const { - return extra_ & UNOPTIMIZABLE_OPERANDS_BIT; - } - void noteUnoptimizableOperands() { - extra_ |= UNOPTIMIZABLE_OPERANDS_BIT; - } // Compiler for this stub kind. class Compiler : public ICStubCompiler { protected: MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm) override; diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -334,10 +334,37 @@ default: break; } } +// This helper handles ICState updates/transitions while attaching CacheIR stubs. +template +static void +TryAttachStub(const char *name, JSContext* cx, BaselineFrame* frame, ICFallbackStub* stub, BaselineCacheIRStubKind kind, Args&&... args) +{ + if (stub->state().maybeTransition()) { + stub->discardStubs(cx); + } + + if (stub->state().canAttachStub()) { + RootedScript script(cx, frame->script()); + jsbytecode* pc = stub->icEntry()->pc(script); + + bool attached = false; + IRGenerator gen(cx, script, pc, stub->state().mode(), std::forward(args)...); + if (gen.tryAttachStub()) { + ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), + kind, script, stub, &attached); + if (newStub) { + JitSpew(JitSpew_BaselineIC, " %s %s CacheIR stub", attached ? "Attached" : "Failed to attach", name); + } + } + if (!attached) { + stub->state().trackNotAttached(); + } + } +} // // WarmUpCounter_Fallback // @@ -1582,34 +1609,11 @@ { FallbackICSpew(cx, stub, "ToBool"); MOZ_ASSERT(!arg.isBoolean()); - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - - RootedScript script(cx, frame->script()); - jsbytecode* pc = stub->icEntry()->pc(script); - - ToBoolIRGenerator gen(cx, script, pc, stub->state().mode(), - arg); - bool attached = false; - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached ToBool CacheIR stub, attached is now %d", attached); - } - } - if (!attached) { - stub->state().trackNotAttached(); - } - } + TryAttachStub("ToBool", cx, frame, stub, BaselineCacheIRStubKind::Regular, arg); bool cond = ToBoolean(arg); ret.setBoolean(cond); return true; @@ -1784,14 +1788,10 @@ // determine that an object has no properties on such indexes. if (rhs.isNumber() && rhs.toNumber() < 0) { stub->noteNegativeIndex(); } - if (!attached && !isTemporarilyUnoptimizable) { - stub->noteUnoptimizableAccess(); - } - return true; } static bool DoGetElemSuperFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback* stub_, @@ -1865,14 +1865,10 @@ // determine that an object has no properties on such indexes. if (rhs.isNumber() && rhs.toNumber() < 0) { stub->noteNegativeIndex(); } - if (!attached && !isTemporarilyUnoptimizable) { - stub->noteUnoptimizableAccess(); - } - return true; } typedef bool (*DoGetElemFallbackFn)(JSContext*, BaselineFrame*, ICGetElem_Fallback*, HandleValue, HandleValue, MutableHandleValue); @@ -2061,18 +2057,19 @@ if (gen.tryAttachAddSlotStub(oldGroup, oldShape)) { ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached); if (newStub) { + JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub"); + + SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo()); + if (gen.shouldNotePreliminaryObjectStub()) { newStub->toCacheIR_Updated()->notePreliminaryObject(); } else if (gen.shouldUnlinkPreliminaryObjectStubs()) { StripPreliminaryObjectStubs(cx, stub); } - - JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub"); - SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo()); return true; } } else { gen.trackAttached(IRGenerator::NotAttached); } @@ -2246,32 +2243,11 @@ if (!objValue.isObject()) { ReportInNotObjectError(cx, key, -2, objValue, -1); return false; } - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - RootedScript script(cx, frame->script()); - jsbytecode* pc = stub->icEntry()->pc(script); - - HasPropIRGenerator gen(cx, script, pc, CacheKind::In, stub->state().mode(), key, objValue); - bool attached = false; - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached In CacheIR stub"); - } - } - if (!attached) { - stub->state().trackNotAttached(); - } - } + TryAttachStub("In", cx, frame, stub, BaselineCacheIRStubKind::Regular, CacheKind::In, key, objValue); RootedObject obj(cx, &objValue.toObject()); bool cond = false; if (!OperatorIn(cx, key, obj, &cond)) { return false; @@ -2315,33 +2291,13 @@ // This fallback stub may trigger debug mode toggling. DebugModeOSRVolatileStub stub(frame, stub_); FallbackICSpew(cx, stub, "HasOwn"); - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - RootedScript script(cx, frame->script()); - jsbytecode* pc = stub->icEntry()->pc(script); - - HasPropIRGenerator gen(cx, script, pc, CacheKind::HasOwn, - stub->state().mode(), keyValue, objValue); - bool attached = false; - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached HasOwn CacheIR stub"); - } - } - if (!attached) { - stub->state().trackNotAttached(); - } - } + TryAttachStub("HasOwn", cx, frame, stub, + BaselineCacheIRStubKind::Regular, CacheKind::HasOwn, + keyValue, objValue); bool found; if (!HasOwnProperty(cx, objValue, keyValue, &found)) { return false; } @@ -2391,30 +2347,12 @@ FallbackICSpew(cx, stub, "GetName(%s)", CodeName[JSOp(*pc)]); MOZ_ASSERT(op == JSOP_GETNAME || op == JSOP_GETGNAME); RootedPropertyName name(cx, script->getName(pc)); - bool attached = false; - - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - GetNameIRGenerator gen(cx, script, pc, stub->state().mode(), envChain, name); - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Monitored, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached GetName CacheIR stub"); - } - } - if (!attached) { - stub->state().trackNotAttached(); - } - } + + TryAttachStub("GetName", cx, frame, stub, BaselineCacheIRStubKind::Monitored, envChain, name); static_assert(JSOP_GETGNAME_LENGTH == JSOP_GETNAME_LENGTH, "Otherwise our check for JSOP_TYPEOF isn't ok"); if (JSOp(pc[JSOP_GETGNAME_LENGTH]) == JSOP_TYPEOF) { if (!GetEnvironmentName(cx, envChain, name, res)) { @@ -2437,13 +2375,10 @@ // Add a type monitor stub for the resulting value. if (!stub->addMonitorStubForValue(cx, frame, types, res)) { return false; } - if (!attached) { - stub->noteUnoptimizableAccess(); - } return true; } typedef bool (*DoGetNameFallbackFn)(JSContext*, BaselineFrame*, ICGetName_Fallback*, HandleObject, MutableHandleValue); @@ -2478,30 +2413,11 @@ MOZ_ASSERT(op == JSOP_BINDNAME || op == JSOP_BINDGNAME); RootedPropertyName name(cx, frame->script()->getName(pc)); - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - bool attached = false; - RootedScript script(cx, frame->script()); - BindNameIRGenerator gen(cx, script, pc, stub->state().mode(), envChain, name); - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached BindName CacheIR stub"); - } - } - if (!attached) { - stub->state().trackNotAttached(); - } - } + TryAttachStub("BindName", cx, frame, stub, BaselineCacheIRStubKind::Regular, envChain, name); RootedObject scope(cx); if (!LookupNameUnqualified(cx, name, envChain, &scope)) { return false; } @@ -2560,30 +2476,11 @@ // Check if debug mode toggling made the stub invalid. if (stub.invalid()) { return true; } - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - bool attached = false; - RootedScript script(cx, frame->script()); - GetIntrinsicIRGenerator gen(cx, script, pc, stub->state().mode(), res); - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached GetIntrinsic CacheIR stub"); - } - } - if (!attached) { - stub->state().trackNotAttached(); - } - } + TryAttachStub("GetIntrinsic", cx, frame, stub, BaselineCacheIRStubKind::Regular, res); return true; } typedef bool (*DoGetIntrinsicFallbackFn)(JSContext*, BaselineFrame*, ICGetIntrinsic_Fallback*, @@ -2677,11 +2574,11 @@ if (gen.tryAttachStub()) { ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), BaselineCacheIRStubKind::Monitored, script, stub, &attached); if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub"); + JitSpew(JitSpew_BaselineIC, " Attached GetProp CacheIR stub"); if (gen.shouldNotePreliminaryObjectStub()) { newStub->toCacheIR_Monitored()->notePreliminaryObject(); } else if (gen.shouldUnlinkPreliminaryObjectStubs()) { StripPreliminaryObjectStubs(cx, stub); } @@ -2706,20 +2603,10 @@ // Add a type monitor stub for the resulting value. if (!stub->addMonitorStubForValue(cx, frame, types, res)) { return false; } - - if (attached) { - return true; - } - - MOZ_ASSERT(!attached); - if (!isTemporarilyUnoptimizable) { - stub->noteUnoptimizableAccess(); - } - return true; } static bool DoGetPropSuperFallback(JSContext* cx, BaselineFrame* frame, ICGetProp_Fallback* stub_, @@ -2755,11 +2642,11 @@ if (gen.tryAttachStub()) { ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), BaselineCacheIRStubKind::Monitored, script, stub, &attached); if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub"); + JitSpew(JitSpew_BaselineIC, " Attached GetPropSuper CacheIR stub"); if (gen.shouldNotePreliminaryObjectStub()) { newStub->toCacheIR_Monitored()->notePreliminaryObject(); } else if (gen.shouldUnlinkPreliminaryObjectStubs()) { StripPreliminaryObjectStubs(cx, stub); } @@ -2787,19 +2674,10 @@ // Add a type monitor stub for the resulting value. if (!stub->addMonitorStubForValue(cx, frame, types, res)) { return false; } - if (attached) { - return true; - } - - MOZ_ASSERT(!attached); - if (!isTemporarilyUnoptimizable) { - stub->noteUnoptimizableAccess(); - } - return true; } typedef bool (*DoGetPropFallbackFn)(JSContext*, BaselineFrame*, ICGetProp_Fallback*, MutableHandleValue, MutableHandleValue); @@ -3023,31 +2901,28 @@ if (gen.tryAttachAddSlotStub(oldGroup, oldShape)) { ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached); if (newStub) { + JitSpew(JitSpew_BaselineIC, " Attached SetProp CacheIR stub"); + + SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo()); + if (gen.shouldNotePreliminaryObjectStub()) { newStub->toCacheIR_Updated()->notePreliminaryObject(); } else if (gen.shouldUnlinkPreliminaryObjectStubs()) { StripPreliminaryObjectStubs(cx, stub); } - - JitSpew(JitSpew_BaselineIC, " Attached SetProp CacheIR stub"); - SetUpdateStubData(newStub->toCacheIR_Updated(), gen.typeCheckInfo()); } } else { gen.trackAttached(IRGenerator::NotAttached); } if (!attached && !isTemporarilyUnoptimizable) { stub->state().trackNotAttached(); } } - if (!attached && !isTemporarilyUnoptimizable) { - stub->noteUnoptimizableAccess(); - } - return true; } typedef bool (*DoSetPropFallbackFn)(JSContext*, BaselineFrame*, ICSetProp_Fallback*, Value*, HandleValue, HandleValue); @@ -3841,11 +3716,10 @@ return false; } } if (!handled) { - stub->noteUnoptimizableCall(); if (canAttachStub) { stub->state().trackNotAttached(); } } return true; @@ -3894,13 +3768,10 @@ StackTypeSet* types = TypeScript::BytecodeTypes(script, pc); if (!stub->addMonitorStubForValue(cx, frame, types, res)) { return false; } - if (!handled) { - stub->noteUnoptimizableCall(); - } return true; } void ICCallStubCompiler::pushCallArguments(MacroAssembler& masm, AllocatableGeneralRegisterSet regs, @@ -5393,32 +5264,11 @@ DoGetIteratorFallback(JSContext* cx, BaselineFrame* frame, ICGetIterator_Fallback* stub, HandleValue value, MutableHandleValue res) { FallbackICSpew(cx, stub, "GetIterator"); - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - RootedScript script(cx, frame->script()); - jsbytecode* pc = stub->icEntry()->pc(script); - - GetIteratorIRGenerator gen(cx, script, pc, stub->state().mode(), value); - bool attached = false; - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached GetIterator CacheIR stub"); - } - } - if (!attached) { - stub->state().trackNotAttached(); - } - } + TryAttachStub("GetIterator", cx, frame, stub, BaselineCacheIRStubKind::Regular, value); JSObject* iterobj = ValueToIterator(cx, value); if (!iterobj) { return false; } @@ -5584,45 +5434,10 @@ // // InstanceOf_Fallback // static bool -TryAttachInstanceOfStub(JSContext* cx, BaselineFrame* frame, ICInstanceOf_Fallback* stub, - HandleValue lhs, HandleObject rhs, bool* attached) -{ - MOZ_ASSERT(!*attached); - FallbackICSpew(cx, stub, "InstanceOf"); - - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - RootedScript script(cx, frame->script()); - jsbytecode* pc = stub->icEntry()->pc(script); - - InstanceOfIRGenerator gen(cx, script, pc, stub->state().mode(), - lhs, - rhs); - - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached InstanceOf CacheIR stub, attached is now %d", *attached); - } - } - if (!attached) { - stub->state().trackNotAttached(); - } - } - - return true; -} - -static bool DoInstanceOfFallback(JSContext* cx, BaselineFrame* frame, ICInstanceOf_Fallback* stub_, HandleValue lhs, HandleValue rhs, MutableHandleValue res) { // This fallback stub may trigger debug mode toggling. DebugModeOSRVolatileStub stub(frame, stub_); @@ -5646,25 +5461,22 @@ if (stub.invalid()) { return true; } if (!obj->is()) { - stub->noteUnoptimizableAccess(); + // ensure we've recorded at least one failure, so we can detect there was a non-optimizable case + if (!stub->state().hasFailures()) { + stub->state().trackNotAttached(); + } return true; } // For functions, keep track of the |prototype| property in type information, // for use during Ion compilation. EnsureTrackPropertyTypes(cx, obj, NameToId(cx->names().prototype)); - bool attached = false; - if (!TryAttachInstanceOfStub(cx, frame, stub, lhs, obj, &attached)) { - return false; - } - if (!attached) { - stub->noteUnoptimizableAccess(); - } + TryAttachStub("InstanceOf", cx, frame, stub, BaselineCacheIRStubKind::Regular, lhs, obj); return true; } typedef bool (*DoInstanceOfFallbackFn)(JSContext*, BaselineFrame*, ICInstanceOf_Fallback*, HandleValue, HandleValue, MutableHandleValue); @@ -5697,32 +5509,11 @@ DoTypeOfFallback(JSContext* cx, BaselineFrame* frame, ICTypeOf_Fallback* stub, HandleValue val, MutableHandleValue res) { FallbackICSpew(cx, stub, "TypeOf"); - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - RootedScript script(cx, frame->script()); - jsbytecode* pc = stub->icEntry()->pc(script); - - TypeOfIRGenerator gen(cx, script, pc, stub->state().mode(), val); - bool attached = false; - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached TypeOf CacheIR stub"); - } - } - if (!attached) { - stub->state().trackNotAttached(); - } - } + TryAttachStub("TypeOf", cx, frame, stub, BaselineCacheIRStubKind::Regular, val); JSType type = js::TypeOfValue(val); RootedString string(cx, TypeName(type, cx->names())); res.setString(string); return true; @@ -6059,28 +5850,11 @@ if (res.isDouble()) { stub->setSawDoubleResult(); } - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - UnaryArithIRGenerator gen(cx, script, pc, stub->state().mode(), - op, val, res); - if (gen.tryAttachStub()) { - bool attached = false; - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached UnaryArith CacheIR stub for %s", CodeName[op]); - } - } - } - + TryAttachStub("UniaryArith", cx, frame, stub, BaselineCacheIRStubKind::Regular, op, val, res); return true; } typedef bool (*DoUnaryArithFallbackFn)(JSContext*, BaselineFrame*, ICUnaryArith_Fallback*, HandleValue, MutableHandleValue); @@ -6210,39 +5984,11 @@ if (ret.isDouble()) { stub->setSawDoubleResult(); } - // Check if debug mode toggling made the stub invalid. - if (stub.invalid()) { - return true; - } - - if (ret.isDouble()) { - stub->setSawDoubleResult(); - } - - if (stub->state().maybeTransition()) { - stub->discardStubs(cx); - } - - if (stub->state().canAttachStub()) { - BinaryArithIRGenerator gen(cx, script, pc, stub->state().mode(), - op, lhs, rhs, ret); - if (gen.tryAttachStub()) { - bool attached = false; - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached BinaryArith CacheIR stub for %s", CodeName[op]); - } - - } else { - stub->noteUnoptimizableOperands(); - } - } + TryAttachStub("BinaryArith", cx, frame, stub, BaselineCacheIRStubKind::Regular, op, lhs, rhs, ret); return true; } typedef bool (*DoBinaryArithFallbackFn)(JSContext*, BaselineFrame*, ICBinaryArith_Fallback*, HandleValue, HandleValue, MutableHandleValue); @@ -6350,32 +6096,11 @@ // Check if debug mode toggling made the stub invalid. if (stub.invalid()) { return true; } - // Check to see if a new stub should be generated. - if (stub->numOptimizedStubs() >= ICCompare_Fallback::MAX_OPTIMIZED_STUBS) { - // TODO: Discard all stubs in this IC and replace with inert megamorphic stub. - // But for now we just bail. - return true; - } - - if (stub->state().canAttachStub()) { - CompareIRGenerator gen(cx, script, pc, stub->state().mode(), op, lhs, rhs); - bool attached = false; - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " Attached CacheIR stub"); - } - return true; - } - } - - stub->noteUnoptimizableAccess(); + TryAttachStub("Compare", cx, frame, stub, BaselineCacheIRStubKind::Regular, op, lhs, rhs); return true; } typedef bool (*DoCompareFallbackFn)(JSContext*, BaselineFrame*, ICCompare_Fallback*, HandleValue, HandleValue, MutableHandleValue); @@ -6484,22 +6209,12 @@ templateObject = NewObjectOperation(cx, script, pc, TenuredObject); if (!templateObject) { return false; } - if (!JitOptions.disableCacheIR) { - bool attached = false; - NewObjectIRGenerator gen(cx, script, pc, stub->state().mode(), JSOp(*pc), templateObject); - if (gen.tryAttachStub()) { - ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Regular, - script, stub, &attached); - if (newStub) { - JitSpew(JitSpew_BaselineIC, " NewObject Attached CacheIR stub"); - } - } - } + TryAttachStub("NewObject", cx, frame, stub, BaselineCacheIRStubKind::Regular, JSOp(*pc), templateObject); + stub->setTemplateObject(templateObject); } } if (!obj) { diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -282,18 +282,12 @@ } stub = stub->next(); } - if (stub->isGetProp_Fallback()) { - if (stub->toGetProp_Fallback()->hadUnoptimizableAccess()) { - receivers.clear(); - } - } else { - if (stub->toSetProp_Fallback()->hadUnoptimizableAccess()) { - receivers.clear(); - } + if (stub->toFallbackStub()->state().hasFailures()) { + receivers.clear(); } // Don't inline if there are more than 5 receivers. if (receivers.length() > 5) { receivers.clear(); @@ -617,11 +611,11 @@ return MCompare::Compare_Unknown; } if (ICStub* fallback = second ? second->next() : first->next()) { MOZ_ASSERT(fallback->isFallback()); - if (fallback->toCompare_Fallback()->hadUnoptimizableAccess()) { + if (fallback->toFallbackStub()->state().hasFailures()) { return MCompare::Compare_Unknown; } } MCompare::CompareType first_type = ParseCacheIRStubForCompareType(first->toCacheIR_Regular()); @@ -695,13 +689,12 @@ MIRType result; ICStub* stubs[2]; const ICEntry& entry = icEntryFromPC(pc); - ICStub* stub = entry.fallbackStub(); - if (stub->isBinaryArith_Fallback() && - stub->toBinaryArith_Fallback()->hadUnoptimizableOperands()) + ICFallbackStub* stub = entry.fallbackStub(); + if (stub->state().hasFailures()) { return MIRType::None; } stubs[0] = monomorphicStub(pc); @@ -845,11 +838,11 @@ } const ICEntry& entry = icEntryFromPC(pc); ICStub* stub = entry.firstStub(); - if (entry.fallbackStub()->toCall_Fallback()->hadUnoptimizableCall()) { + if (entry.fallbackStub()->state().hasFailures()) { return nullptr; } if (!stub->isCall_Scripted() || stub->next() != entry.fallbackStub()) { return nullptr; @@ -1247,17 +1240,13 @@ commonGetter, globalShape, isOwnProperty, receivers, convertUnboxedGroups, script)) { return false; } - } else if (stub->isGetProp_Fallback()) { + } else if (stub->isFallback()) { // If we have an unoptimizable access, don't try to optimize. - if (stub->toGetProp_Fallback()->hadUnoptimizableAccess()) { - return false; - } - } else if (stub->isGetName_Fallback()) { - if (stub->toGetName_Fallback()->hadUnoptimizableAccess()) { + if (stub->toFallbackStub()->state().hasFailures()) { return false; } } else { return false; } @@ -1332,24 +1321,15 @@ return false; } *getterOrSetter = setter; continue; } - if (stub->isGetProp_Fallback()) { - if (stub->toGetProp_Fallback()->hadUnoptimizableAccess()) { - return false; - } - if (stub->toGetProp_Fallback()->state().mode() != ICState::Mode::Megamorphic) { + if (stub->isFallback()) { + if (stub->toFallbackStub()->state().hasFailures()) { return false; } - continue; - } - if (stub->isSetProp_Fallback()) { - if (stub->toSetProp_Fallback()->hadUnoptimizableAccess()) { - return false; - } - if (stub->toSetProp_Fallback()->state().mode() != ICState::Mode::Megamorphic) { + if (stub->toFallbackStub()->state().mode() != ICState::Mode::Megamorphic) { return false; } continue; } @@ -1485,12 +1465,12 @@ commonSetter, isOwnProperty, receivers, convertUnboxedGroups)) { return false; } - } else if (!stub->isSetProp_Fallback() || - stub->toSetProp_Fallback()->hadUnoptimizableAccess()) + } else if (!stub->isFallback() || + stub->toFallbackStub()->state().hasFailures()) { // We have an unoptimizable access, so don't try to optimize. return false; } } @@ -1595,11 +1575,11 @@ } stub = stub->next(); } - if (stub->toGetProp_Fallback()->hadUnoptimizableAccess()) { + if (stub->toFallbackStub()->state().hasFailures()) { receivers.clear(); } // Don't inline if there are more than 5 receivers. if (receivers.length() > 5) { @@ -1639,32 +1619,22 @@ const ICEntry& entry = icEntryFromPC(pc); MIRType type = MIRType::None; for (ICStub* stub = entry.firstStub(); stub; stub = stub->next()) { - MIRType stubType; - switch (stub->kind()) { - case ICStub::GetProp_Fallback: - if (stub->toGetProp_Fallback()->hadUnoptimizableAccess()) { - return MIRType::Value; - } - continue; - - case ICStub::GetElem_Fallback: - if (stub->toGetElem_Fallback()->hadUnoptimizableAccess()) { - return MIRType::Value; - } - continue; - - case ICStub::CacheIR_Monitored: + MIRType stubType = MIRType::None; + if (stub->isCacheIR_Monitored()) { stubType = GetCacheIRExpectedInputType(stub->toCacheIR_Monitored()); if (stubType == MIRType::Value) { return MIRType::Value; } - break; - - default: + } else if (stub->isGetElem_Fallback() || stub->isGetProp_Fallback()) { + // If we have an unoptimizable access, don't try to optimize. + if (stub->toFallbackStub()->state().hasFailures()) { + return MIRType::Value; + } + } else { MOZ_CRASH("Unexpected stub"); } if (type != MIRType::None) { if (type != stubType) { @@ -1692,11 +1662,11 @@ // Ensure singleton instanceof stub if (!firstStub->next() || !firstStub->isCacheIR_Regular() || !firstStub->next()->isInstanceOf_Fallback() || - firstStub->next()->toInstanceOf_Fallback()->hadUnoptimizableAccess()) + firstStub->next()->toInstanceOf_Fallback()->state().hasFailures()) { return false; } ICCacheIR_Regular* stub = entry.firstStub()->toCacheIR_Regular(); diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h --- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -1822,12 +1822,12 @@ void trackAttached(const char* name); public: // NOTE: Argument order is PROPERTY, OBJECT - HasPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, CacheKind cacheKind, - ICState::Mode mode, HandleValue idVal, HandleValue val); + HasPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, ICState::Mode mode, + CacheKind cacheKind, HandleValue idVal, HandleValue val); bool tryAttachStub(); }; class MOZ_RAII InstanceOfIRGenerator : public IRGenerator diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -2880,11 +2880,11 @@ } #endif } HasPropIRGenerator::HasPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, - CacheKind cacheKind, ICState::Mode mode, + ICState::Mode mode, CacheKind cacheKind, HandleValue idVal, HandleValue val) : IRGenerator(cx, script, pc, cacheKind, mode), val_(val), idVal_(idVal) { } diff --git a/js/src/jit/ICState.h b/js/src/jit/ICState.h --- a/js/src/jit/ICState.h +++ b/js/src/jit/ICState.h @@ -62,10 +62,11 @@ reset(); } Mode mode() const { return mode_; } size_t numOptimizedStubs() const { return numOptimizedStubs_; } + bool hasFailures() const { return (numFailures_ != 0); } MOZ_ALWAYS_INLINE bool canAttachStub() const { // Note: we cannot assert that numOptimizedStubs_ <= MaxOptimizedStubs // because old-style baseline ICs may attach more stubs than // MaxOptimizedStubs allows. @@ -108,11 +109,14 @@ // since this code is also used for non-CacheIR Baseline stubs, assert // < 16 for now. Note that we do have the stronger assert in other // methods, because they are only used by CacheIR ICs. MOZ_ASSERT(numOptimizedStubs_ < 16); numOptimizedStubs_++; - numFailures_ = 0; + // As a heuristic, reduce the failure count after each successful attach + // to delay hitting Generic mode. Reset to 1 instead of 0 so that + // BaselineInspector can distinguish no-failures from rare-failures. + numFailures_ = std::min(numFailures_, static_cast(1)); } void trackNotAttached() { // Note: we can't assert numFailures_ < maxFailures() because // maxFailures() depends on numOptimizedStubs_ and it's possible a // GC discarded stubs before we got here. diff --git a/js/src/jit/IonIC.cpp b/js/src/jit/IonIC.cpp --- a/js/src/jit/IonIC.cpp +++ b/js/src/jit/IonIC.cpp @@ -478,11 +478,11 @@ jsbytecode* pc = ic->pc(); if (ic->state().canAttachStub()) { bool attached = false; RootedScript script(cx, ic->script()); - HasPropIRGenerator gen(cx, script, pc, CacheKind::HasOwn, ic->state().mode(), idVal, val); + HasPropIRGenerator gen(cx, script, pc, ic->state().mode(), CacheKind::HasOwn, idVal, val); if (gen.tryAttachStub()) { ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript, &attached); } if (!attached) { @@ -512,11 +512,11 @@ if (ic->state().canAttachStub()) { bool attached = false; RootedScript script(cx, ic->script()); RootedValue objV(cx, ObjectValue(*obj)); jsbytecode* pc = ic->pc(); - HasPropIRGenerator gen(cx, script, pc, CacheKind::In, ic->state().mode(), key, objV); + HasPropIRGenerator gen(cx, script, pc, ic->state().mode(), CacheKind::In, key, objV); if (gen.tryAttachStub()) { ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript, &attached); } if (!attached) { diff --git a/js/src/jsexn.h b/js/src/jsexn.h --- a/js/src/jsexn.h +++ b/js/src/jsexn.h @@ -115,24 +115,10 @@ ~AutoClearPendingException() { JS_ClearPendingException(cx); } }; -class AutoAssertNoPendingException -{ - mozilla::DebugOnly cx; - - public: - explicit AutoAssertNoPendingException(JSContext* cxArg) - : cx(cxArg) - { } - - ~AutoAssertNoPendingException() { - MOZ_ASSERT(!JS_IsExceptionPending(cx)); - } -}; - extern const char* ValueToSourceForError(JSContext* cx, HandleValue val, JS::UniqueChars& bytes); bool GetInternalError(JSContext* cx, unsigned errorNumber, MutableHandleValue error); diff --git a/js/src/jsmath.cpp b/js/src/jsmath.cpp --- a/js/src/jsmath.cpp +++ b/js/src/jsmath.cpp @@ -233,11 +233,11 @@ } double js::ecmaAtan2(double y, double x) { - AutoUnsafeCallWithABI unsafe; + AutoUnsafeCallWithABI unsafe(UnsafeABIStrictness::AllowPendingExceptions); return fdlibm::atan2(y, x); } bool js::math_atan2_handle(JSContext* cx, HandleValue y, HandleValue x, MutableHandleValue res) @@ -266,11 +266,11 @@ } double js::math_ceil_impl(double x) { - AutoUnsafeCallWithABI unsafe; + AutoUnsafeCallWithABI unsafe(UnsafeABIStrictness::AllowPendingExceptions); return fdlibm::ceil(x); } bool js::math_ceil_handle(JSContext* cx, HandleValue v, MutableHandleValue res) @@ -348,11 +348,11 @@ } double js::math_floor_impl(double x) { - AutoUnsafeCallWithABI unsafe; + AutoUnsafeCallWithABI unsafe(UnsafeABIStrictness::AllowPendingExceptions); return fdlibm::floor(x); } bool js::math_floor_handle(JSContext* cx, HandleValue v, MutableHandleValue r) @@ -441,11 +441,11 @@ double js::math_log_impl(double x) { - AutoUnsafeCallWithABI unsafe; + AutoUnsafeCallWithABI unsafe(UnsafeABIStrictness::AllowPendingExceptions); return fdlibm::log(x); } bool js::math_log_handle(JSContext* cx, HandleValue val, MutableHandleValue res) @@ -728,11 +728,11 @@ template float js::GetBiggestNumberLessThan<>(float x); double js::math_round_impl(double x) { - AutoUnsafeCallWithABI unsafe; + AutoUnsafeCallWithABI unsafe(UnsafeABIStrictness::AllowPendingExceptions); int32_t ignored; if (NumberEqualsInt32(x, &ignored)) { return x; } @@ -779,11 +779,11 @@ } double js::math_sin_impl(double x) { - AutoUnsafeCallWithABI unsafe; + AutoUnsafeCallWithABI unsafe(UnsafeABIStrictness::AllowPendingExceptions); return sin(x); } bool js::math_sin_handle(JSContext* cx, HandleValue val, MutableHandleValue res) @@ -812,11 +812,11 @@ } double js::math_sqrt_impl(double x) { - AutoUnsafeCallWithABI unsafe; + AutoUnsafeCallWithABI unsafe(UnsafeABIStrictness::AllowPendingExceptions); return sqrt(x); } bool js::math_sqrt_handle(JSContext* cx, HandleValue number, MutableHandleValue result) @@ -1083,11 +1083,11 @@ } double js::math_trunc_impl(double x) { - AutoUnsafeCallWithABI unsafe; + AutoUnsafeCallWithABI unsafe(UnsafeABIStrictness::AllowPendingExceptions); return fdlibm::trunc(x); } float js::math_truncf_impl(float x) diff --git a/js/src/vm/JSContext.h b/js/src/vm/JSContext.h --- a/js/src/vm/JSContext.h +++ b/js/src/vm/JSContext.h @@ -1148,30 +1148,31 @@ Value* array_; size_t length_; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; -class AutoAssertNoException + +class AutoAssertNoPendingException { #ifdef DEBUG - JSContext* cx; - bool hadException; -#endif + JSContext* cx_; public: - explicit AutoAssertNoException(JSContext* cx) -#ifdef DEBUG - : cx(cx), - hadException(cx->isExceptionPending()) -#endif + explicit AutoAssertNoPendingException(JSContext* cxArg) + : cx_(cxArg) { + MOZ_ASSERT(!JS_IsExceptionPending(cx_)); } - ~AutoAssertNoException() - { - MOZ_ASSERT_IF(!hadException, !cx->isExceptionPending()); + ~AutoAssertNoPendingException() { + MOZ_ASSERT(!JS_IsExceptionPending(cx_)); } +#else + public: + explicit AutoAssertNoPendingException(JSContext* cxArg) + {} +#endif }; class MOZ_RAII AutoLockScriptData { JSRuntime* runtime; @@ -1259,24 +1260,46 @@ } MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; +enum UnsafeABIStrictness { + NoExceptions, + AllowPendingExceptions, + AllowThrownExceptions +}; + // Should be used in functions called directly from JIT code (with // masm.callWithABI) to assert invariants in debug builds. +// In debug mode, masm.callWithABI inserts code to verify that the +// callee function uses AutoUnsafeCallWithABI. +// While this object is live: +// 1. cx->hasAutoUnsafeCallWithABI must be true. +// 2. We can't GC. +// 3. Exceptions should not be pending/thrown. +// +// Note that #3 is a precaution, not a requirement. By default, we +// assert that the function is not called with a pending exception, +// and that it does not throw an exception itself. class MOZ_RAII AutoUnsafeCallWithABI { #ifdef DEBUG JSContext* cx_; bool nested_; + bool checkForPendingException_; #endif JS::AutoCheckCannotGC nogc; public: #ifdef DEBUG - AutoUnsafeCallWithABI(); + explicit AutoUnsafeCallWithABI(UnsafeABIStrictness strictness = + UnsafeABIStrictness::NoExceptions); ~AutoUnsafeCallWithABI(); +#else + explicit AutoUnsafeCallWithABI(UnsafeABIStrictness unused_ = + UnsafeABIStrictness::NoExceptions) + {} #endif }; namespace gc { diff --git a/js/src/vm/JSContext.cpp b/js/src/vm/JSContext.cpp --- a/js/src/vm/JSContext.cpp +++ b/js/src/vm/JSContext.cpp @@ -1675,22 +1675,36 @@ } crash(reason); } #ifdef DEBUG -AutoUnsafeCallWithABI::AutoUnsafeCallWithABI() +AutoUnsafeCallWithABI::AutoUnsafeCallWithABI(UnsafeABIStrictness strictness) : cx_(TlsContext.get()), nested_(cx_->hasAutoUnsafeCallWithABI), nogc(cx_) { + switch(strictness) { + case UnsafeABIStrictness::NoExceptions: + MOZ_ASSERT(!JS_IsExceptionPending(cx_)); + checkForPendingException_ = true; + break; + case UnsafeABIStrictness::AllowPendingExceptions: + checkForPendingException_ = !JS_IsExceptionPending(cx_); + break; + case UnsafeABIStrictness::AllowThrownExceptions: + checkForPendingException_ = false; + break; + } + cx_->hasAutoUnsafeCallWithABI = true; } AutoUnsafeCallWithABI::~AutoUnsafeCallWithABI() { MOZ_ASSERT(cx_->hasAutoUnsafeCallWithABI); if (!nested_) { cx_->hasAutoUnsafeCallWithABI = false; cx_->inUnsafeCallWithABI = false; } + MOZ_ASSERT_IF(checkForPendingException_, !JS_IsExceptionPending(cx_)); } #endif diff --git a/js/src/vm/JSObject.cpp b/js/src/vm/JSObject.cpp --- a/js/src/vm/JSObject.cpp +++ b/js/src/vm/JSObject.cpp @@ -2465,11 +2465,11 @@ bool js::LookupNameNoGC(JSContext* cx, PropertyName* name, JSObject* envChain, JSObject** objp, JSObject** pobjp, PropertyResult* propp) { - AutoAssertNoException nogc(cx); + AutoAssertNoPendingException nogc(cx); MOZ_ASSERT(!*objp && !*pobjp && !*propp); for (JSObject* env = envChain; env; env = env->enclosingEnvironment()) { if (env->getOpsLookupProperty()) { diff --git a/js/src/vm/NativeObject.cpp b/js/src/vm/NativeObject.cpp --- a/js/src/vm/NativeObject.cpp +++ b/js/src/vm/NativeObject.cpp @@ -2563,11 +2563,11 @@ } bool js::NativeGetPropertyNoGC(JSContext* cx, NativeObject* obj, const Value& receiver, jsid id, Value* vp) { - AutoAssertNoException noexc(cx); + AutoAssertNoPendingException noexc(cx); return NativeGetPropertyInline(cx, obj, receiver, id, NotNameLookup, vp); } bool js::NativeGetElement(JSContext* cx, HandleNativeObject obj, HandleValue receiver, diff --git a/mobile/android/chrome/jar.mn b/mobile/android/chrome/jar.mn --- a/mobile/android/chrome/jar.mn +++ b/mobile/android/chrome/jar.mn @@ -59,11 +59,10 @@ % override chrome://global/content/config.xul chrome://browser/content/config.xhtml % override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml % override chrome://mozapps/content/extensions/extensions.xul chrome://browser/content/aboutAddons.xhtml # L10n resource overrides. -% override chrome://global/locale/aboutAbout.dtd chrome://browser/locale/overrides/aboutAbout.dtd % override chrome://global/locale/aboutReader.properties chrome://browser/locale/overrides/aboutReader.properties % override chrome://global/locale/aboutRights.dtd chrome://browser/locale/overrides/aboutRights.dtd % override chrome://global/locale/charsetMenu.properties chrome://browser/locale/overrides/charsetMenu.properties % override chrome://global/locale/commonDialogs.properties chrome://browser/locale/overrides/commonDialogs.properties % override chrome://global/locale/intl.properties chrome://browser/locale/overrides/intl.properties diff --git a/mobile/android/locales/filter.py b/mobile/android/locales/filter.py --- a/mobile/android/locales/filter.py +++ b/mobile/android/locales/filter.py @@ -16,11 +16,10 @@ return "ignore" if mod == "toolkit": # keep this file list in sync with jar.mn if path in ( - "chrome/global/aboutAbout.dtd", "chrome/global/aboutReader.properties", "chrome/global/aboutRights.dtd", "chrome/global/charsetMenu.properties", "chrome/global/commonDialogs.properties", "chrome/global/intl.properties", @@ -36,10 +35,13 @@ ): return "error" if re.match(r"crashreporter/[^/]*.ftl", path): # error on crashreporter/*.ftl return "error" + if re.match(r"toolkit/about/[^/]*About.ftl", path): + # error on toolkit/about/*About.ftl + return "error" return "ignore" if mod == "dom": # keep this file list in sync with jar.mn if path in ( diff --git a/mobile/android/locales/jar.mn b/mobile/android/locales/jar.mn --- a/mobile/android/locales/jar.mn +++ b/mobile/android/locales/jar.mn @@ -35,11 +35,10 @@ #endif # overrides for toolkit l10n, also for en-US # keep this file list in sync with l10n.toml and filter.py relativesrcdir toolkit/locales: - locale/@AB_CD@/browser/overrides/aboutAbout.dtd (%chrome/global/aboutAbout.dtd) locale/@AB_CD@/browser/overrides/aboutReader.properties (%chrome/global/aboutReader.properties) locale/@AB_CD@/browser/overrides/aboutRights.dtd (%chrome/global/aboutRights.dtd) locale/@AB_CD@/browser/overrides/charsetMenu.properties (%chrome/global/charsetMenu.properties) locale/@AB_CD@/browser/overrides/commonDialogs.properties (%chrome/global/commonDialogs.properties) locale/@AB_CD@/browser/overrides/intl.properties (%chrome/global/intl.properties) @@ -77,5 +76,7 @@ [localization] @AB_CD@.jar: relativesrcdir toolkit/locales: #about:crashes crashreporter (%crashreporter/**/*.ftl) #endif +#about:about + toolkit (%toolkit/about/*About.ftl) diff --git a/mobile/android/locales/l10n.toml b/mobile/android/locales/l10n.toml --- a/mobile/android/locales/l10n.toml +++ b/mobile/android/locales/l10n.toml @@ -156,10 +156,14 @@ [[paths]] reference = "dom/locales/en-US/chrome/plugins.properties" l10n = "{l}dom/chrome/plugins.properties" [[paths]] + reference = "toolkit/locales/en-US/toolkit/about/*About.ftl" + l10n = "{l}toolkit/toolkit/about/*About.ftl" + +[[paths]] reference = "toolkit/locales/en-US/chrome/global/aboutAbout.dtd" l10n = "{l}toolkit/chrome/global/aboutAbout.dtd" [[paths]] reference = "toolkit/locales/en-US/chrome/global/aboutReader.properties" diff --git a/mobile/locales/filter.py b/mobile/locales/filter.py --- a/mobile/locales/filter.py +++ b/mobile/locales/filter.py @@ -16,11 +16,10 @@ return "ignore" if mod == "toolkit": # keep this file list in sync with jar.mn if path in ( - "chrome/global/aboutAbout.dtd", "chrome/global/aboutReader.properties", "chrome/global/aboutRights.dtd", "chrome/global/charsetMenu.properties", "chrome/global/commonDialogs.properties", "chrome/global/intl.properties", @@ -36,10 +35,14 @@ ): return "error" if re.match(r"crashreporter/[^/]*.ftl", path): # error on crashreporter/*.ftl return "error" + + if re.match(r"toolkit/about/[^/]*About.ftl", path): + # error on toolkit/about/*About.ftl + return "error" return "ignore" if mod == "dom": # keep this file list in sync with jar.mn if path in ( diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -236,10 +236,14 @@ void nsHostRecord::SetExpiration(const mozilla::TimeStamp& now, unsigned int valid, unsigned int grace) { mValidStart = now; + if ((valid + grace) < 60) { + grace = 60 - valid; + LOG(("SetExpiration: artificially bumped grace to %d\n", grace)); + } mGraceStart = now + TimeDuration::FromSeconds(valid); mValidEnd = now + TimeDuration::FromSeconds(valid + grace); } void diff --git a/taskcluster/ci/beetmover-l10n/kind.yml b/taskcluster/ci/beetmover-l10n/kind.yml --- a/taskcluster/ci/beetmover-l10n/kind.yml +++ b/taskcluster/ci/beetmover-l10n/kind.yml @@ -3,27 +3,30 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. loader: taskgraph.loader.single_dep:loader transforms: - - taskgraph.transforms.beetmover_l10n:transforms - - taskgraph.transforms.name_sanity:transforms - - taskgraph.transforms.beetmover:transforms - - taskgraph.transforms.task:transforms + - taskgraph.transforms.beetmover_l10n:transforms + - taskgraph.transforms.name_sanity:transforms + - taskgraph.transforms.beetmover:transforms + - taskgraph.transforms.task:transforms kind-dependencies: - - nightly-l10n-signing + - nightly-l10n-signing only-for-attributes: - - nightly + - nightly not-for-build-platforms: - - linux-nightly/opt - - linux64-nightly/opt - - macosx64-nightly/opt - - win32-nightly/opt - - win64-nightly/opt - - linux-devedition-nightly/opt - - linux64-devedition-nightly/opt - - macosx64-devedition-nightly/opt - - win32-devedition-nightly/opt - - win64-devedition-nightly/opt + - linux-nightly/opt + - linux64-nightly/opt + - macosx64-nightly/opt + - win32-nightly/opt + - win64-nightly/opt + - linux-devedition-nightly/opt + - linux64-devedition-nightly/opt + - macosx64-devedition-nightly/opt + - win32-devedition-nightly/opt + - win64-devedition-nightly/opt + +job-template: + shipping-phase: promote diff --git a/taskcluster/ci/beetmover/kind.yml b/taskcluster/ci/beetmover/kind.yml --- a/taskcluster/ci/beetmover/kind.yml +++ b/taskcluster/ci/beetmover/kind.yml @@ -3,28 +3,31 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. loader: taskgraph.loader.single_dep:loader transforms: - - taskgraph.transforms.name_sanity:transforms - - taskgraph.transforms.beetmover:transforms - - taskgraph.transforms.task:transforms + - taskgraph.transforms.name_sanity:transforms + - taskgraph.transforms.beetmover:transforms + - taskgraph.transforms.task:transforms kind-dependencies: - - build-signing + - build-signing only-for-attributes: - - nightly + - nightly not-for-build-platforms: - - linux-nightly/opt - - linux64-nightly/opt - - macosx64-nightly/opt - - win32-nightly/opt - - win64-nightly/opt - - linux-devedition-nightly/opt - - linux64-devedition-nightly/opt - - macosx64-devedition-nightly/opt - - win32-devedition-nightly/opt - - win64-devedition-nightly/opt - - linux64-asan-reporter-nightly/opt - - win64-asan-reporter-nightly/opt + - linux-nightly/opt + - linux64-nightly/opt + - macosx64-nightly/opt + - win32-nightly/opt + - win64-nightly/opt + - linux-devedition-nightly/opt + - linux64-devedition-nightly/opt + - macosx64-devedition-nightly/opt + - win32-devedition-nightly/opt + - win64-devedition-nightly/opt + - linux64-asan-reporter-nightly/opt + - win64-asan-reporter-nightly/opt + +job-template: + shipping-phase: promote diff --git a/taskcluster/ci/build/android.yml b/taskcluster/ci/build/android.yml --- a/taskcluster/ci/build/android.yml +++ b/taskcluster/ci/build/android.yml @@ -227,11 +227,11 @@ android-x86-nightly/opt: description: "Android 4.2 x86 Nightly" attributes: nightly: true enable-full-crashsymbols: true - shipping-phase: promote + shipping-phase: build shipping-product: fennec index: product: mobile job-name: android-x86-opt type: nightly @@ -400,11 +400,11 @@ android-api-16-nightly/opt: description: "Android 4.0 api-16+ Nightly" attributes: nightly: true enable-full-crashsymbols: true - shipping-phase: promote + shipping-phase: build shipping-product: fennec index: product: mobile job-name: android-api-16-opt type: nightly-with-multi-l10n @@ -519,11 +519,11 @@ android-aarch64-nightly/opt: description: "Android 5.0 AArch64 Nightly" attributes: nightly: true enable-full-crashsymbols: true - shipping-phase: promote + shipping-phase: build shipping-product: fennec index: product: mobile job-name: android-aarch64-opt type: nightly @@ -638,11 +638,11 @@ android-x86_64-nightly/opt: description: "Android 5.0 x86-64 Nightly" attributes: nightly: true enable-full-crashsymbols: true - shipping-phase: promote + shipping-phase: build shipping-product: fennec index: product: mobile job-name: android-x86_64-opt type: nightly diff --git a/taskcluster/ci/release-final-verify/kind.yml b/taskcluster/ci/release-final-verify/kind.yml --- a/taskcluster/ci/release-final-verify/kind.yml +++ b/taskcluster/ci/release-final-verify/kind.yml @@ -23,15 +23,11 @@ docker-image: in-tree: "update-verify" max-run-time: 7200 retry-exit-status: [1] env: - BUILD_TOOLS_REPO: - by-project: - jamun: https://hg.mozilla.org/users/stage-ffxbld/tools - maple: https://hg.mozilla.org/users/asasaki_mozilla.com/tools - default: https://hg.mozilla.org/build/tools + BUILD_TOOLS_REPO: https://hg.mozilla.org/build/tools jobs: firefox: description: final verify shipping-phase: push diff --git a/taskcluster/ci/release-secondary-final-verify/kind.yml b/taskcluster/ci/release-secondary-final-verify/kind.yml --- a/taskcluster/ci/release-secondary-final-verify/kind.yml +++ b/taskcluster/ci/release-secondary-final-verify/kind.yml @@ -25,15 +25,11 @@ docker-image: in-tree: "update-verify" max-run-time: 7200 retry-exit-status: [1] env: - BUILD_TOOLS_REPO: - by-project: - jamun: https://hg.mozilla.org/users/stage-ffxbld/tools - maple: https://hg.mozilla.org/users/asasaki_mozilla.com/tools - default: https://hg.mozilla.org/build/tools + BUILD_TOOLS_REPO: https://hg.mozilla.org/build/tools jobs: firefox: description: secondary final verify shipping-phase: promote diff --git a/taskcluster/ci/release-secondary-update-verify/kind.yml b/taskcluster/ci/release-secondary-update-verify/kind.yml --- a/taskcluster/ci/release-secondary-update-verify/kind.yml +++ b/taskcluster/ci/release-secondary-update-verify/kind.yml @@ -32,16 +32,11 @@ max-run-time: 7200 retry-exit-status: - 255 env: NO_BBCONFIG: "1" - BUILD_TOOLS_REPO: - by-project: - birch: https://hg.mozilla.org/users/bhearsum_mozilla.com/tools - jamun: https://hg.mozilla.org/users/stage-ffxbld/tools - maple: https://hg.mozilla.org/users/asasaki_mozilla.com/tools - default: https://hg.mozilla.org/build/tools + BUILD_TOOLS_REPO: https://hg.mozilla.org/build/tools CHANNEL: "beta-localtest" extra: chunks: 12 jobs: diff --git a/taskcluster/ci/release-update-verify/kind.yml b/taskcluster/ci/release-update-verify/kind.yml --- a/taskcluster/ci/release-update-verify/kind.yml +++ b/taskcluster/ci/release-update-verify/kind.yml @@ -32,16 +32,11 @@ max-run-time: 3600 retry-exit-status: - 255 env: NO_BBCONFIG: "1" - BUILD_TOOLS_REPO: - by-project: - birch: https://hg.mozilla.org/users/bhearsum_mozilla.com/tools - jamun: https://hg.mozilla.org/users/stage-ffxbld/tools - maple: https://hg.mozilla.org/users/asasaki_mozilla.com/tools - default: https://hg.mozilla.org/build/tools + BUILD_TOOLS_REPO: https://hg.mozilla.org/build/tools extra: chunks: 12 jobs: firefox-linux64: diff --git a/taskcluster/taskgraph/target_tasks.py b/taskcluster/taskgraph/target_tasks.py --- a/taskcluster/taskgraph/target_tasks.py +++ b/taskcluster/taskgraph/target_tasks.py @@ -60,12 +60,10 @@ # ASAN is central-only 'linux64-asan-reporter-nightly', 'win64-asan-reporter-nightly', ): return False - if str(platform).startswith('android') and 'nightly' in str(platform): - return False if platform in ( 'linux', 'linux64', 'macosx64', 'win32', 'win64', @@ -308,27 +306,14 @@ def target_tasks_promote_desktop(full_task_graph, parameters, graph_config): """Select the superset of tasks required to promote a beta or release build of a desktop product. This should include all non-android mozilla_{beta,release} tasks, plus l10n, beetmover, balrog, etc.""" - beta_release_tasks = [l for l, t in full_task_graph.tasks.iteritems() if - filter_beta_release_tasks(t, parameters, - ignore_kinds=[], - allow_l10n=True)] - def filter(task): if task.attributes.get('shipping_product') != parameters['release_product']: return False - # Allow for {beta,release}_tasks; these will get optimized out to point - # to the previous graph using ``previous_graph_ids`` and - # ``previous_graph_kinds``. - # At some point this should filter by shipping_phase == 'build' and - # shipping_product matches. - if task.label in beta_release_tasks: - return True - # 'secondary' balrog/update verify/final verify tasks only run for RCs if parameters.get('release_type') != 'release-rc': if 'secondary' in task.kind: return False @@ -393,21 +378,16 @@ @_target_task('promote_fennec') def target_tasks_promote_fennec(full_task_graph, parameters, graph_config): """Select the set of tasks required for a candidates build of fennec. The nightly build process involves a pipeline of builds, signing, and, eventually, uploading the tasks to balrog.""" - filtered_for_project = target_tasks_nightly_fennec(full_task_graph, parameters, graph_config) def filter(task): attr = task.attributes.get # Don't ship single locale fennec anymore - Bug 1408083 if attr("locale") or attr("chunk_locales"): return False - if task.label in filtered_for_project: - if task.kind not in ('balrog', 'push-apk'): - if task.attributes.get('nightly'): - return True if task.attributes.get('shipping_product') == 'fennec' and \ task.attributes.get('shipping_phase') == 'promote': return True return [l for l, t in full_task_graph.tasks.iteritems() if filter(full_task_graph[l])] diff --git a/taskcluster/taskgraph/transforms/beetmover.py b/taskcluster/taskgraph/transforms/beetmover.py --- a/taskcluster/taskgraph/transforms/beetmover.py +++ b/taskcluster/taskgraph/transforms/beetmover.py @@ -10,11 +10,10 @@ from taskgraph.transforms.base import TransformSequence from taskgraph.util.attributes import copy_attributes_from_dependent_job from taskgraph.util.schema import validate_schema, Schema from taskgraph.util.scriptworker import (get_beetmover_bucket_scope, get_beetmover_action_scope, - get_phase, get_worker_type_for_scope) from taskgraph.util.taskcluster import get_artifact_prefix from taskgraph.transforms.task import task_description_schema from voluptuous import Any, Required, Optional @@ -138,11 +137,11 @@ Optional('treeherder'): task_description_schema['treeherder'], # locale is passed only for l10n beetmoving Optional('locale'): basestring, - Optional('shipping-phase'): task_description_schema['shipping-phase'], + Required('shipping-phase'): task_description_schema['shipping-phase'], Optional('shipping-product'): task_description_schema['shipping-product'], }) @transforms.add @@ -196,22 +195,21 @@ if job.get('locale'): attributes['locale'] = job['locale'] bucket_scope = get_beetmover_bucket_scope(config) action_scope = get_beetmover_action_scope(config) - phase = get_phase(config) task = { 'label': label, 'description': description, 'worker-type': get_worker_type_for_scope(config, bucket_scope), 'scopes': [bucket_scope, action_scope], 'dependencies': dependencies, 'attributes': attributes, 'run-on-projects': dep_job.attributes.get('run_on_projects'), 'treeherder': treeherder, - 'shipping-phase': phase, + 'shipping-phase': job['shipping-phase'], } yield task diff --git a/taskcluster/taskgraph/transforms/beetmover_geckoview.py b/taskcluster/taskgraph/transforms/beetmover_geckoview.py --- a/taskcluster/taskgraph/transforms/beetmover_geckoview.py +++ b/taskcluster/taskgraph/transforms/beetmover_geckoview.py @@ -10,12 +10,11 @@ from taskgraph.transforms.base import TransformSequence from taskgraph.transforms.beetmover import \ craft_release_properties as beetmover_craft_release_properties from taskgraph.util.attributes import copy_attributes_from_dependent_job from taskgraph.util.schema import validate_schema, Schema, resolve_keyed_by, optionally_keyed_by -from taskgraph.util.scriptworker import (get_phase, - get_worker_type_for_scope) +from taskgraph.util.scriptworker import get_worker_type_for_scope from taskgraph.transforms.task import task_description_schema from voluptuous import Required, Optional _ARTIFACT_ID_PER_PLATFORM = { @@ -102,11 +101,11 @@ 'scopes': [job['bucket-scope'], 'project:releng:beetmover:action:push-to-maven'], 'dependencies': dependencies, 'attributes': attributes, 'run-on-projects': ['mozilla-central'], 'treeherder': treeherder, - 'shipping-phase': job.get('shipping-phase', get_phase(config)), + 'shipping-phase': job['shipping-phase'], } yield task diff --git a/taskcluster/taskgraph/transforms/beetmover_l10n.py b/taskcluster/taskgraph/transforms/beetmover_l10n.py --- a/taskcluster/taskgraph/transforms/beetmover_l10n.py +++ b/taskcluster/taskgraph/transforms/beetmover_l10n.py @@ -30,7 +30,8 @@ beet_description = { 'dependent-task': dep_job, 'treeherder': treeherder, 'locale': locale, + 'shipping-phase': job['shipping-phase'], } yield beet_description diff --git a/taskcluster/taskgraph/transforms/beetmover_push_to_release.py b/taskcluster/taskgraph/transforms/beetmover_push_to_release.py --- a/taskcluster/taskgraph/transforms/beetmover_push_to_release.py +++ b/taskcluster/taskgraph/transforms/beetmover_push_to_release.py @@ -10,11 +10,11 @@ from taskgraph.transforms.base import TransformSequence from taskgraph.util.schema import ( validate_schema, Schema, ) from taskgraph.util.scriptworker import ( - get_beetmover_bucket_scope, get_beetmover_action_scope, + get_beetmover_bucket_scope, add_scope_prefix, get_worker_type_for_scope, ) from taskgraph.transforms.job import job_description_schema from taskgraph.transforms.task import task_description_schema from voluptuous import Any, Required, Optional @@ -72,11 +72,11 @@ product=job['product'] ) ) bucket_scope = get_beetmover_bucket_scope(config) - action_scope = get_beetmover_action_scope(config) + action_scope = add_scope_prefix(config, 'beetmover:action:push-to-releases') task = { 'label': label, 'description': description, 'worker-type': get_worker_type_for_scope(config, bucket_scope), diff --git a/taskcluster/taskgraph/transforms/beetmover_repackage.py b/taskcluster/taskgraph/transforms/beetmover_repackage.py --- a/taskcluster/taskgraph/transforms/beetmover_repackage.py +++ b/taskcluster/taskgraph/transforms/beetmover_repackage.py @@ -14,11 +14,10 @@ get_partials_artifacts, get_partials_artifact_map) from taskgraph.util.schema import validate_schema, Schema from taskgraph.util.scriptworker import (get_beetmover_bucket_scope, get_beetmover_action_scope, - get_phase, get_worker_type_for_scope) from taskgraph.util.taskcluster import get_artifact_prefix from taskgraph.transforms.task import task_description_schema from voluptuous import Any, Required, Optional @@ -169,11 +168,11 @@ # below transforms for defaults of various values. Optional('treeherder'): task_description_schema['treeherder'], # locale is passed only for l10n beetmoving Optional('locale'): basestring, - Optional('shipping-phase'): task_description_schema['shipping-phase'], + Required('shipping-phase'): task_description_schema['shipping-phase'], Optional('shipping-product'): task_description_schema['shipping-product'], }) @transforms.add @@ -239,22 +238,21 @@ if job.get('locale'): attributes['locale'] = job['locale'] bucket_scope = get_beetmover_bucket_scope(config) action_scope = get_beetmover_action_scope(config) - phase = get_phase(config) task = { 'label': label, 'description': description, 'worker-type': get_worker_type_for_scope(config, bucket_scope), 'scopes': [bucket_scope, action_scope], 'dependencies': dependencies, 'attributes': attributes, 'run-on-projects': dep_job.attributes.get('run_on_projects'), 'treeherder': treeherder, - 'shipping-phase': job.get('shipping-phase', phase), + 'shipping-phase': job['shipping-phase'], 'shipping-product': job.get('shipping-product'), } yield task diff --git a/taskcluster/taskgraph/transforms/release_generate_checksums_beetmover.py b/taskcluster/taskgraph/transforms/release_generate_checksums_beetmover.py --- a/taskcluster/taskgraph/transforms/release_generate_checksums_beetmover.py +++ b/taskcluster/taskgraph/transforms/release_generate_checksums_beetmover.py @@ -9,11 +9,10 @@ from taskgraph.transforms.base import TransformSequence from taskgraph.util.attributes import copy_attributes_from_dependent_job from taskgraph.util.schema import validate_schema, Schema from taskgraph.util.scriptworker import (get_beetmover_bucket_scope, get_beetmover_action_scope, - get_phase, get_worker_type_for_scope, ) from taskgraph.util.taskcluster import get_artifact_prefix from taskgraph.transforms.beetmover import craft_release_properties from taskgraph.transforms.task import task_description_schema @@ -102,22 +101,21 @@ # update the dependencies with the dependencies of the signing task dependencies.update(dep_job.dependencies) bucket_scope = get_beetmover_bucket_scope(config) action_scope = get_beetmover_action_scope(config) - phase = get_phase(config) task = { 'label': label, 'description': description, 'worker-type': get_worker_type_for_scope(config, bucket_scope), 'scopes': [bucket_scope, action_scope], 'dependencies': dependencies, 'attributes': attributes, 'run-on-projects': dep_job.attributes.get('run_on_projects'), 'treeherder': treeherder, - 'shipping-phase': phase, + 'shipping-phase': 'promote', } yield task diff --git a/taskcluster/taskgraph/util/scriptworker.py b/taskcluster/taskgraph/util/scriptworker.py --- a/taskcluster/taskgraph/util/scriptworker.py +++ b/taskcluster/taskgraph/util/scriptworker.py @@ -74,13 +74,10 @@ """Map beetmover scope aliases to sets of projects. """ BEETMOVER_SCOPE_ALIAS_TO_PROJECT = [[ 'all-nightly-branches', set([ 'mozilla-central', - 'mozilla-beta', - 'mozilla-release', - 'mozilla-esr60', 'comm-central', ]) ], [ 'all-release-branches', set([ 'mozilla-beta', @@ -89,80 +86,26 @@ 'comm-beta', 'comm-esr60', ]) ]] -"""The set of all beetmover release target tasks. - -Used for both `BEETMOVER_SCOPE_ALIAS_TO_TARGET_TASK` and `get_release_build_number` -""" -BEETMOVER_CANDIDATES_TARGET_TASKS = set([ - 'promote_fennec', - 'promote_desktop', -]) -BEETMOVER_PUSH_TARGET_TASKS = set([ - 'push_fennec', - 'ship_fennec', - 'push_desktop', - 'ship_desktop', -]) -BEETMOVER_RELEASE_TARGET_TASKS = BEETMOVER_CANDIDATES_TARGET_TASKS | BEETMOVER_PUSH_TARGET_TASKS - -"""Map beetmover tasks aliases to sets of target task methods. - -This is a list of list-pairs, for ordering. -""" -BEETMOVER_SCOPE_ALIAS_TO_TARGET_TASK = [[ - 'all-nightly-tasks', set([ - 'nightly_fennec', - 'nightly_linux', - 'nightly_macosx', - 'nightly_win32', - 'nightly_win64', - 'nightly_desktop', - 'mozilla_beta_tasks', - 'mozilla_release_tasks', - ]) -], [ - 'all-candidates-tasks', BEETMOVER_CANDIDATES_TARGET_TASKS -], [ - 'all-push-tasks', BEETMOVER_PUSH_TARGET_TASKS -]] - """Map the beetmover scope aliases to the actual scopes. """ BEETMOVER_BUCKET_SCOPES = { - 'all-candidates-tasks': { - 'all-release-branches': 'beetmover:bucket:release', - }, - 'all-push-tasks': { - 'all-release-branches': 'beetmover:bucket:release', - }, - 'all-nightly-tasks': { - 'all-nightly-branches': 'beetmover:bucket:nightly', - }, + 'all-release-branches': 'beetmover:bucket:release', + 'all-nightly-branches': 'beetmover:bucket:nightly', 'default': 'beetmover:bucket:dep', } """Map the beetmover tasks aliases to the actual action scopes. """ BEETMOVER_ACTION_SCOPES = { - 'all-candidates-tasks': 'beetmover:action:push-to-candidates', - 'all-push-tasks': 'beetmover:action:push-to-releases', - 'all-nightly-tasks': 'beetmover:action:push-to-nightly', - 'default': 'beetmover:action:push-to-nightly', + 'nightly': 'beetmover:action:push-to-nightly', + 'default': 'beetmover:action:push-to-candidates', } -"""Map the beetmover tasks aliases to phases. -""" -PHASES = { - 'all-candidates-tasks': 'promote', - 'all-push-tasks': 'push', - 'default': None, -} - """Known balrog actions.""" BALROG_ACTIONS = ('submit-locale', 'submit-toplevel', 'schedule') """Map balrog scope aliases to sets of projects. @@ -294,57 +237,24 @@ return alias_to_scope_map[alias] return alias_to_scope_map['default'] @with_scope_prefix -def get_scope_from_target_method(config, alias_to_tasks_map, alias_to_scope_map): +def get_scope_from_release_type(config, release_type_to_scope_map): """Determine the restricted scope from `config.params['target_tasks_method']`. Args: config (TransformConfig): The configuration for the kind being transformed. - alias_to_tasks_map (list of lists): each list pair contains the - alias and the set of target methods that match. This is ordered. - alias_to_scope_map (dict): the alias alias to scope + release_type_to_scope_map (dict): the maps release types to scopes Returns: string: the scope to use. """ - for alias, tasks in alias_to_tasks_map: - if config.params['target_tasks_method'] in tasks and alias in alias_to_scope_map: - return alias_to_scope_map[alias] - return alias_to_scope_map['default'] - - -@with_scope_prefix -def get_scope_from_target_method_and_project(config, alias_to_tasks_map, - alias_to_project_map, aliases_to_scope_map): - """Determine the restricted scope from both `target_tasks_method` and `project`. - - On certain branches, we'll need differing restricted scopes based on - `target_tasks_method`. However, we can't key solely on that, since that - `target_tasks_method` might be run on an unprivileged branch. This method - checks both. - - Args: - config (TransformConfig): The configuration for the kind being transformed. - alias_to_tasks_map (list of lists): each list pair contains the - alias and the set of target methods that match. This is ordered. - alias_to_project_map (list of lists): each list pair contains the - alias and the set of projects that match. This is ordered. - aliases_to_scope_map (dict of dicts): the task alias to project alias to scope - - Returns: - string: the scope to use. - """ - project = config.params['project'] - target = config.params['target_tasks_method'] - for alias1, tasks in alias_to_tasks_map: - for alias2, projects in alias_to_project_map: - if target in tasks and project in projects and \ - aliases_to_scope_map.get(alias1, {}).get(alias2): - return aliases_to_scope_map[alias1][alias2] - return aliases_to_scope_map['default'] + return release_type_to_scope_map.get( + config.params['release_type'], + release_type_to_scope_map['default'] + ) def get_phase_from_target_method(config, alias_to_tasks_map, alias_to_phase_map): """Determine the phase from `config.params['target_tasks_method']`. @@ -380,26 +290,18 @@ alias_to_project_map=DEVEDITION_SIGNING_SCOPE_ALIAS_TO_PROJECT, alias_to_scope_map=DEVEDITION_SIGNING_CERT_SCOPES, ) get_beetmover_bucket_scope = functools.partial( - get_scope_from_target_method_and_project, - alias_to_tasks_map=BEETMOVER_SCOPE_ALIAS_TO_TARGET_TASK, + get_scope_from_project, alias_to_project_map=BEETMOVER_SCOPE_ALIAS_TO_PROJECT, - aliases_to_scope_map=BEETMOVER_BUCKET_SCOPES, + alias_to_scope_map=BEETMOVER_BUCKET_SCOPES, ) get_beetmover_action_scope = functools.partial( - get_scope_from_target_method, - alias_to_tasks_map=BEETMOVER_SCOPE_ALIAS_TO_TARGET_TASK, - alias_to_scope_map=BEETMOVER_ACTION_SCOPES, -) - -get_phase = functools.partial( - get_phase_from_target_method, - alias_to_tasks_map=BEETMOVER_SCOPE_ALIAS_TO_TARGET_TASK, - alias_to_phase_map=PHASES, + get_scope_from_release_type, + release_type_to_scope_map=BEETMOVER_ACTION_SCOPES, ) get_balrog_server_scope = functools.partial( get_scope_from_project, alias_to_project_map=BALROG_SCOPE_ALIAS_TO_PROJECT, diff --git a/toolkit/content/aboutAbout.xhtml b/toolkit/content/aboutAbout.xhtml --- a/toolkit/content/aboutAbout.xhtml +++ b/toolkit/content/aboutAbout.xhtml @@ -1,27 +1,24 @@ - -%aboutAboutDTD; - -%globalDTD; -]> + - &aboutAbout.title; + + + - +
-

&aboutAbout.title;

-

&aboutAbout.note;

+

+

    diff --git a/toolkit/locales/jar.mn b/toolkit/locales/jar.mn --- a/toolkit/locales/jar.mn +++ b/toolkit/locales/jar.mn @@ -7,11 +7,10 @@ crashreporter (%crashreporter/**/*.ftl) toolkit (%toolkit/**/*.ftl) @AB_CD@.jar: % locale global @AB_CD@ %locale/@AB_CD@/global/ - locale/@AB_CD@/global/aboutAbout.dtd (%chrome/global/aboutAbout.dtd) locale/@AB_CD@/global/aboutReader.properties (%chrome/global/aboutReader.properties) locale/@AB_CD@/global/aboutRights.dtd (%chrome/global/aboutRights.dtd) locale/@AB_CD@/global/aboutNetworking.dtd (%chrome/global/aboutNetworking.dtd) locale/@AB_CD@/global/aboutStudies.properties (%chrome/global/aboutStudies.properties) locale/@AB_CD@/global/aboutServiceWorkers.dtd (%chrome/global/aboutServiceWorkers.dtd) diff --git a/toolkit/mozapps/extensions/content/extensions.js b/toolkit/mozapps/extensions/content/extensions.js --- a/toolkit/mozapps/extensions/content/extensions.js +++ b/toolkit/mozapps/extensions/content/extensions.js @@ -1133,11 +1133,14 @@ info: { type: "sideload", addon: aAddon, icon: aAddon.iconURL, permissions: perms, - resolve() { aAddon.enable(); }, + resolve() { + aAddon.markAsSeen(); + aAddon.enable(); + }, reject() {}, }, }, }; Services.obs.notifyObservers(subject, "webextension-permission-prompt"); diff --git a/toolkit/mozapps/extensions/test/browser/browser.ini b/toolkit/mozapps/extensions/test/browser/browser.ini --- a/toolkit/mozapps/extensions/test/browser/browser.ini +++ b/toolkit/mozapps/extensions/test/browser/browser.ini @@ -55,10 +55,11 @@ [browser_checkAddonCompatibility.js] [browser_details.js] [browser_discovery.js] [browser_dragdrop.js] [browser_dragdrop_incompat.js] +[browser_extension_sideloading_permission.js] [browser_file_xpi_no_process_switch.js] skip-if = true # Bug 1449071 - Frequent failures [browser_getmorethemes.js] [browser_globalwarnings.js] [browser_gmpProvider.js] diff --git a/toolkit/mozapps/extensions/test/browser/browser_bug567127.js b/toolkit/mozapps/extensions/test/browser/browser_bug567127.js --- a/toolkit/mozapps/extensions/test/browser/browser_bug567127.js +++ b/toolkit/mozapps/extensions/test/browser/browser_bug567127.js @@ -7,36 +7,10 @@ var MockFilePicker = SpecialPowers.MockFilePicker; MockFilePicker.init(window); var gManagerWindow; -/** - * Wait for the given PopupNotification to display - * - * @param {string} name - * The name of the notification to wait for. - * - * @returns {Promise} - * Resolves with the notification window. - */ -function promisePopupNotificationShown(name) { - return new Promise(resolve => { - function popupshown() { - let notification = PopupNotifications.getNotification(name); - if (!notification) { return; } - - ok(notification, `${name} notification shown`); - ok(PopupNotifications.isPanelOpen, "notification panel open"); - - PopupNotifications.panel.removeEventListener("popupshown", popupshown); - resolve(PopupNotifications.panel.firstChild); - } - - PopupNotifications.panel.addEventListener("popupshown", popupshown); - }); -} - async function checkInstallConfirmation(...names) { let notificationCount = 0; let observer = { observe(aSubject, aTopic, aData) { var installInfo = aSubject.wrappedJSObject; diff --git a/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js b/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js --- a/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js +++ b/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js @@ -12,36 +12,10 @@ // we only need EventUtils.js for a few files which is why we are using loadSubScript. var gManagerWindow; var EventUtils = {}; Services.scriptloader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils); -/** - * Wait for the given PopupNotification to display - * - * @param {string} name - * The name of the notification to wait for. - * - * @returns {Promise} - * Resolves with the notification window. - */ -function promisePopupNotificationShown(name) { - return new Promise(resolve => { - function popupshown() { - let notification = PopupNotifications.getNotification(name); - if (!notification) { return; } - - ok(notification, `${name} notification shown`); - ok(PopupNotifications.isPanelOpen, "notification panel open"); - - PopupNotifications.panel.removeEventListener("popupshown", popupshown); - resolve(PopupNotifications.panel.firstElementChild); - } - - PopupNotifications.panel.addEventListener("popupshown", popupshown); - }); -} - async function checkInstallConfirmation(...names) { let notificationCount = 0; let observer = { observe(aSubject, aTopic, aData) { var installInfo = aSubject.wrappedJSObject; diff --git a/toolkit/mozapps/extensions/test/browser/head.js b/toolkit/mozapps/extensions/test/browser/head.js --- a/toolkit/mozapps/extensions/test/browser/head.js +++ b/toolkit/mozapps/extensions/test/browser/head.js @@ -1386,10 +1386,35 @@ } PopupNotifications.panel.addEventListener("popupshown", popupshown); }); } +/** + * Wait for the given PopupNotification to display + * + * @param {string} name + * The name of the notification to wait for. + * + * @returns {Promise} + * Resolves with the notification window. + */ +function promisePopupNotificationShown(name = "addon-webext-permissions") { + return new Promise(resolve => { + function popupshown() { + let notification = PopupNotifications.getNotification(name); + if (!notification) { return; } + + ok(notification, `${name} notification shown`); + ok(PopupNotifications.isPanelOpen, "notification panel open"); + + PopupNotifications.panel.removeEventListener("popupshown", popupshown); + resolve(PopupNotifications.panel.firstChild); + } + PopupNotifications.panel.addEventListener("popupshown", popupshown); + }); +} + function acceptAppMenuNotificationWhenShown(id) { ChromeUtils.import("resource://gre/modules/AppMenuNotifications.jsm"); return new Promise(resolve => { function popupshown() { let notification = AppMenuNotifications.activeNotification; diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_doorhanger_installs.js b/toolkit/mozapps/extensions/test/xpinstall/browser_doorhanger_installs.js --- a/toolkit/mozapps/extensions/test/xpinstall/browser_doorhanger_installs.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_doorhanger_installs.js @@ -73,26 +73,46 @@ } return PopupNotifications.panel; } -function acceptAppMenuNotificationWhenShown(id) { +function acceptAppMenuNotificationWhenShown(id, dismiss = false) { ChromeUtils.import("resource://gre/modules/AppMenuNotifications.jsm"); return new Promise(resolve => { + function appMenuPopupHidden() { + PanelUI.panel.removeEventListener("popuphidden", appMenuPopupHidden); + is(PanelUI.menuButton.getAttribute("badge-status"), false, "badge is not set after addon-installed"); + resolve(); + } + function appMenuPopupShown() { + PanelUI.panel.removeEventListener("popupshown", appMenuPopupShown); + PanelUI.menuButton.click(); + } function popupshown() { let notification = AppMenuNotifications.activeNotification; - if (!notification) { return; } + if (!notification) { + return; + } is(notification.id, id, `${id} notification shown`); ok(PanelUI.isNotificationPanelOpen, "notification panel open"); PanelUI.notificationPanel.removeEventListener("popupshown", popupshown); + if (dismiss) { + // Dismiss the panel by clicking on the appMenu button. + PanelUI.panel.addEventListener("popupshown", appMenuPopupShown); + PanelUI.panel.addEventListener("popuphidden", appMenuPopupHidden); + PanelUI.menuButton.click(); + return; + } + + // Dismiss the panel by clicking the primary button. let popupnotificationID = PanelUI._getPopupId(notification); let popupnotification = document.getElementById(popupnotificationID); + popupnotification.button.click(); - resolve(); } PanelUI.notificationPanel.addEventListener("popupshown", popupshown); }); } @@ -286,11 +306,11 @@ await BrowserTestUtils.waitForCondition(() => !!tab, "tab should be present"); is(gBrowser.selectedTab, tab, "tab selected in response to the addon-install-confirmation notification"); - let notificationPromise = acceptAppMenuNotificationWhenShown("addon-installed"); + let notificationPromise = acceptAppMenuNotificationWhenShown("addon-installed", true); acceptInstallDialog(installDialog); await notificationPromise; let installs = await AddonManager.getAllInstalls(); is(installs.length, 0, "Should be no pending installs");