From c08fd0c5f3bd58028738d593bd9a3fc4a4f2ebe5 Mon Sep 17 00:00:00 2001 From: JW Wang Date: Thu, 18 Feb 2016 11:34:04 +0800 Subject: [PATCH 001/115] Bug 1248513 - Fix static analysis errors in non-unified build for AudioStream.cpp. r=gerald. MozReview-Commit-ID: 77AC9c2TKqb --- dom/media/AudioStream.cpp | 51 ++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/dom/media/AudioStream.cpp b/dom/media/AudioStream.cpp index 4290669caaba..a5fc1f6e934b 100644 --- a/dom/media/AudioStream.cpp +++ b/dom/media/AudioStream.cpp @@ -273,6 +273,25 @@ OpenDumpFile(AudioStream* aStream) return f; } +template +typename EnableIf::value, void>::Type +WriteDumpFileHelper(T* aInput, size_t aSamples, FILE* aFile) { + fwrite(aInput, sizeof(T), aSamples, aFile); +} + +template +typename EnableIf::value, void>::Type +WriteDumpFileHelper(T* aInput, size_t aSamples, FILE* aFile) { + AutoTArray buf; + buf.SetLength(aSamples*2); + uint8_t* output = buf.Elements(); + for (uint32_t i = 0; i < aSamples; ++i) { + SetUint16LE(output + i*2, int16_t(aInput[i]*32767.0f)); + } + fwrite(output, 2, aSamples, aFile); + fflush(aFile); +} + static void WriteDumpFile(FILE* aDumpFile, AudioStream* aStream, uint32_t aFrames, void* aBuffer) @@ -281,23 +300,21 @@ WriteDumpFile(FILE* aDumpFile, AudioStream* aStream, uint32_t aFrames, return; uint32_t samples = aStream->GetOutChannels()*aFrames; - if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) { - fwrite(aBuffer, 2, samples, aDumpFile); - return; - } - NS_ASSERTION(AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_FLOAT32, "bad format"); - AutoTArray buf; - buf.SetLength(samples*2); - float* input = static_cast(aBuffer); - uint8_t* output = buf.Elements(); - for (uint32_t i = 0; i < samples; ++i) { - SetUint16LE(output + i*2, int16_t(input[i]*32767.0f)); - } - fwrite(output, 2, samples, aDumpFile); - fflush(aDumpFile); + using SampleT = AudioSampleTraits::Type; + WriteDumpFileHelper(reinterpret_cast(aBuffer), samples, aDumpFile); } +template +struct ToCubebFormat { + static const cubeb_sample_format value = CUBEB_SAMPLE_FLOAT32NE; +}; + +template <> +struct ToCubebFormat { + static const cubeb_sample_format value = CUBEB_SAMPLE_S16NE; +}; + nsresult AudioStream::Init(uint32_t aNumChannels, uint32_t aRate, const dom::AudioChannel aAudioChannel) @@ -333,12 +350,8 @@ AudioStream::Init(uint32_t aNumChannels, uint32_t aRate, return NS_ERROR_INVALID_ARG; } #endif - if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) { - params.format = CUBEB_SAMPLE_S16NE; - } else { - params.format = CUBEB_SAMPLE_FLOAT32NE; - } + params.format = ToCubebFormat::value; mAudioClock.Init(); return OpenCubeb(params); From 27e4eadbcebbaffc94c77dce7b63e25b09c73049 Mon Sep 17 00:00:00 2001 From: Cervantes Yu Date: Thu, 18 Feb 2016 15:33:59 +0800 Subject: [PATCH 002/115] Bug 1248896 - don't conditional compile on config ENABLE_TESTS in Nuwa. r=khuey --- ipc/glue/MessageLink.cpp | 7 +++---- mozglue/build/Nuwa.cpp | 2 +- mozglue/build/Nuwa.h | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ipc/glue/MessageLink.cpp b/ipc/glue/MessageLink.cpp index 14edb93b00a8..75e12500086d 100644 --- a/ipc/glue/MessageLink.cpp +++ b/ipc/glue/MessageLink.cpp @@ -16,7 +16,7 @@ #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/PNuwa.h" #include "mozilla/hal_sandbox/PHal.h" -#if defined(DEBUG) || defined(ENABLE_TESTS) +#ifdef DEBUG #include "jsprf.h" extern "C" char* PrintJSStack(); #endif @@ -202,18 +202,17 @@ ProcessLink::SendMessage(Message *msg) } } +#if defined(DEBUG) // Nuwa to parent: check whether we are currently blocked. if (IsNuwaProcess() && mIsBlocked) { -#if defined(ENABLE_TESTS) || defined(DEBUG) char* jsstack = PrintJSStack(); printf_stderr("Fatal error: sending a message to the chrome process" "with a blocked IPC channel from \n%s", jsstack ? jsstack : ""); JS_smprintf_free(jsstack); MOZ_CRASH(); -#endif } - +#endif #endif mIOLoop->PostTask( diff --git a/mozglue/build/Nuwa.cpp b/mozglue/build/Nuwa.cpp index 42d9bad34a39..4be83e699609 100644 --- a/mozglue/build/Nuwa.cpp +++ b/mozglue/build/Nuwa.cpp @@ -2077,7 +2077,7 @@ IsNuwaReady() { return sNuwaReady; } -#if defined(DEBUG) || defined(ENABLE_TESTS) +#if defined(DEBUG) MFBT_API void NuwaAssertNotFrozen(unsigned int aThread, const char* aThreadName) { if (!sIsNuwaProcess || !sIsFreezing) { diff --git a/mozglue/build/Nuwa.h b/mozglue/build/Nuwa.h index 37c8baebf603..13d71ebfef02 100644 --- a/mozglue/build/Nuwa.h +++ b/mozglue/build/Nuwa.h @@ -187,7 +187,7 @@ MFBT_API bool IsNuwaProcess(); */ MFBT_API bool IsNuwaReady(); -#if defined(DEBUG) || defined(ENABLE_TESTS) +#if defined(DEBUG) /** * Asserts that aThread is not frozen. */ From b88a6dfa63fdfe7af916422d169a0b62efb8e997 Mon Sep 17 00:00:00 2001 From: Heiher Date: Thu, 18 Feb 2016 15:55:07 +0800 Subject: [PATCH 003/115] Bug 1248863 - IonMonkey: MIPS32: Fix LIRGeneratorMIPS::visitBox. r=arai --- js/src/jit/mips32/Lowering-mips32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- js/src/jit/mips32/Lowering-mips32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/jit/mips32/Lowering-mips32.cpp b/js/src/jit/mips32/Lowering-mips32.cpp index aa9a55795bd9..79349dc1cc34 100644 --- a/js/src/jit/mips32/Lowering-mips32.cpp +++ b/js/src/jit/mips32/Lowering-mips32.cpp @@ -45,7 +45,7 @@ LIRGeneratorMIPS::visitBox(MBox* box) } if (inner->isConstant()) { - defineBox(new(alloc()) LValue(inner->toConstant()->value()), box); + defineBox(new(alloc()) LValue(inner->toConstant()->toJSValue()), box); return; } From f04a1e0f1c10f774d21b0350e5f1458d0242b186 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Thu, 18 Feb 2016 15:27:48 +1100 Subject: [PATCH 004/115] Bug 1248909: [MSE] P2. Simplify diagnostic. r=gerald Also, an assert could have been incorrectly triggered, if eviction occurred on a source buffer while data was also being appended to it. MozReview-Commit-ID: 6gVHZdbL07B --- dom/media/mediasource/TrackBuffersManager.cpp | 9 ++------- dom/media/mediasource/TrackBuffersManager.h | 5 +---- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp index 3c9c6c9cc0d2..3f8857199fd7 100644 --- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -104,7 +104,6 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBufferAttributes* aAttribute , mEvictionOccurred(false) , mMonitor("TrackBuffersManager") , mAppendRunning(false) - , mSegmentParserLoopRunning(false) { MOZ_ASSERT(NS_IsMainThread(), "Must be instanciated on the main thread"); } @@ -301,7 +300,7 @@ void TrackBuffersManager::CompleteResetParserState() { MOZ_ASSERT(OnTaskQueue()); - MOZ_DIAGNOSTIC_ASSERT(!mSegmentParserLoopRunning); + MOZ_DIAGNOSTIC_ASSERT(!mAppendRunning, "Append is running"); MSE_DEBUG(""); for (auto& track : GetTracksList()) { @@ -429,6 +428,7 @@ RefPtr TrackBuffersManager::CodedFrameRemovalWithPromise(TimeInterval aInterval) { MOZ_ASSERT(OnTaskQueue()); + MOZ_DIAGNOSTIC_ASSERT(!mAppendRunning, "Logic error: Append in progress"); bool rv = CodedFrameRemoval(aInterval); return RangeRemovalPromise::CreateAndResolve(rv, __func__); } @@ -437,7 +437,6 @@ bool TrackBuffersManager::CodedFrameRemoval(TimeInterval aInterval) { MOZ_ASSERT(OnTaskQueue()); - MOZ_ASSERT(!mSegmentParserLoopRunning, "Logic error: Append in progress"); MSE_DEBUG("From %.2fs to %.2f", aInterval.mStart.ToSeconds(), aInterval.mEnd.ToSeconds()); @@ -576,8 +575,6 @@ TrackBuffersManager::SegmentParserLoop() { MOZ_ASSERT(OnTaskQueue()); - mSegmentParserLoopRunning = true; - while (true) { // 1. If the input buffer is empty, then jump to the need more data step below. if (!mInputBuffer || mInputBuffer->IsEmpty()) { @@ -702,7 +699,6 @@ TrackBuffersManager::NeedMoreData() MSE_DEBUG(""); RestoreCachedVariables(); mAppendRunning = false; - mSegmentParserLoopRunning = false; { // Wake-up any pending Abort() MonitorAutoLock mon(mMonitor); @@ -716,7 +712,6 @@ TrackBuffersManager::RejectAppend(nsresult aRejectValue, const char* aName) { MSE_DEBUG("rv=%d", aRejectValue); mAppendRunning = false; - mSegmentParserLoopRunning = false; { // Wake-up any pending Abort() MonitorAutoLock mon(mMonitor); diff --git a/dom/media/mediasource/TrackBuffersManager.h b/dom/media/mediasource/TrackBuffersManager.h index f150e0d49819..6188df4d5474 100644 --- a/dom/media/mediasource/TrackBuffersManager.h +++ b/dom/media/mediasource/TrackBuffersManager.h @@ -350,11 +350,8 @@ private: // Monitor to protect following objects accessed across multipple threads. // mMonitor is also notified if the value of mAppendRunning becomes false. mutable Monitor mMonitor; - // Set to true while SegmentParserLoop is running. + // Set to true while a BufferAppend is running or is pending. Atomic mAppendRunning; - // Set to true while SegmentParserLoop is running. - // This is for diagnostic only. Only accessed on the task queue. - bool mSegmentParserLoopRunning; // Stable audio and video track time ranges. media::TimeIntervals mVideoBufferedRanges; media::TimeIntervals mAudioBufferedRanges; From 01c41693ba584c4628827c672c30f06a9070e161 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 18 Feb 2016 08:33:07 +0000 Subject: [PATCH 005/115] Bug 1245124 - window.open() should open a new tab in the same container, r=gijs, r=smaug --- browser/base/content/browser.js | 19 ++++++++++++++++--- dom/base/nsOpenURIInFrameParams.cpp | 17 +++++++++++++++-- dom/base/nsOpenURIInFrameParams.h | 8 +++++++- dom/interfaces/base/nsIBrowserDOMWindow.idl | 4 +++- dom/ipc/ContentChild.cpp | 11 +++++++++++ dom/ipc/ContentParent.cpp | 4 +++- dom/ipc/ContentParent.h | 1 + dom/ipc/PContent.ipdl | 4 +++- 8 files changed, 59 insertions(+), 9 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index b9f5fe220dbf..d5f9d5fb851b 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -4719,7 +4719,8 @@ nsBrowserAccess.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow, Ci.nsISupports]), _openURIInNewTab: function(aURI, aReferrer, aReferrerPolicy, aIsPrivate, - aIsExternal, aForceNotRemote=false) { + aIsExternal, aForceNotRemote=false, + aUserContextId=Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID) { let win, needToFocusWin; // try the current window. if we're in a popup, fall back on the most recent browser window @@ -4746,6 +4747,7 @@ nsBrowserAccess.prototype = { let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", { referrerURI: aReferrer, referrerPolicy: aReferrerPolicy, + userContextId: aUserContextId, fromExternal: aIsExternal, inBackground: loadInBackground, forceNotRemote: aForceNotRemote}); @@ -4818,9 +4820,12 @@ nsBrowserAccess.prototype = { // will do the job of shuttling off the newly opened browser to run in // the right process once it starts loading a URI. let forceNotRemote = !!aOpener; + let userContextId = aOpener && aOpener.document + ? aOpener.document.nodePrincipal.originAttributes.userContextId + : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID; let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy, isPrivate, isExternal, - forceNotRemote); + forceNotRemote, userContextId); if (browser) newWindow = browser.contentWindow; break; @@ -4849,9 +4854,17 @@ nsBrowserAccess.prototype = { } var isExternal = (aContext == Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL); + + var userContextId = aParams.openerOriginAttributes && + ("userContextId" in aParams.openerOriginAttributes) + ? aParams.openerOriginAttributes.userContextId + : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID + let browser = this._openURIInNewTab(aURI, aParams.referrer, aParams.referrerPolicy, - aParams.isPrivate, isExternal); + aParams.isPrivate, + isExternal, false, + userContextId); if (browser) return browser.QueryInterface(Ci.nsIFrameLoaderOwner); diff --git a/dom/base/nsOpenURIInFrameParams.cpp b/dom/base/nsOpenURIInFrameParams.cpp index 97706c0edd26..3f26dde20e42 100644 --- a/dom/base/nsOpenURIInFrameParams.cpp +++ b/dom/base/nsOpenURIInFrameParams.cpp @@ -5,11 +5,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsOpenURIInFrameParams.h" +#include "mozilla/BasePrincipal.h" NS_IMPL_ISUPPORTS(nsOpenURIInFrameParams, nsIOpenURIInFrameParams) -nsOpenURIInFrameParams::nsOpenURIInFrameParams() : - mIsPrivate(false) +nsOpenURIInFrameParams::nsOpenURIInFrameParams(const mozilla::DocShellOriginAttributes& aOriginAttributes) + : mOpenerOriginAttributes(aOriginAttributes) + , mIsPrivate(false) { } @@ -22,6 +24,7 @@ nsOpenURIInFrameParams::GetReferrer(nsAString& aReferrer) aReferrer = mReferrer; return NS_OK; } + NS_IMETHODIMP nsOpenURIInFrameParams::SetReferrer(const nsAString& aReferrer) { @@ -36,9 +39,19 @@ nsOpenURIInFrameParams::GetIsPrivate(bool* aIsPrivate) *aIsPrivate = mIsPrivate; return NS_OK; } + NS_IMETHODIMP nsOpenURIInFrameParams::SetIsPrivate(bool aIsPrivate) { mIsPrivate = aIsPrivate; return NS_OK; } + +NS_IMETHODIMP +nsOpenURIInFrameParams::GetOpenerOriginAttributes(JSContext* aCx, + JS::MutableHandle aValue) +{ + bool ok = ToJSValue(aCx, mOpenerOriginAttributes, aValue); + NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); + return NS_OK; +} diff --git a/dom/base/nsOpenURIInFrameParams.h b/dom/base/nsOpenURIInFrameParams.h index 3e606fc682b9..7fdd6a4bd85a 100644 --- a/dom/base/nsOpenURIInFrameParams.h +++ b/dom/base/nsOpenURIInFrameParams.h @@ -7,16 +7,22 @@ #include "nsIBrowserDOMWindow.h" #include "nsString.h" +namespace mozilla { +class DocShellOriginAttributes; +} + class nsOpenURIInFrameParams final : public nsIOpenURIInFrameParams { public: NS_DECL_ISUPPORTS NS_DECL_NSIOPENURIINFRAMEPARAMS - nsOpenURIInFrameParams(); + explicit nsOpenURIInFrameParams(const mozilla::DocShellOriginAttributes& aOriginAttributes); private: ~nsOpenURIInFrameParams(); + + mozilla::DocShellOriginAttributes mOpenerOriginAttributes; nsString mReferrer; bool mIsPrivate; }; diff --git a/dom/interfaces/base/nsIBrowserDOMWindow.idl b/dom/interfaces/base/nsIBrowserDOMWindow.idl index 5515f066d55e..993e6ac0d28f 100644 --- a/dom/interfaces/base/nsIBrowserDOMWindow.idl +++ b/dom/interfaces/base/nsIBrowserDOMWindow.idl @@ -11,11 +11,13 @@ interface nsIURI; interface nsIFrameLoaderOwner; [scriptable, uuid(e774db14-79ac-4156-a7a3-aa3fd0a22c10)] - interface nsIOpenURIInFrameParams : nsISupports { attribute DOMString referrer; attribute boolean isPrivate; + + [implicit_jscontext] + readonly attribute jsval openerOriginAttributes; }; [scriptable, uuid(9d17f3dd-672b-451e-afd2-b1115df780d5)] diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 7caac03fd375..c2e334f1b75f 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -73,6 +73,7 @@ #include "mozilla/unused.h" #include "mozInlineSpellChecker.h" +#include "nsDocShell.h" #include "nsIConsoleListener.h" #include "nsICycleCollectorListener.h" #include "nsIDragService.h" @@ -872,12 +873,22 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener, baseURI->GetSpec(baseURIString); } + auto* opener = nsPIDOMWindowOuter::From(aParent); + nsIDocShell* openerShell; + RefPtr openerDocShell; + if (opener && (openerShell = opener->GetDocShell())) { + openerDocShell = static_cast(openerShell); + } + nsresult rv; if (!SendCreateWindow(aTabOpener, newChild, aChromeFlags, aCalledFromJS, aPositionSpecified, aSizeSpecified, url, name, features, baseURIString, + openerDocShell + ? openerDocShell->GetOriginAttributes() + : DocShellOriginAttributes(), &rv, aWindowIsNew, &frameScripts, diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 82ef86946308..19273a86d192 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -5465,6 +5465,7 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab, const nsString& aName, const nsCString& aFeatures, const nsCString& aBaseURI, + const DocShellOriginAttributes& aOpenerOriginAttributes, nsresult* aResult, bool* aWindowIsNew, InfallibleTArray* aFrameScripts, @@ -5563,7 +5564,8 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab, loadContext->GetUsePrivateBrowsing(&isPrivate); } - nsCOMPtr params = new nsOpenURIInFrameParams(); + nsCOMPtr params = + new nsOpenURIInFrameParams(aOpenerOriginAttributes); params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI)); params->SetIsPrivate(isPrivate); diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index bbd791186e13..37b01f180b80 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -501,6 +501,7 @@ public: const nsString& aName, const nsCString& aFeatures, const nsCString& aBaseURI, + const DocShellOriginAttributes& aOpenerOriginAttributes, nsresult* aResult, bool* aWindowIsNew, InfallibleTArray* aFrameScripts, diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 8a41b8e5ee26..f2257416c90f 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -94,6 +94,7 @@ using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h"; using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h"; using class mozilla::dom::ipc::StructuredCloneData from "ipc/IPCMessageUtils.h"; using mozilla::DataStorageType from "ipc/DataStorageIPCUtils.h"; +using mozilla::DocShellOriginAttributes from "mozilla/ipc/BackgroundUtils.h"; union ChromeRegistryItem { @@ -1172,7 +1173,8 @@ parent: nsCString aURI, nsString aName, nsCString aFeatures, - nsCString aBaseURI) + nsCString aBaseURI, + DocShellOriginAttributes aOpenerOriginAttributes) returns (nsresult rv, bool windowOpened, FrameScriptInfo[] frameScripts, From d5d114572af2ccbb0b049e78e3de395314fcf1bc Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Wed, 17 Feb 2016 10:46:00 +0100 Subject: [PATCH 006/115] Bug 587177 - Update all comments before SetOriginalURI to reflect reality, r=mcmanus --HG-- extra : rebase_source : adbb70cbdc4a1f58af02f19bdba4f5a6eb06e9f0 --- netwerk/protocol/http/nsHttpChannel.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index a638b4809fcb..5c3a5f3df578 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -2076,7 +2076,8 @@ nsHttpChannel::OpenRedirectChannel(nsresult rv) { AutoRedirectVetoNotifier notifier(this); - // Make sure to do this _after_ calling OnChannelRedirect + // Make sure to do this after we received redirect veto answer, + // i.e. after all sinks had been notified mRedirectChannel->SetOriginalURI(mOriginalURI); // And now, notify observers the deprecated way @@ -2156,7 +2157,8 @@ nsHttpChannel::ContinueDoReplaceWithProxy(nsresult rv) NS_PRECONDITION(mRedirectChannel, "No redirect channel?"); - // Make sure to do this _after_ calling OnChannelRedirect + // Make sure to do this after we received redirect veto answer, + // i.e. after all sinks had been notified mRedirectChannel->SetOriginalURI(mOriginalURI); // open new channel @@ -2823,7 +2825,8 @@ nsHttpChannel::ContinueProcessFallback(nsresult rv) NS_PRECONDITION(mRedirectChannel, "No redirect channel?"); - // Make sure to do this _after_ calling OnChannelRedirect + // Make sure to do this after we received redirect veto answer, + // i.e. after all sinks had been notified mRedirectChannel->SetOriginalURI(mOriginalURI); if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) { @@ -4765,7 +4768,8 @@ nsHttpChannel::ContinueProcessRedirection(nsresult rv) NS_PRECONDITION(mRedirectChannel, "No redirect channel?"); - // Make sure to do this _after_ calling OnChannelRedirect + // Make sure to do this after we received redirect veto answer, + // i.e. after all sinks had been notified mRedirectChannel->SetOriginalURI(mOriginalURI); // And now, the deprecated way From 65450528659ae7f94269b430dc2ea8f2e948fe4c Mon Sep 17 00:00:00 2001 From: Louis Christie Date: Fri, 12 Feb 2016 14:45:28 +1300 Subject: [PATCH 007/115] Bug 851530: Part 1 - Added support for decoding uLaw and aLaw enconded wave files. r=jya --HG-- extra : rebase_source : f9179aa998afb3bf6b7c3a2ef2b841aded6c1153 --- dom/media/DecoderTraits.cpp | 4 +- dom/media/platforms/agnostic/WAVDecoder.cpp | 65 ++++++++++++++++--- .../android/AndroidDecoderModule.cpp | 2 + dom/media/wave/WaveDecoder.cpp | 5 +- 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/dom/media/DecoderTraits.cpp b/dom/media/DecoderTraits.cpp index a801fe0818ed..9d43550243bf 100644 --- a/dom/media/DecoderTraits.cpp +++ b/dom/media/DecoderTraits.cpp @@ -134,8 +134,10 @@ static const char* const gWaveTypes[5] = { nullptr }; -static char const *const gWaveCodecs[2] = { +static char const *const gWaveCodecs[4] = { "1", // Microsoft PCM Format + "6", // aLaw Encoding + "7", // uLaw Encoding nullptr }; diff --git a/dom/media/platforms/agnostic/WAVDecoder.cpp b/dom/media/platforms/agnostic/WAVDecoder.cpp index 648e46a15c90..8f3512625e66 100644 --- a/dom/media/platforms/agnostic/WAVDecoder.cpp +++ b/dom/media/platforms/agnostic/WAVDecoder.cpp @@ -12,6 +12,39 @@ using mp4_demuxer::ByteReader; namespace mozilla { +int16_t +DecodeALawSample(uint8_t aValue) +{ + aValue = aValue ^ 0x55; + int8_t sign = (aValue & 0x80) ? -1 : 1; + uint8_t exponent = (aValue & 0x70) >> 4; + uint8_t mantissa = aValue & 0x0F; + int16_t sample = mantissa << 4; + switch (exponent) { + case 0: + sample += 8; + break; + case 1: + sample += 0x108; + break; + default: + sample += 0x108; + sample <<= exponent - 1; + } + return sign * sample; +} + +int16_t +DecodeULawSample(uint8_t aValue) +{ + aValue = aValue ^ 0xFF; + int8_t sign = (aValue & 0x80) ? -1 : 1; + uint8_t exponent = (aValue & 0x70) >> 4; + uint8_t mantissa = aValue & 0x0F; + int16_t sample = (33 + 2 * mantissa) * (2 << (exponent + 1)) - 33; + return sign * sample; +} + WaveDataDecoder::WaveDataDecoder(const AudioInfo& aConfig, FlushableTaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback) @@ -69,18 +102,30 @@ WaveDataDecoder::DoDecode(MediaRawData* aSample) auto buffer = MakeUnique(frames * mInfo.mChannels); for (int i = 0; i < frames; ++i) { for (unsigned int j = 0; j < mInfo.mChannels; ++j) { - if (mInfo.mBitDepth == 8) { + if (mInfo.mProfile == 6) { //ALAW Data uint8_t v = aReader.ReadU8(); + int16_t decoded = DecodeALawSample(v); buffer[i * mInfo.mChannels + j] = - UInt8bitToAudioSample(v); - } else if (mInfo.mBitDepth == 16) { - int16_t v = aReader.ReadLE16(); + IntegerToAudioSample(decoded); + } else if (mInfo.mProfile == 7) { //ULAW Data + uint8_t v = aReader.ReadU8(); + int16_t decoded = DecodeULawSample(v); buffer[i * mInfo.mChannels + j] = - IntegerToAudioSample(v); - } else if (mInfo.mBitDepth == 24) { - int32_t v = aReader.ReadLE24(); - buffer[i * mInfo.mChannels + j] = - Int24bitToAudioSample(v); + IntegerToAudioSample(decoded); + } else { //PCM Data + if (mInfo.mBitDepth == 8) { + uint8_t v = aReader.ReadU8(); + buffer[i * mInfo.mChannels + j] = + UInt8bitToAudioSample(v); + } else if (mInfo.mBitDepth == 16) { + int16_t v = aReader.ReadLE16(); + buffer[i * mInfo.mChannels + j] = + IntegerToAudioSample(v); + } else if (mInfo.mBitDepth == 24) { + int32_t v = aReader.ReadLE24(); + buffer[i * mInfo.mChannels + j] = + Int24bitToAudioSample(v); + } } } } @@ -132,6 +177,8 @@ WaveDataDecoder::IsWave(const nsACString& aMimeType) // WAVdemuxer uses "audio/wave; codecs=aNum". return aMimeType.EqualsLiteral("audio/x-wav") || aMimeType.EqualsLiteral("audio/wave; codecs=1") || + aMimeType.EqualsLiteral("audio/wave; codecs=6") || + aMimeType.EqualsLiteral("audio/wave; codecs=7") || aMimeType.EqualsLiteral("audio/wave; codecs=65534"); } diff --git a/dom/media/platforms/android/AndroidDecoderModule.cpp b/dom/media/platforms/android/AndroidDecoderModule.cpp index b3ad89b05a1a..c7a69bbb2e5b 100644 --- a/dom/media/platforms/android/AndroidDecoderModule.cpp +++ b/dom/media/platforms/android/AndroidDecoderModule.cpp @@ -263,6 +263,8 @@ AndroidDecoderModule::SupportsMimeType(const nsACString& aMimeType) const // To avoid this we check for wav types here. if (aMimeType.EqualsLiteral("audio/x-wav") || aMimeType.EqualsLiteral("audio/wave; codecs=1") || + aMimeType.EqualsLiteral("audio/wave; codecs=6") || + aMimeType.EqualsLiteral("audio/wave; codecs=7") || aMimeType.EqualsLiteral("audio/wave; codecs=65534")) { return false; } diff --git a/dom/media/wave/WaveDecoder.cpp b/dom/media/wave/WaveDecoder.cpp index 70ab22c285a1..1962825a6718 100644 --- a/dom/media/wave/WaveDecoder.cpp +++ b/dom/media/wave/WaveDecoder.cpp @@ -52,7 +52,10 @@ WaveDecoder::CanHandleMediaType(const nsACString& aType, { if (aType.EqualsASCII("audio/wave") || aType.EqualsASCII("audio/x-wav") || aType.EqualsASCII("audio/wav") || aType.EqualsASCII("audio/x-pn-wav")) { - return IsEnabled() && (aCodecs.IsEmpty() || aCodecs.EqualsASCII("1")); + return IsEnabled() && (aCodecs.IsEmpty() || + aCodecs.EqualsASCII("1") || + aCodecs.EqualsASCII("6") || + aCodecs.EqualsASCII("7")); } return false; From ac975a3e11b6872cedd6f8d1d7c93c216e988694 Mon Sep 17 00:00:00 2001 From: Louis Christie Date: Fri, 12 Feb 2016 14:45:47 +1300 Subject: [PATCH 008/115] Bug 851530: Part 2 - Added test cases for uLaw and aLaw wave files. r=jya --HG-- extra : rebase_source : d3875f16601d3eab254fdaa144dc84a5db0384ac --- dom/media/test/can_play_type_wave.js | 2 ++ dom/media/test/manifest.js | 4 ++++ dom/media/test/mochitest.ini | 4 ++++ dom/media/test/wavedata_alaw.wav | Bin 0 -> 11067 bytes dom/media/test/wavedata_alaw.wav^headers^ | 1 + dom/media/test/wavedata_ulaw.wav | Bin 0 -> 11067 bytes dom/media/test/wavedata_ulaw.wav^headers^ | 1 + 7 files changed, 12 insertions(+) create mode 100644 dom/media/test/wavedata_alaw.wav create mode 100644 dom/media/test/wavedata_alaw.wav^headers^ create mode 100644 dom/media/test/wavedata_ulaw.wav create mode 100644 dom/media/test/wavedata_ulaw.wav^headers^ diff --git a/dom/media/test/can_play_type_wave.js b/dom/media/test/can_play_type_wave.js index 14b8d21acaf2..d3ce534f92c5 100644 --- a/dom/media/test/can_play_type_wave.js +++ b/dom/media/test/can_play_type_wave.js @@ -11,6 +11,8 @@ function check_wave(v, enabled) { // Supported Wave codecs check("audio/wave; codecs=1", "probably"); + check("audio/wave; codecs=6", "probably"); + check("audio/wave; codecs=7", "probably"); // "no codecs" should be supported, I guess check("audio/wave; codecs=", "probably"); check("audio/wave; codecs=\"\"", "probably"); diff --git a/dom/media/test/manifest.js b/dom/media/test/manifest.js index a7b26f3184b4..037249328df4 100644 --- a/dom/media/test/manifest.js +++ b/dom/media/test/manifest.js @@ -158,6 +158,10 @@ var gPlayTests = [ { name:"16bit_wave_extrametadata.wav", type:"audio/x-wav", duration:1.108 }, // 24-bit samples { name:"wavedata_s24.wav", type:"audio/x-wav", duration:1.0 }, + // aLaw compressed wave file + { name:"wavedata_alaw.wav", type:"audio/x-wav", duration:1.0 }, + // uLaw compressed wave file + { name:"wavedata_ulaw.wav", type:"audio/x-wav", duration:1.0 }, // Ogg stream without eof marker { name:"bug461281.ogg", type:"application/ogg", duration:2.208 }, diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini index 73731d9fb6ae..9e2e3d1b812e 100644 --- a/dom/media/test/mochitest.ini +++ b/dom/media/test/mochitest.ini @@ -557,12 +557,16 @@ support-files = wave_metadata_unknown_tag.wav^headers^ wave_metadata_utf8.wav wave_metadata_utf8.wav^headers^ + wavedata_alaw.wav + wavedata_alaw.wav^headers^ wavedata_s24.wav wavedata_s24.wav^headers^ wavedata_s16.wav wavedata_s16.wav^headers^ wavedata_u8.wav wavedata_u8.wav^headers^ + wavedata_ulaw.wav + wavedata_ulaw.wav^headers^ [test_access_control.html] skip-if = buildapp == 'b2g' && toolkit != 'gonk' # bug 1082984 diff --git a/dom/media/test/wavedata_alaw.wav b/dom/media/test/wavedata_alaw.wav new file mode 100644 index 0000000000000000000000000000000000000000..ef090d16e0f634f9afd97675412311cc46a13fba GIT binary patch literal 11067 zcmeIuF$#k~5QfoN5J{^iur_5*kU}A?h1QE=mu^p$`{X`Zj}dqS!w+Bime)K#?h)H_ zoz8a|`iN*FMOWMPDQ>l#c`r@fRLhY|zVYTm0~bsU)_71hGn)f=ae)#UUX*!>h$7Q}Q z?{PdN*`{S*ZT*&Am8Cz&rnXgi_0iY;V!Z literal 0 HcmV?d00001 diff --git a/dom/media/test/wavedata_ulaw.wav^headers^ b/dom/media/test/wavedata_ulaw.wav^headers^ new file mode 100644 index 000000000000..4030ea1d3ddb --- /dev/null +++ b/dom/media/test/wavedata_ulaw.wav^headers^ @@ -0,0 +1 @@ +Cache-Control: no-store From 842cd6d33ffcfb38ec864cc6e9fd94f01529c8fb Mon Sep 17 00:00:00 2001 From: Martijn Wargers Date: Wed, 17 Feb 2016 18:47:14 +0100 Subject: [PATCH 009/115] Bug 1160342 - Implement marquee using mutation observers, r=smaug --- dom/tests/mochitest/bugs/mochitest.ini | 1 + .../bugs/test_bug1160342_marquee.html | 228 ++++++++++++++++++ layout/reftests/marquee/1160342-1.html | 10 + layout/reftests/marquee/1160342-2.html | 10 + layout/reftests/marquee/1160342-ref.html | 10 + layout/reftests/marquee/reftest.list | 2 + layout/style/xbl-marquee/xbl-marquee.xml | 184 +++++++------- 7 files changed, 352 insertions(+), 93 deletions(-) create mode 100644 dom/tests/mochitest/bugs/test_bug1160342_marquee.html create mode 100644 layout/reftests/marquee/1160342-1.html create mode 100644 layout/reftests/marquee/1160342-2.html create mode 100644 layout/reftests/marquee/1160342-ref.html diff --git a/dom/tests/mochitest/bugs/mochitest.ini b/dom/tests/mochitest/bugs/mochitest.ini index 059788ef4fd9..ac4b17ae2b96 100644 --- a/dom/tests/mochitest/bugs/mochitest.ini +++ b/dom/tests/mochitest/bugs/mochitest.ini @@ -168,4 +168,5 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e1 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s [test_bug1022869.html] [test_bug1112040.html] +[test_bug1160342_marquee.html] [test_bug1171215.html] diff --git a/dom/tests/mochitest/bugs/test_bug1160342_marquee.html b/dom/tests/mochitest/bugs/test_bug1160342_marquee.html new file mode 100644 index 000000000000..760d98b0b59c --- /dev/null +++ b/dom/tests/mochitest/bugs/test_bug1160342_marquee.html @@ -0,0 +1,228 @@ + + + + + Test for Bug 411103 + + + + +Mozilla Bug 1160342 +

+
+marquee +
+ +
+
+
+ + diff --git a/layout/reftests/marquee/1160342-1.html b/layout/reftests/marquee/1160342-1.html new file mode 100644 index 000000000000..85e7215fbbab --- /dev/null +++ b/layout/reftests/marquee/1160342-1.html @@ -0,0 +1,10 @@ + + +Bug 1160342 - Implement marquee using mutation observers + + + +This text should be visible + + + diff --git a/layout/reftests/marquee/1160342-2.html b/layout/reftests/marquee/1160342-2.html new file mode 100644 index 000000000000..99b288568bac --- /dev/null +++ b/layout/reftests/marquee/1160342-2.html @@ -0,0 +1,10 @@ + + +Bug 1160342 - Implement marquee using mutation observers + + + +This text should be visible + + + diff --git a/layout/reftests/marquee/1160342-ref.html b/layout/reftests/marquee/1160342-ref.html new file mode 100644 index 000000000000..d56c90642aad --- /dev/null +++ b/layout/reftests/marquee/1160342-ref.html @@ -0,0 +1,10 @@ + + +Bug 1160342 - Implement marquee using mutation observers + + + +This text should be visible + + + diff --git a/layout/reftests/marquee/reftest.list b/layout/reftests/marquee/reftest.list index 298a02b0b5d8..932298a272c7 100644 --- a/layout/reftests/marquee/reftest.list +++ b/layout/reftests/marquee/reftest.list @@ -7,3 +7,5 @@ fuzzy-if(Android&&AndroidVersion>=15,8,220) == 413027-4.html 413027-4-ref.html fuzzy-if(Android&&AndroidVersion>=15,8,30) == 425247-1.html 425247-1-ref.html fuzzy-if(Android&&AndroidVersion>=15,8,30) == 425247-2.html 425247-2-ref.html random == 429849-1.html 429849-1-ref.html # bug 432288 +== 1160342-1.html 1160342-ref.html +== 1160342-2.html 1160342-ref.html diff --git a/layout/style/xbl-marquee/xbl-marquee.xml b/layout/style/xbl-marquee/xbl-marquee.xml index 4951553fe3b4..1b5b71a256ef 100644 --- a/layout/style/xbl-marquee/xbl-marquee.xml +++ b/layout/style/xbl-marquee/xbl-marquee.xml @@ -20,6 +20,7 @@ + this._mutationActor(this._mutationObserver.takeRecords()); return this._behavior; @@ -90,6 +93,7 @@ + + + + 0) { + var mutation = aMutations.shift(); + var attrName = mutation.attributeName.toLowerCase(); + var oldValue = mutation.oldValue; + var target = mutation.target; + var newValue = target.getAttribute(attrName); + + if (oldValue != newValue) { + switch (attrName) { + case "loop": + if (!target._set_loop(newValue)) { + if (!newValue) { + target._loop = -1; + if (target.runId == 0) + target.start(); + } + } + if (target.rundId == 0) + target.start(); + break; + case "scrollamount": + if (!newValue) + target._scrollAmount = 6; + else + target._set_scrollAmount(newValue); + break; + case "scrolldelay": + if (!newValue) + target._scrollDelay = 85; + else + target._set_scrollDelay(newValue); + target.stop(); + target.start(); + break; + case "truespeed": + //needed to update target._scrollDelay + var myThis = target; + var lambda = function() {myThis._set_scrollDelay(myThis.getAttribute('scrolldelay'));} + window.setTimeout(lambda, 0); + break; + case "behavior": + if (!newValue) + target._behavior = "scroll"; + else + target._set_behavior(newValue); + target.startNewDirection = true; + if ((oldValue == "slide" && target.newPosition == target.stopAt) || + newValue == "alternate" || newValue == "slide") { + target.stop(); + target._doMove(true); + } + break; + case "direction": + if (!newValue) + target._direction = "left"; + else + target._set_direction(newValue); + break; + case "width": + case "height": + target.startNewDirection = true; + break; + case "onstart": + target._setEventListener("start", newValue); + break; + case "onfinish": + target._setEventListener("finish", newValue); + break; + case "onbounce": + target._setEventListener("bounce", newValue); + break; + } + } + } + ]]> + + + - - - - - - Date: Wed, 3 Feb 2016 02:53:00 +0100 Subject: [PATCH 010/115] Bug 1170572 - MQ CSS change not observed by picture source elements r=jdm --- dom/html/HTMLSourceElement.cpp | 30 ++++++++++++------- dom/html/HTMLSourceElement.h | 4 +++ .../general/test_picture_mutations.html | 3 +- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/dom/html/HTMLSourceElement.cpp b/dom/html/HTMLSourceElement.cpp index 33c238a28ae3..378c86abf76b 100644 --- a/dom/html/HTMLSourceElement.cpp +++ b/dom/html/HTMLSourceElement.cpp @@ -82,6 +82,20 @@ HTMLSourceElement::WouldMatchMediaForDocument(const nsAString& aMedia, return pctx && mediaList->Matches(pctx, nullptr); } +void +HTMLSourceElement::UpdateMediaList(const nsAttrValue* aValue) +{ + mMediaList = nullptr; + nsString mediaStr; + if (!aValue || (mediaStr = aValue->GetStringValue()).IsEmpty()) { + return; + } + + nsCSSParser cssParser; + mMediaList = new nsMediaList(); + cssParser.ParseMediaList(mediaStr, nullptr, 0, mMediaList, false); +} + nsresult HTMLSourceElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) @@ -105,23 +119,17 @@ HTMLSourceElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, img->PictureSourceSrcsetChanged(AsContent(), strVal, aNotify); } else if (aName == nsGkAtoms::sizes) { img->PictureSourceSizesChanged(AsContent(), strVal, aNotify); - } else if (aName == nsGkAtoms::media || - aName == nsGkAtoms::type) { + } else if (aName == nsGkAtoms::media) { + UpdateMediaList(aValue); + img->PictureSourceMediaOrTypeChanged(AsContent(), aNotify); + } else if (aName == nsGkAtoms::type) { img->PictureSourceMediaOrTypeChanged(AsContent(), aNotify); } } } } else if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::media) { - mMediaList = nullptr; - if (aValue) { - nsString mediaStr = aValue->GetStringValue(); - if (!mediaStr.IsEmpty()) { - nsCSSParser cssParser; - mMediaList = new nsMediaList(); - cssParser.ParseMediaList(mediaStr, nullptr, 0, mMediaList, false); - } - } + UpdateMediaList(aValue); } else if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) { mSrcMediaSource = nullptr; if (aValue) { diff --git a/dom/html/HTMLSourceElement.h b/dom/html/HTMLSourceElement.h index a49685765d04..cce02930ef3f 100644 --- a/dom/html/HTMLSourceElement.h +++ b/dom/html/HTMLSourceElement.h @@ -13,6 +13,7 @@ #include "mozilla/dom/HTMLMediaElement.h" class nsMediaList; +class nsAttrValue; namespace mozilla { namespace dom { @@ -118,6 +119,9 @@ protected: private: RefPtr mMediaList; RefPtr mSrcMediaSource; + + // Generates a new nsMediaList using the given input + void UpdateMediaList(const nsAttrValue* aValue); }; } // namespace dom diff --git a/dom/tests/mochitest/general/test_picture_mutations.html b/dom/tests/mochitest/general/test_picture_mutations.html index bdfd9f7db54c..752b02fa7b34 100644 --- a/dom/tests/mochitest/general/test_picture_mutations.html +++ b/dom/tests/mochitest/general/test_picture_mutations.html @@ -165,7 +165,6 @@ expectEvents(1, 0, function() { is(img.currentSrc, testPNG50, "Should have switched to testPNG50"); -Math.sin(90); // Now add a source *also* wanting that DPI *just before* the // selected source. Properly re-running the algorithm should @@ -231,7 +230,7 @@ Math.sin(90); is(img.currentSrc, testPNG100, "Should still have testPNG100"); // And a valid MQ - source1.media = "(min-resolution: 3dppx)"; + source1.media = "(min-resolution: 1dppx)"; expectEvents(1, 0, function() { // And a valid type... source1.type = "image/png"; From 140ab016c2465834837a7a2d1b09201cf70af4b5 Mon Sep 17 00:00:00 2001 From: Nick Robson Date: Sun, 14 Feb 2016 14:05:00 +0100 Subject: [PATCH 011/115] Bug 1170572 - Web Platform Test for setting MQ on picture source after srcset. r=jdm --- testing/web-platform/meta/MANIFEST.json | 11 ++++++- .../the-img-element/update-media.html | 32 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-media.html diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 427edc6a0893..667a06226f09 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -33758,7 +33758,16 @@ }, "local_changes": { "deleted": [], - "items": {}, + "items": { + "testharness": { + "html/semantics/embedded-content/the-img-element/update-media.html": [ + { + "path": "html/semantics/embedded-content/the-img-element/update-media.html", + "url": "/html/semantics/embedded-content/the-img-element/update-media.html" + } + ] + } + }, "reftest_nodes": {} }, "reftest_nodes": { diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-media.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-media.html new file mode 100644 index 000000000000..dd679ef57158 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-media.html @@ -0,0 +1,32 @@ + + +img update media + + + + +
+ + + + + \ No newline at end of file From d5f84ee56faf7b4043a3223f1d0c5d8aade933c1 Mon Sep 17 00:00:00 2001 From: Kershaw Chang Date: Wed, 17 Feb 2016 22:29:00 +0100 Subject: [PATCH 012/115] Bug 1239955 - Let DNSService rely on IOService::Offline, r=bagder --- netwerk/base/nsIOService.cpp | 4 ---- netwerk/dns/ChildDNSService.cpp | 24 +++++++++++------------- netwerk/dns/ChildDNSService.h | 3 ++- netwerk/dns/nsDNSService2.cpp | 24 ++++++++++-------------- netwerk/dns/nsDNSService2.h | 3 ++- netwerk/dns/nsPIDNSService.idl | 7 +------ 6 files changed, 26 insertions(+), 39 deletions(-) diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp index e72ebafe374c..2e519f7dcc4d 100644 --- a/netwerk/base/nsIOService.cpp +++ b/netwerk/base/nsIOService.cpp @@ -1021,9 +1021,6 @@ nsIOService::SetOffline(bool offline) NS_IOSERVICE_GOING_OFFLINE_TOPIC, offlineString.get()); - if (mDNSService) - mDNSService->SetOffline(true); - if (mSocketTransportService) mSocketTransportService->SetOffline(true); @@ -1036,7 +1033,6 @@ nsIOService::SetOffline(bool offline) else if (!offline && mOffline) { // go online if (mDNSService) { - mDNSService->SetOffline(false); DebugOnly rv = mDNSService->Init(); NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service init failed"); } diff --git a/netwerk/dns/ChildDNSService.cpp b/netwerk/dns/ChildDNSService.cpp index d202c68fceb6..a7b49679e3ea 100644 --- a/netwerk/dns/ChildDNSService.cpp +++ b/netwerk/dns/ChildDNSService.cpp @@ -4,11 +4,13 @@ #include "mozilla/net/ChildDNSService.h" #include "nsIDNSListener.h" +#include "nsIIOService.h" #include "nsIThread.h" #include "nsThreadUtils.h" #include "nsIXPConnect.h" #include "nsIPrefService.h" #include "nsIProtocolProxyService.h" +#include "nsNetCID.h" #include "mozilla/net/NeckoChild.h" #include "mozilla/net/DNSListenerProxy.h" #include "nsServiceManagerUtils.h" @@ -42,7 +44,6 @@ NS_IMPL_ISUPPORTS(ChildDNSService, ChildDNSService::ChildDNSService() : mFirstTime(true) - , mOffline(false) , mDisablePrefetch(false) , mPendingRequestsLock("DNSPendingRequestsLock") { @@ -103,7 +104,7 @@ ChildDNSService::AsyncResolveExtended(const nsACString &hostname, // Support apps being 'offline' even if parent is not: avoids DNS traffic by // apps that have been told they are offline. - if (mOffline) { + if (GetOffline()) { flags |= RESOLVE_OFFLINE; } @@ -298,18 +299,15 @@ ChildDNSService::SetPrefetchEnabled(bool inVal) return NS_OK; } -NS_IMETHODIMP -ChildDNSService::GetOffline(bool* aResult) +bool +ChildDNSService::GetOffline() const { - *aResult = mOffline; - return NS_OK; -} - -NS_IMETHODIMP -ChildDNSService::SetOffline(bool value) -{ - mOffline = value; - return NS_OK; + bool offline = false; + nsCOMPtr io = do_GetService(NS_IOSERVICE_CONTRACTID); + if (io) { + io->GetOffline(&offline); + } + return offline; } //----------------------------------------------------------------------------- diff --git a/netwerk/dns/ChildDNSService.h b/netwerk/dns/ChildDNSService.h index b2c3a1dbcc1e..1662960bbec0 100644 --- a/netwerk/dns/ChildDNSService.h +++ b/netwerk/dns/ChildDNSService.h @@ -35,6 +35,8 @@ public: static ChildDNSService* GetSingleton(); void NotifyRequestDone(DNSRequestChild *aDnsRequest); + + bool GetOffline() const; private: virtual ~ChildDNSService(); @@ -45,7 +47,6 @@ private: nsACString &aHashKey); bool mFirstTime; - bool mOffline; bool mDisablePrefetch; // We need to remember pending dns requests to be able to cancel them. diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp index 172405da6985..6659c03b22be 100644 --- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -483,7 +483,6 @@ nsDNSService::nsDNSService() , mDisableIPv6(false) , mDisablePrefetch(false) , mFirstTime(true) - , mOffline(false) , mNotifyResolution(false) , mOfflineLocalhost(false) { @@ -677,18 +676,15 @@ nsDNSService::Shutdown() return NS_OK; } -NS_IMETHODIMP -nsDNSService::GetOffline(bool *offline) +bool +nsDNSService::GetOffline() const { - *offline = mOffline; - return NS_OK; -} - -NS_IMETHODIMP -nsDNSService::SetOffline(bool offline) -{ - mOffline = offline; - return NS_OK; + bool offline = false; + nsCOMPtr io = do_GetService(NS_IOSERVICE_CONTRACTID); + if (io) { + io->GetOffline(&offline); + } + return offline; } NS_IMETHODIMP @@ -784,7 +780,7 @@ nsDNSService::AsyncResolveExtended(const nsACString &aHostname, return rv; } - if (mOffline && + if (GetOffline() && (!mOfflineLocalhost || !hostname.LowerCaseEqualsASCII("localhost"))) { flags |= RESOLVE_OFFLINE; } @@ -899,7 +895,7 @@ nsDNSService::Resolve(const nsACString &aHostname, return rv; } - if (mOffline && + if (GetOffline() && (!mOfflineLocalhost || !hostname.LowerCaseEqualsASCII("localhost"))) { flags |= RESOLVE_OFFLINE; } diff --git a/netwerk/dns/nsDNSService2.h b/netwerk/dns/nsDNSService2.h index a33e2dd9b48a..79454b901b3f 100644 --- a/netwerk/dns/nsDNSService2.h +++ b/netwerk/dns/nsDNSService2.h @@ -36,6 +36,8 @@ public: size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + bool GetOffline() const; + private: ~nsDNSService(); @@ -62,7 +64,6 @@ private: bool mDisablePrefetch; bool mBlockDotOnion; bool mFirstTime; - bool mOffline; bool mNotifyResolution; bool mOfflineLocalhost; nsTHashtable mLocalDomains; diff --git a/netwerk/dns/nsPIDNSService.idl b/netwerk/dns/nsPIDNSService.idl index d89f1bdfb841..9bed0555c5ef 100644 --- a/netwerk/dns/nsPIDNSService.idl +++ b/netwerk/dns/nsPIDNSService.idl @@ -10,7 +10,7 @@ * This is a private interface used by the internals of the networking library. * It will never be frozen. Do not use it in external code. */ -[scriptable, uuid(6b16fb1f-5709-4c94-a89f-a22be873c54d)] +[scriptable, uuid(24e598fd-7b1a-436c-9154-14d8b38df8a5)] interface nsPIDNSService : nsIDNSService { /** @@ -31,9 +31,4 @@ interface nsPIDNSService : nsIDNSService * Whether or not DNS prefetching (aka RESOLVE_SPECULATE) is enabled */ attribute boolean prefetchEnabled; - - /** - * @return whether the DNS service is offline. - */ - attribute boolean offline; }; From 9bc9dd2c5c917423ef1bfa28db2e2a40357ac35f Mon Sep 17 00:00:00 2001 From: Louis Christie Date: Fri, 12 Feb 2016 10:02:00 +1300 Subject: [PATCH 013/115] Bug 1238433: Added telemtry for the proportion of frames dropped during playback. r=cpearce --- dom/html/HTMLMediaElement.cpp | 14 ++++++++++++++ toolkit/components/telemetry/Histograms.json | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index e2d23fa4ac9e..edf48c844bfa 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -108,6 +108,9 @@ static mozilla::LazyLogModule gMediaElementEventsLog("nsMediaElementEvents"); #include "mozilla/EventStateManager.h" +#include "mozilla/dom/HTMLVideoElement.h" +#include "mozilla/dom/VideoPlaybackQuality.h" + using namespace mozilla::layers; using mozilla::net::nsMediaFragmentURIParser; @@ -2701,6 +2704,17 @@ HTMLMediaElement::ReportMSETelemetry() } } + if (HTMLVideoElement* vid = HTMLVideoElement::FromContentOrNull(this)) { + RefPtr quality = vid->GetVideoPlaybackQuality(); + uint64_t totalFrames = quality->TotalVideoFrames(); + uint64_t droppedFrames = quality->DroppedVideoFrames(); + uint32_t percentage = 100 * droppedFrames / totalFrames; + LOG(LogLevel::Debug, + ("Reporting telemetry DROPPED_FRAMES_IN_VIDEO_PLAYBACK")); + Telemetry::Accumulate(Telemetry::VIDEO_DROPPED_FRAMES_PROPORTION, + percentage); + } + Telemetry::Accumulate(Telemetry::VIDEO_MSE_UNLOAD_STATE, state); LOG(LogLevel::Debug, ("%p VIDEO_MSE_UNLOAD_STATE = %d", this, state)); diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index fd17887a9cc4..86b603a43d3c 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -10201,6 +10201,15 @@ "kind": "count", "description": "Uses of HTMLMediaElement.fastSeek" }, + "VIDEO_DROPPED_FRAMES_PROPORTION" : { + "alert_emails": ["lchristie@mozilla.com", "cpearce@mozilla.com"], + "expires_in_version": "55", + "kind": "linear", + "high": "100", + "n_buckets": 101, + "bug_numbers": [1238433], + "description": "Percentage of frames decoded frames dropped in an HTMLVideoElement" + }, "TAB_SWITCH_CACHE_POSITION": { "expires_in_version": "55", "bug_numbers": [1242013], From f820da8f38e2cd92611b0155f46dbcbfafc88c5f Mon Sep 17 00:00:00 2001 From: Liang-Heng Chen Date: Wed, 17 Feb 2016 00:43:00 +0100 Subject: [PATCH 014/115] Bug 1244044 - remember display status; r=jerry --- widget/gonk/nsScreenManagerGonk.cpp | 14 +++++++++++++- widget/gonk/nsScreenManagerGonk.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/widget/gonk/nsScreenManagerGonk.cpp b/widget/gonk/nsScreenManagerGonk.cpp index 976c7fb26d7a..828b6de08d21 100644 --- a/widget/gonk/nsScreenManagerGonk.cpp +++ b/widget/gonk/nsScreenManagerGonk.cpp @@ -754,6 +754,9 @@ NS_IMPL_ISUPPORTS(nsScreenManagerGonk, nsIScreenManager) nsScreenManagerGonk::nsScreenManagerGonk() : mInitialized(false) +#if ANDROID_VERSION >= 19 + , mDisplayEnabled(false) +#endif { } @@ -816,9 +819,16 @@ nsScreenManagerGonk::Initialize() void nsScreenManagerGonk::DisplayEnabled(bool aEnabled) { + MOZ_ASSERT(NS_IsMainThread()); + #if ANDROID_VERSION >= 19 + /* Bug 1244044 + * This function could be called before |mCompositorVsyncScheduler| is set. + * To avoid this issue, keep the value stored in |mDisplayEnabled|. + */ + mDisplayEnabled = aEnabled; if (mCompositorVsyncScheduler) { - mCompositorVsyncScheduler->SetDisplay(aEnabled); + mCompositorVsyncScheduler->SetDisplay(mDisplayEnabled); } #endif @@ -1063,6 +1073,8 @@ nsScreenManagerGonk::SetCompositorVsyncScheduler(mozilla::layers::CompositorVsyn // We assume on b2g that there is only 1 CompositorParent MOZ_ASSERT(mCompositorVsyncScheduler == nullptr); + MOZ_ASSERT(aObserver); mCompositorVsyncScheduler = aObserver; + mCompositorVsyncScheduler->SetDisplay(mDisplayEnabled); } #endif diff --git a/widget/gonk/nsScreenManagerGonk.h b/widget/gonk/nsScreenManagerGonk.h index 3947ea98eaa1..23a2f24b4122 100644 --- a/widget/gonk/nsScreenManagerGonk.h +++ b/widget/gonk/nsScreenManagerGonk.h @@ -220,6 +220,7 @@ protected: RefPtr mScreenOffEvent; #if ANDROID_VERSION >= 19 + bool mDisplayEnabled; RefPtr mCompositorVsyncScheduler; #endif }; From 1c46abe6c4cbe799cb92a3893e9e12dc7cd186b2 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Fri, 12 Feb 2016 14:38:50 +0000 Subject: [PATCH 015/115] Bug 1247336 - De-dupe changes in ActiveLayerTracker before treating property as animated. r=roc In ActiveLayerTracker check if the value of a property has actually changed, rather than being set to its existing value, before treating the property as animated. This will help avoid over-layerization of some frames. --- layout/base/ActiveLayerTracker.cpp | 22 +++++++++++++++++----- layout/base/ActiveLayerTracker.h | 13 +++++++++++-- layout/style/nsDOMCSSAttrDeclaration.cpp | 2 +- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/layout/base/ActiveLayerTracker.cpp b/layout/base/ActiveLayerTracker.cpp index cd071b739a6f..6ae671f09611 100644 --- a/layout/base/ActiveLayerTracker.cpp +++ b/layout/base/ActiveLayerTracker.cpp @@ -20,6 +20,7 @@ #include "nsStyleTransformMatrix.h" #include "nsTransitionManager.h" #include "nsDisplayList.h" +#include "nsDOMCSSDeclaration.h" namespace mozilla { @@ -311,12 +312,21 @@ ActiveLayerTracker::NotifyOffsetRestyle(nsIFrame* aFrame) } /* static */ void -ActiveLayerTracker::NotifyAnimated(nsIFrame* aFrame, nsCSSProperty aProperty) +ActiveLayerTracker::NotifyAnimated(nsIFrame* aFrame, + nsCSSProperty aProperty, + const nsAString& aNewValue, + nsDOMCSSDeclaration* aDOMCSSDecl) { LayerActivity* layerActivity = GetLayerActivityForUpdate(aFrame); uint8_t& mutationCount = layerActivity->RestyleCountForProperty(aProperty); - // We know this is animated, so just hack the mutation count. - mutationCount = 0xFF; + if (mutationCount != 0xFF) { + nsAutoString oldValue; + aDOMCSSDecl->GetPropertyValue(aProperty, oldValue); + if (aNewValue != oldValue) { + // We know this is animated, so just hack the mutation count. + mutationCount = 0xFF; + } + } } /* static */ void @@ -354,10 +364,12 @@ IsPresContextInScriptAnimationCallback(nsPresContext* aPresContext) /* static */ void ActiveLayerTracker::NotifyInlineStyleRuleModified(nsIFrame* aFrame, - nsCSSProperty aProperty) + nsCSSProperty aProperty, + const nsAString& aNewValue, + nsDOMCSSDeclaration* aDOMCSSDecl) { if (IsPresContextInScriptAnimationCallback(aFrame->PresContext())) { - NotifyAnimated(aFrame, aProperty); + NotifyAnimated(aFrame, aProperty, aNewValue, aDOMCSSDecl); } if (gLayerActivityTracker && gLayerActivityTracker->mCurrentScrollHandlerFrame.IsAlive()) { diff --git a/layout/base/ActiveLayerTracker.h b/layout/base/ActiveLayerTracker.h index 302b0ba13d20..479fb89a1f0e 100644 --- a/layout/base/ActiveLayerTracker.h +++ b/layout/base/ActiveLayerTracker.h @@ -10,6 +10,7 @@ class nsIFrame; class nsIContent; class nsDisplayListBuilder; +class nsDOMCSSDeclaration; namespace mozilla { @@ -47,8 +48,12 @@ public: /** * Mark aFrame as being known to have an animation of aProperty. * Any such marking will time out after a short period. + * aNewValue and aDOMCSSDecl are used to determine whether the property's + * value has changed. */ - static void NotifyAnimated(nsIFrame* aFrame, nsCSSProperty aProperty); + static void NotifyAnimated(nsIFrame* aFrame, nsCSSProperty aProperty, + const nsAString& aNewValue, + nsDOMCSSDeclaration* aDOMCSSDecl); /** * Notify aFrame as being known to have an animation of aProperty through an * inline style modification during aScrollFrame's scroll event handler. @@ -60,8 +65,12 @@ public: * has been modified. * This notification is incomplete --- not all modifications to inline * style will trigger this. + * aNewValue and aDOMCSSDecl are used to determine whether the property's + * value has changed. */ - static void NotifyInlineStyleRuleModified(nsIFrame* aFrame, nsCSSProperty aProperty); + static void NotifyInlineStyleRuleModified(nsIFrame* aFrame, nsCSSProperty aProperty, + const nsAString& aNewValue, + nsDOMCSSDeclaration* aDOMCSSDecl); /** * Return true if aFrame's aProperty style should be considered as being animated * for pre-rendering. diff --git a/layout/style/nsDOMCSSAttrDeclaration.cpp b/layout/style/nsDOMCSSAttrDeclaration.cpp index 9462f2344892..7b9ba2a870dc 100644 --- a/layout/style/nsDOMCSSAttrDeclaration.cpp +++ b/layout/style/nsDOMCSSAttrDeclaration.cpp @@ -186,7 +186,7 @@ nsDOMCSSAttributeDeclaration::SetPropertyValue(const nsCSSProperty aPropID, aPropID == eCSSProperty_background_position) { nsIFrame* frame = mElement->GetPrimaryFrame(); if (frame) { - ActiveLayerTracker::NotifyInlineStyleRuleModified(frame, aPropID); + ActiveLayerTracker::NotifyInlineStyleRuleModified(frame, aPropID, aValue, this); } } return nsDOMCSSDeclaration::SetPropertyValue(aPropID, aValue); From 3fe5de3dab1cc7e772475571de9d5ba6ee7531fc Mon Sep 17 00:00:00 2001 From: Milan Sreckovic Date: Mon, 15 Feb 2016 12:53:00 +0100 Subject: [PATCH 016/115] Bug 1247706 - "Please don't disable WebGL if crashed on WebGL context". r=dvander --- gfx/gl/GLContext.cpp | 6 ------ gfx/src/DriverCrashGuard.cpp | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 06d4d4fccfa8..2fc629466b60 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -31,7 +31,6 @@ #include "TextureGarbageBin.h" #include "gfx2DGlue.h" #include "gfxPrefs.h" -#include "DriverCrashGuard.h" #include "mozilla/IntegerPrintfMacros.h" #include "OGLShaderProgram.h" // for ShaderProgramType @@ -476,11 +475,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) return true; } - GLContextCrashGuard crashGuard; - if (crashGuard.Crashed()) { - return false; - } - mWorkAroundDriverBugs = gfxPrefs::WorkAroundDriverBugs(); SymLoadStruct symbols[] = { diff --git a/gfx/src/DriverCrashGuard.cpp b/gfx/src/DriverCrashGuard.cpp index 34aa39fa1720..4edbe127ab43 100644 --- a/gfx/src/DriverCrashGuard.cpp +++ b/gfx/src/DriverCrashGuard.cpp @@ -525,13 +525,13 @@ GLContextCrashGuard::UpdateEnvironment() void GLContextCrashGuard::LogCrashRecovery() { - gfxCriticalNote << "GLContext just crashed and is now disabled."; + gfxCriticalNote << "GLContext just crashed."; } void GLContextCrashGuard::LogFeatureDisabled() { - gfxCriticalNote << "GLContext is disabled due to a previous crash."; + gfxCriticalNote << "GLContext remains enabled despite a previous crash."; } } // namespace gfx From 581cd94d0a26d665da6ea0620bd84e05cb70d720 Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Mon, 15 Feb 2016 11:45:00 +0100 Subject: [PATCH 017/115] Bug 1248003 - Purge from HTTP cache memory pool only in reasonable intervals, r=michal --- netwerk/cache2/CacheStorageService.cpp | 10 ++++++++++ netwerk/cache2/CacheStorageService.h | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/netwerk/cache2/CacheStorageService.cpp b/netwerk/cache2/CacheStorageService.cpp index a3dd75d2e3da..22cce5cff8e7 100644 --- a/netwerk/cache2/CacheStorageService.cpp +++ b/netwerk/cache2/CacheStorageService.cpp @@ -1239,6 +1239,16 @@ CacheStorageService::PurgeOverMemoryLimit() LOG(("CacheStorageService::PurgeOverMemoryLimit")); + static TimeDuration const kFourSeconds = TimeDuration::FromSeconds(4); + TimeStamp now = TimeStamp::NowLoRes(); + + if (!mLastPurgeTime.IsNull() && now - mLastPurgeTime < kFourSeconds) { + LOG((" bypassed, too soon")); + return; + } + + mLastPurgeTime = now; + Pool(true).PurgeOverMemoryLimit(); Pool(false).PurgeOverMemoryLimit(); } diff --git a/netwerk/cache2/CacheStorageService.h b/netwerk/cache2/CacheStorageService.h index d8bbdd3c84e1..7da8297067e9 100644 --- a/netwerk/cache2/CacheStorageService.h +++ b/netwerk/cache2/CacheStorageService.h @@ -312,7 +312,7 @@ private: nsTArray > mFrecencyArray; nsTArray > mExpirationArray; - mozilla::Atomic mMemorySize; + Atomic mMemorySize; bool OnMemoryConsumptionChange(uint32_t aSavedMemorySize, uint32_t aCurrentMemoryConsumption); @@ -331,6 +331,7 @@ private: MemoryPool mDiskPool; MemoryPool mMemoryPool; + TimeStamp mLastPurgeTime; MemoryPool& Pool(bool aUsingDisk) { return aUsingDisk ? mDiskPool : mMemoryPool; From 3d59de44973c0f9d5cc2e5f0c7bdf04f07ed9885 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Wed, 17 Feb 2016 15:57:01 +0100 Subject: [PATCH 018/115] Bug 1248981 - Fix spelling error in nsMenuUtilsX.mm, a=tomcat MozReview-Commit-ID: FQNNmz9Mirk --HG-- extra : transplant_source : %FA%9D%02%83%AC%14%1F%BB%20%E7%9D%26W%7Fk%94ah%D6%BA --- widget/cocoa/nsMenuUtilsX.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/cocoa/nsMenuUtilsX.mm b/widget/cocoa/nsMenuUtilsX.mm index b3108d9a0804..db6471712794 100644 --- a/widget/cocoa/nsMenuUtilsX.mm +++ b/widget/cocoa/nsMenuUtilsX.mm @@ -116,7 +116,7 @@ NSMenuItem* nsMenuUtilsX::GetStandardEditMenuItem() NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; // In principle we should be able to allocate this once and then always - // return the same object. But wierd interactions happen between native + // return the same object. But weird interactions happen between native // app-modal dialogs and Gecko-modal dialogs that open above them. So what // we return here isn't always released before it needs to be added to // another menu. See bmo bug 468393. From e91daadfb4c14ff75deba5a6a37d209b3bf82bde Mon Sep 17 00:00:00 2001 From: Luca Greco Date: Wed, 17 Feb 2016 15:57:15 +0100 Subject: [PATCH 019/115] Bug 1248982 - Fix spelling error in nsOSHelperAppService.mm inline comments. r=jdm MozReview-Commit-ID: 8QiITYlDd6o --- uriloader/exthandler/mac/nsOSHelperAppService.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uriloader/exthandler/mac/nsOSHelperAppService.mm b/uriloader/exthandler/mac/nsOSHelperAppService.mm index 5f030cc4cf92..0367e49bee4e 100644 --- a/uriloader/exthandler/mac/nsOSHelperAppService.mm +++ b/uriloader/exthandler/mac/nsOSHelperAppService.mm @@ -329,7 +329,7 @@ nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType, if (!aMIMEType.IsEmpty()) { CFURLRef appURL = NULL; // CFStringCreateWithCString() can fail even if we're not out of memory -- - // for example if the 'cStr' parameter is something very wierd (like "ÿÿ~" + // for example if the 'cStr' parameter is something very weird (like "ÿÿ~" // aka "\xFF\xFF~"), or possibly if it can't be interpreted as using what's // specified in the 'encoding' parameter. See bug 548719. cfMIMEType = ::CFStringCreateWithCString(NULL, flatType.get(), From 6867ecf8e731efd38552a722a9cb74e4353b8b1c Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Wed, 17 Feb 2016 10:30:00 +0100 Subject: [PATCH 020/115] Bug 1248711 - Make Mochitest NSPR upload work with --run-by-dir, r=jmaher --- testing/mochitest/runtests.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/testing/mochitest/runtests.py b/testing/mochitest/runtests.py index ef30a99accb4..c6889db88c07 100644 --- a/testing/mochitest/runtests.py +++ b/testing/mochitest/runtests.py @@ -31,6 +31,7 @@ import tempfile import time import traceback import urllib2 +import uuid import zipfile import bisection @@ -1210,8 +1211,6 @@ toolbar#nav-bar { self.nsprLogs = NSPR_LOG_MODULES and "MOZ_UPLOAD_DIR" in os.environ if self.nsprLogs: browserEnv["NSPR_LOG_MODULES"] = NSPR_LOG_MODULES - - browserEnv["NSPR_LOG_FILE"] = "%s/nspr.log" % tempfile.gettempdir() browserEnv["GECKO_SEPARATE_NSPR_LOGS"] = "1" if debugger and not options.slowscript: @@ -2288,6 +2287,9 @@ class MochitestDesktop(MochitestBase): if self.browserEnv is None: return 1 + if self.nsprLogs: + self.browserEnv["NSPR_LOG_FILE"] = "{}/nspr-pid=%PID-uid={}.log".format(self.browserEnv["MOZ_UPLOAD_DIR"], str(uuid.uuid4())) + try: self.startServers(options, debuggerInfo) @@ -2400,14 +2402,6 @@ class MochitestDesktop(MochitestBase): options.symbolsPath), ) - if self.nsprLogs: - with zipfile.ZipFile("%s/nsprlog.zip" % self.browserEnv["MOZ_UPLOAD_DIR"], "w", zipfile.ZIP_DEFLATED) as logzip: - for logfile in glob.glob( - "%s/nspr*.log*" % - tempfile.gettempdir()): - logzip.write(logfile) - os.remove(logfile) - self.log.info("runtests.py | Running tests: end.") if self.manifest is not None: @@ -2654,6 +2648,14 @@ def run_test_harness(options): result = runner.runTests(options) + if runner.nsprLogs: + with zipfile.ZipFile("{}/nsprlogs.zip".format(runner.browserEnv["MOZ_UPLOAD_DIR"]), + "w", zipfile.ZIP_DEFLATED) as logzip: + for logfile in glob.glob("{}/nspr*.log*".format(runner.browserEnv["MOZ_UPLOAD_DIR"])): + logzip.write(logfile) + os.remove(logfile) + logzip.close() + # don't dump failures if running from automation as treeherder already displays them if build_obj: if runner.message_logger.errors: From 474154ff850abfd526413fd8d5f2cb9283717455 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Thu, 18 Feb 2016 10:52:03 +0100 Subject: [PATCH 021/115] Backed out changeset c7be30a5321e (bug 1238433) for bustage --- dom/html/HTMLMediaElement.cpp | 14 -------------- toolkit/components/telemetry/Histograms.json | 9 --------- 2 files changed, 23 deletions(-) diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index edf48c844bfa..e2d23fa4ac9e 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -108,9 +108,6 @@ static mozilla::LazyLogModule gMediaElementEventsLog("nsMediaElementEvents"); #include "mozilla/EventStateManager.h" -#include "mozilla/dom/HTMLVideoElement.h" -#include "mozilla/dom/VideoPlaybackQuality.h" - using namespace mozilla::layers; using mozilla::net::nsMediaFragmentURIParser; @@ -2704,17 +2701,6 @@ HTMLMediaElement::ReportMSETelemetry() } } - if (HTMLVideoElement* vid = HTMLVideoElement::FromContentOrNull(this)) { - RefPtr quality = vid->GetVideoPlaybackQuality(); - uint64_t totalFrames = quality->TotalVideoFrames(); - uint64_t droppedFrames = quality->DroppedVideoFrames(); - uint32_t percentage = 100 * droppedFrames / totalFrames; - LOG(LogLevel::Debug, - ("Reporting telemetry DROPPED_FRAMES_IN_VIDEO_PLAYBACK")); - Telemetry::Accumulate(Telemetry::VIDEO_DROPPED_FRAMES_PROPORTION, - percentage); - } - Telemetry::Accumulate(Telemetry::VIDEO_MSE_UNLOAD_STATE, state); LOG(LogLevel::Debug, ("%p VIDEO_MSE_UNLOAD_STATE = %d", this, state)); diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 86b603a43d3c..fd17887a9cc4 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -10201,15 +10201,6 @@ "kind": "count", "description": "Uses of HTMLMediaElement.fastSeek" }, - "VIDEO_DROPPED_FRAMES_PROPORTION" : { - "alert_emails": ["lchristie@mozilla.com", "cpearce@mozilla.com"], - "expires_in_version": "55", - "kind": "linear", - "high": "100", - "n_buckets": 101, - "bug_numbers": [1238433], - "description": "Percentage of frames decoded frames dropped in an HTMLVideoElement" - }, "TAB_SWITCH_CACHE_POSITION": { "expires_in_version": "55", "bug_numbers": [1242013], From 5dd7fcd3014a30b49e2953b8f0a5942fe9c2dce2 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Thu, 18 Feb 2016 11:33:12 +0100 Subject: [PATCH 022/115] Bug 1245566 - Enable taskcluster scheduling for valgrind-mochitest runs: basic_tc_scheduling. r=armenzg. --- .../tasks/branches/base_job_flags.yml | 2 ++ .../tasks/tests/fx_linux64_mochitest_vg.yml | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 testing/taskcluster/tasks/tests/fx_linux64_mochitest_vg.yml diff --git a/testing/taskcluster/tasks/branches/base_job_flags.yml b/testing/taskcluster/tasks/branches/base_job_flags.yml index f78bfad9aaea..0be9293bab8b 100644 --- a/testing/taskcluster/tasks/branches/base_job_flags.yml +++ b/testing/taskcluster/tasks/branches/base_job_flags.yml @@ -54,6 +54,7 @@ flags: mochitest-dt-e10s: /mochitest-devtools-chrome-e10s.*/ mochitest-gl: /mochitest-webgl.*/ mochitest-push: /mochitest-push.*/ + mochitest-vg: /mochitest-valgrind.*/ reftest: /(plain-)?reftest.*/ reftest-no-accel: /(plain-)?reftest-no-accel.*/ reftests: /(plain-)?reftest.*/ @@ -143,6 +144,7 @@ flags: - mochitest-oop - mochitest-push - mochitest-webgl + - mochitest-valgrind - mozmill - reftest - reftest-e10s diff --git a/testing/taskcluster/tasks/tests/fx_linux64_mochitest_vg.yml b/testing/taskcluster/tasks/tests/fx_linux64_mochitest_vg.yml new file mode 100644 index 000000000000..012425c32ca4 --- /dev/null +++ b/testing/taskcluster/tasks/tests/fx_linux64_mochitest_vg.yml @@ -0,0 +1,35 @@ +--- +$inherits: + from: 'tasks/tests/fx_desktop_generic.yml' +task: + scopes: + - 'docker-worker:capability:device:loopbackVideo' + - 'docker-worker:capability:device:loopbackAudio' + payload: + maxRunTime: 28800 + capabilities: + devices: + loopbackVideo: true + loopbackAudio: true + command: + - --no-read-buildbot-config + - --installer-url={{build_url}} + - --test-packages-url={{test_packages_url}} + - --mochitest-suite=valgrind-plain + - --total-chunk={{total_chunks}} + - --this-chunk={{chunk}} + env: + MOZHARNESS_SCRIPT: 'mozharness/scripts/desktop_unittest.py' + MOZHARNESS_CONFIG: > + mozharness/configs/unittests/linux_unittest.py + mozharness/configs/remove_executables.py + metadata: + name: '[TC] Linux64 mochitest-valgrind-{{chunk}}' + description: Mochitest Valgrind + extra: + chunks: + total: 40 + treeherder: + groupName: Mochitest Valgrind + groupSymbol: M-vg + symbol: {{chunk}} From 9c5cac601663af03559d9b71c3ab8a0cfa3a71bf Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Thu, 18 Feb 2016 11:34:40 +0100 Subject: [PATCH 023/115] Bug 1245566 - Enable taskcluster scheduling for valgrind-mochitest runs: mochitest_valgrind_mods. r=jgraham. --- testing/mozbase/mozdebug/mozdebug/mozdebug.py | 11 ++++++----- .../mozbase/mozlog/mozlog/formatters/tbplformatter.py | 2 +- .../mozharness/configs/unittests/linux_unittest.py | 5 +++-- .../mozharness/mozharness/mozilla/testing/errors.py | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/testing/mozbase/mozdebug/mozdebug/mozdebug.py b/testing/mozbase/mozdebug/mozdebug/mozdebug.py index 864af83abd27..618a6c5ceb29 100755 --- a/testing/mozbase/mozdebug/mozdebug/mozdebug.py +++ b/testing/mozbase/mozdebug/mozdebug/mozdebug.py @@ -233,8 +233,6 @@ def get_default_valgrind_args(): '--vex-iropt-register-updates=allregs-at-mem-access', '--trace-children=yes', '--child-silent-after-fork=yes', - '--leak-check=full', - '--show-possibly-lost=no', ('--trace-children-skip=' + '/usr/bin/hg,/bin/rm,*/bin/certutil,*/bin/pk12util,' + '*/bin/ssltunnel,*/bin/uname,*/bin/which,*/bin/ps,' @@ -242,7 +240,10 @@ def get_default_valgrind_args(): ] + get_default_valgrind_tool_specific_args()) +# The default tool is Memcheck. Feeding these arguments to a different +# Valgrind tool will cause it to fail at startup, so don't do that! def get_default_valgrind_tool_specific_args(): - return [ - '--partial-loads-ok=yes' - ] + return ['--partial-loads-ok=yes', + '--leak-check=full', + '--show-possibly-lost=no', + ] diff --git a/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py b/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py index ca450adf4cda..1c609e60307a 100644 --- a/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py +++ b/testing/mozbase/mozlog/mozlog/formatters/tbplformatter.py @@ -154,7 +154,7 @@ class TbplFormatter(BaseFormatter): return " ".join(test_id) def valgrind_error(self, data): - rv = "TEST-VALGRIND-ERROR | " + data['primary'] + "\n" + rv = "TEST-UNEXPECTED-VALGRIND-ERROR | " + data['primary'] + "\n" for line in data['secondary']: rv = rv + line + "\n" diff --git a/testing/mozharness/configs/unittests/linux_unittest.py b/testing/mozharness/configs/unittests/linux_unittest.py index 540af2acd596..33c1f9d8de9b 100644 --- a/testing/mozharness/configs/unittests/linux_unittest.py +++ b/testing/mozharness/configs/unittests/linux_unittest.py @@ -205,8 +205,9 @@ config = { "all_mochitest_suites": { "valgrind-plain": ["--valgrind=/usr/bin/valgrind", "--valgrind-supp-files=" + VALGRIND_SUPP_ARCH + - "," + VALGRIND_SUPP_CROSS_ARCH], - "plain": [], + "," + VALGRIND_SUPP_CROSS_ARCH, + "--timeout=900", "--max-timeouts=50"], + "plain": [], "plain-chunked": ["--chunk-by-dir=4"], "mochitest-push": ["--subsuite=push"], "chrome": ["--chrome"], diff --git a/testing/mozharness/mozharness/mozilla/testing/errors.py b/testing/mozharness/mozharness/mozilla/testing/errors.py index d0acd29ad53c..606f2f65772b 100644 --- a/testing/mozharness/mozharness/mozilla/testing/errors.py +++ b/testing/mozharness/mozharness/mozilla/testing/errors.py @@ -88,7 +88,7 @@ TinderBoxPrintRe = { "harness_error": { 'full_regex': re.compile(r"(?:TEST-UNEXPECTED-FAIL|PROCESS-CRASH) \| .* \| (application crashed|missing output line for total leaks!|negative leaks caught!|\d+ bytes leaked)"), - 'minimum_regex': re.compile(r'''(TEST-UNEXPECTED|PROCESS-CRASH|TEST-VALGRIND-ERROR)'''), + 'minimum_regex': re.compile(r'''(TEST-UNEXPECTED|PROCESS-CRASH)'''), 'retry_regex': re.compile(r'''FAIL-SHOULD-RETRY''') }, } From d1f7045e5c3b4babaeb54ad85aea56efc8bcf97c Mon Sep 17 00:00:00 2001 From: Emanuel Hoogeveen Date: Tue, 16 Feb 2016 14:36:00 +0100 Subject: [PATCH 024/115] Bug 1232229 - Instrument setting ArenaHeader::next to catch misuse and fix existing instrumentation. r=terrence --HG-- extra : rebase_source : c9063d9745c8331f8d45ac84e043c0545e0dc583 --- js/src/jsgc.cpp | 6 +++++- js/src/jsgc.h | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 0c7afc820744..6cf8e10cf046 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -923,6 +923,7 @@ void Chunk::addArenaToFreeList(JSRuntime* rt, ArenaHeader* aheader) { MOZ_ASSERT(!aheader->allocated()); + MOZ_RELEASE_ASSERT(uintptr_t(info.freeArenasHead) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b))); aheader->next = info.freeArenasHead; info.freeArenasHead = aheader; ++info.numArenasFreeCommitted; @@ -2255,6 +2256,7 @@ ArenaList::relocateArenas(ArenaHeader* toRelocate, ArenaHeader* relocated, Slice toRelocate = arena->next; RelocateArena(arena, sliceBudget); // Prepend to list of relocated arenas + MOZ_RELEASE_ASSERT(uintptr_t(relocated) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b))); arena->next = relocated; relocated = arena; stats.count(gcstats::STAT_ARENA_RELOCATED); @@ -2803,6 +2805,8 @@ GCRuntime::protectAndHoldArenas(ArenaHeader* arenaList) ArenaHeader* next = arena->next; if (!next) { // Prepend to hold list before we protect the memory. + MOZ_RELEASE_ASSERT( + uintptr_t(relocatedArenasToRelease) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b))); arena->next = relocatedArenasToRelease; relocatedArenasToRelease = arenaList; } @@ -3432,7 +3436,7 @@ GCRuntime::sweepBackgroundThings(ZoneList& zones, LifoAlloc& freeBlocks, ThreadT for (unsigned index = 0 ; index < BackgroundFinalizePhases[phase].length ; ++index) { AllocKind kind = BackgroundFinalizePhases[phase].kinds[index]; ArenaHeader* arenas = zone->arenas.arenaListsToSweep[kind]; - MOZ_RELEASE_ASSERT(uintptr_t(arenas) != uintptr_t(-1)); + MOZ_RELEASE_ASSERT(uintptr_t(arenas) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b))); if (arenas) ArenaLists::backgroundFinalize(&fop, arenas, &emptyArenas); } diff --git a/js/src/jsgc.h b/js/src/jsgc.h index e19b4ce607ff..eec0b9e1135f 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -306,6 +306,7 @@ struct SortedArenaListSegment void append(ArenaHeader* aheader) { MOZ_ASSERT(aheader); MOZ_ASSERT_IF(head, head->getAllocKind() == aheader->getAllocKind()); + MOZ_RELEASE_ASSERT(uintptr_t(aheader) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b))); *tailp = aheader; tailp = &aheader->next; } @@ -316,6 +317,7 @@ struct SortedArenaListSegment // description of ArenaList), but from the perspective of a SortedArenaList // this makes no difference. void linkTo(ArenaHeader* aheader) { + MOZ_RELEASE_ASSERT(uintptr_t(aheader) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b))); *tailp = aheader; } }; @@ -544,6 +546,7 @@ class SortedArenaList void extractEmpty(ArenaHeader** empty) { SortedArenaListSegment& segment = segments[thingsPerArena_]; if (segment.head) { + MOZ_RELEASE_ASSERT(uintptr_t(*empty) != uintptr_t(UINT64_C(0x4b4b4b4b4b4b4b4b))); *segment.tailp = *empty; *empty = segment.head; segment.clear(); From 185a769719d2547521583515392782827d3a5654 Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Tue, 16 Feb 2016 23:07:00 +0100 Subject: [PATCH 025/115] Bug 1244049 - Part 1: Define scoped enum for CSSPseudoElement type. r=dbaron --HG-- extra : rebase_source : e53dd269e47fa97eb259ebd9295d012eacbdb612 --- dom/animation/CSSPseudoElement.cpp | 8 +-- dom/animation/EffectCompositor.cpp | 18 +++---- dom/animation/EffectSet.cpp | 6 +-- dom/animation/KeyframeEffect.cpp | 15 +++--- dom/animation/PseudoElementHashEntry.h | 4 +- dom/base/Element.cpp | 2 +- dom/base/nsDOMWindowUtils.cpp | 13 +++-- dom/base/nsNodeUtils.cpp | 2 +- dom/smil/nsSMILCSSValueType.cpp | 15 +++--- layout/base/RestyleManager.cpp | 65 +++++++++++----------- layout/base/RestyleManager.h | 18 +++---- layout/base/nsCSSFrameConstructor.cpp | 34 ++++++------ layout/base/nsCSSRendering.cpp | 2 +- layout/forms/nsButtonFrameRenderer.cpp | 4 +- layout/forms/nsColorControlFrame.cpp | 4 +- layout/forms/nsMeterFrame.cpp | 4 +- layout/forms/nsNumberControlFrame.cpp | 26 ++++----- layout/forms/nsProgressFrame.cpp | 4 +- layout/forms/nsRangeFrame.cpp | 14 ++--- layout/forms/nsTextControlFrame.cpp | 5 +- layout/generic/nsBlockFrame.cpp | 6 +-- layout/generic/nsBlockFrame.h | 2 +- layout/generic/nsFrame.cpp | 6 +-- layout/generic/nsTextFrame.cpp | 2 +- layout/inspector/inDOMUtils.cpp | 3 +- layout/mathml/nsMathMLFrame.cpp | 2 +- layout/style/AnimationCommon.cpp | 12 ++--- layout/style/AnimationCommon.h | 14 ++--- layout/style/StyleAnimationValue.cpp | 2 +- layout/style/StyleRule.cpp | 8 +-- layout/style/StyleRule.h | 2 +- layout/style/nsCSSParser.cpp | 22 ++++---- layout/style/nsCSSPseudoElements.cpp | 12 ++--- layout/style/nsCSSPseudoElements.h | 46 +++++++++------- layout/style/nsCSSRuleProcessor.cpp | 25 +++++---- layout/style/nsComputedDOMStyle.cpp | 2 +- layout/style/nsRuleProcessorData.h | 3 +- layout/style/nsStyleContext.cpp | 4 +- layout/style/nsStyleSet.cpp | 75 +++++++++++++------------- layout/style/nsTransitionManager.cpp | 10 ++-- 40 files changed, 263 insertions(+), 258 deletions(-) diff --git a/dom/animation/CSSPseudoElement.cpp b/dom/animation/CSSPseudoElement.cpp index 8bf8606cbe3b..41bf3d2a0dec 100644 --- a/dom/animation/CSSPseudoElement.cpp +++ b/dom/animation/CSSPseudoElement.cpp @@ -22,8 +22,8 @@ CSSPseudoElement::CSSPseudoElement(Element* aElement, , mPseudoType(aType) { MOZ_ASSERT(aElement); - MOZ_ASSERT(aType == nsCSSPseudoElements::ePseudo_after || - aType == nsCSSPseudoElements::ePseudo_before, + MOZ_ASSERT(aType == CSSPseudoElementType::after || + aType == CSSPseudoElementType::before, "Unexpected Pseudo Type"); } @@ -100,10 +100,10 @@ CSSPseudoElement::GetCSSPseudoElementPropertyAtom( nsCSSPseudoElements::Type aType) { switch (aType) { - case nsCSSPseudoElements::ePseudo_before: + case CSSPseudoElementType::before: return nsGkAtoms::cssPseudoElementBeforeProperty; - case nsCSSPseudoElements::ePseudo_after: + case CSSPseudoElementType::after: return nsGkAtoms::cssPseudoElementAfterProperty; default: diff --git a/dom/animation/EffectCompositor.cpp b/dom/animation/EffectCompositor.cpp index d4a11200d5d5..be7c623922cd 100644 --- a/dom/animation/EffectCompositor.cpp +++ b/dom/animation/EffectCompositor.cpp @@ -283,7 +283,7 @@ EffectCompositor::GetAnimationRule(dom::Element* aElement, EffectCompositor::GetElementToRestyle(dom::Element* aElement, nsCSSPseudoElements::Type aPseudoType) { - if (aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) { + if (aPseudoType == CSSPseudoElementType::NotPseudo) { return aElement; } @@ -292,9 +292,9 @@ EffectCompositor::GetElementToRestyle(dom::Element* aElement, return nullptr; } nsIFrame* pseudoFrame; - if (aPseudoType == nsCSSPseudoElements::ePseudo_before) { + if (aPseudoType == CSSPseudoElementType::before) { pseudoFrame = nsLayoutUtils::GetBeforeFrame(primaryFrame); - } else if (aPseudoType == nsCSSPseudoElements::ePseudo_after) { + } else if (aPseudoType == CSSPseudoElementType::after) { pseudoFrame = nsLayoutUtils::GetAfterFrame(primaryFrame); } else { NS_NOTREACHED("Should not try to get the element to restyle for a pseudo " @@ -497,7 +497,7 @@ EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame) } nsCSSPseudoElements::Type pseudoType = - nsCSSPseudoElements::ePseudo_NotPseudoElement; + CSSPseudoElementType::NotPseudo; if (aFrame->IsGeneratedContentFrame()) { nsIFrame* parent = aFrame->GetParent(); @@ -506,9 +506,9 @@ EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame) } nsIAtom* name = content->NodeInfo()->NameAtom(); if (name == nsGkAtoms::mozgeneratedcontentbefore) { - pseudoType = nsCSSPseudoElements::ePseudo_before; + pseudoType = CSSPseudoElementType::before; } else if (name == nsGkAtoms::mozgeneratedcontentafter) { - pseudoType = nsCSSPseudoElements::ePseudo_after; + pseudoType = CSSPseudoElementType::after; } else { return result; } @@ -763,7 +763,7 @@ EffectCompositor::AnimationStyleRuleProcessor::RulesMatching( { nsIStyleRule *rule = mCompositor->GetAnimationRule(aData->mElement, - nsCSSPseudoElements::ePseudo_NotPseudoElement, + CSSPseudoElementType::NotPseudo, mCascadeLevel); if (rule) { aData->mRuleWalker->Forward(rule); @@ -775,8 +775,8 @@ void EffectCompositor::AnimationStyleRuleProcessor::RulesMatching( PseudoElementRuleProcessorData* aData) { - if (aData->mPseudoType != nsCSSPseudoElements::ePseudo_before && - aData->mPseudoType != nsCSSPseudoElements::ePseudo_after) { + if (aData->mPseudoType != CSSPseudoElementType::before && + aData->mPseudoType != CSSPseudoElementType::after) { return; } diff --git a/dom/animation/EffectSet.cpp b/dom/animation/EffectSet.cpp index 1af88580bf1f..035a4e666af2 100644 --- a/dom/animation/EffectSet.cpp +++ b/dom/animation/EffectSet.cpp @@ -155,13 +155,13 @@ EffectSet::GetEffectSetPropertyAtoms() EffectSet::GetEffectSetPropertyAtom(nsCSSPseudoElements::Type aPseudoType) { switch (aPseudoType) { - case nsCSSPseudoElements::ePseudo_NotPseudoElement: + case CSSPseudoElementType::NotPseudo: return nsGkAtoms::animationEffectsProperty; - case nsCSSPseudoElements::ePseudo_before: + case CSSPseudoElementType::before: return nsGkAtoms::animationEffectsForBeforeProperty; - case nsCSSPseudoElements::ePseudo_after: + case CSSPseudoElementType::after: return nsGkAtoms::animationEffectsForAfterProperty; default: diff --git a/dom/animation/KeyframeEffect.cpp b/dom/animation/KeyframeEffect.cpp index 82fb7679d725..961cb5cdd4f2 100644 --- a/dom/animation/KeyframeEffect.cpp +++ b/dom/animation/KeyframeEffect.cpp @@ -624,8 +624,7 @@ KeyframeEffectReadOnly::ConstructKeyframeEffect(const GlobalObject& aGlobal, "Uninitialized target"); RefPtr targetElement; - nsCSSPseudoElements::Type pseudoType = - nsCSSPseudoElements::ePseudo_NotPseudoElement; + nsCSSPseudoElements::Type pseudoType = CSSPseudoElementType::NotPseudo; if (target.IsElement()) { targetElement = &target.GetAsElement(); } else { @@ -1721,13 +1720,13 @@ KeyframeEffectReadOnly::GetTarget( } switch (mPseudoType) { - case nsCSSPseudoElements::ePseudo_before: - case nsCSSPseudoElements::ePseudo_after: + case CSSPseudoElementType::before: + case CSSPseudoElementType::after: aRv.SetValue().SetAsCSSPseudoElement() = CSSPseudoElement::GetCSSPseudoElement(mTarget, mPseudoType); break; - case nsCSSPseudoElements::ePseudo_NotPseudoElement: + case CSSPseudoElementType::NotPseudo: aRv.SetValue().SetAsElement() = mTarget; break; @@ -1975,12 +1974,12 @@ KeyframeEffectReadOnly::GetAnimationFrame() const return nullptr; } - if (mPseudoType == nsCSSPseudoElements::ePseudo_before) { + if (mPseudoType == CSSPseudoElementType::before) { frame = nsLayoutUtils::GetBeforeFrame(frame); - } else if (mPseudoType == nsCSSPseudoElements::ePseudo_after) { + } else if (mPseudoType == CSSPseudoElementType::after) { frame = nsLayoutUtils::GetAfterFrame(frame); } else { - MOZ_ASSERT(mPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement, + MOZ_ASSERT(mPseudoType == CSSPseudoElementType::NotPseudo, "unknown mPseudoType"); } if (!frame) { diff --git a/dom/animation/PseudoElementHashEntry.h b/dom/animation/PseudoElementHashEntry.h index 84aaf597ffef..574be9f27002 100644 --- a/dom/animation/PseudoElementHashEntry.h +++ b/dom/animation/PseudoElementHashEntry.h @@ -47,7 +47,9 @@ public: if (!aKey) return 0; - return mozilla::HashGeneric(aKey->mElement, aKey->mPseudoType); + // Convert the scoped enum into an integer while adding it to hash. + return mozilla::HashGeneric(aKey->mElement, + static_cast(aKey->mPseudoType)); } enum { ALLOW_MEMMOVE = true }; diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index b903ace5d6a6..c63df7b4b44a 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -3368,7 +3368,7 @@ void Element::GetAnimationsUnsorted(nsTArray>& aAnimations) { EffectSet* effects = EffectSet::GetEffectSet(this, - nsCSSPseudoElements::ePseudo_NotPseudoElement); + CSSPseudoElementType::NotPseudo); if (!effects) { return; } diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 06805278f2e4..82353938bfc6 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2247,13 +2247,12 @@ ComputeAnimationValue(nsCSSProperty aProperty, StyleAnimationValue& aOutput) { - if (!StyleAnimationValue::ComputeValue( - aProperty, - aElement, - nsCSSPseudoElements::ePseudo_NotPseudoElement, - aInput, - false, - aOutput)) { + if (!StyleAnimationValue::ComputeValue(aProperty, + aElement, + CSSPseudoElementType::NotPseudo, + aInput, + false, + aOutput)) { return false; } diff --git a/dom/base/nsNodeUtils.cpp b/dom/base/nsNodeUtils.cpp index 7a356339c089..bc133aa7a7db 100644 --- a/dom/base/nsNodeUtils.cpp +++ b/dom/base/nsNodeUtils.cpp @@ -241,7 +241,7 @@ nsNodeUtils::GetTargetForAnimation(const Animation* aAnimation) // If the animation targets a pseudo-element, we don't dispatch // notifications for it. (In the future we will have PseudoElement // objects we can use as the target of the notifications.) - if (pseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement) { + if (pseudoType != CSSPseudoElementType::NotPseudo) { return nullptr; } diff --git a/dom/smil/nsSMILCSSValueType.cpp b/dom/smil/nsSMILCSSValueType.cpp index 7cc2adf9533d..60871ea08e06 100644 --- a/dom/smil/nsSMILCSSValueType.cpp +++ b/dom/smil/nsSMILCSSValueType.cpp @@ -360,14 +360,13 @@ ValueFromStringHelper(nsCSSProperty aPropID, } } nsDependentSubstring subString(aString, subStringBegin); - if (!StyleAnimationValue::ComputeValue( - aPropID, - aTargetElement, - nsCSSPseudoElements::ePseudo_NotPseudoElement, - subString, - true, - aStyleAnimValue, - aIsContextSensitive)) { + if (!StyleAnimationValue::ComputeValue(aPropID, + aTargetElement, + CSSPseudoElementType::NotPseudo, + subString, + true, + aStyleAnimValue, + aIsContextSensitive)) { return false; } if (isNegative) { diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 947048132daa..f9ce85dc5f65 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -1105,11 +1105,11 @@ void RestyleManager::AnimationsWithDestroyedFrame::StopAnimationsForElementsWithoutFrames() { StopAnimationsWithoutFrame(mContents, - nsCSSPseudoElements::ePseudo_NotPseudoElement); + CSSPseudoElementType::NotPseudo); StopAnimationsWithoutFrame(mBeforeContents, - nsCSSPseudoElements::ePseudo_before); + CSSPseudoElementType::before); StopAnimationsWithoutFrame(mAfterContents, - nsCSSPseudoElements::ePseudo_after); + CSSPseudoElementType::after); } void @@ -1160,7 +1160,7 @@ RestyleManager::ContentStateChanged(nsIContent* aContent, // call will handle things. nsIFrame* primaryFrame = aElement->GetPrimaryFrame(); nsCSSPseudoElements::Type pseudoType = - nsCSSPseudoElements::ePseudo_NotPseudoElement; + CSSPseudoElementType::NotPseudo; if (primaryFrame) { // If it's generated content, ignore LOADING/etc state changes on it. if (!primaryFrame->IsGeneratedContentFrame() && @@ -1192,7 +1192,7 @@ RestyleManager::ContentStateChanged(nsIContent* aContent, nsRestyleHint rshint; - if (pseudoType >= nsCSSPseudoElements::ePseudo_PseudoElementCount) { + if (pseudoType >= CSSPseudoElementType::Count) { rshint = styleSet->HasStateDependentStyle(aElement, aStateMask); } else if (nsCSSPseudoElements::PseudoElementSupportsUserActionState( pseudoType)) { @@ -2132,28 +2132,28 @@ ElementForStyleContext(nsIContent* aParentContent, nsCSSPseudoElements::Type aPseudoType) { // We don't expect XUL tree stuff here. - NS_PRECONDITION(aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement || - aPseudoType == nsCSSPseudoElements::ePseudo_AnonBox || - aPseudoType < nsCSSPseudoElements::ePseudo_PseudoElementCount, + NS_PRECONDITION(aPseudoType == CSSPseudoElementType::NotPseudo || + aPseudoType == CSSPseudoElementType::AnonBox || + aPseudoType < CSSPseudoElementType::Count, "Unexpected pseudo"); // XXX see the comments about the various element confusion in // ElementRestyler::Restyle. - if (aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) { + if (aPseudoType == CSSPseudoElementType::NotPseudo) { return aFrame->GetContent()->AsElement(); } - if (aPseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { + if (aPseudoType == CSSPseudoElementType::AnonBox) { return nullptr; } - if (aPseudoType == nsCSSPseudoElements::ePseudo_firstLetter) { + if (aPseudoType == CSSPseudoElementType::firstLetter) { NS_ASSERTION(aFrame->GetType() == nsGkAtoms::letterFrame, "firstLetter pseudoTag without a nsFirstLetterFrame"); nsBlockFrame* block = nsBlockFrame::GetNearestAncestorBlock(aFrame); return block->GetContent()->AsElement(); } - if (aPseudoType == nsCSSPseudoElements::ePseudo_mozColorSwatch) { + if (aPseudoType == CSSPseudoElementType::mozColorSwatch) { MOZ_ASSERT(aFrame->GetParent() && aFrame->GetParent()->GetParent(), "Color swatch frame should have a parent & grandparent"); @@ -2165,11 +2165,11 @@ ElementForStyleContext(nsIContent* aParentContent, return grandparentFrame->GetContent()->AsElement(); } - if (aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberText || - aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberWrapper || - aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinBox || - aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinUp || - aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinDown) { + if (aPseudoType == CSSPseudoElementType::mozNumberText || + aPseudoType == CSSPseudoElementType::mozNumberWrapper || + aPseudoType == CSSPseudoElementType::mozNumberSpinBox || + aPseudoType == CSSPseudoElementType::mozNumberSpinUp || + aPseudoType == CSSPseudoElementType::mozNumberSpinDown) { // Get content for nearest nsNumberControlFrame: nsIFrame* f = aFrame->GetParent(); MOZ_ASSERT(f); @@ -2203,7 +2203,7 @@ static dom::Element* PseudoElementForStyleContext(nsIFrame* aFrame, nsCSSPseudoElements::Type aPseudoType) { - if (aPseudoType >= nsCSSPseudoElements::ePseudo_PseudoElementCount) { + if (aPseudoType >= CSSPseudoElementType::Count) { return nullptr; } @@ -3942,7 +3942,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, parentContext, oldContext, rshint); } - } else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { + } else if (pseudoType == CSSPseudoElementType::AnonBox) { newContext = styleSet->ResolveAnonymousBoxStyle(pseudoTag, parentContext); } @@ -3977,7 +3977,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, // Don't expect XUL tree stuff here, since it needs a comparator and // all. NS_ASSERTION(pseudoType < - nsCSSPseudoElements::ePseudo_PseudoElementCount, + CSSPseudoElementType::Count, "Unexpected pseudo type"); Element* pseudoElement = PseudoElementForStyleContext(aSelf, pseudoType); @@ -4263,7 +4263,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, NS_ASSERTION(extraPseudoTag && extraPseudoTag != nsCSSAnonBoxes::mozNonElement, "extra style context is not pseudo element"); - Element* element = extraPseudoType != nsCSSPseudoElements::ePseudo_AnonBox + Element* element = extraPseudoType != CSSPseudoElementType::AnonBox ? mContent->AsElement() : nullptr; if (!MustRestyleSelf(aRestyleHint, element)) { if (CanReparentStyleContext(aRestyleHint)) { @@ -4285,14 +4285,13 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, newContext, oldExtraContext, nsRestyleHint(0)); } - } else if (extraPseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { + } else if (extraPseudoType == CSSPseudoElementType::AnonBox) { newExtraContext = styleSet->ResolveAnonymousBoxStyle(extraPseudoTag, newContext); } else { // Don't expect XUL tree stuff here, since it needs a comparator and // all. - NS_ASSERTION(extraPseudoType < - nsCSSPseudoElements::ePseudo_PseudoElementCount, + NS_ASSERTION(extraPseudoType < CSSPseudoElementType::Count, "Unexpected type"); newExtraContext = styleSet->ResolvePseudoElementStyle(mContent->AsElement(), extraPseudoType, @@ -4401,11 +4400,11 @@ ElementRestyler::RestyleChildrenOfDisplayContentsElement( const bool mightReframePseudos = aRestyleHint & eRestyle_Subtree; DoRestyleUndisplayedDescendants(nsRestyleHint(0), mContent, aNewContext); if (!(mHintsHandled & nsChangeHint_ReconstructFrame) && mightReframePseudos) { - MaybeReframeForPseudo(nsCSSPseudoElements::ePseudo_before, + MaybeReframeForPseudo(CSSPseudoElementType::before, aParentFrame, nullptr, mContent, aNewContext); } if (!(mHintsHandled & nsChangeHint_ReconstructFrame) && mightReframePseudos) { - MaybeReframeForPseudo(nsCSSPseudoElements::ePseudo_after, + MaybeReframeForPseudo(CSSPseudoElementType::after, aParentFrame, nullptr, mContent, aNewContext); } if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) { @@ -4646,7 +4645,7 @@ ElementRestyler::RestyleUndisplayedNodes(nsRestyleHint aChildRestyleHint, void ElementRestyler::MaybeReframeForBeforePseudo() { - MaybeReframeForPseudo(nsCSSPseudoElements::ePseudo_before, + MaybeReframeForPseudo(CSSPseudoElementType::before, mFrame, mFrame, mFrame->GetContent(), mFrame->StyleContext()); } @@ -4659,7 +4658,7 @@ void ElementRestyler::MaybeReframeForAfterPseudo(nsIFrame* aFrame) { MOZ_ASSERT(aFrame); - MaybeReframeForPseudo(nsCSSPseudoElements::ePseudo_after, + MaybeReframeForPseudo(CSSPseudoElementType::after, aFrame, aFrame, aFrame->GetContent(), aFrame->StyleContext()); } @@ -4668,7 +4667,7 @@ ElementRestyler::MaybeReframeForAfterPseudo(nsIFrame* aFrame) bool ElementRestyler::MustReframeForBeforePseudo() { - return MustReframeForPseudo(nsCSSPseudoElements::ePseudo_before, + return MustReframeForPseudo(CSSPseudoElementType::before, mFrame, mFrame, mFrame->GetContent(), mFrame->StyleContext()); } @@ -4677,7 +4676,7 @@ bool ElementRestyler::MustReframeForAfterPseudo(nsIFrame* aFrame) { MOZ_ASSERT(aFrame); - return MustReframeForPseudo(nsCSSPseudoElements::ePseudo_after, + return MustReframeForPseudo(CSSPseudoElementType::after, aFrame, aFrame, aFrame->GetContent(), aFrame->StyleContext()); } @@ -4707,8 +4706,8 @@ ElementRestyler::MustReframeForPseudo(nsCSSPseudoElements::Type aPseudoType, nsIContent* aContent, nsStyleContext* aStyleContext) { - MOZ_ASSERT(aPseudoType == nsCSSPseudoElements::ePseudo_before || - aPseudoType == nsCSSPseudoElements::ePseudo_after); + MOZ_ASSERT(aPseudoType == CSSPseudoElementType::before || + aPseudoType == CSSPseudoElementType::after); // Make sure not to do this for pseudo-frames... if (aStyleContext->GetPseudo()) { @@ -4724,7 +4723,7 @@ ElementRestyler::MustReframeForPseudo(nsCSSPseudoElements::Type aPseudoType, } } - if (aPseudoType == nsCSSPseudoElements::ePseudo_before) { + if (aPseudoType == CSSPseudoElementType::before) { // Check for a ::before pseudo style and the absence of a ::before content, // but only if aFrame is null or is the first continuation/ib-split. if ((aFrame && !nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(aFrame)) || diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 7bb8cb7ab8c2..a7d1916992cc 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -192,12 +192,12 @@ public: void Put(nsIContent* aContent, nsStyleContext* aStyleContext) { MOZ_ASSERT(aContent); nsCSSPseudoElements::Type pseudoType = aStyleContext->GetPseudoType(); - if (pseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) { + if (pseudoType == CSSPseudoElementType::NotPseudo) { mElementContexts.Put(aContent, aStyleContext); - } else if (pseudoType == nsCSSPseudoElements::ePseudo_before) { + } else if (pseudoType == CSSPseudoElementType::before) { MOZ_ASSERT(aContent->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore); mBeforePseudoContexts.Put(aContent->GetParent(), aStyleContext); - } else if (pseudoType == nsCSSPseudoElements::ePseudo_after) { + } else if (pseudoType == CSSPseudoElementType::after) { MOZ_ASSERT(aContent->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentafter); mAfterPseudoContexts.Put(aContent->GetParent(), aStyleContext); } @@ -206,14 +206,14 @@ public: nsStyleContext* Get(nsIContent* aContent, nsCSSPseudoElements::Type aPseudoType) { MOZ_ASSERT(aContent); - if (aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) { + if (aPseudoType == CSSPseudoElementType::NotPseudo) { return mElementContexts.GetWeak(aContent); } - if (aPseudoType == nsCSSPseudoElements::ePseudo_before) { + if (aPseudoType == CSSPseudoElementType::before) { MOZ_ASSERT(aContent->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore); return mBeforePseudoContexts.GetWeak(aContent->GetParent()); } - if (aPseudoType == nsCSSPseudoElements::ePseudo_after) { + if (aPseudoType == CSSPseudoElementType::after) { MOZ_ASSERT(aContent->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentafter); return mAfterPseudoContexts.GetWeak(aContent->GetParent()); } @@ -270,12 +270,12 @@ public: void Put(nsIContent* aContent, nsStyleContext* aStyleContext) { MOZ_ASSERT(aContent); nsCSSPseudoElements::Type pseudoType = aStyleContext->GetPseudoType(); - if (pseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) { + if (pseudoType == CSSPseudoElementType::NotPseudo) { mContents.AppendElement(aContent); - } else if (pseudoType == nsCSSPseudoElements::ePseudo_before) { + } else if (pseudoType == CSSPseudoElementType::before) { MOZ_ASSERT(aContent->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore); mBeforeContents.AppendElement(aContent->GetParent()); - } else if (pseudoType == nsCSSPseudoElements::ePseudo_after) { + } else if (pseudoType == CSSPseudoElementType::after) { MOZ_ASSERT(aContent->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentafter); mAfterContents.AppendElement(aContent->GetParent()); } diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 17778401eade..1b3466d4ca86 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1760,8 +1760,8 @@ nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aStat nsCSSPseudoElements::Type aPseudoElement, FrameConstructionItemList& aItems) { - MOZ_ASSERT(aPseudoElement == nsCSSPseudoElements::ePseudo_before || - aPseudoElement == nsCSSPseudoElements::ePseudo_after, + MOZ_ASSERT(aPseudoElement == CSSPseudoElementType::before || + aPseudoElement == CSSPseudoElementType::after, "unexpected aPseudoElement"); // XXXbz is this ever true? @@ -1782,7 +1782,7 @@ nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aStat if (!pseudoStyleContext) return; - bool isBefore = aPseudoElement == nsCSSPseudoElements::ePseudo_before; + bool isBefore = aPseudoElement == CSSPseudoElementType::before; // |ProbePseudoStyleFor| checked the 'display' property and the // |ContentCount()| of the 'content' property for us. @@ -2961,7 +2961,7 @@ nsCSSFrameConstructor::CreateBackdropFrameFor(nsIPresShell* aPresShell, RefPtr style = aPresShell->StyleSet()-> ResolvePseudoElementStyle(aContent->AsElement(), - nsCSSPseudoElements::ePseudo_backdrop, + CSSPseudoElementType::backdrop, /* aParentStyleContext */ nullptr, /* aPseudoElement */ nullptr); nsBackdropFrame* backdropFrame = new (aPresShell) nsBackdropFrame(style); @@ -4922,7 +4922,7 @@ nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext, RestyleManager()->GetReframingStyleContexts(); if (rsc) { nsStyleContext* oldStyleContext = - rsc->Get(aContent, nsCSSPseudoElements::ePseudo_NotPseudoElement); + rsc->Get(aContent, CSSPseudoElementType::NotPseudo); nsPresContext* presContext = mPresShell->GetPresContext(); if (oldStyleContext) { RestyleManager::TryStartingTransition(presContext, aContent, @@ -4930,7 +4930,7 @@ nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext, } else if (aContent->IsElement()) { presContext->TransitionManager()-> PruneCompletedTransitions(aContent->AsElement(), - nsCSSPseudoElements::ePseudo_NotPseudoElement, result); + CSSPseudoElementType::NotPseudo, result); } } @@ -5763,7 +5763,7 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState aParentFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT); } CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext, - nsCSSPseudoElements::ePseudo_before, aItems); + CSSPseudoElementType::before, aItems); FlattenedChildIterator iter(aContent); for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { @@ -5796,7 +5796,7 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState aItems.SetParentHasNoXBLChildren(!iter.XBLInvolved()); CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext, - nsCSSPseudoElements::ePseudo_after, aItems); + CSSPseudoElementType::after, aItems); if (canHavePageBreak && display->mBreakAfter) { AddPageBreakItem(aContent, aStyleContext, aItems); } @@ -6170,7 +6170,7 @@ AdjustAppendParentForAfterContent(nsFrameManager* aFrameManager, // document than aChild and return that in aAfterFrame. if (aParentFrame->GetGenConPseudos() || nsLayoutUtils::HasPseudoStyle(aContainer, aParentFrame->StyleContext(), - nsCSSPseudoElements::ePseudo_after, + CSSPseudoElementType::after, aParentFrame->PresContext()) || aFrameManager->GetDisplayContentsStyleFor(aContainer)) { nsIFrame* afterFrame = nullptr; @@ -9556,7 +9556,7 @@ nsCSSFrameConstructor::GetFirstLetterStyle(nsIContent* aContent, if (aContent) { return mPresShell->StyleSet()-> ResolvePseudoElementStyle(aContent->AsElement(), - nsCSSPseudoElements::ePseudo_firstLetter, + CSSPseudoElementType::firstLetter, aStyleContext, nullptr); } @@ -9570,7 +9570,7 @@ nsCSSFrameConstructor::GetFirstLineStyle(nsIContent* aContent, if (aContent) { return mPresShell->StyleSet()-> ResolvePseudoElementStyle(aContent->AsElement(), - nsCSSPseudoElements::ePseudo_firstLine, + CSSPseudoElementType::firstLine, aStyleContext, nullptr); } @@ -9584,7 +9584,7 @@ nsCSSFrameConstructor::ShouldHaveFirstLetterStyle(nsIContent* aContent, nsStyleContext* aStyleContext) { return nsLayoutUtils::HasPseudoStyle(aContent, aStyleContext, - nsCSSPseudoElements::ePseudo_firstLetter, + CSSPseudoElementType::firstLetter, mPresShell->GetPresContext()); } @@ -9604,7 +9604,7 @@ nsCSSFrameConstructor::ShouldHaveFirstLineStyle(nsIContent* aContent, { bool hasFirstLine = nsLayoutUtils::HasPseudoStyle(aContent, aStyleContext, - nsCSSPseudoElements::ePseudo_firstLine, + CSSPseudoElementType::firstLine, mPresShell->GetPresContext()); if (hasFirstLine) { // But disable for fieldsets @@ -10532,7 +10532,7 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState, nsFrame::CorrectStyleParentFrame(aFrame, nullptr)->StyleContext(); // Probe for generated content before CreateGeneratedContentItem(aState, aFrame, aContent, styleContext, - nsCSSPseudoElements::ePseudo_before, + CSSPseudoElementType::before, itemsToConstruct); } @@ -10580,7 +10580,7 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState, if (aCanHaveGeneratedContent) { // Probe for generated content after CreateGeneratedContentItem(aState, aFrame, aContent, styleContext, - nsCSSPseudoElements::ePseudo_after, + CSSPseudoElementType::after, itemsToConstruct); } } else { @@ -11830,7 +11830,7 @@ nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState, if (!aItemIsWithinSVGText) { // Probe for generated content before CreateGeneratedContentItem(aState, nullptr, parentContent, parentStyleContext, - nsCSSPseudoElements::ePseudo_before, + CSSPseudoElementType::before, aParentItem.mChildItems); } @@ -11900,7 +11900,7 @@ nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState, if (!aItemIsWithinSVGText) { // Probe for generated content after CreateGeneratedContentItem(aState, nullptr, parentContent, parentStyleContext, - nsCSSPseudoElements::ePseudo_after, + CSSPseudoElementType::after, aParentItem.mChildItems); } diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 027c0175e9fd..c6cd21d0d7d6 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -857,7 +857,7 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext, nsRect innerRect; if ( #ifdef MOZ_XUL - aStyleContext->GetPseudoType() == nsCSSPseudoElements::ePseudo_XULTree + aStyleContext->GetPseudoType() == CSSPseudoElementType::XULTree #else false #endif diff --git a/layout/forms/nsButtonFrameRenderer.cpp b/layout/forms/nsButtonFrameRenderer.cpp index 376c8fed2d94..0254f4b05cba 100644 --- a/layout/forms/nsButtonFrameRenderer.cpp +++ b/layout/forms/nsButtonFrameRenderer.cpp @@ -465,13 +465,13 @@ nsButtonFrameRenderer::ReResolveStyles(nsPresContext* aPresContext) // style for the inner such as a dotted line (Windows) mInnerFocusStyle = styleSet->ProbePseudoElementStyle(mFrame->GetContent()->AsElement(), - nsCSSPseudoElements::ePseudo_mozFocusInner, + CSSPseudoElementType::mozFocusInner, context); // style for outer focus like a ridged border (MAC). mOuterFocusStyle = styleSet->ProbePseudoElementStyle(mFrame->GetContent()->AsElement(), - nsCSSPseudoElements::ePseudo_mozFocusOuter, + CSSPseudoElementType::mozFocusOuter, context); #ifdef DEBUG diff --git a/layout/forms/nsColorControlFrame.cpp b/layout/forms/nsColorControlFrame.cpp index f2c6aa168375..1b6414cb0dfd 100644 --- a/layout/forms/nsColorControlFrame.cpp +++ b/layout/forms/nsColorControlFrame.cpp @@ -72,7 +72,7 @@ nsColorControlFrame::CreateAnonymousContent(nsTArray& aElements) nsresult rv = UpdateColor(); NS_ENSURE_SUCCESS(rv, rv); - nsCSSPseudoElements::Type pseudoType = nsCSSPseudoElements::ePseudo_mozColorSwatch; + nsCSSPseudoElements::Type pseudoType = CSSPseudoElementType::mozColorSwatch; RefPtr newStyleContext = PresContext()->StyleSet()-> ResolvePseudoElementStyle(mContent->AsElement(), pseudoType, StyleContext(), mColorContent->AsElement()); @@ -137,7 +137,7 @@ nsColorControlFrame::GetContentInsertionFrame() Element* nsColorControlFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) { - if (aType == nsCSSPseudoElements::ePseudo_mozColorSwatch) { + if (aType == CSSPseudoElementType::mozColorSwatch) { return mColorContent; } diff --git a/layout/forms/nsMeterFrame.cpp b/layout/forms/nsMeterFrame.cpp index d2797278b59e..7093b53d31f4 100644 --- a/layout/forms/nsMeterFrame.cpp +++ b/layout/forms/nsMeterFrame.cpp @@ -66,7 +66,7 @@ nsMeterFrame::CreateAnonymousContent(nsTArray& aElements) mBarDiv = doc->CreateHTMLElement(nsGkAtoms::div); // Associate ::-moz-meter-bar pseudo-element to the anonymous child. - nsCSSPseudoElements::Type pseudoType = nsCSSPseudoElements::ePseudo_mozMeterBar; + nsCSSPseudoElements::Type pseudoType = CSSPseudoElementType::mozMeterBar; RefPtr newStyleContext = PresContext()->StyleSet()-> ResolvePseudoElementStyle(mContent->AsElement(), pseudoType, StyleContext(), mBarDiv->AsElement()); @@ -283,7 +283,7 @@ nsMeterFrame::ShouldUseNativeStyle() const Element* nsMeterFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) { - if (aType == nsCSSPseudoElements::ePseudo_mozMeterBar) { + if (aType == CSSPseudoElementType::mozMeterBar) { return mBarDiv; } diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index 349afba3a61a..44f7b3ba705e 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -334,7 +334,7 @@ nsNumberControlFrame::MakeAnonymousElement(Element** aResult, // non-pseudo-element anonymous children, then we'll need to add a branch // that calls ResolveStyleFor((*aResult)->AsElement(), aParentContext)") to // set newStyleContext. - NS_ASSERTION(aPseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement, + NS_ASSERTION(aPseudoType != CSSPseudoElementType::NotPseudo, "Expecting anonymous children to all be pseudo-elements"); // Associate the pseudo-element with the anonymous child RefPtr newStyleContext = @@ -347,8 +347,8 @@ nsNumberControlFrame::MakeAnonymousElement(Element** aResult, return NS_ERROR_OUT_OF_MEMORY; } - if (aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinDown || - aPseudoType == nsCSSPseudoElements::ePseudo_mozNumberSpinUp) { + if (aPseudoType == CSSPseudoElementType::mozNumberSpinDown || + aPseudoType == CSSPseudoElementType::mozNumberSpinUp) { resultElement->SetAttr(kNameSpaceID_None, nsGkAtoms::role, NS_LITERAL_STRING("button"), false); } @@ -380,7 +380,7 @@ nsNumberControlFrame::CreateAnonymousContent(nsTArray& aElements) rv = MakeAnonymousElement(getter_AddRefs(mOuterWrapper), aElements, nsGkAtoms::div, - nsCSSPseudoElements::ePseudo_mozNumberWrapper, + CSSPseudoElementType::mozNumberWrapper, mStyleContext); NS_ENSURE_SUCCESS(rv, rv); @@ -390,7 +390,7 @@ nsNumberControlFrame::CreateAnonymousContent(nsTArray& aElements) rv = MakeAnonymousElement(getter_AddRefs(mTextField), outerWrapperCI.mChildren, nsGkAtoms::input, - nsCSSPseudoElements::ePseudo_mozNumberText, + CSSPseudoElementType::mozNumberText, outerWrapperCI.mStyleContext); NS_ENSURE_SUCCESS(rv, rv); @@ -438,7 +438,7 @@ nsNumberControlFrame::CreateAnonymousContent(nsTArray& aElements) rv = MakeAnonymousElement(getter_AddRefs(mSpinBox), outerWrapperCI.mChildren, nsGkAtoms::div, - nsCSSPseudoElements::ePseudo_mozNumberSpinBox, + CSSPseudoElementType::mozNumberSpinBox, outerWrapperCI.mStyleContext); NS_ENSURE_SUCCESS(rv, rv); @@ -448,7 +448,7 @@ nsNumberControlFrame::CreateAnonymousContent(nsTArray& aElements) rv = MakeAnonymousElement(getter_AddRefs(mSpinUp), spinBoxCI.mChildren, nsGkAtoms::div, - nsCSSPseudoElements::ePseudo_mozNumberSpinUp, + CSSPseudoElementType::mozNumberSpinUp, spinBoxCI.mStyleContext); NS_ENSURE_SUCCESS(rv, rv); @@ -456,7 +456,7 @@ nsNumberControlFrame::CreateAnonymousContent(nsTArray& aElements) rv = MakeAnonymousElement(getter_AddRefs(mSpinDown), spinBoxCI.mChildren, nsGkAtoms::div, - nsCSSPseudoElements::ePseudo_mozNumberSpinDown, + CSSPseudoElementType::mozNumberSpinDown, spinBoxCI.mStyleContext); SyncDisabledState(); @@ -826,25 +826,25 @@ nsNumberControlFrame::AnonTextControlIsEmpty() Element* nsNumberControlFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) { - if (aType == nsCSSPseudoElements::ePseudo_mozNumberWrapper) { + if (aType == CSSPseudoElementType::mozNumberWrapper) { return mOuterWrapper; } - if (aType == nsCSSPseudoElements::ePseudo_mozNumberText) { + if (aType == CSSPseudoElementType::mozNumberText) { return mTextField; } - if (aType == nsCSSPseudoElements::ePseudo_mozNumberSpinBox) { + if (aType == CSSPseudoElementType::mozNumberSpinBox) { // Might be null. return mSpinBox; } - if (aType == nsCSSPseudoElements::ePseudo_mozNumberSpinUp) { + if (aType == CSSPseudoElementType::mozNumberSpinUp) { // Might be null. return mSpinUp; } - if (aType == nsCSSPseudoElements::ePseudo_mozNumberSpinDown) { + if (aType == CSSPseudoElementType::mozNumberSpinDown) { // Might be null. return mSpinDown; } diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp index d093bc26abc6..bf21c8d2fb77 100644 --- a/layout/forms/nsProgressFrame.cpp +++ b/layout/forms/nsProgressFrame.cpp @@ -63,7 +63,7 @@ nsProgressFrame::CreateAnonymousContent(nsTArray& aElements) mBarDiv = doc->CreateHTMLElement(nsGkAtoms::div); // Associate ::-moz-progress-bar pseudo-element to the anonymous child. - nsCSSPseudoElements::Type pseudoType = nsCSSPseudoElements::ePseudo_mozProgressBar; + nsCSSPseudoElements::Type pseudoType = CSSPseudoElementType::mozProgressBar; RefPtr newStyleContext = PresContext()->StyleSet()-> ResolvePseudoElementStyle(mContent->AsElement(), pseudoType, StyleContext(), mBarDiv->AsElement()); @@ -289,7 +289,7 @@ nsProgressFrame::ShouldUseNativeStyle() const Element* nsProgressFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) { - if (aType == nsCSSPseudoElements::ePseudo_mozProgressBar) { + if (aType == CSSPseudoElementType::mozProgressBar) { return mBarDiv; } diff --git a/layout/forms/nsRangeFrame.cpp b/layout/forms/nsRangeFrame.cpp index c8fbe3772b23..cc331fc5618c 100644 --- a/layout/forms/nsRangeFrame.cpp +++ b/layout/forms/nsRangeFrame.cpp @@ -86,7 +86,7 @@ nsRangeFrame::Init(nsIContent* aContent, mOuterFocusStyle = styleSet->ProbePseudoElementStyle(aContent->AsElement(), - nsCSSPseudoElements::ePseudo_mozFocusOuter, + CSSPseudoElementType::mozFocusOuter, StyleContext()); return nsContainerFrame::Init(aContent, aParent, aPrevInFlow); @@ -138,19 +138,19 @@ nsRangeFrame::CreateAnonymousContent(nsTArray& aElements) // Create the ::-moz-range-track pseuto-element (a div): rv = MakeAnonymousDiv(getter_AddRefs(mTrackDiv), - nsCSSPseudoElements::ePseudo_mozRangeTrack, + CSSPseudoElementType::mozRangeTrack, aElements); NS_ENSURE_SUCCESS(rv, rv); // Create the ::-moz-range-progress pseudo-element (a div): rv = MakeAnonymousDiv(getter_AddRefs(mProgressDiv), - nsCSSPseudoElements::ePseudo_mozRangeProgress, + CSSPseudoElementType::mozRangeProgress, aElements); NS_ENSURE_SUCCESS(rv, rv); // Create the ::-moz-range-thumb pseudo-element (a div): rv = MakeAnonymousDiv(getter_AddRefs(mThumbDiv), - nsCSSPseudoElements::ePseudo_mozRangeThumb, + CSSPseudoElementType::mozRangeThumb, aElements); return rv; } @@ -896,15 +896,15 @@ nsRangeFrame::ShouldUseNativeStyle() const Element* nsRangeFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) { - if (aType == nsCSSPseudoElements::ePseudo_mozRangeTrack) { + if (aType == CSSPseudoElementType::mozRangeTrack) { return mTrackDiv; } - if (aType == nsCSSPseudoElements::ePseudo_mozRangeThumb) { + if (aType == CSSPseudoElementType::mozRangeThumb) { return mThumbDiv; } - if (aType == nsCSSPseudoElements::ePseudo_mozRangeProgress) { + if (aType == CSSPseudoElementType::mozRangeProgress) { return mProgressDiv; } diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index 36e8e66e7a9c..156f33081efb 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -346,8 +346,7 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray& aElements) NS_ENSURE_TRUE(placeholderNode, NS_ERROR_OUT_OF_MEMORY); // Associate ::-moz-placeholder pseudo-element with the placeholder node. - nsCSSPseudoElements::Type pseudoType = - nsCSSPseudoElements::ePseudo_mozPlaceholder; + nsCSSPseudoElements::Type pseudoType = CSSPseudoElementType::mozPlaceholder; RefPtr placeholderStyleContext = PresContext()->StyleSet()->ResolvePseudoElementStyle( @@ -1446,7 +1445,7 @@ nsTextControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, mozilla::dom::Element* nsTextControlFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) { - if (aType == nsCSSPseudoElements::ePseudo_mozPlaceholder) { + if (aType == CSSPseudoElementType::mozPlaceholder) { nsCOMPtr txtCtrl = do_QueryInterface(GetContent()); return txtCtrl->GetPlaceholderNode(); } diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 0018bb94f17c..a1dca21953bc 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -6897,9 +6897,9 @@ nsBlockFrame::CreateBulletFrameForListItem(bool aCreateBulletList, { nsIPresShell* shell = PresContext()->PresShell(); - nsCSSPseudoElements::Type pseudoType = aCreateBulletList ? - nsCSSPseudoElements::ePseudo_mozListBullet : - nsCSSPseudoElements::ePseudo_mozListNumber; + CSSPseudoElementType pseudoType = aCreateBulletList ? + CSSPseudoElementType::mozListBullet : + CSSPseudoElementType::mozListNumber; nsStyleContext* parentStyle = CorrectStyleParentFrame(this, diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 2eaeae08afca..51cafa255514 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -367,7 +367,7 @@ protected: { return aPresContext->StyleSet()-> ProbePseudoElementStyle(mContent->AsElement(), - nsCSSPseudoElements::ePseudo_firstLetter, + mozilla::CSSPseudoElementType::firstLetter, mStyleContext); } #endif diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 98088a84a902..553048d82c45 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -9125,9 +9125,9 @@ nsIFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) { nsIFrame* frame = nullptr; - if (aType == nsCSSPseudoElements::ePseudo_before) { + if (aType == CSSPseudoElementType::before) { frame = nsLayoutUtils::GetBeforeFrame(this); - } else if (aType == nsCSSPseudoElements::ePseudo_after) { + } else if (aType == CSSPseudoElementType::after) { frame = nsLayoutUtils::GetAfterFrame(this); } @@ -9137,7 +9137,7 @@ nsIFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) return content->AsElement(); } } - + return nullptr; } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index c09338014e8d..f4cb0b480d83 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -3807,7 +3807,7 @@ nsTextPaintStyle::InitSelectionColorsAndShadow() RefPtr sc = nullptr; sc = mPresContext->StyleSet()-> ProbePseudoElementStyle(selectionElement, - nsCSSPseudoElements::ePseudo_mozSelection, + CSSPseudoElementType::mozSelection, mFrame->StyleContext()); // Use -moz-selection pseudo class. if (sc) { diff --git a/layout/inspector/inDOMUtils.cpp b/layout/inspector/inDOMUtils.cpp index 5c15eb3d2194..59f1262300ec 100644 --- a/layout/inspector/inDOMUtils.cpp +++ b/layout/inspector/inDOMUtils.cpp @@ -1194,7 +1194,8 @@ inDOMUtils::GetCSSPseudoElementNames(uint32_t* aLength, char16_t*** aNames) { nsTArray array; - for (int i = 0; i < nsCSSPseudoElements::ePseudo_PseudoElementCount; ++i) { + const uint8_t pseudoCount = static_cast(CSSPseudoElementType::Count); + for (uint8_t i = 0; i < pseudoCount; ++i) { nsCSSPseudoElements::Type type = static_cast(i); if (!nsCSSPseudoElements::PseudoElementIsUASheetOnly(type)) { nsIAtom* atom = nsCSSPseudoElements::GetPseudoAtom(type); diff --git a/layout/mathml/nsMathMLFrame.cpp b/layout/mathml/nsMathMLFrame.cpp index 7a2c578f3116..c7e69a931580 100644 --- a/layout/mathml/nsMathMLFrame.cpp +++ b/layout/mathml/nsMathMLFrame.cpp @@ -99,7 +99,7 @@ nsMathMLFrame::ResolveMathMLCharStyle(nsPresContext* aPresContext, nsMathMLChar* aMathMLChar) { nsCSSPseudoElements::Type pseudoType = - nsCSSPseudoElements::ePseudo_mozMathAnonymous; // savings + CSSPseudoElementType::mozMathAnonymous; // savings RefPtr newStyleContext; newStyleContext = aPresContext->StyleSet()-> ResolvePseudoElementStyle(aContent->AsElement(), pseudoType, diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index 79926224c72f..d9e967aaf413 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -78,11 +78,11 @@ CommonAnimationManager::GetAnimationCollection(dom::Element *aElement, } nsIAtom *propName; - if (aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) { + if (aPseudoType == CSSPseudoElementType::NotPseudo) { propName = GetAnimationsAtom(); - } else if (aPseudoType == nsCSSPseudoElements::ePseudo_before) { + } else if (aPseudoType == CSSPseudoElementType::before) { propName = GetAnimationsBeforeAtom(); - } else if (aPseudoType == nsCSSPseudoElements::ePseudo_after) { + } else if (aPseudoType == CSSPseudoElementType::after) { propName = GetAnimationsAfterAtom(); } else { NS_ASSERTION(!aCreateIfNeeded, @@ -155,12 +155,12 @@ CommonAnimationManager::ExtractComputedValueForTransition( AnimationCollection::PseudoTypeAsString(nsCSSPseudoElements::Type aPseudoType) { switch (aPseudoType) { - case nsCSSPseudoElements::ePseudo_before: + case CSSPseudoElementType::before: return NS_LITERAL_STRING("::before"); - case nsCSSPseudoElements::ePseudo_after: + case CSSPseudoElementType::after: return NS_LITERAL_STRING("::after"); default: - MOZ_ASSERT(aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement, + MOZ_ASSERT(aPseudoType == CSSPseudoElementType::NotPseudo, "Unexpected pseudo type"); return EmptyString(); } diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index 9892acdafbd2..a32840da69f7 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -177,14 +177,14 @@ public: nsCSSPseudoElements::Type PseudoElementType() const { if (IsForElement()) { - return nsCSSPseudoElements::ePseudo_NotPseudoElement; + return CSSPseudoElementType::NotPseudo; } if (IsForBeforePseudo()) { - return nsCSSPseudoElements::ePseudo_before; + return CSSPseudoElementType::before; } MOZ_ASSERT(IsForAfterPseudo(), "::before & ::after should be the only pseudo-elements here"); - return nsCSSPseudoElements::ePseudo_after; + return CSSPseudoElementType::after; } static nsString PseudoTypeAsString(nsCSSPseudoElements::Type aPseudoType); @@ -235,7 +235,7 @@ class OwningElementRef final public: OwningElementRef() : mElement(nullptr) - , mPseudoType(nsCSSPseudoElements::ePseudo_NotPseudoElement) + , mPseudoType(CSSPseudoElementType::NotPseudo) { } OwningElementRef(dom::Element& aElement, @@ -259,9 +259,9 @@ public: return nsContentUtils::PositionIsBefore(mElement, aOther.mElement); } - return mPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement || - (mPseudoType == nsCSSPseudoElements::ePseudo_before && - aOther.mPseudoType == nsCSSPseudoElements::ePseudo_after); + return mPseudoType == CSSPseudoElementType::NotPseudo || + (mPseudoType == CSSPseudoElementType::before && + aOther.mPseudoType == CSSPseudoElementType::after); } bool IsSet() const { return !!mElement; } diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index bfe8936b397a..7a81818b06b6 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -2535,7 +2535,7 @@ LookupStyleContext(dom::Element* aElement, } nsIAtom* pseudo = - aPseudoType < nsCSSPseudoElements::ePseudo_PseudoElementCount ? + aPseudoType < CSSPseudoElementType::Count ? nsCSSPseudoElements::GetPseudoAtom(aPseudoType) : nullptr; return nsComputedDOMStyle::GetStyleContextForElement(aElement, pseudo, shell); } diff --git a/layout/style/StyleRule.cpp b/layout/style/StyleRule.cpp index e72c4198cc79..b7a880d8d20b 100644 --- a/layout/style/StyleRule.cpp +++ b/layout/style/StyleRule.cpp @@ -315,10 +315,10 @@ nsCSSSelector::nsCSSSelector(void) mNext(nullptr), mNameSpace(kNameSpaceID_Unknown), mOperator(0), - mPseudoType(nsCSSPseudoElements::ePseudo_NotPseudoElement) + mPseudoType(static_cast(CSSPseudoElementType::NotPseudo)) { MOZ_COUNT_CTOR(nsCSSSelector); - static_assert(nsCSSPseudoElements::ePseudo_MAX < INT16_MAX, + static_assert(static_cast(CSSPseudoElementType::MAX) < INT16_MAX, "nsCSSPseudoElements::Type values overflow mPseudoType"); } @@ -492,7 +492,7 @@ int32_t nsCSSSelector::CalcWeightWithoutNegations() const #ifdef MOZ_XUL MOZ_ASSERT(!(IsPseudoElement() && - PseudoType() != nsCSSPseudoElements::ePseudo_XULTree && + PseudoType() != CSSPseudoElementType::XULTree && mClassList), "If non-XUL-tree pseudo-elements can have class selectors " "after them, specificity calculation must be updated"); @@ -517,7 +517,7 @@ int32_t nsCSSSelector::CalcWeightWithoutNegations() const #ifdef MOZ_XUL // XUL tree pseudo-elements abuse mClassList to store some private // data; ignore that. - if (PseudoType() == nsCSSPseudoElements::ePseudo_XULTree) { + if (PseudoType() == CSSPseudoElementType::XULTree) { list = nullptr; } #endif diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index 212110d9f00c..e66a5a7688fd 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -178,7 +178,7 @@ public: bool aAppend = false) const; bool IsRestrictedSelector() const { - return PseudoType() == nsCSSPseudoElements::ePseudo_NotPseudoElement; + return PseudoType() == mozilla::CSSPseudoElementType::NotPseudo; } #ifdef DEBUG diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 40d03ec2b07b..bf3c87f11af2 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -5875,7 +5875,7 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, nsCSSPseudoClasses::IsUserActionPseudoClass(pseudoClassType); if (!AgentRulesEnabled() && - ((pseudoElementType < nsCSSPseudoElements::ePseudo_PseudoElementCount && + ((pseudoElementType < CSSPseudoElementType::Count && nsCSSPseudoElements::PseudoElementIsUASheetOnly(pseudoElementType)) || (pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass && nsCSSPseudoClasses::PseudoClassIsUASheetOnly(pseudoClassType)))) { @@ -5887,17 +5887,17 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, // We currently allow :-moz-placeholder and ::-moz-placeholder. We have to // be a bit stricter regarding the pseudo-element parsing rules. - if (pseudoElementType == nsCSSPseudoElements::ePseudo_mozPlaceholder && + if (pseudoElementType == CSSPseudoElementType::mozPlaceholder && pseudoClassType == nsCSSPseudoClasses::ePseudoClass_mozPlaceholder) { if (parsingPseudoElement) { pseudoClassType = nsCSSPseudoClasses::ePseudoClass_NotPseudoClass; } else { - pseudoElementType = nsCSSPseudoElements::ePseudo_NotPseudoElement; + pseudoElementType = CSSPseudoElementType::NotPseudo; } } #ifdef MOZ_XUL - isTreePseudo = (pseudoElementType == nsCSSPseudoElements::ePseudo_XULTree); + isTreePseudo = (pseudoElementType == CSSPseudoElementType::XULTree); // If a tree pseudo-element is using the function syntax, it will // get isTree set here and will pass the check below that only // allows functions if they are in our list of things allowed to be @@ -5907,18 +5907,17 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, // desired. bool isTree = (eCSSToken_Function == mToken.mType) && isTreePseudo; #endif - bool isPseudoElement = - (pseudoElementType < nsCSSPseudoElements::ePseudo_PseudoElementCount); + bool isPseudoElement = (pseudoElementType < CSSPseudoElementType::Count); // anonymous boxes are only allowed if they're the tree boxes or we have // enabled agent rules bool isAnonBox = isTreePseudo || - (pseudoElementType == nsCSSPseudoElements::ePseudo_AnonBox && + (pseudoElementType == CSSPseudoElementType::AnonBox && AgentRulesEnabled()); bool isPseudoClass = (pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass); NS_ASSERTION(!isPseudoClass || - pseudoElementType == nsCSSPseudoElements::ePseudo_NotPseudoElement, + pseudoElementType == CSSPseudoElementType::NotPseudo, "Why is this atom both a pseudo-class and a pseudo-element?"); NS_ASSERTION(isPseudoClass + isPseudoElement + isAnonBox <= 1, "Shouldn't be more than one of these"); @@ -6413,8 +6412,7 @@ CSSParserImpl::ParseSelector(nsCSSSelectorList* aList, nsCSSSelector* selector = aList->AddSelector(aPrevCombinator); nsCOMPtr pseudoElement; nsAutoPtr pseudoElementArgs; - nsCSSPseudoElements::Type pseudoElementType = - nsCSSPseudoElements::ePseudo_NotPseudoElement; + nsCSSPseudoElements::Type pseudoElementType = CSSPseudoElementType::NotPseudo; int32_t dataMask = 0; nsSelectorParsingStatus parsingStatus = @@ -6433,7 +6431,7 @@ CSSParserImpl::ParseSelector(nsCSSSelectorList* aList, getter_Transfers(pseudoElementArgs), &pseudoElementType); if (pseudoElement && - pseudoElementType != nsCSSPseudoElements::ePseudo_AnonBox) { + pseudoElementType != CSSPseudoElementType::AnonBox) { // Pseudo-elements other than anonymous boxes are represented with // a special ':' combinator. @@ -6481,7 +6479,7 @@ CSSParserImpl::ParseSelector(nsCSSSelectorList* aList, return false; } - if (pseudoElementType == nsCSSPseudoElements::ePseudo_AnonBox) { + if (pseudoElementType == CSSPseudoElementType::AnonBox) { // We got an anonymous box pseudo-element; it must be the only // thing in this selector group. if (selector->mNext || !IsUniversalSelector(*selector)) { diff --git a/layout/style/nsCSSPseudoElements.cpp b/layout/style/nsCSSPseudoElements.cpp index fd140f75cd29..7cc5d24a0a77 100644 --- a/layout/style/nsCSSPseudoElements.cpp +++ b/layout/style/nsCSSPseudoElements.cpp @@ -73,7 +73,7 @@ nsCSSPseudoElements::IsCSS2PseudoElement(nsIAtom *aAtom) return result; } -/* static */ nsCSSPseudoElements::Type +/* static */ CSSPseudoElementType nsCSSPseudoElements::GetPseudoType(nsIAtom *aAtom) { for (uint32_t i = 0; i < ArrayLength(CSSPseudoElements_info); ++i) { @@ -85,22 +85,22 @@ nsCSSPseudoElements::GetPseudoType(nsIAtom *aAtom) if (nsCSSAnonBoxes::IsAnonBox(aAtom)) { #ifdef MOZ_XUL if (nsCSSAnonBoxes::IsTreePseudoElement(aAtom)) { - return ePseudo_XULTree; + return Type::XULTree; } #endif - return ePseudo_AnonBox; + return Type::AnonBox; } - return ePseudo_NotPseudoElement; + return Type::NotPseudo; } /* static */ nsIAtom* nsCSSPseudoElements::GetPseudoAtom(Type aType) { - NS_ASSERTION(aType < nsCSSPseudoElements::ePseudo_PseudoElementCount, + NS_ASSERTION(aType < Type::Count, "Unexpected type"); - return *CSSPseudoElements_info[aType].mAtom; + return *CSSPseudoElements_info[static_cast(aType)].mAtom; } /* static */ uint32_t diff --git a/layout/style/nsCSSPseudoElements.h b/layout/style/nsCSSPseudoElements.h index dc4b910c8c4c..da66f5c288d3 100644 --- a/layout/style/nsCSSPseudoElements.h +++ b/layout/style/nsCSSPseudoElements.h @@ -35,12 +35,36 @@ // Is content prevented from parsing selectors containing this pseudo-element? #define CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY (1<<4) +namespace mozilla { + +// The total count of CSSPseudoElement is less than 256, +// so use uint8_t as its underlying type. +enum class CSSPseudoElementType : uint8_t { + // If the actual pseudo-elements stop being first here, change + // GetPseudoType. +#define CSS_PSEUDO_ELEMENT(_name, _value_, _flags) \ + _name, +#include "nsCSSPseudoElementList.h" +#undef CSS_PSEUDO_ELEMENT + Count, + AnonBox = Count, +#ifdef MOZ_XUL + XULTree, +#endif + NotPseudo, + MAX +}; + +} // namespace mozilla + // Empty class derived from nsIAtom so that function signatures can // require an atom from this atom list. class nsICSSPseudoElement : public nsIAtom {}; class nsCSSPseudoElements { public: + // FIXME: Remove this in later patch + using Type = mozilla::CSSPseudoElementType; static void AddRefAtoms(); @@ -53,25 +77,9 @@ public: #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT - enum Type { - // If the actual pseudo-elements stop being first here, change - // GetPseudoType. -#define CSS_PSEUDO_ELEMENT(_name, _value_, _flags) \ - ePseudo_##_name, -#include "nsCSSPseudoElementList.h" -#undef CSS_PSEUDO_ELEMENT - ePseudo_PseudoElementCount, - ePseudo_AnonBox = ePseudo_PseudoElementCount, -#ifdef MOZ_XUL - ePseudo_XULTree, -#endif - ePseudo_NotPseudoElement, - ePseudo_MAX - }; - static Type GetPseudoType(nsIAtom* aAtom); - // Get the atom for a given Type. aType must be < ePseudo_PseudoElementCount + // Get the atom for a given Type. aType must be < Type::Count static nsIAtom* GetPseudoAtom(Type aType); static bool PseudoElementContainsElements(const Type aType) { @@ -79,14 +87,14 @@ public: } static bool PseudoElementSupportsStyleAttribute(const Type aType) { - MOZ_ASSERT(aType < ePseudo_PseudoElementCount); + MOZ_ASSERT(aType < Type::Count); return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE); } static bool PseudoElementSupportsUserActionState(const Type aType); static bool PseudoElementIsUASheetOnly(const Type aType) { - MOZ_ASSERT(aType < ePseudo_PseudoElementCount); + MOZ_ASSERT(aType < Type::Count); return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY); } diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 33f73518ae6d..b48dc14eb765 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -911,7 +911,7 @@ struct RuleCascadeData { RuleHash mRuleHash; RuleHash* - mPseudoElementRuleHashes[nsCSSPseudoElements::ePseudo_PseudoElementCount]; + mPseudoElementRuleHashes[static_cast(CSSPseudoElementType::Count)]; nsTArray mStateSelectors; EventStates mSelectorDocumentStates; PLDHashTable mClassSelectors; @@ -2644,7 +2644,9 @@ nsCSSRuleProcessor::RulesMatching(PseudoElementRuleProcessorData* aData) RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext); if (cascade) { - RuleHash* ruleHash = cascade->mPseudoElementRuleHashes[aData->mPseudoType]; + RuleHash* ruleHash = + cascade->mPseudoElementRuleHashes[static_cast( + aData->mPseudoType)]; if (ruleHash) { NodeMatchContext nodeContext(EventStates(), nsCSSRuleProcessor::IsLink(aData->mElement)); @@ -2722,7 +2724,7 @@ nsCSSRuleProcessor::HasStateDependentStyle(ElementDependentRuleProcessorData* aD "SelectorMatchesTree call"); bool isPseudoElement = - aPseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement; + aPseudoType != CSSPseudoElementType::NotPseudo; RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext); @@ -2806,7 +2808,7 @@ nsCSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData) { return HasStateDependentStyle(aData, aData->mElement, - nsCSSPseudoElements::ePseudo_NotPseudoElement, + CSSPseudoElementType::NotPseudo, aData->mStateMask); } @@ -2888,7 +2890,7 @@ RestyleHintForSelectorWithAttributeChange(nsRestyleHint aCurrentHint, sel != aSelector; sel = sel->mNext) { MOZ_ASSERT(sel, "aSelector must be reachable from aRightmostSelector"); - if (sel->PseudoType() != nsCSSPseudoElements::ePseudo_NotPseudoElement) { + if (sel->PseudoType() != CSSPseudoElementType::NotPseudo) { return eRestyle_Subtree; } } @@ -3410,10 +3412,11 @@ AddRule(RuleSelectorPair* aRuleInfo, RuleCascadeData* aCascade) // Build the rule hash. nsCSSPseudoElements::Type pseudoType = aRuleInfo->mSelector->PseudoType(); - if (MOZ_LIKELY(pseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement)) { + if (MOZ_LIKELY(pseudoType == CSSPseudoElementType::NotPseudo)) { cascade->mRuleHash.AppendRule(*aRuleInfo); - } else if (pseudoType < nsCSSPseudoElements::ePseudo_PseudoElementCount) { - RuleHash*& ruleHash = cascade->mPseudoElementRuleHashes[pseudoType]; + } else if (pseudoType < CSSPseudoElementType::Count) { + RuleHash*& ruleHash = + cascade->mPseudoElementRuleHashes[static_cast(pseudoType)]; if (!ruleHash) { ruleHash = new RuleHash(cascade->mQuirksMode); if (!ruleHash) { @@ -3426,7 +3429,7 @@ AddRule(RuleSelectorPair* aRuleInfo, RuleCascadeData* aCascade) NS_ASSERTION(aRuleInfo->mSelector->mNext->mOperator == ':', "Unexpected mNext combinator"); ruleHash->AppendRule(*aRuleInfo); - } else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { + } else if (pseudoType == CSSPseudoElementType::AnonBox) { NS_ASSERTION(!aRuleInfo->mSelector->mCasedTag && !aRuleInfo->mSelector->mIDList && !aRuleInfo->mSelector->mClassList && @@ -3444,7 +3447,7 @@ AddRule(RuleSelectorPair* aRuleInfo, RuleCascadeData* aCascade) RuleValue(*aRuleInfo, 0, aCascade->mQuirksMode)); } else { #ifdef MOZ_XUL - NS_ASSERTION(pseudoType == nsCSSPseudoElements::ePseudo_XULTree, + NS_ASSERTION(pseudoType == CSSPseudoElementType::XULTree, "Unexpected pseudo type"); // Index doesn't matter here, since we'll just be walking these // rules in order; just pass 0. @@ -3460,7 +3463,7 @@ AddRule(RuleSelectorPair* aRuleInfo, RuleCascadeData* aCascade) selector; selector = selector->mNext) { if (selector->IsPseudoElement()) { nsCSSPseudoElements::Type pseudo = selector->PseudoType(); - if (pseudo >= nsCSSPseudoElements::ePseudo_PseudoElementCount || + if (pseudo >= CSSPseudoElementType::Count || !nsCSSPseudoElements::PseudoElementSupportsUserActionState(pseudo)) { NS_ASSERTION(!selector->mNegations, "Shouldn't have negations"); // We do store selectors ending with pseudo-elements that allow :hover diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index b8680fe23e59..fc19437b30ea 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -489,7 +489,7 @@ nsComputedDOMStyle::GetStyleContextForElementNoFlush(Element* aElement, RefPtr sc; if (aPseudo) { nsCSSPseudoElements::Type type = nsCSSPseudoElements::GetPseudoType(aPseudo); - if (type >= nsCSSPseudoElements::ePseudo_PseudoElementCount) { + if (type >= CSSPseudoElementType::Count) { return nullptr; } nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement); diff --git a/layout/style/nsRuleProcessorData.h b/layout/style/nsRuleProcessorData.h index 3deefbc6f265..e23722aede62 100644 --- a/layout/style/nsRuleProcessorData.h +++ b/layout/style/nsRuleProcessorData.h @@ -478,8 +478,7 @@ struct MOZ_STACK_CLASS PseudoElementRuleProcessorData : mPseudoType(aPseudoType), mPseudoElement(aPseudoElement) { - NS_PRECONDITION(aPseudoType < - nsCSSPseudoElements::ePseudo_PseudoElementCount, + NS_PRECONDITION(aPseudoType < mozilla::CSSPseudoElementType::Count, "invalid aPseudoType value"); NS_PRECONDITION(aTreeMatchContext.mForStyling, "Styling here!"); NS_PRECONDITION(aRuleWalker, "Must have rule walker"); diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 95afde7f6044..2d55a052b7e0 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -89,7 +89,7 @@ nsStyleContext::nsStyleContext(nsStyleContext* aParent, // This check has to be done "backward", because if it were written the // more natural way it wouldn't fail even when it needed to. static_assert((UINT64_MAX >> NS_STYLE_CONTEXT_TYPE_SHIFT) >= - nsCSSPseudoElements::ePseudo_MAX, + static_cast(CSSPseudoElementType::MAX), "pseudo element bits no longer fit in a uint64_t"); MOZ_ASSERT(aRuleNode); @@ -526,7 +526,7 @@ ShouldSuppressLineBreak(const nsStyleContext* aContext, // some other frame with a ruby display value. Non-element pseudos // which represents text frames, as well as ruby pseudos are excluded // because we still want to set the flag for them. - if (aContext->GetPseudoType() == nsCSSPseudoElements::ePseudo_AnonBox && + if (aContext->GetPseudoType() == CSSPseudoElementType::AnonBox && aContext->GetPseudo() != nsCSSAnonBoxes::mozNonElement && !RubyUtils::IsRubyPseudo(aContext->GetPseudo())) { return false; diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index d7c600716429..b8d30e89728d 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -891,7 +891,7 @@ nsStyleSet::GetContext(nsStyleContext* aParentContext, { NS_PRECONDITION((!aPseudoTag && aPseudoType == - nsCSSPseudoElements::ePseudo_NotPseudoElement) || + CSSPseudoElementType::NotPseudo) || (aPseudoTag && nsCSSPseudoElements::GetPseudoType(aPseudoTag) == aPseudoType), @@ -1016,7 +1016,7 @@ nsStyleSet::GetContext(nsStyleContext* aParentContext, if (aElementForAnimation && aElementForAnimation->IsHTMLElement(nsGkAtoms::body) && - aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement && + aPseudoType == CSSPseudoElementType::NotPseudo && PresContext()->CompatibilityMode() == eCompatibility_NavQuirks) { nsIDocument* doc = aElementForAnimation->GetCurrentDoc(); if (doc && doc->GetBodyElement() == aElementForAnimation) { @@ -1395,7 +1395,7 @@ nsStyleSet::ResolveStyleFor(Element* aElement, } return GetContext(aParentContext, ruleNode, visitedRuleNode, - nullptr, nsCSSPseudoElements::ePseudo_NotPseudoElement, + nullptr, CSSPseudoElementType::NotPseudo, aElement, flags); } @@ -1414,7 +1414,7 @@ nsStyleSet::ResolveStyleForRules(nsStyleContext* aParentContext, } return GetContext(aParentContext, ruleWalker.CurrentNode(), nullptr, - nullptr, nsCSSPseudoElements::ePseudo_NotPseudoElement, + nullptr, CSSPseudoElementType::NotPseudo, nullptr, eNoFlags); } @@ -1510,7 +1510,7 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement, NS_ASSERTION(mBatching == 0, "rule processors out of date"); MOZ_ASSERT(!aPseudoElement == - (aPseudoType >= nsCSSPseudoElements::ePseudo_PseudoElementCount || + (aPseudoType >= CSSPseudoElementType::Count || !(nsCSSPseudoElements::PseudoElementSupportsStyleAttribute(aPseudoType) || nsCSSPseudoElements::PseudoElementSupportsUserActionState(aPseudoType))), "should have aPseudoElement only for certain pseudo elements"); @@ -1565,9 +1565,9 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement, if (doReplace) { switch (level->mLevel) { case SheetType::Animation: { - if (aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement || - aPseudoType == nsCSSPseudoElements::ePseudo_before || - aPseudoType == nsCSSPseudoElements::ePseudo_after) { + if (aPseudoType == CSSPseudoElementType::NotPseudo || + aPseudoType == CSSPseudoElementType::before || + aPseudoType == CSSPseudoElementType::after) { nsIStyleRule* rule = PresContext()->EffectCompositor()-> GetAnimationRule(aElement, aPseudoType, EffectCompositor::CascadeLevel::Animations); @@ -1579,9 +1579,9 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement, break; } case SheetType::Transition: { - if (aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement || - aPseudoType == nsCSSPseudoElements::ePseudo_before || - aPseudoType == nsCSSPseudoElements::ePseudo_after) { + if (aPseudoType == CSSPseudoElementType::NotPseudo || + aPseudoType == CSSPseudoElementType::before || + aPseudoType == CSSPseudoElementType::after) { nsIStyleRule* rule = PresContext()->EffectCompositor()-> GetAnimationRule(aElement, aPseudoType, EffectCompositor::CascadeLevel::Transitions); @@ -1597,7 +1597,7 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement, static_cast( mRuleProcessors[SheetType::SVGAttrAnimation].get()); if (ruleProcessor && - aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) { + aPseudoType == CSSPseudoElementType::NotPseudo) { ruleProcessor->ElementRulesMatching(aElement, &ruleWalker); } break; @@ -1611,12 +1611,12 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement, if (ruleProcessor) { lastScopedRN = ruleWalker.CurrentNode(); if (aPseudoType == - nsCSSPseudoElements::ePseudo_NotPseudoElement) { + CSSPseudoElementType::NotPseudo) { ruleProcessor->ElementRulesMatching(PresContext(), aElement, &ruleWalker); } else if (aPseudoType < - nsCSSPseudoElements::ePseudo_PseudoElementCount && + CSSPseudoElementType::Count && nsCSSPseudoElements:: PseudoElementSupportsStyleAttribute(aPseudoType)) { ruleProcessor->PseudoElementRulesMatching(aPseudoElement, @@ -1709,9 +1709,9 @@ nsStyleSet::ResolveStyleWithReplacement(Element* aElement, nsCSSPseudoElements::Type pseudoType = aOldStyleContext->GetPseudoType(); Element* elementForAnimation = nullptr; if (!(aFlags & eSkipStartingAnimations) && - (pseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement || - pseudoType == nsCSSPseudoElements::ePseudo_before || - pseudoType == nsCSSPseudoElements::ePseudo_after)) { + (pseudoType == CSSPseudoElementType::NotPseudo || + pseudoType == CSSPseudoElementType::before || + pseudoType == CSSPseudoElementType::after)) { // We want to compute a correct elementForAnimation to pass in // because at this point the parameter is more than just the element // for animation; it's also used for the SetBodyTextColor call when @@ -1728,11 +1728,10 @@ nsStyleSet::ResolveStyleWithReplacement(Element* aElement, #ifdef DEBUG { nsIFrame* styleFrame = nsLayoutUtils::GetStyleFrame(elementForAnimation); - NS_ASSERTION(pseudoType == - nsCSSPseudoElements::ePseudo_NotPseudoElement || + NS_ASSERTION(pseudoType == CSSPseudoElementType::NotPseudo || !styleFrame || styleFrame->StyleContext()->GetPseudoType() == - nsCSSPseudoElements::ePseudo_NotPseudoElement, + CSSPseudoElementType::NotPseudo, "aElement should be the element and not the pseudo-element"); } #endif @@ -1759,9 +1758,9 @@ nsStyleSet::ResolveStyleWithoutAnimation(dom::Element* aTarget, #ifdef DEBUG nsCSSPseudoElements::Type pseudoType = aStyleContext->GetPseudoType(); #endif - MOZ_ASSERT(pseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement || - pseudoType == nsCSSPseudoElements::ePseudo_before || - pseudoType == nsCSSPseudoElements::ePseudo_after, + MOZ_ASSERT(pseudoType == CSSPseudoElementType::NotPseudo || + pseudoType == CSSPseudoElementType::before || + pseudoType == CSSPseudoElementType::after, "unexpected type for animations"); RestyleManager* restyleManager = PresContext()->RestyleManager(); @@ -1783,7 +1782,7 @@ nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext) { return GetContext(aParentContext, mRuleTree, nullptr, nsCSSAnonBoxes::mozNonElement, - nsCSSPseudoElements::ePseudo_AnonBox, nullptr, + CSSPseudoElementType::AnonBox, nullptr, eNoFlags); } @@ -1793,11 +1792,11 @@ nsStyleSet::WalkRestrictionRule(nsCSSPseudoElements::Type aPseudoType, { // This needs to match GetPseudoRestriction in nsRuleNode.cpp. aRuleWalker->SetLevel(SheetType::Agent, false, false); - if (aPseudoType == nsCSSPseudoElements::ePseudo_firstLetter) + if (aPseudoType == CSSPseudoElementType::firstLetter) aRuleWalker->Forward(mFirstLetterRule); - else if (aPseudoType == nsCSSPseudoElements::ePseudo_firstLine) + else if (aPseudoType == CSSPseudoElementType::firstLine) aRuleWalker->Forward(mFirstLineRule); - else if (aPseudoType == nsCSSPseudoElements::ePseudo_mozPlaceholder) + else if (aPseudoType == CSSPseudoElementType::mozPlaceholder) aRuleWalker->Forward(mPlaceholderRule); } @@ -1817,7 +1816,7 @@ nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement, { NS_ENSURE_FALSE(mInShutdown, nullptr); - NS_ASSERTION(aType < nsCSSPseudoElements::ePseudo_PseudoElementCount, + NS_ASSERTION(aType < CSSPseudoElementType::Count, "must have pseudo element type"); NS_ASSERTION(aParentElement, "Must have parent element"); @@ -1847,8 +1846,8 @@ nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement, // For pseudos, |data.IsLink()| being true means that // our parent node is a link. uint32_t flags = eNoFlags; - if (aType == nsCSSPseudoElements::ePseudo_before || - aType == nsCSSPseudoElements::ePseudo_after) { + if (aType == CSSPseudoElementType::before || + aType == CSSPseudoElementType::after) { flags |= eDoAnimation; } else { // Flex and grid containers don't expect to have any pseudo-element children @@ -1884,7 +1883,7 @@ nsStyleSet::ProbePseudoElementStyle(Element* aParentElement, { NS_ENSURE_FALSE(mInShutdown, nullptr); - NS_ASSERTION(aType < nsCSSPseudoElements::ePseudo_PseudoElementCount, + NS_ASSERTION(aType < CSSPseudoElementType::Count, "must have pseudo element type"); NS_ASSERTION(aParentElement, "aParentElement must not be null"); @@ -1919,8 +1918,8 @@ nsStyleSet::ProbePseudoElementStyle(Element* aParentElement, // For pseudos, |data.IsLink()| being true means that // our parent node is a link. uint32_t flags = eNoFlags; - if (aType == nsCSSPseudoElements::ePseudo_before || - aType == nsCSSPseudoElements::ePseudo_after) { + if (aType == CSSPseudoElementType::before || + aType == CSSPseudoElementType::after) { flags |= eDoAnimation; } else { // Flex and grid containers don't expect to have any pseudo-element children @@ -1995,7 +1994,7 @@ nsStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, } return GetContext(aParentContext, ruleWalker.CurrentNode(), nullptr, - aPseudoTag, nsCSSPseudoElements::ePseudo_AnonBox, + aPseudoTag, CSSPseudoElementType::AnonBox, nullptr, aFlags); } @@ -2035,7 +2034,7 @@ nsStyleSet::ResolveXULTreePseudoStyle(Element* aParentElement, return GetContext(aParentContext, ruleNode, visitedRuleNode, // For pseudos, |data.IsLink()| being true means that // our parent node is a link. - aPseudoTag, nsCSSPseudoElements::ePseudo_XULTree, + aPseudoTag, CSSPseudoElementType::XULTree, nullptr, eNoFlags); } #endif @@ -2294,9 +2293,9 @@ nsStyleSet::ReparentStyleContext(nsStyleContext* aStyleContext, } } - if (pseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement || - pseudoType == nsCSSPseudoElements::ePseudo_before || - pseudoType == nsCSSPseudoElements::ePseudo_after) { + if (pseudoType == CSSPseudoElementType::NotPseudo || + pseudoType == CSSPseudoElementType::before || + pseudoType == CSSPseudoElementType::after) { flags |= eDoAnimation; } diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index 483796b81ea9..b6bb12e81016 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -262,15 +262,15 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement, // common case: no transitions specified or running. const nsStyleDisplay *disp = newStyleContext->StyleDisplay(); nsCSSPseudoElements::Type pseudoType = newStyleContext->GetPseudoType(); - if (pseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement) { - if (pseudoType != nsCSSPseudoElements::ePseudo_before && - pseudoType != nsCSSPseudoElements::ePseudo_after) { + if (pseudoType != CSSPseudoElementType::NotPseudo) { + if (pseudoType != CSSPseudoElementType::before && + pseudoType != CSSPseudoElementType::after) { return; } - NS_ASSERTION((pseudoType == nsCSSPseudoElements::ePseudo_before && + NS_ASSERTION((pseudoType == CSSPseudoElementType::before && aElement->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore) || - (pseudoType == nsCSSPseudoElements::ePseudo_after && + (pseudoType == CSSPseudoElementType::after && aElement->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentafter), "Unexpected aElement coming through"); From e436478f26ad5a40cc88c8a1e63b27fb92998db7 Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Wed, 17 Feb 2016 21:37:00 +0100 Subject: [PATCH 026/115] Bug 1244049 - Part 2: Replace nsCSSPseudoElements::Type with CSSPseudoElementType. r=dbaron Also, try to use forward declaraions for CSSPseudoElementType; --HG-- extra : rebase_source : c00eb9753e8f618a33aa711538ac45c0132b353c --- dom/animation/Animation.cpp | 2 +- dom/animation/CSSPseudoElement.cpp | 7 +++--- dom/animation/CSSPseudoElement.h | 11 ++++----- dom/animation/EffectCompositor.cpp | 33 ++++++++++++-------------- dom/animation/EffectCompositor.h | 24 +++++++++---------- dom/animation/EffectSet.cpp | 9 +++---- dom/animation/EffectSet.h | 12 +++++----- dom/animation/KeyframeEffect.cpp | 17 ++++++------- dom/animation/KeyframeEffect.h | 14 +++++------ dom/animation/PseudoElementHashEntry.h | 9 +++---- dom/base/nsDOMMutationObserver.cpp | 2 +- dom/base/nsDOMWindowUtils.cpp | 1 + dom/base/nsNodeUtils.cpp | 3 ++- layout/base/RestyleManager.cpp | 32 +++++++++++-------------- layout/base/RestyleManager.h | 14 +++++------ layout/base/nsCSSFrameConstructor.cpp | 3 ++- layout/base/nsCSSFrameConstructor.h | 4 ++-- layout/base/nsLayoutUtils.cpp | 2 +- layout/base/nsLayoutUtils.h | 7 +++--- layout/forms/nsColorControlFrame.cpp | 5 ++-- layout/forms/nsColorControlFrame.h | 7 +++++- layout/forms/nsMeterFrame.cpp | 5 ++-- layout/forms/nsMeterFrame.h | 2 +- layout/forms/nsNumberControlFrame.cpp | 5 ++-- layout/forms/nsNumberControlFrame.h | 6 +++-- layout/forms/nsProgressFrame.cpp | 5 ++-- layout/forms/nsProgressFrame.h | 7 +++++- layout/forms/nsRangeFrame.cpp | 5 ++-- layout/forms/nsRangeFrame.h | 5 ++-- layout/forms/nsTextControlFrame.cpp | 5 ++-- layout/forms/nsTextControlFrame.h | 6 +++-- layout/generic/nsFrame.cpp | 3 ++- layout/generic/nsIFrame.h | 4 +++- layout/inspector/inDOMUtils.cpp | 2 +- layout/mathml/nsMathMLFrame.cpp | 2 +- layout/style/AnimationCommon.cpp | 6 ++--- layout/style/AnimationCommon.h | 12 +++++----- layout/style/StyleAnimationValue.cpp | 9 +++---- layout/style/StyleAnimationValue.h | 8 +++---- layout/style/StyleRule.cpp | 3 +-- layout/style/StyleRule.h | 11 ++++----- layout/style/nsAnimationManager.cpp | 4 ++-- layout/style/nsAnimationManager.h | 7 +++--- layout/style/nsCSSParser.cpp | 10 ++++---- layout/style/nsCSSPseudoElements.cpp | 13 +++++----- layout/style/nsCSSPseudoElements.h | 13 +++++----- layout/style/nsCSSRuleProcessor.cpp | 6 ++--- layout/style/nsCSSRuleProcessor.h | 4 ++-- layout/style/nsComputedDOMStyle.cpp | 5 ++-- layout/style/nsHTMLCSSStyleSheet.cpp | 3 ++- layout/style/nsHTMLCSSStyleSheet.h | 4 ++-- layout/style/nsRuleProcessorData.h | 8 +++---- layout/style/nsStyleContext.cpp | 7 +++--- layout/style/nsStyleContext.h | 21 +++++++++------- layout/style/nsStyleSet.cpp | 22 ++++++++--------- layout/style/nsStyleSet.h | 18 +++++++------- layout/style/nsTransitionManager.cpp | 8 +++---- layout/style/nsTransitionManager.h | 8 +++---- 58 files changed, 257 insertions(+), 233 deletions(-) diff --git a/dom/animation/Animation.cpp b/dom/animation/Animation.cpp index e57c1b4882ad..e479be06ea38 100644 --- a/dom/animation/Animation.cpp +++ b/dom/animation/Animation.cpp @@ -1107,7 +1107,7 @@ Animation::PostUpdate() } Element* targetElement; - nsCSSPseudoElements::Type targetPseudoType; + CSSPseudoElementType targetPseudoType; mEffect->GetTarget(targetElement, targetPseudoType); if (!targetElement) { return; diff --git a/dom/animation/CSSPseudoElement.cpp b/dom/animation/CSSPseudoElement.cpp index 41bf3d2a0dec..e27f3d646aa6 100644 --- a/dom/animation/CSSPseudoElement.cpp +++ b/dom/animation/CSSPseudoElement.cpp @@ -17,7 +17,7 @@ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CSSPseudoElement, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CSSPseudoElement, Release) CSSPseudoElement::CSSPseudoElement(Element* aElement, - nsCSSPseudoElements::Type aType) + CSSPseudoElementType aType) : mParentElement(aElement) , mPseudoType(aType) { @@ -69,7 +69,7 @@ CSSPseudoElement::Animate( /* static */ already_AddRefed CSSPseudoElement::GetCSSPseudoElement(Element* aElement, - nsCSSPseudoElements::Type aType) + CSSPseudoElementType aType) { if (!aElement) { return nullptr; @@ -96,8 +96,7 @@ CSSPseudoElement::GetCSSPseudoElement(Element* aElement, } /* static */ nsIAtom* -CSSPseudoElement::GetCSSPseudoElementPropertyAtom( - nsCSSPseudoElements::Type aType) +CSSPseudoElement::GetCSSPseudoElementPropertyAtom(CSSPseudoElementType aType) { switch (aType) { case CSSPseudoElementType::before: diff --git a/dom/animation/CSSPseudoElement.h b/dom/animation/CSSPseudoElement.h index 9428187ccab8..ee4107ef390b 100644 --- a/dom/animation/CSSPseudoElement.h +++ b/dom/animation/CSSPseudoElement.h @@ -38,7 +38,7 @@ public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - nsCSSPseudoElements::Type GetType() const { return mPseudoType; } + CSSPseudoElementType GetType() const { return mPseudoType; } void GetType(nsString& aRetVal) const { MOZ_ASSERT(nsCSSPseudoElements::GetPseudoAtom(mPseudoType), @@ -64,20 +64,19 @@ public: // pseudo-type on element, a new CSSPseudoElement will be created and stored // on the element. static already_AddRefed - GetCSSPseudoElement(Element* aElement, nsCSSPseudoElements::Type aType); + GetCSSPseudoElement(Element* aElement, CSSPseudoElementType aType); private: // Only ::before and ::after are supported. - CSSPseudoElement(Element* aElement, nsCSSPseudoElements::Type aType); + CSSPseudoElement(Element* aElement, CSSPseudoElementType aType); - static nsIAtom* - GetCSSPseudoElementPropertyAtom(nsCSSPseudoElements::Type aType); + static nsIAtom* GetCSSPseudoElementPropertyAtom(CSSPseudoElementType aType); // mParentElement needs to be an owning reference since if script is holding // on to the pseudo-element, it needs to continue to be able to refer to // the parent element. RefPtr mParentElement; - nsCSSPseudoElements::Type mPseudoType; + CSSPseudoElementType mPseudoType; }; } // namespace dom diff --git a/dom/animation/EffectCompositor.cpp b/dom/animation/EffectCompositor.cpp index be7c623922cd..4dcad3ef2b94 100644 --- a/dom/animation/EffectCompositor.cpp +++ b/dom/animation/EffectCompositor.cpp @@ -16,6 +16,7 @@ #include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetPresShellForContent #include "nsCSSPropertySet.h" #include "nsCSSProps.h" +#include "nsCSSPseudoElements.h" #include "nsIPresShell.h" #include "nsLayoutUtils.h" #include "nsRuleNode.h" // For nsRuleNode::ComputePropertiesOverridingAnimation @@ -80,7 +81,7 @@ FindAnimationsForCompositor(const nsIFrame* aFrame, // Those cases are probably not important but just to be safe, let's make // sure the cascade is up to date since if it *is* up to date, this is // basically a no-op. - Maybe> pseudoElement = + Maybe> pseudoElement = EffectCompositor::GetAnimationElementAndPseudoForFrame(aFrame); if (pseudoElement) { EffectCompositor::MaybeUpdateCascadeResults(pseudoElement->first(), @@ -131,7 +132,7 @@ FindAnimationsForCompositor(const nsIFrame* aFrame, void EffectCompositor::RequestRestyle(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, RestyleType aRestyleType, CascadeLevel aCascadeLevel) { @@ -171,7 +172,7 @@ EffectCompositor::RequestRestyle(dom::Element* aElement, void EffectCompositor::PostRestyleForAnimation(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, CascadeLevel aCascadeLevel) { if (!mPresContext) { @@ -212,8 +213,7 @@ EffectCompositor::PostRestyleForThrottledAnimations() void EffectCompositor::MaybeUpdateAnimationRule(dom::Element* aElement, - nsCSSPseudoElements::Type - aPseudoType, + CSSPseudoElementType aPseudoType, CascadeLevel aCascadeLevel) { // First update cascade results since that may cause some elements to @@ -235,7 +235,7 @@ EffectCompositor::MaybeUpdateAnimationRule(dom::Element* aElement, nsIStyleRule* EffectCompositor::GetAnimationRule(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, CascadeLevel aCascadeLevel) { // NOTE: We need to be careful about early returns in this method where @@ -281,7 +281,7 @@ EffectCompositor::GetAnimationRule(dom::Element* aElement, /* static */ dom::Element* EffectCompositor::GetElementToRestyle(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType) + CSSPseudoElementType aPseudoType) { if (aPseudoType == CSSPseudoElementType::NotPseudo) { return aElement; @@ -417,8 +417,7 @@ EffectCompositor::ClearIsRunningOnCompositor(const nsIFrame *aFrame, /* static */ void EffectCompositor::MaybeUpdateCascadeResults(Element* aElement, - nsCSSPseudoElements::Type - aPseudoType, + CSSPseudoElementType aPseudoType, nsStyleContext* aStyleContext) { EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType); @@ -433,8 +432,7 @@ EffectCompositor::MaybeUpdateCascadeResults(Element* aElement, /* static */ void EffectCompositor::MaybeUpdateCascadeResults(Element* aElement, - nsCSSPseudoElements::Type - aPseudoType) + CSSPseudoElementType aPseudoType) { nsStyleContext* styleContext = nullptr; { @@ -474,7 +472,7 @@ namespace { /* static */ void EffectCompositor::UpdateCascadeResults(Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsStyleContext* aStyleContext) { EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType); @@ -485,19 +483,18 @@ EffectCompositor::UpdateCascadeResults(Element* aElement, UpdateCascadeResults(*effects, aElement, aPseudoType, aStyleContext); } -/* static */ Maybe> +/* static */ Maybe> EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame) { // Always return the same object to benefit from return-value optimization. - Maybe> result; + Maybe> result; nsIContent* content = aFrame->GetContent(); if (!content) { return result; } - nsCSSPseudoElements::Type pseudoType = - CSSPseudoElementType::NotPseudo; + CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo; if (aFrame->IsGeneratedContentFrame()) { nsIFrame* parent = aFrame->GetParent(); @@ -534,7 +531,7 @@ EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame) /* static */ void EffectCompositor::ComposeAnimationRule(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, CascadeLevel aCascadeLevel, TimeStamp aRefreshTime) { @@ -615,7 +612,7 @@ EffectCompositor::GetOverriddenProperties(nsStyleContext* aStyleContext, /* static */ void EffectCompositor::UpdateCascadeResults(EffectSet& aEffectSet, Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsStyleContext* aStyleContext) { MOZ_ASSERT(EffectSet::GetEffectSet(aElement, aPseudoType) == &aEffectSet, diff --git a/dom/animation/EffectCompositor.h b/dom/animation/EffectCompositor.h index 5f21ae3e651b..679fbf337471 100644 --- a/dom/animation/EffectCompositor.h +++ b/dom/animation/EffectCompositor.h @@ -14,7 +14,6 @@ #include "mozilla/PseudoElementHashEntry.h" #include "mozilla/RefPtr.h" #include "nsCSSProperty.h" -#include "nsCSSPseudoElements.h" #include "nsCycleCollectionParticipant.h" #include "nsDataHashtable.h" #include "nsIStyleRuleProcessor.h" @@ -30,6 +29,7 @@ namespace mozilla { class EffectSet; class RestyleTracker; +enum class CSSPseudoElementType : uint8_t; namespace dom { class Animation; @@ -94,7 +94,7 @@ public: // The specified steps taken to update the animation rule depend on // |aRestyleType| whose values are described above. void RequestRestyle(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, RestyleType aRestyleType, CascadeLevel aCascadeLevel); @@ -103,7 +103,7 @@ public: // need to perform this step when triggering transitions *without* also // invalidating the animation style rule (which RequestRestyle would do). void PostRestyleForAnimation(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, CascadeLevel aCascadeLevel); // Posts an animation restyle for any elements whose animation style rule @@ -116,11 +116,11 @@ public: // If the animation rule is not marked as needing an update, // no work is done. void MaybeUpdateAnimationRule(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, CascadeLevel aCascadeLevel); nsIStyleRule* GetAnimationRule(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, CascadeLevel aCascadeLevel); bool HasPendingStyleUpdates() const; @@ -155,14 +155,14 @@ public: // animation level of the cascade have changed. static void MaybeUpdateCascadeResults(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsStyleContext* aStyleContext); // An overload of MaybeUpdateCascadeResults that uses the style context // of the primary frame of the specified (pseudo-)element, when available. static void MaybeUpdateCascadeResults(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType); + CSSPseudoElementType aPseudoType); // Update the mWinsInCascade member for each property in effects targetting // the specified (pseudo-)element. @@ -172,7 +172,7 @@ public: // other cases we should call MaybeUpdateCascadeResults. static void UpdateCascadeResults(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsStyleContext* aStyleContext); // Helper to fetch the corresponding element and pseudo-type from a frame. @@ -184,7 +184,7 @@ public: // Returns an empty result when a suitable element cannot be found including // when the frame represents a pseudo-element on which we do not support // animations. - static Maybe> + static Maybe> GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame); private: @@ -193,12 +193,12 @@ private: // Rebuilds the animation rule corresponding to |aCascadeLevel| on the // EffectSet associated with the specified (pseudo-)element. static void ComposeAnimationRule(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, CascadeLevel aCascadeLevel, TimeStamp aRefreshTime); static dom::Element* GetElementToRestyle(dom::Element* aElement, - nsCSSPseudoElements::Type + CSSPseudoElementType aPseudoType); // Get the properties in |aEffectSet| that we are able to animate on the @@ -212,7 +212,7 @@ private: static void UpdateCascadeResults(EffectSet& aEffectSet, dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsStyleContext* aStyleContext); static nsPresContext* GetPresContext(dom::Element* aElement); diff --git a/dom/animation/EffectSet.cpp b/dom/animation/EffectSet.cpp index 035a4e666af2..04dbeba4ba24 100644 --- a/dom/animation/EffectSet.cpp +++ b/dom/animation/EffectSet.cpp @@ -7,6 +7,7 @@ #include "EffectSet.h" #include "mozilla/dom/Element.h" // For Element #include "RestyleManager.h" +#include "nsCSSPseudoElements.h" // For CSSPseudoElementType #include "nsCycleCollectionNoteChild.h" // For CycleCollectionNoteChild #include "nsPresContext.h" #include "nsLayoutUtils.h" @@ -38,7 +39,7 @@ EffectSet::Traverse(nsCycleCollectionTraversalCallback& aCallback) /* static */ EffectSet* EffectSet::GetEffectSet(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType) + CSSPseudoElementType aPseudoType) { nsIAtom* propName = GetEffectSetPropertyAtom(aPseudoType); return static_cast(aElement->GetProperty(propName)); @@ -87,7 +88,7 @@ EffectSet::GetEffectSet(const nsIFrame* aFrame) /* static */ EffectSet* EffectSet::GetOrCreateEffectSet(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType) + CSSPseudoElementType aPseudoType) { EffectSet* effectSet = GetEffectSet(aElement, aPseudoType); if (effectSet) { @@ -114,7 +115,7 @@ EffectSet::GetOrCreateEffectSet(dom::Element* aElement, /* static */ void EffectSet::DestroyEffectSet(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType) + CSSPseudoElementType aPseudoType) { nsIAtom* propName = GetEffectSetPropertyAtom(aPseudoType); EffectSet* effectSet = @@ -152,7 +153,7 @@ EffectSet::GetEffectSetPropertyAtoms() } /* static */ nsIAtom* -EffectSet::GetEffectSetPropertyAtom(nsCSSPseudoElements::Type aPseudoType) +EffectSet::GetEffectSetPropertyAtom(CSSPseudoElementType aPseudoType) { switch (aPseudoType) { case CSSPseudoElementType::NotPseudo: diff --git a/dom/animation/EffectSet.h b/dom/animation/EffectSet.h index e1277658f3f4..4d1ecf8b16cf 100644 --- a/dom/animation/EffectSet.h +++ b/dom/animation/EffectSet.h @@ -12,7 +12,6 @@ #include "mozilla/EffectCompositor.h" #include "mozilla/EnumeratedArray.h" #include "mozilla/TimeStamp.h" -#include "nsCSSPseudoElements.h" // For nsCSSPseudoElements::Type #include "nsHashKeys.h" // For nsPtrHashKey #include "nsTHashtable.h" // For nsTHashtable @@ -25,6 +24,8 @@ class Element; class KeyframeEffectReadOnly; } // namespace dom +enum class CSSPseudoElementType : uint8_t; + // A wrapper around a hashset of AnimationEffect objects to handle // storing the set as a property of an element. class EffectSet @@ -57,12 +58,12 @@ public: void Traverse(nsCycleCollectionTraversalCallback& aCallback); static EffectSet* GetEffectSet(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType); + CSSPseudoElementType aPseudoType); static EffectSet* GetEffectSet(const nsIFrame* aFrame); static EffectSet* GetOrCreateEffectSet(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType); + CSSPseudoElementType aPseudoType); static void DestroyEffectSet(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType); + CSSPseudoElementType aPseudoType); void AddEffect(dom::KeyframeEffectReadOnly& aEffect); void RemoveEffect(dom::KeyframeEffectReadOnly& aEffect); @@ -182,8 +183,7 @@ public: static nsIAtom** GetEffectSetPropertyAtoms(); private: - static nsIAtom* GetEffectSetPropertyAtom(nsCSSPseudoElements::Type - aPseudoType); + static nsIAtom* GetEffectSetPropertyAtom(CSSPseudoElementType aPseudoType); OwningEffectSet mEffects; diff --git a/dom/animation/KeyframeEffect.cpp b/dom/animation/KeyframeEffect.cpp index 961cb5cdd4f2..300d348264dc 100644 --- a/dom/animation/KeyframeEffect.cpp +++ b/dom/animation/KeyframeEffect.cpp @@ -17,6 +17,7 @@ #include "nsCSSParser.h" #include "nsCSSPropertySet.h" #include "nsCSSProps.h" // For nsCSSProps::PropHasFlags +#include "nsCSSPseudoElements.h" #include "nsCSSValue.h" #include "nsStyleUtil.h" #include // For std::max @@ -74,7 +75,7 @@ NS_IMPL_RELEASE_INHERITED(KeyframeEffectReadOnly, AnimationEffectReadOnly) KeyframeEffectReadOnly::KeyframeEffectReadOnly( nsIDocument* aDocument, Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, const TimingParams& aTiming) : KeyframeEffectReadOnly(aDocument, aTarget, aPseudoType, new AnimationEffectTimingReadOnly(aTiming)) @@ -84,7 +85,7 @@ KeyframeEffectReadOnly::KeyframeEffectReadOnly( KeyframeEffectReadOnly::KeyframeEffectReadOnly( nsIDocument* aDocument, Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, AnimationEffectTimingReadOnly* aTiming) : AnimationEffectReadOnly(aDocument) , mTarget(aTarget) @@ -624,7 +625,7 @@ KeyframeEffectReadOnly::ConstructKeyframeEffect(const GlobalObject& aGlobal, "Uninitialized target"); RefPtr targetElement; - nsCSSPseudoElements::Type pseudoType = CSSPseudoElementType::NotPseudo; + CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo; if (target.IsElement()) { targetElement = &target.GetAsElement(); } else { @@ -1229,7 +1230,7 @@ ApplyDistributeSpacing(nsTArray& aKeyframes) */ static void GenerateValueEntries(Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsTArray& aKeyframes, nsTArray& aResult, ErrorResult& aRv) @@ -1433,7 +1434,7 @@ static void BuildAnimationPropertyListFromKeyframeSequence( JSContext* aCx, Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, JS::ForOfIterator& aIterator, nsTArray& aResult, ErrorResult& aRv) @@ -1491,7 +1492,7 @@ static void BuildAnimationPropertyListFromPropertyIndexedKeyframes( JSContext* aCx, Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, JS::Handle aValue, InfallibleTArray& aResult, ErrorResult& aRv) @@ -1666,7 +1667,7 @@ BuildAnimationPropertyListFromPropertyIndexedKeyframes( KeyframeEffectReadOnly::BuildAnimationPropertyList( JSContext* aCx, Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, JS::Handle aFrames, InfallibleTArray& aResult, ErrorResult& aRv) @@ -2125,7 +2126,7 @@ KeyframeEffectReadOnly::ShouldBlockCompositorAnimations(const nsIFrame* KeyframeEffect::KeyframeEffect(nsIDocument* aDocument, Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, const TimingParams& aTiming) : KeyframeEffectReadOnly(aDocument, aTarget, aPseudoType, new AnimationEffectTiming(aTiming)) diff --git a/dom/animation/KeyframeEffect.h b/dom/animation/KeyframeEffect.h index 53be0c96cb17..f3b746b2cd88 100644 --- a/dom/animation/KeyframeEffect.h +++ b/dom/animation/KeyframeEffect.h @@ -9,7 +9,6 @@ #include "nsAutoPtr.h" #include "nsCycleCollectionParticipant.h" -#include "nsCSSPseudoElements.h" #include "nsIDocument.h" #include "nsWrapperCache.h" #include "mozilla/Attributes.h" @@ -38,6 +37,7 @@ namespace mozilla { struct AnimationCollection; class AnimValuesStyleRule; +enum class CSSPseudoElementType : uint8_t; namespace dom { class ElementOrCSSPseudoElement; @@ -172,7 +172,7 @@ class KeyframeEffectReadOnly : public AnimationEffectReadOnly public: KeyframeEffectReadOnly(nsIDocument* aDocument, Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, const TimingParams& aTiming); NS_DECL_ISUPPORTS_INHERITED @@ -209,7 +209,7 @@ public: // Temporary workaround to return both the target element and pseudo-type // until we implement PseudoElement (bug 1174575). void GetTarget(Element*& aTarget, - nsCSSPseudoElements::Type& aPseudoType) const { + CSSPseudoElementType& aPseudoType) const { aTarget = mTarget; aPseudoType = mPseudoType; } @@ -322,7 +322,7 @@ public: protected: KeyframeEffectReadOnly(nsIDocument* aDocument, Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, AnimationEffectTimingReadOnly* aTiming); virtual ~KeyframeEffectReadOnly(); @@ -351,7 +351,7 @@ protected: static void BuildAnimationPropertyList( JSContext* aCx, Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, JS::Handle aFrames, InfallibleTArray& aResult, ErrorResult& aRv); @@ -360,7 +360,7 @@ protected: RefPtr mAnimation; OwningNonNull mTiming; - nsCSSPseudoElements::Type mPseudoType; + CSSPseudoElementType mPseudoType; InfallibleTArray mProperties; @@ -395,7 +395,7 @@ class KeyframeEffect : public KeyframeEffectReadOnly public: KeyframeEffect(nsIDocument* aDocument, Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, const TimingParams& aTiming); JSObject* WrapObject(JSContext* aCx, diff --git a/dom/animation/PseudoElementHashEntry.h b/dom/animation/PseudoElementHashEntry.h index 574be9f27002..c1f90e670cd1 100644 --- a/dom/animation/PseudoElementHashEntry.h +++ b/dom/animation/PseudoElementHashEntry.h @@ -9,18 +9,19 @@ #include "mozilla/dom/Element.h" #include "mozilla/HashFunctions.h" -#include "nsCSSPseudoElements.h" #include "PLDHashTable.h" namespace mozilla { +enum class CSSPseudoElementType : uint8_t; + struct PseudoElementHashKey { dom::Element* mElement; - nsCSSPseudoElements::Type mPseudoType; + CSSPseudoElementType mPseudoType; }; -// A hash entry that uses a RefPtr, nsCSSPseudoElements::Type pair +// A hash entry that uses a RefPtr, CSSPseudoElementType pair class PseudoElementHashEntry : public PLDHashEntryHdr { public: @@ -54,7 +55,7 @@ public: enum { ALLOW_MEMMOVE = true }; RefPtr mElement; - nsCSSPseudoElements::Type mPseudoType; + CSSPseudoElementType mPseudoType; }; } // namespace mozilla diff --git a/dom/base/nsDOMMutationObserver.cpp b/dom/base/nsDOMMutationObserver.cpp index 095cda319c1d..c809adc9d91b 100644 --- a/dom/base/nsDOMMutationObserver.cpp +++ b/dom/base/nsDOMMutationObserver.cpp @@ -389,7 +389,7 @@ nsAnimationReceiver::RecordAnimationMutation(Animation* aAnimation, } mozilla::dom::Element* animationTarget; - nsCSSPseudoElements::Type pseudoType; + CSSPseudoElementType pseudoType; effect->GetTarget(animationTarget, pseudoType); if (!animationTarget) { return; diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 82353938bfc6..3bf8fce33c9f 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -101,6 +101,7 @@ #include "nsIDOMStyleSheet.h" #include "nsIStyleSheetService.h" #include "nsContentPermissionHelper.h" +#include "nsCSSPseudoElements.h" // for CSSPseudoElementType #include "nsNetUtil.h" #include "nsDocument.h" #include "HTMLImageElement.h" diff --git a/dom/base/nsNodeUtils.cpp b/dom/base/nsNodeUtils.cpp index bc133aa7a7db..0186a3e35d3b 100644 --- a/dom/base/nsNodeUtils.cpp +++ b/dom/base/nsNodeUtils.cpp @@ -6,6 +6,7 @@ #include "nsNodeUtils.h" #include "nsContentUtils.h" +#include "nsCSSPseudoElements.h" #include "nsINode.h" #include "nsIContent.h" #include "mozilla/dom/Element.h" @@ -235,7 +236,7 @@ nsNodeUtils::GetTargetForAnimation(const Animation* aAnimation) } Element* target; - nsCSSPseudoElements::Type pseudoType; + CSSPseudoElementType pseudoType; effect->GetTarget(target, pseudoType); // If the animation targets a pseudo-element, we don't dispatch diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index f9ce85dc5f65..bbc0109d3194 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -21,6 +21,7 @@ #include "nsStyleUtil.h" #include "nsCSSFrameConstructor.h" #include "nsSVGEffects.h" +#include "nsCSSPseudoElements.h" #include "nsCSSRendering.h" #include "nsAnimationManager.h" #include "nsTransitionManager.h" @@ -1104,18 +1105,15 @@ RestyleManager::AnimationsWithDestroyedFrame::AnimationsWithDestroyedFrame( void RestyleManager::AnimationsWithDestroyedFrame::StopAnimationsForElementsWithoutFrames() { - StopAnimationsWithoutFrame(mContents, - CSSPseudoElementType::NotPseudo); - StopAnimationsWithoutFrame(mBeforeContents, - CSSPseudoElementType::before); - StopAnimationsWithoutFrame(mAfterContents, - CSSPseudoElementType::after); + StopAnimationsWithoutFrame(mContents, CSSPseudoElementType::NotPseudo); + StopAnimationsWithoutFrame(mBeforeContents, CSSPseudoElementType::before); + StopAnimationsWithoutFrame(mAfterContents, CSSPseudoElementType::after); } void RestyleManager::AnimationsWithDestroyedFrame::StopAnimationsWithoutFrame( nsTArray>& aArray, - nsCSSPseudoElements::Type aPseudoType) + CSSPseudoElementType aPseudoType) { nsAnimationManager* animationManager = mRestyleManager->PresContext()->AnimationManager(); @@ -1132,7 +1130,7 @@ RestyleManager::AnimationsWithDestroyedFrame::StopAnimationsWithoutFrame( static inline dom::Element* ElementForStyleContext(nsIContent* aParentContent, nsIFrame* aFrame, - nsCSSPseudoElements::Type aPseudoType); + CSSPseudoElementType aPseudoType); // Forwarded nsIDocumentObserver method, to handle restyling (and // passing the notification to the frame). @@ -1159,8 +1157,7 @@ RestyleManager::ContentStateChanged(nsIContent* aContent, // need to force a reframe -- if it's needed, the HasStateDependentStyle // call will handle things. nsIFrame* primaryFrame = aElement->GetPrimaryFrame(); - nsCSSPseudoElements::Type pseudoType = - CSSPseudoElementType::NotPseudo; + CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo; if (primaryFrame) { // If it's generated content, ignore LOADING/etc state changes on it. if (!primaryFrame->IsGeneratedContentFrame() && @@ -2129,7 +2126,7 @@ RestyleManager::TryStartingTransition(nsPresContext* aPresContext, static dom::Element* ElementForStyleContext(nsIContent* aParentContent, nsIFrame* aFrame, - nsCSSPseudoElements::Type aPseudoType) + CSSPseudoElementType aPseudoType) { // We don't expect XUL tree stuff here. NS_PRECONDITION(aPseudoType == CSSPseudoElementType::NotPseudo || @@ -2201,7 +2198,7 @@ ElementForStyleContext(nsIContent* aParentContent, */ static dom::Element* PseudoElementForStyleContext(nsIFrame* aFrame, - nsCSSPseudoElements::Type aPseudoType) + CSSPseudoElementType aPseudoType) { if (aPseudoType >= CSSPseudoElementType::Count) { return nullptr; @@ -3847,7 +3844,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, #endif nsIAtom* const pseudoTag = oldContext->GetPseudo(); - const nsCSSPseudoElements::Type pseudoType = oldContext->GetPseudoType(); + const CSSPseudoElementType pseudoType = oldContext->GetPseudoType(); // Get the frame providing the parent style context. If it is a // child, then resolve the provider first. @@ -3976,8 +3973,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, } else { // Don't expect XUL tree stuff here, since it needs a comparator and // all. - NS_ASSERTION(pseudoType < - CSSPseudoElementType::Count, + NS_ASSERTION(pseudoType < CSSPseudoElementType::Count, "Unexpected pseudo type"); Element* pseudoElement = PseudoElementForStyleContext(aSelf, pseudoType); @@ -4258,7 +4254,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, LOG_RESTYLE_INDENT(); RefPtr newExtraContext; nsIAtom* const extraPseudoTag = oldExtraContext->GetPseudo(); - const nsCSSPseudoElements::Type extraPseudoType = + const CSSPseudoElementType extraPseudoType = oldExtraContext->GetPseudoType(); NS_ASSERTION(extraPseudoTag && extraPseudoTag != nsCSSAnonBoxes::mozNonElement, @@ -4683,7 +4679,7 @@ ElementRestyler::MustReframeForAfterPseudo(nsIFrame* aFrame) #endif void -ElementRestyler::MaybeReframeForPseudo(nsCSSPseudoElements::Type aPseudoType, +ElementRestyler::MaybeReframeForPseudo(CSSPseudoElementType aPseudoType, nsIFrame* aGenConParentFrame, nsIFrame* aFrame, nsIContent* aContent, @@ -4700,7 +4696,7 @@ ElementRestyler::MaybeReframeForPseudo(nsCSSPseudoElements::Type aPseudoType, } bool -ElementRestyler::MustReframeForPseudo(nsCSSPseudoElements::Type aPseudoType, +ElementRestyler::MustReframeForPseudo(CSSPseudoElementType aPseudoType, nsIFrame* aGenConParentFrame, nsIFrame* aFrame, nsIContent* aContent, diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index a7d1916992cc..de4f1757dcb6 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -18,7 +18,6 @@ #include "nsPresContext.h" #include "nsRefreshDriver.h" #include "nsRefPtrHashtable.h" -#include "nsCSSPseudoElements.h" #include "nsTransitionManager.h" class nsIFrame; @@ -26,6 +25,7 @@ class nsStyleChangeList; struct TreeMatchContext; namespace mozilla { + enum class CSSPseudoElementType : uint8_t; class EventStates; struct UndisplayedNode; @@ -191,7 +191,7 @@ public: void Put(nsIContent* aContent, nsStyleContext* aStyleContext) { MOZ_ASSERT(aContent); - nsCSSPseudoElements::Type pseudoType = aStyleContext->GetPseudoType(); + CSSPseudoElementType pseudoType = aStyleContext->GetPseudoType(); if (pseudoType == CSSPseudoElementType::NotPseudo) { mElementContexts.Put(aContent, aStyleContext); } else if (pseudoType == CSSPseudoElementType::before) { @@ -204,7 +204,7 @@ public: } nsStyleContext* Get(nsIContent* aContent, - nsCSSPseudoElements::Type aPseudoType) { + CSSPseudoElementType aPseudoType) { MOZ_ASSERT(aContent); if (aPseudoType == CSSPseudoElementType::NotPseudo) { return mElementContexts.GetWeak(aContent); @@ -269,7 +269,7 @@ public: // the real element. void Put(nsIContent* aContent, nsStyleContext* aStyleContext) { MOZ_ASSERT(aContent); - nsCSSPseudoElements::Type pseudoType = aStyleContext->GetPseudoType(); + CSSPseudoElementType pseudoType = aStyleContext->GetPseudoType(); if (pseudoType == CSSPseudoElementType::NotPseudo) { mContents.AppendElement(aContent); } else if (pseudoType == CSSPseudoElementType::before) { @@ -285,7 +285,7 @@ public: private: void StopAnimationsWithoutFrame(nsTArray>& aArray, - nsCSSPseudoElements::Type aPseudoType); + CSSPseudoElementType aPseudoType); RestyleManager* mRestyleManager; AutoRestore mRestorePointer; @@ -792,7 +792,7 @@ private: const uint8_t aDisplay); void MaybeReframeForBeforePseudo(); void MaybeReframeForAfterPseudo(nsIFrame* aFrame); - void MaybeReframeForPseudo(nsCSSPseudoElements::Type aPseudoType, + void MaybeReframeForPseudo(CSSPseudoElementType aPseudoType, nsIFrame* aGenConParentFrame, nsIFrame* aFrame, nsIContent* aContent, @@ -801,7 +801,7 @@ private: bool MustReframeForBeforePseudo(); bool MustReframeForAfterPseudo(nsIFrame* aFrame); #endif - bool MustReframeForPseudo(nsCSSPseudoElements::Type aPseudoType, + bool MustReframeForPseudo(CSSPseudoElementType aPseudoType, nsIFrame* aGenConParentFrame, nsIFrame* aFrame, nsIContent* aContent, diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 1b3466d4ca86..ed687745dd9b 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -20,6 +20,7 @@ #include "mozilla/Likely.h" #include "mozilla/LinkedList.h" #include "nsAbsoluteContainingBlock.h" +#include "nsCSSPseudoElements.h" #include "nsIAtom.h" #include "nsIFrameInlines.h" #include "nsGkAtoms.h" @@ -1757,7 +1758,7 @@ nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aStat nsContainerFrame* aParentFrame, nsIContent* aParentContent, nsStyleContext* aStyleContext, - nsCSSPseudoElements::Type aPseudoElement, + CSSPseudoElementType aPseudoElement, FrameConstructionItemList& aItems) { MOZ_ASSERT(aPseudoElement == CSSPseudoElementType::before || diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 9c5613fd825d..db359312d75b 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -17,7 +17,6 @@ #include "nsILayoutHistoryState.h" #include "nsQuoteList.h" #include "nsCounterManager.h" -#include "nsCSSPseudoElements.h" #include "nsIAnonymousContentCreator.h" #include "nsFrameManager.h" #include "nsIDocument.h" @@ -51,6 +50,7 @@ class FlattenedChildIterator; class nsCSSFrameConstructor : public nsFrameManager { public: + typedef mozilla::CSSPseudoElementType CSSPseudoElementType; typedef mozilla::dom::Element Element; friend class mozilla::RestyleManager; @@ -452,7 +452,7 @@ private: nsContainerFrame* aFrame, nsIContent* aContent, nsStyleContext* aStyleContext, - nsCSSPseudoElements::Type aPseudoElement, + CSSPseudoElementType aPseudoElement, FrameConstructionItemList& aItems); // This method can change aFrameList: it can chop off the beginning and put diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 2043b053a981..a9fd068a7fee 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2035,7 +2035,7 @@ nsLayoutUtils::GetScrolledRect(nsIFrame* aScrolledFrame, bool nsLayoutUtils::HasPseudoStyle(nsIContent* aContent, nsStyleContext* aStyleContext, - nsCSSPseudoElements::Type aPseudoElement, + CSSPseudoElementType aPseudoElement, nsPresContext* aPresContext) { NS_PRECONDITION(aPresContext, "Must have a prescontext"); diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index b4dfc8a16adc..5723d9b5f09b 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -16,7 +16,6 @@ #include "mozilla/layout/FrameChildList.h" #include "nsThreadUtils.h" #include "nsIPrincipal.h" -#include "nsCSSPseudoElements.h" #include "FrameMetrics.h" #include "nsIWidget.h" #include "nsCSSProperty.h" @@ -63,6 +62,7 @@ struct nsStyleImageOrientation; struct nsOverflowAreas; namespace mozilla { +enum class CSSPseudoElementType : uint8_t; class EventListenerManager; class SVGImageContext; struct IntrinsicSize; @@ -661,7 +661,7 @@ public: */ static bool HasPseudoStyle(nsIContent* aContent, nsStyleContext* aStyleContext, - nsCSSPseudoElements::Type aPseudoElement, + mozilla::CSSPseudoElementType aPseudoElement, nsPresContext* aPresContext); /** @@ -2199,7 +2199,8 @@ public: */ static bool GetAnimationContent(const nsIFrame* aFrame, nsIContent* &aContentResult, - nsCSSPseudoElements::Type &aPseudoTypeResult); + mozilla::CSSPseudoElementType + &aPseudoTypeResult); /** * Returns true if the frame has current (i.e. running or scheduled-to-run) diff --git a/layout/forms/nsColorControlFrame.cpp b/layout/forms/nsColorControlFrame.cpp index 1b6414cb0dfd..4621c14dc9a7 100644 --- a/layout/forms/nsColorControlFrame.cpp +++ b/layout/forms/nsColorControlFrame.cpp @@ -8,6 +8,7 @@ #include "nsContentCreatorFunctions.h" #include "nsContentList.h" #include "nsContentUtils.h" +#include "nsCSSPseudoElements.h" #include "nsFormControlFrame.h" #include "nsGkAtoms.h" #include "nsIDOMHTMLInputElement.h" @@ -72,7 +73,7 @@ nsColorControlFrame::CreateAnonymousContent(nsTArray& aElements) nsresult rv = UpdateColor(); NS_ENSURE_SUCCESS(rv, rv); - nsCSSPseudoElements::Type pseudoType = CSSPseudoElementType::mozColorSwatch; + CSSPseudoElementType pseudoType = CSSPseudoElementType::mozColorSwatch; RefPtr newStyleContext = PresContext()->StyleSet()-> ResolvePseudoElementStyle(mContent->AsElement(), pseudoType, StyleContext(), mColorContent->AsElement()); @@ -135,7 +136,7 @@ nsColorControlFrame::GetContentInsertionFrame() } Element* -nsColorControlFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) +nsColorControlFrame::GetPseudoElement(CSSPseudoElementType aType) { if (aType == CSSPseudoElementType::mozColorSwatch) { return mColorContent; diff --git a/layout/forms/nsColorControlFrame.h b/layout/forms/nsColorControlFrame.h index 584491e56c66..568485c033d7 100644 --- a/layout/forms/nsColorControlFrame.h +++ b/layout/forms/nsColorControlFrame.h @@ -10,6 +10,10 @@ #include "nsHTMLButtonControlFrame.h" #include "nsIAnonymousContentCreator.h" +namespace mozilla { +enum class CSSPseudoElementType : uint8_t; +} // namespace mozilla + typedef nsHTMLButtonControlFrame nsColorControlFrameSuper; // Class which implements the input type=color @@ -17,6 +21,7 @@ typedef nsHTMLButtonControlFrame nsColorControlFrameSuper; class nsColorControlFrame final : public nsColorControlFrameSuper, public nsIAnonymousContentCreator { + typedef mozilla::CSSPseudoElementType CSSPseudoElementType; typedef mozilla::dom::Element Element; public: @@ -47,7 +52,7 @@ public: virtual bool IsLeaf() const override { return true; } virtual nsContainerFrame* GetContentInsertionFrame() override; - virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) override; + virtual Element* GetPseudoElement(CSSPseudoElementType aType) override; // Refresh the color swatch, using associated input's value nsresult UpdateColor(); diff --git a/layout/forms/nsMeterFrame.cpp b/layout/forms/nsMeterFrame.cpp index 7093b53d31f4..a6cf69141b97 100644 --- a/layout/forms/nsMeterFrame.cpp +++ b/layout/forms/nsMeterFrame.cpp @@ -19,6 +19,7 @@ #include "mozilla/dom/Element.h" #include "mozilla/dom/HTMLMeterElement.h" #include "nsContentList.h" +#include "nsCSSPseudoElements.h" #include "nsStyleSet.h" #include "nsThemeConstants.h" #include @@ -66,7 +67,7 @@ nsMeterFrame::CreateAnonymousContent(nsTArray& aElements) mBarDiv = doc->CreateHTMLElement(nsGkAtoms::div); // Associate ::-moz-meter-bar pseudo-element to the anonymous child. - nsCSSPseudoElements::Type pseudoType = CSSPseudoElementType::mozMeterBar; + CSSPseudoElementType pseudoType = CSSPseudoElementType::mozMeterBar; RefPtr newStyleContext = PresContext()->StyleSet()-> ResolvePseudoElementStyle(mContent->AsElement(), pseudoType, StyleContext(), mBarDiv->AsElement()); @@ -281,7 +282,7 @@ nsMeterFrame::ShouldUseNativeStyle() const } Element* -nsMeterFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) +nsMeterFrame::GetPseudoElement(CSSPseudoElementType aType) { if (aType == CSSPseudoElementType::mozMeterBar) { return mBarDiv; diff --git a/layout/forms/nsMeterFrame.h b/layout/forms/nsMeterFrame.h index d7cc32470530..fc6e72cb6f74 100644 --- a/layout/forms/nsMeterFrame.h +++ b/layout/forms/nsMeterFrame.h @@ -73,7 +73,7 @@ public: */ bool ShouldUseNativeStyle() const; - virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) override; + virtual Element* GetPseudoElement(CSSPseudoElementType aType) override; protected: // Helper function which reflow the anonymous div frame. diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index 44f7b3ba705e..7e3813be0075 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -20,6 +20,7 @@ #include "nsContentUtils.h" #include "nsContentCreatorFunctions.h" #include "nsContentList.h" +#include "nsCSSPseudoElements.h" #include "nsStyleSet.h" #include "nsIDOMMutationEvent.h" #include "nsThreadUtils.h" @@ -323,7 +324,7 @@ nsresult nsNumberControlFrame::MakeAnonymousElement(Element** aResult, nsTArray& aElements, nsIAtom* aTagName, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsStyleContext* aParentContext) { // Get the NodeInfoManager and tag necessary to create the anonymous divs. @@ -824,7 +825,7 @@ nsNumberControlFrame::AnonTextControlIsEmpty() } Element* -nsNumberControlFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) +nsNumberControlFrame::GetPseudoElement(CSSPseudoElementType aType) { if (aType == CSSPseudoElementType::mozNumberWrapper) { return mOuterWrapper; diff --git a/layout/forms/nsNumberControlFrame.h b/layout/forms/nsNumberControlFrame.h index 458e0abe4b63..1cec12dcd0d9 100644 --- a/layout/forms/nsNumberControlFrame.h +++ b/layout/forms/nsNumberControlFrame.h @@ -16,6 +16,7 @@ class nsPresContext; namespace mozilla { +enum class CSSPseudoElementType : uint8_t; class WidgetEvent; class WidgetGUIEvent; namespace dom { @@ -33,6 +34,7 @@ class nsNumberControlFrame final : public nsContainerFrame friend nsIFrame* NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + typedef mozilla::CSSPseudoElementType CSSPseudoElementType; typedef mozilla::dom::Element Element; typedef mozilla::dom::HTMLInputElement HTMLInputElement; typedef mozilla::WidgetEvent WidgetEvent; @@ -186,7 +188,7 @@ public: */ nsresult HandleSelectCall(); - virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) override; + virtual Element* GetPseudoElement(CSSPseudoElementType aType) override; bool ShouldUseNativeStyleForSpinner() const; @@ -196,7 +198,7 @@ private: nsresult MakeAnonymousElement(Element** aResult, nsTArray& aElements, nsIAtom* aTagName, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsStyleContext* aParentContext); class SyncDisabledStateEvent; diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp index bf21c8d2fb77..4c6c80b3becc 100644 --- a/layout/forms/nsProgressFrame.cpp +++ b/layout/forms/nsProgressFrame.cpp @@ -19,6 +19,7 @@ #include "mozilla/dom/Element.h" #include "mozilla/dom/HTMLProgressElement.h" #include "nsContentList.h" +#include "nsCSSPseudoElements.h" #include "nsStyleSet.h" #include "nsThemeConstants.h" #include @@ -63,7 +64,7 @@ nsProgressFrame::CreateAnonymousContent(nsTArray& aElements) mBarDiv = doc->CreateHTMLElement(nsGkAtoms::div); // Associate ::-moz-progress-bar pseudo-element to the anonymous child. - nsCSSPseudoElements::Type pseudoType = CSSPseudoElementType::mozProgressBar; + CSSPseudoElementType pseudoType = CSSPseudoElementType::mozProgressBar; RefPtr newStyleContext = PresContext()->StyleSet()-> ResolvePseudoElementStyle(mContent->AsElement(), pseudoType, StyleContext(), mBarDiv->AsElement()); @@ -287,7 +288,7 @@ nsProgressFrame::ShouldUseNativeStyle() const } Element* -nsProgressFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) +nsProgressFrame::GetPseudoElement(CSSPseudoElementType aType) { if (aType == CSSPseudoElementType::mozProgressBar) { return mBarDiv; diff --git a/layout/forms/nsProgressFrame.h b/layout/forms/nsProgressFrame.h index 980e8ba9e2d8..0cecbd25ca8e 100644 --- a/layout/forms/nsProgressFrame.h +++ b/layout/forms/nsProgressFrame.h @@ -11,9 +11,14 @@ #include "nsIAnonymousContentCreator.h" #include "nsCOMPtr.h" +namespace mozilla { +enum class CSSPseudoElementType : uint8_t; +} // namespace mozilla + class nsProgressFrame : public nsContainerFrame, public nsIAnonymousContentCreator { + typedef mozilla::CSSPseudoElementType CSSPseudoElementType; typedef mozilla::dom::Element Element; public: @@ -76,7 +81,7 @@ public: */ bool ShouldUseNativeStyle() const; - virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) override; + virtual Element* GetPseudoElement(CSSPseudoElementType aType) override; protected: // Helper function which reflow the anonymous div frame. diff --git a/layout/forms/nsRangeFrame.cpp b/layout/forms/nsRangeFrame.cpp index cc331fc5618c..5b74a9e6d274 100644 --- a/layout/forms/nsRangeFrame.cpp +++ b/layout/forms/nsRangeFrame.cpp @@ -11,6 +11,7 @@ #include "nsContentCreatorFunctions.h" #include "nsContentList.h" #include "nsContentUtils.h" +#include "nsCSSPseudoElements.h" #include "nsCSSRendering.h" #include "nsFormControlFrame.h" #include "nsIContent.h" @@ -110,7 +111,7 @@ nsRangeFrame::DestroyFrom(nsIFrame* aDestructRoot) nsresult nsRangeFrame::MakeAnonymousDiv(Element** aResult, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsTArray& aElements) { nsCOMPtr doc = mContent->GetComposedDoc(); @@ -894,7 +895,7 @@ nsRangeFrame::ShouldUseNativeStyle() const } Element* -nsRangeFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) +nsRangeFrame::GetPseudoElement(CSSPseudoElementType aType) { if (aType == CSSPseudoElementType::mozRangeTrack) { return mTrackDiv; diff --git a/layout/forms/nsRangeFrame.h b/layout/forms/nsRangeFrame.h index 63b7a5086172..80412247757d 100644 --- a/layout/forms/nsRangeFrame.h +++ b/layout/forms/nsRangeFrame.h @@ -27,6 +27,7 @@ class nsRangeFrame : public nsContainerFrame, explicit nsRangeFrame(nsStyleContext* aContext); virtual ~nsRangeFrame(); + typedef mozilla::CSSPseudoElementType CSSPseudoElementType; typedef mozilla::dom::Element Element; public: @@ -147,12 +148,12 @@ public: */ void UpdateForValueChange(); - virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) override; + virtual Element* GetPseudoElement(CSSPseudoElementType aType) override; private: nsresult MakeAnonymousDiv(Element** aResult, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsTArray& aElements); // Helper function which reflows the anonymous div frames. diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index 156f33081efb..e29b76e11806 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -10,6 +10,7 @@ #include "nsTextControlFrame.h" #include "nsIPlaintextEditor.h" #include "nsCaret.h" +#include "nsCSSPseudoElements.h" #include "nsGenericHTMLElement.h" #include "nsIEditor.h" #include "nsIEditorIMESupport.h" @@ -346,7 +347,7 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray& aElements) NS_ENSURE_TRUE(placeholderNode, NS_ERROR_OUT_OF_MEMORY); // Associate ::-moz-placeholder pseudo-element with the placeholder node. - nsCSSPseudoElements::Type pseudoType = CSSPseudoElementType::mozPlaceholder; + CSSPseudoElementType pseudoType = CSSPseudoElementType::mozPlaceholder; RefPtr placeholderStyleContext = PresContext()->StyleSet()->ResolvePseudoElementStyle( @@ -1443,7 +1444,7 @@ nsTextControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } mozilla::dom::Element* -nsTextControlFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) +nsTextControlFrame::GetPseudoElement(CSSPseudoElementType aType) { if (aType == CSSPseudoElementType::mozPlaceholder) { nsCOMPtr txtCtrl = do_QueryInterface(GetContent()); diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index 0157d3b4a785..9e12342cf1c2 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -19,6 +19,7 @@ class EditorInitializerEntryTracker; class nsTextEditorState; class nsIEditor; namespace mozilla { +enum class CSSPseudoElementType : uint8_t; namespace dom { class Element; } // namespace dom @@ -98,10 +99,11 @@ public: const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; - virtual mozilla::dom::Element* GetPseudoElement(nsCSSPseudoElements::Type aType) override; + virtual mozilla::dom::Element* + GetPseudoElement(mozilla::CSSPseudoElementType aType) override; //==== BEGIN NSIFORMCONTROLFRAME - virtual void SetFocus(bool aOn , bool aRepaint) override; + virtual void SetFocus(bool aOn , bool aRepaint) override; virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) override; //==== END NSIFORMCONTROLFRAME diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 553048d82c45..d9c4448f66b0 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -24,6 +24,7 @@ #include "nsPlaceholderFrame.h" #include "nsIContent.h" #include "nsContentUtils.h" +#include "nsCSSPseudoElements.h" #include "nsIAtom.h" #include "nsString.h" #include "nsReadableUtils.h" @@ -9121,7 +9122,7 @@ nsIFrame::IsPseudoStackingContextFromStyle() { } Element* -nsIFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) +nsIFrame::GetPseudoElement(CSSPseudoElementType aType) { nsIFrame* frame = nullptr; diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 29e238710730..3db07f136fa2 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -90,6 +90,7 @@ struct CharacterDataChangeInfo; namespace mozilla { +enum class CSSPseudoElementType : uint8_t; class EventStates; namespace layers { @@ -3094,7 +3095,8 @@ public: * generated and which corresponds to the specified pseudo-element type, * or nullptr if there is no such anonymous content. */ - virtual mozilla::dom::Element* GetPseudoElement(nsCSSPseudoElements::Type aType); + virtual mozilla::dom::Element* + GetPseudoElement(mozilla::CSSPseudoElementType aType); bool BackfaceIsHidden() { return StyleDisplay()->BackfaceIsHidden(); diff --git a/layout/inspector/inDOMUtils.cpp b/layout/inspector/inDOMUtils.cpp index 59f1262300ec..a85d38aa939b 100644 --- a/layout/inspector/inDOMUtils.cpp +++ b/layout/inspector/inDOMUtils.cpp @@ -1196,7 +1196,7 @@ inDOMUtils::GetCSSPseudoElementNames(uint32_t* aLength, char16_t*** aNames) const uint8_t pseudoCount = static_cast(CSSPseudoElementType::Count); for (uint8_t i = 0; i < pseudoCount; ++i) { - nsCSSPseudoElements::Type type = static_cast(i); + CSSPseudoElementType type = static_cast(i); if (!nsCSSPseudoElements::PseudoElementIsUASheetOnly(type)) { nsIAtom* atom = nsCSSPseudoElements::GetPseudoAtom(type); array.AppendElement(atom); diff --git a/layout/mathml/nsMathMLFrame.cpp b/layout/mathml/nsMathMLFrame.cpp index c7e69a931580..aec0b2516318 100644 --- a/layout/mathml/nsMathMLFrame.cpp +++ b/layout/mathml/nsMathMLFrame.cpp @@ -98,7 +98,7 @@ nsMathMLFrame::ResolveMathMLCharStyle(nsPresContext* aPresContext, nsStyleContext* aParentStyleContext, nsMathMLChar* aMathMLChar) { - nsCSSPseudoElements::Type pseudoType = + CSSPseudoElementType pseudoType = CSSPseudoElementType::mozMathAnonymous; // savings RefPtr newStyleContext; newStyleContext = aPresContext->StyleSet()-> diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index d9e967aaf413..330086493cf0 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -68,7 +68,7 @@ CommonAnimationManager::RemoveAllElementCollections() AnimationCollection* CommonAnimationManager::GetAnimationCollection(dom::Element *aElement, - nsCSSPseudoElements::Type + CSSPseudoElementType aPseudoType, bool aCreateIfNeeded) { @@ -117,7 +117,7 @@ CommonAnimationManager::GetAnimationCollection(dom::Element *aElement, AnimationCollection* CommonAnimationManager::GetAnimationCollection(const nsIFrame* aFrame) { - Maybe> pseudoElement = + Maybe> pseudoElement = EffectCompositor::GetAnimationElementAndPseudoForFrame(aFrame); if (!pseudoElement) { return nullptr; @@ -152,7 +152,7 @@ CommonAnimationManager::ExtractComputedValueForTransition( } /*static*/ nsString -AnimationCollection::PseudoTypeAsString(nsCSSPseudoElements::Type aPseudoType) +AnimationCollection::PseudoTypeAsString(CSSPseudoElementType aPseudoType) { switch (aPseudoType) { case CSSPseudoElementType::before: diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index a32840da69f7..2b492827ee09 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -83,7 +83,7 @@ public: // by this class for the given |aElement| and |aPseudoType|. AnimationCollection* GetAnimationCollection(dom::Element *aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, bool aCreateIfNeeded); // Given the frame |aFrame| with possibly animated content, finds its @@ -174,7 +174,7 @@ public: mElementProperty == nsGkAtoms::animationsOfAfterProperty; } - nsCSSPseudoElements::Type PseudoElementType() const + CSSPseudoElementType PseudoElementType() const { if (IsForElement()) { return CSSPseudoElementType::NotPseudo; @@ -187,7 +187,7 @@ public: return CSSPseudoElementType::after; } - static nsString PseudoTypeAsString(nsCSSPseudoElements::Type aPseudoType); + static nsString PseudoTypeAsString(CSSPseudoElementType aPseudoType); dom::Element* GetElementToRestyle() const; @@ -239,7 +239,7 @@ public: { } OwningElementRef(dom::Element& aElement, - nsCSSPseudoElements::Type aPseudoType) + CSSPseudoElementType aPseudoType) : mElement(&aElement) , mPseudoType(aPseudoType) { } @@ -267,7 +267,7 @@ public: bool IsSet() const { return !!mElement; } void GetElement(dom::Element*& aElement, - nsCSSPseudoElements::Type& aPseudoType) const { + CSSPseudoElementType& aPseudoType) const { aElement = mElement; aPseudoType = mPseudoType; } @@ -276,7 +276,7 @@ public: private: dom::Element* MOZ_NON_OWNING_REF mElement; - nsCSSPseudoElements::Type mPseudoType; + CSSPseudoElementType mPseudoType; }; template diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index 7a81818b06b6..8b17fe8a4966 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -19,6 +19,7 @@ #include "nsStyleSet.h" #include "nsComputedDOMStyle.h" #include "nsCSSParser.h" +#include "nsCSSPseudoElements.h" #include "mozilla/css/Declaration.h" #include "mozilla/dom/Element.h" #include "mozilla/FloatingPoint.h" @@ -2526,7 +2527,7 @@ BuildStyleRule(nsCSSProperty aProperty, inline already_AddRefed LookupStyleContext(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType) + CSSPseudoElementType aPseudoType) { nsIDocument* doc = aElement->GetCurrentDoc(); nsIPresShell* shell = doc->GetShell(); @@ -2543,7 +2544,7 @@ LookupStyleContext(dom::Element* aElement, /* static */ bool StyleAnimationValue::ComputeValue(nsCSSProperty aProperty, dom::Element* aTargetElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, const nsAString& aSpecifiedValue, bool aUseSVGMode, StyleAnimationValue& aComputedValue, @@ -2595,7 +2596,7 @@ StyleAnimationValue::ComputeValue(nsCSSProperty aProperty, StyleAnimationValue::ComputeValues(nsCSSProperty aProperty, nsCSSProps::EnabledState aEnabledState, dom::Element* aTargetElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, const nsAString& aSpecifiedValue, bool aUseSVGMode, nsTArray& aResult) @@ -2625,7 +2626,7 @@ StyleAnimationValue::ComputeValues( nsCSSProperty aProperty, nsCSSProps::EnabledState aEnabledState, dom::Element* aTargetElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, css::StyleRule* aStyleRule, nsTArray& aValues, bool* aIsContextSensitive) diff --git a/layout/style/StyleAnimationValue.h b/layout/style/StyleAnimationValue.h index 1af9a922c4ee..09798cd9a76a 100644 --- a/layout/style/StyleAnimationValue.h +++ b/layout/style/StyleAnimationValue.h @@ -14,7 +14,6 @@ #include "nsCoord.h" #include "nsColor.h" #include "nsCSSProps.h" -#include "nsCSSPseudoElements.h" #include "nsCSSValue.h" class nsIFrame; @@ -31,6 +30,7 @@ namespace dom { class Element; } // namespace dom +enum class CSSPseudoElementType : uint8_t; struct PropertyStyleAnimationValuePair; /** @@ -156,7 +156,7 @@ public: */ static bool ComputeValue(nsCSSProperty aProperty, mozilla::dom::Element* aTargetElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, const nsAString& aSpecifiedValue, bool aUseSVGMode, StyleAnimationValue& aComputedValue, @@ -175,7 +175,7 @@ public: static bool ComputeValues(nsCSSProperty aProperty, nsCSSProps::EnabledState aEnabledState, mozilla::dom::Element* aTargetElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, const nsAString& aSpecifiedValue, bool aUseSVGMode, nsTArray& aResult); @@ -403,7 +403,7 @@ private: static bool ComputeValues(nsCSSProperty aProperty, nsCSSProps::EnabledState aEnabledState, mozilla::dom::Element* aTargetElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, mozilla::css::StyleRule* aStyleRule, nsTArray& aValues, bool* aIsContextSensitive); diff --git a/layout/style/StyleRule.cpp b/layout/style/StyleRule.cpp index b7a880d8d20b..3bb5169cf3fd 100644 --- a/layout/style/StyleRule.cpp +++ b/layout/style/StyleRule.cpp @@ -23,7 +23,6 @@ #include "nsDOMCSSDeclaration.h" #include "nsNameSpaceManager.h" #include "nsXMLNameSpaceMap.h" -#include "nsCSSPseudoElements.h" #include "nsCSSPseudoClasses.h" #include "nsCSSAnonBoxes.h" #include "nsTArray.h" @@ -319,7 +318,7 @@ nsCSSSelector::nsCSSSelector(void) { MOZ_COUNT_CTOR(nsCSSSelector); static_assert(static_cast(CSSPseudoElementType::MAX) < INT16_MAX, - "nsCSSPseudoElements::Type values overflow mPseudoType"); + "CSSPseudoElementType values overflow mPseudoType"); } nsCSSSelector* diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index e66a5a7688fd..20775c379588 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -17,8 +17,8 @@ #include "nsString.h" #include "nsCOMPtr.h" -#include "nsCSSPseudoElements.h" #include "nsCSSPseudoClasses.h" +#include "nsCSSPseudoElements.h" #include "nsIStyleRule.h" class nsIAtom; @@ -208,13 +208,10 @@ private: public: // Get and set the selector's pseudo type - nsCSSPseudoElements::Type PseudoType() const { - return static_cast(mPseudoType); + mozilla::CSSPseudoElementType PseudoType() const { + return static_cast(mPseudoType); } - void SetPseudoType(nsCSSPseudoElements::Type aType) { - NS_ASSERTION(static_cast(aType) >= INT16_MIN && - static_cast(aType) <= INT16_MAX, - "Out of bounds - this will overflow mPseudoType"); + void SetPseudoType(mozilla::CSSPseudoElementType aType) { mPseudoType = static_cast(aType); } diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index 759df682bd99..5225cb12bc8a 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -168,7 +168,7 @@ CSSAnimation::QueueEvents() } dom::Element* owningElement; - nsCSSPseudoElements::Type owningPseudoType; + CSSPseudoElementType owningPseudoType; mOwningElement.GetElement(owningElement, owningPseudoType); MOZ_ASSERT(owningElement, "Owning element should be set"); @@ -488,7 +488,7 @@ nsAnimationManager::UpdateAnimations(nsStyleContext* aStyleContext, void nsAnimationManager::StopAnimationsForElement( mozilla::dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType) + mozilla::CSSPseudoElementType aPseudoType) { MOZ_ASSERT(aElement); AnimationCollection* collection = diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 0b1280b71a50..7869e5907461 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -9,7 +9,6 @@ #include "mozilla/ContentEvents.h" #include "mozilla/EventForwards.h" #include "AnimationCommon.h" -#include "nsCSSPseudoElements.h" #include "mozilla/dom/Animation.h" #include "mozilla/MemoryReporting.h" #include "mozilla/TimeStamp.h" @@ -26,6 +25,8 @@ class KeyframeEffectReadOnly; class Promise; } /* namespace dom */ +enum class CSSPseudoElementType : uint8_t; + struct AnimationEventInfo { RefPtr mElement; RefPtr mAnimation; @@ -33,7 +34,7 @@ struct AnimationEventInfo { TimeStamp mTimeStamp; AnimationEventInfo(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, EventMessage aMessage, const nsSubstring& aAnimationName, const StickyTimeDuration& aElapsedTime, @@ -322,7 +323,7 @@ public: // rather than the element for the generated content for animations on // ::before and ::after. void StopAnimationsForElement(mozilla::dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType); + mozilla::CSSPseudoElementType aPseudoType); bool IsAnimationManager() override { return true; diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index bf3c87f11af2..b481bad14bb8 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -753,7 +753,7 @@ protected: bool aIsNegated, nsIAtom** aPseudoElement, nsAtomList** aPseudoElementArgs, - nsCSSPseudoElements::Type* aPseudoElementType); + CSSPseudoElementType* aPseudoElementType); nsSelectorParsingStatus ParseAttributeSelector(int32_t& aDataMask, nsCSSSelector& aSelector); @@ -5827,7 +5827,7 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, bool aIsNegated, nsIAtom** aPseudoElement, nsAtomList** aPseudoElementArgs, - nsCSSPseudoElements::Type* aPseudoElementType) + CSSPseudoElementType* aPseudoElementType) { NS_ASSERTION(aIsNegated || (aPseudoElement && aPseudoElementArgs), "expected location to store pseudo element"); @@ -5867,7 +5867,7 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, // stash away some info about this pseudo so we only have to get it once. bool isTreePseudo = false; - nsCSSPseudoElements::Type pseudoElementType = + CSSPseudoElementType pseudoElementType = nsCSSPseudoElements::GetPseudoType(pseudo); nsCSSPseudoClasses::Type pseudoClassType = nsCSSPseudoClasses::GetPseudoType(pseudo); @@ -5971,7 +5971,7 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, } else if (!parsingPseudoElement && isPseudoClass) { if (aSelector.IsPseudoElement()) { - nsCSSPseudoElements::Type type = aSelector.PseudoType(); + CSSPseudoElementType type = aSelector.PseudoType(); if (!nsCSSPseudoElements::PseudoElementSupportsUserActionState(type)) { // We only allow user action pseudo-classes on certain pseudo-elements. REPORT_UNEXPECTED_TOKEN(PEPseudoSelNoUserActionPC); @@ -6412,7 +6412,7 @@ CSSParserImpl::ParseSelector(nsCSSSelectorList* aList, nsCSSSelector* selector = aList->AddSelector(aPrevCombinator); nsCOMPtr pseudoElement; nsAutoPtr pseudoElementArgs; - nsCSSPseudoElements::Type pseudoElementType = CSSPseudoElementType::NotPseudo; + CSSPseudoElementType pseudoElementType = CSSPseudoElementType::NotPseudo; int32_t dataMask = 0; nsSelectorParsingStatus parsingStatus = diff --git a/layout/style/nsCSSPseudoElements.cpp b/layout/style/nsCSSPseudoElements.cpp index 7cc5d24a0a77..7f5d85e39bdd 100644 --- a/layout/style/nsCSSPseudoElements.cpp +++ b/layout/style/nsCSSPseudoElements.cpp @@ -67,8 +67,8 @@ nsCSSPseudoElements::IsCSS2PseudoElement(nsIAtom *aAtom) aAtom == nsCSSPseudoElements::firstLetter || aAtom == nsCSSPseudoElements::firstLine; NS_ASSERTION(nsCSSAnonBoxes::IsAnonBox(aAtom) || - result == - PseudoElementHasFlags(GetPseudoType(aAtom), CSS_PSEUDO_ELEMENT_IS_CSS2), + result == PseudoElementHasFlags(GetPseudoType(aAtom), + CSS_PSEUDO_ELEMENT_IS_CSS2), "result doesn't match flags"); return result; } @@ -76,9 +76,9 @@ nsCSSPseudoElements::IsCSS2PseudoElement(nsIAtom *aAtom) /* static */ CSSPseudoElementType nsCSSPseudoElements::GetPseudoType(nsIAtom *aAtom) { - for (uint32_t i = 0; i < ArrayLength(CSSPseudoElements_info); ++i) { + for (uint8_t i = 0; i < ArrayLength(CSSPseudoElements_info); ++i) { if (*CSSPseudoElements_info[i].mAtom == aAtom) { - return Type(i); + return static_cast(i); } } @@ -98,15 +98,14 @@ nsCSSPseudoElements::GetPseudoType(nsIAtom *aAtom) /* static */ nsIAtom* nsCSSPseudoElements::GetPseudoAtom(Type aType) { - NS_ASSERTION(aType < Type::Count, - "Unexpected type"); + NS_ASSERTION(aType < Type::Count, "Unexpected type"); return *CSSPseudoElements_info[static_cast(aType)].mAtom; } /* static */ uint32_t nsCSSPseudoElements::FlagsForPseudoElement(const Type aType) { - size_t index = static_cast(aType); + uint8_t index = static_cast(aType); NS_ASSERTION(index < ArrayLength(CSSPseudoElements_flags), "argument must be a pseudo-element"); return CSSPseudoElements_flags[index]; diff --git a/layout/style/nsCSSPseudoElements.h b/layout/style/nsCSSPseudoElements.h index da66f5c288d3..8d7ec5c6cfca 100644 --- a/layout/style/nsCSSPseudoElements.h +++ b/layout/style/nsCSSPseudoElements.h @@ -61,11 +61,11 @@ enum class CSSPseudoElementType : uint8_t { // require an atom from this atom list. class nsICSSPseudoElement : public nsIAtom {}; -class nsCSSPseudoElements { -public: - // FIXME: Remove this in later patch - using Type = mozilla::CSSPseudoElementType; +class nsCSSPseudoElements +{ + typedef mozilla::CSSPseudoElementType Type; +public: static void AddRefAtoms(); static bool IsPseudoElement(nsIAtom *aAtom); @@ -79,7 +79,7 @@ public: static Type GetPseudoType(nsIAtom* aAtom); - // Get the atom for a given Type. aType must be < Type::Count + // Get the atom for a given Type. aType must be < CSSPseudoElementType::Count static nsIAtom* GetPseudoAtom(Type aType); static bool PseudoElementContainsElements(const Type aType) { @@ -88,7 +88,8 @@ public: static bool PseudoElementSupportsStyleAttribute(const Type aType) { MOZ_ASSERT(aType < Type::Count); - return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE); + return PseudoElementHasFlags(aType, + CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE); } static bool PseudoElementSupportsUserActionState(const Type aType); diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index b48dc14eb765..7871e8922011 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -2716,7 +2716,7 @@ static inline nsRestyleHint RestyleHintForOp(char16_t oper) nsRestyleHint nsCSSRuleProcessor::HasStateDependentStyle(ElementDependentRuleProcessorData* aData, Element* aStatefulElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, EventStates aStateMask) { MOZ_ASSERT(!aData->mTreeMatchContext.mForScopedStyle, @@ -3411,7 +3411,7 @@ AddRule(RuleSelectorPair* aRuleInfo, RuleCascadeData* aCascade) RuleCascadeData * const cascade = aCascade; // Build the rule hash. - nsCSSPseudoElements::Type pseudoType = aRuleInfo->mSelector->PseudoType(); + CSSPseudoElementType pseudoType = aRuleInfo->mSelector->PseudoType(); if (MOZ_LIKELY(pseudoType == CSSPseudoElementType::NotPseudo)) { cascade->mRuleHash.AppendRule(*aRuleInfo); } else if (pseudoType < CSSPseudoElementType::Count) { @@ -3462,7 +3462,7 @@ AddRule(RuleSelectorPair* aRuleInfo, RuleCascadeData* aCascade) for (nsCSSSelector* selector = aRuleInfo->mSelector; selector; selector = selector->mNext) { if (selector->IsPseudoElement()) { - nsCSSPseudoElements::Type pseudo = selector->PseudoType(); + CSSPseudoElementType pseudo = selector->PseudoType(); if (pseudo >= CSSPseudoElementType::Count || !nsCSSPseudoElements::PseudoElementSupportsUserActionState(pseudo)) { NS_ASSERTION(!selector->mNegations, "Shouldn't have negations"); diff --git a/layout/style/nsCSSRuleProcessor.h b/layout/style/nsCSSRuleProcessor.h index 38b4094939af..8dc1e21d1d23 100644 --- a/layout/style/nsCSSRuleProcessor.h +++ b/layout/style/nsCSSRuleProcessor.h @@ -19,7 +19,6 @@ #include "mozilla/SheetType.h" #include "mozilla/UniquePtr.h" #include "nsAutoPtr.h" -#include "nsCSSPseudoElements.h" #include "nsExpirationTracker.h" #include "nsIMediaList.h" #include "nsIStyleRuleProcessor.h" @@ -40,6 +39,7 @@ class nsCSSCounterStyleRule; namespace mozilla { class CSSStyleSheet; +enum class CSSPseudoElementType : uint8_t; namespace css { class DocumentRule; } // namespace css @@ -234,7 +234,7 @@ private: nsRestyleHint HasStateDependentStyle(ElementDependentRuleProcessorData* aData, mozilla::dom::Element* aStatefulElement, - nsCSSPseudoElements::Type aPseudoType, + mozilla::CSSPseudoElementType aPseudoType, mozilla::EventStates aStateMask); void ClearSheets(); diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index fc19437b30ea..21b0d5f46fa3 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -488,7 +488,7 @@ nsComputedDOMStyle::GetStyleContextForElementNoFlush(Element* aElement, RefPtr sc; if (aPseudo) { - nsCSSPseudoElements::Type type = nsCSSPseudoElements::GetPseudoType(aPseudo); + CSSPseudoElementType type = nsCSSPseudoElements::GetPseudoType(aPseudo); if (type >= CSSPseudoElementType::Count) { return nullptr; } @@ -696,8 +696,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush) while (topWithPseudoElementData->GetParent()->HasPseudoElementData()) { topWithPseudoElementData = topWithPseudoElementData->GetParent(); } - nsCSSPseudoElements::Type pseudo = - topWithPseudoElementData->GetPseudoType(); + CSSPseudoElementType pseudo = topWithPseudoElementData->GetPseudoType(); nsIAtom* pseudoAtom = nsCSSPseudoElements::GetPseudoAtom(pseudo); nsAutoString assertMsg( NS_LITERAL_STRING("we should be in a pseudo-element that is expected to contain elements (")); diff --git a/layout/style/nsHTMLCSSStyleSheet.cpp b/layout/style/nsHTMLCSSStyleSheet.cpp index 51dd7db55fd9..f6b2ae54908f 100644 --- a/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/layout/style/nsHTMLCSSStyleSheet.cpp @@ -18,6 +18,7 @@ #include "mozilla/dom/Element.h" #include "nsAttrValue.h" #include "nsAttrValueInlines.h" +#include "nsCSSPseudoElements.h" #include "RestyleManager.h" using namespace mozilla; @@ -81,7 +82,7 @@ nsHTMLCSSStyleSheet::ElementRulesMatching(nsPresContext* aPresContext, void nsHTMLCSSStyleSheet::PseudoElementRulesMatching(Element* aPseudoElement, - nsCSSPseudoElements::Type + CSSPseudoElementType aPseudoType, nsRuleWalker* aRuleWalker) { diff --git a/layout/style/nsHTMLCSSStyleSheet.h b/layout/style/nsHTMLCSSStyleSheet.h index b8fdc4c81303..2b7ea7ae8322 100644 --- a/layout/style/nsHTMLCSSStyleSheet.h +++ b/layout/style/nsHTMLCSSStyleSheet.h @@ -13,7 +13,6 @@ #include "mozilla/Attributes.h" #include "mozilla/MemoryReporting.h" -#include "nsCSSPseudoElements.h" #include "nsDataHashtable.h" #include "nsIStyleRuleProcessor.h" @@ -21,6 +20,7 @@ class nsRuleWalker; struct MiscContainer; namespace mozilla { +enum class CSSPseudoElementType : uint8_t; namespace dom { class Element; } // namespace dom @@ -60,7 +60,7 @@ public: // aPseudoElement here is the content node for the pseudo-element, not // its corresponding real element. void PseudoElementRulesMatching(mozilla::dom::Element* aPseudoElement, - nsCSSPseudoElements::Type aPseudoType, + mozilla::CSSPseudoElementType aPseudoType, nsRuleWalker* aRuleWalker); void CacheStyleAttr(const nsAString& aSerialized, MiscContainer* aValue); diff --git a/layout/style/nsRuleProcessorData.h b/layout/style/nsRuleProcessorData.h index e23722aede62..3373cb9f1d2d 100644 --- a/layout/style/nsRuleProcessorData.h +++ b/layout/style/nsRuleProcessorData.h @@ -470,7 +470,7 @@ struct MOZ_STACK_CLASS PseudoElementRuleProcessorData : PseudoElementRuleProcessorData(nsPresContext* aPresContext, mozilla::dom::Element* aParentElement, nsRuleWalker* aRuleWalker, - nsCSSPseudoElements::Type aPseudoType, + mozilla::CSSPseudoElementType aPseudoType, TreeMatchContext& aTreeMatchContext, mozilla::dom::Element* aPseudoElement) : ElementDependentRuleProcessorData(aPresContext, aParentElement, aRuleWalker, @@ -484,7 +484,7 @@ struct MOZ_STACK_CLASS PseudoElementRuleProcessorData : NS_PRECONDITION(aRuleWalker, "Must have rule walker"); } - nsCSSPseudoElements::Type mPseudoType; + mozilla::CSSPseudoElementType mPseudoType; mozilla::dom::Element* const mPseudoElement; // weak ref }; @@ -549,7 +549,7 @@ struct MOZ_STACK_CLASS PseudoElementStateRuleProcessorData : PseudoElementStateRuleProcessorData(nsPresContext* aPresContext, mozilla::dom::Element* aElement, mozilla::EventStates aStateMask, - nsCSSPseudoElements::Type aPseudoType, + mozilla::CSSPseudoElementType aPseudoType, TreeMatchContext& aTreeMatchContext, mozilla::dom::Element* aPseudoElement) : StateRuleProcessorData(aPresContext, aElement, aStateMask, @@ -563,7 +563,7 @@ struct MOZ_STACK_CLASS PseudoElementStateRuleProcessorData : // We kind of want to inherit from both StateRuleProcessorData and // PseudoElementRuleProcessorData. Instead we've just copied those // members from PseudoElementRuleProcessorData to this struct. - nsCSSPseudoElements::Type mPseudoType; + mozilla::CSSPseudoElementType mPseudoType; mozilla::dom::Element* const mPseudoElement; // weak ref }; diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 2d55a052b7e0..90c58c69c6f8 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -2,13 +2,14 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - + /* the interface (to internal code) for retrieving computed style data */ #include "CSSVariableImageTable.h" #include "mozilla/DebugOnly.h" #include "nsCSSAnonBoxes.h" +#include "nsCSSPseudoElements.h" #include "nsStyleConsts.h" #include "nsString.h" #include "nsPresContext.h" @@ -70,7 +71,7 @@ static bool sExpensiveStyleStructAssertionsEnabled; nsStyleContext::nsStyleContext(nsStyleContext* aParent, nsIAtom* aPseudoTag, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsRuleNode* aRuleNode, bool aSkipParentDisplayBasedStyleFixup) : mParent(aParent) @@ -1216,7 +1217,7 @@ nsStyleContext::Destroy() already_AddRefed NS_NewStyleContext(nsStyleContext* aParentContext, nsIAtom* aPseudoTag, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsRuleNode* aRuleNode, bool aSkipParentDisplayBasedStyleFixup) { diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 7e0a1f119601..edd9e9518f65 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -11,11 +11,14 @@ #include "mozilla/RestyleLogging.h" #include "mozilla/Assertions.h" #include "nsRuleNode.h" -#include "nsCSSPseudoElements.h" class nsIAtom; class nsPresContext; +namespace mozilla { +enum class CSSPseudoElementType : uint8_t; +} // namespace mozilla + /** * An nsStyleContext represents the computed style data for an element. * The computed style data are stored in a set of structs (see @@ -60,13 +63,13 @@ public: * matches. See |nsRuleNode| and |nsIStyleRule|. * @param aSkipParentDisplayBasedStyleFixup * If set, this flag indicates that we should skip - * the chunk of ApplyStyleFixups() that applies to - * special cases where a child element's style may - * need to be modified based on its parent's display + * the chunk of ApplyStyleFixups() that applies to + * special cases where a child element's style may + * need to be modified based on its parent's display * value. */ nsStyleContext(nsStyleContext* aParent, nsIAtom* aPseudoTag, - nsCSSPseudoElements::Type aPseudoType, + mozilla::CSSPseudoElementType aPseudoType, nsRuleNode* aRuleNode, bool aSkipParentDisplayBasedStyleFixup); @@ -137,9 +140,9 @@ public: nsStyleContext* GetParent() const { return mParent; } nsIAtom* GetPseudo() const { return mPseudoTag; } - nsCSSPseudoElements::Type GetPseudoType() const { - return static_cast(mBits >> - NS_STYLE_CONTEXT_TYPE_SHIFT); + mozilla::CSSPseudoElementType GetPseudoType() const { + return static_cast( + mBits >> NS_STYLE_CONTEXT_TYPE_SHIFT); } // Find, if it already exists *and is easily findable* (i.e., near the @@ -629,7 +632,7 @@ private: already_AddRefed NS_NewStyleContext(nsStyleContext* aParentContext, nsIAtom* aPseudoTag, - nsCSSPseudoElements::Type aPseudoType, + mozilla::CSSPseudoElementType aPseudoType, nsRuleNode* aRuleNode, bool aSkipParentDisplayBasedStyleFixup); #endif diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index b8d30e89728d..f7e706af1555 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -885,7 +885,7 @@ nsStyleSet::GetContext(nsStyleContext* aParentContext, // should be used.) nsRuleNode* aVisitedRuleNode, nsIAtom* aPseudoTag, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, Element* aElementForAnimation, uint32_t aFlags) { @@ -1504,7 +1504,7 @@ nsRuleNode* nsStyleSet::RuleNodeWithReplacement(Element* aElement, Element* aPseudoElement, nsRuleNode* aOldRuleNode, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsRestyleHint aReplacements) { NS_ASSERTION(mBatching == 0, "rule processors out of date"); @@ -1706,7 +1706,7 @@ nsStyleSet::ResolveStyleWithReplacement(Element* aElement, } } - nsCSSPseudoElements::Type pseudoType = aOldStyleContext->GetPseudoType(); + CSSPseudoElementType pseudoType = aOldStyleContext->GetPseudoType(); Element* elementForAnimation = nullptr; if (!(aFlags & eSkipStartingAnimations) && (pseudoType == CSSPseudoElementType::NotPseudo || @@ -1756,7 +1756,7 @@ nsStyleSet::ResolveStyleWithoutAnimation(dom::Element* aTarget, nsRestyleHint aWhichToRemove) { #ifdef DEBUG - nsCSSPseudoElements::Type pseudoType = aStyleContext->GetPseudoType(); + CSSPseudoElementType pseudoType = aStyleContext->GetPseudoType(); #endif MOZ_ASSERT(pseudoType == CSSPseudoElementType::NotPseudo || pseudoType == CSSPseudoElementType::before || @@ -1787,7 +1787,7 @@ nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext) } void -nsStyleSet::WalkRestrictionRule(nsCSSPseudoElements::Type aPseudoType, +nsStyleSet::WalkRestrictionRule(CSSPseudoElementType aPseudoType, nsRuleWalker* aRuleWalker) { // This needs to match GetPseudoRestriction in nsRuleNode.cpp. @@ -1810,7 +1810,7 @@ nsStyleSet::WalkDisableTextZoomRule(Element* aElement, nsRuleWalker* aRuleWalker already_AddRefed nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement, - nsCSSPseudoElements::Type aType, + CSSPseudoElementType aType, nsStyleContext* aParentContext, Element* aPseudoElement) { @@ -1864,7 +1864,7 @@ nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement, already_AddRefed nsStyleSet::ProbePseudoElementStyle(Element* aParentElement, - nsCSSPseudoElements::Type aType, + CSSPseudoElementType aType, nsStyleContext* aParentContext) { TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited, @@ -1876,7 +1876,7 @@ nsStyleSet::ProbePseudoElementStyle(Element* aParentElement, already_AddRefed nsStyleSet::ProbePseudoElementStyle(Element* aParentElement, - nsCSSPseudoElements::Type aType, + CSSPseudoElementType aType, nsStyleContext* aParentContext, TreeMatchContext& aTreeMatchContext, Element* aPseudoElement) @@ -2265,7 +2265,7 @@ nsStyleSet::ReparentStyleContext(nsStyleContext* aStyleContext, } nsIAtom* pseudoTag = aStyleContext->GetPseudo(); - nsCSSPseudoElements::Type pseudoType = aStyleContext->GetPseudoType(); + CSSPseudoElementType pseudoType = aStyleContext->GetPseudoType(); nsRuleNode* ruleNode = aStyleContext->RuleNode(); NS_ASSERTION(!PresContext()->RestyleManager()->SkipAnimationRules(), @@ -2324,7 +2324,7 @@ struct MOZ_STACK_CLASS StatefulData : public StateRuleProcessorData { struct MOZ_STACK_CLASS StatefulPseudoElementData : public PseudoElementStateRuleProcessorData { StatefulPseudoElementData(nsPresContext* aPresContext, Element* aElement, - EventStates aStateMask, nsCSSPseudoElements::Type aPseudoType, + EventStates aStateMask, CSSPseudoElementType aPseudoType, TreeMatchContext& aTreeMatchContext, Element* aPseudoElement) : PseudoElementStateRuleProcessorData(aPresContext, aElement, aStateMask, aPseudoType, aTreeMatchContext, @@ -2395,7 +2395,7 @@ nsStyleSet::HasStateDependentStyle(Element* aElement, nsRestyleHint nsStyleSet::HasStateDependentStyle(Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, Element* aPseudoElement, EventStates aStateMask) { diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index 2af75dc1abfb..a05bcf210d06 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -25,7 +25,6 @@ #include "nsCOMArray.h" #include "nsAutoPtr.h" #include "nsIStyleRule.h" -#include "nsCSSPseudoElements.h" class gfxFontFeatureValueSet; class nsCSSKeyframesRule; @@ -41,6 +40,7 @@ struct TreeMatchContext; namespace mozilla { class CSSStyleSheet; class EventStates; +enum class CSSPseudoElementType : uint8_t; } // namespace mozilla class nsEmptyStyleRule final : public nsIStyleRule @@ -172,13 +172,13 @@ class nsStyleSet final ResolveStyleForNonElement(nsStyleContext* aParentContext); // Get a style context for a pseudo-element. aParentElement must be - // non-null. aPseudoID is the nsCSSPseudoElements::Type for the + // non-null. aPseudoID is the CSSPseudoElementType for the // pseudo-element. aPseudoElement must be non-null if the pseudo-element // type is one that allows user action pseudo-classes after it or allows // style attributes; otherwise, it is ignored. already_AddRefed ResolvePseudoElementStyle(mozilla::dom::Element* aParentElement, - nsCSSPseudoElements::Type aType, + mozilla::CSSPseudoElementType aType, nsStyleContext* aParentContext, mozilla::dom::Element* aPseudoElement); @@ -187,11 +187,11 @@ class nsStyleSet final // pseudo element. already_AddRefed ProbePseudoElementStyle(mozilla::dom::Element* aParentElement, - nsCSSPseudoElements::Type aType, + mozilla::CSSPseudoElementType aType, nsStyleContext* aParentContext); already_AddRefed ProbePseudoElementStyle(mozilla::dom::Element* aParentElement, - nsCSSPseudoElements::Type aType, + mozilla::CSSPseudoElementType aType, nsStyleContext* aParentContext, TreeMatchContext& aTreeMatchContext, mozilla::dom::Element* aPseudoElement = nullptr); @@ -283,7 +283,7 @@ class nsStyleSet final nsRestyleHint HasStateDependentStyle(mozilla::dom::Element* aElement, mozilla::EventStates aStateMask); nsRestyleHint HasStateDependentStyle(mozilla::dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + mozilla::CSSPseudoElementType aPseudoType, mozilla::dom::Element* aPseudoElement, mozilla::EventStates aStateMask); @@ -419,7 +419,7 @@ private: // Move aRuleWalker forward by the appropriate rule if we need to add // a rule due to property restrictions on pseudo-elements. - void WalkRestrictionRule(nsCSSPseudoElements::Type aPseudoType, + void WalkRestrictionRule(mozilla::CSSPseudoElementType aPseudoType, nsRuleWalker* aRuleWalker); void WalkDisableTextZoomRule(mozilla::dom::Element* aElement, @@ -460,7 +460,7 @@ private: nsRuleNode* RuleNodeWithReplacement(mozilla::dom::Element* aElement, mozilla::dom::Element* aPseudoElement, nsRuleNode* aOldRuleNode, - nsCSSPseudoElements::Type aPseudoType, + mozilla::CSSPseudoElementType aPseudoType, nsRestyleHint aReplacements); already_AddRefed @@ -468,7 +468,7 @@ private: nsRuleNode* aRuleNode, nsRuleNode* aVisitedRuleNode, nsIAtom* aPseudoTag, - nsCSSPseudoElements::Type aPseudoType, + mozilla::CSSPseudoElementType aPseudoType, mozilla::dom::Element* aElementForAnimation, uint32_t aFlags); diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index b6bb12e81016..4ea84fbca763 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -28,6 +28,7 @@ #include "Layers.h" #include "FrameLayerBuilder.h" #include "nsCSSProps.h" +#include "nsCSSPseudoElements.h" #include "nsDisplayList.h" #include "nsStyleChangeList.h" #include "nsStyleSet.h" @@ -129,7 +130,7 @@ CSSTransition::QueueEvents() } dom::Element* owningElement; - nsCSSPseudoElements::Type owningPseudoType; + CSSPseudoElementType owningPseudoType; mOwningElement.GetElement(owningElement, owningPseudoType); MOZ_ASSERT(owningElement, "Owning element should be set"); @@ -261,7 +262,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement, // Return sooner (before the startedAny check below) for the most // common case: no transitions specified or running. const nsStyleDisplay *disp = newStyleContext->StyleDisplay(); - nsCSSPseudoElements::Type pseudoType = newStyleContext->GetPseudoType(); + CSSPseudoElementType pseudoType = newStyleContext->GetPseudoType(); if (pseudoType != CSSPseudoElementType::NotPseudo) { if (pseudoType != CSSPseudoElementType::before && pseudoType != CSSPseudoElementType::after) { @@ -734,8 +735,7 @@ nsTransitionManager::ConsiderStartingTransition( void nsTransitionManager::PruneCompletedTransitions(mozilla::dom::Element* aElement, - nsCSSPseudoElements::Type - aPseudoType, + CSSPseudoElementType aPseudoType, nsStyleContext* aNewStyleContext) { AnimationCollection* collection = diff --git a/layout/style/nsTransitionManager.h b/layout/style/nsTransitionManager.h index 35c627af82b2..a4c35f46b463 100644 --- a/layout/style/nsTransitionManager.h +++ b/layout/style/nsTransitionManager.h @@ -16,7 +16,6 @@ #include "mozilla/dom/KeyframeEffect.h" #include "AnimationCommon.h" #include "nsCSSProps.h" -#include "nsCSSPseudoElements.h" class nsIGlobalObject; class nsStyleContext; @@ -24,6 +23,7 @@ class nsPresContext; class nsCSSPropertySet; namespace mozilla { +enum class CSSPseudoElementType : uint8_t; struct StyleTransition; } // namespace mozilla @@ -37,7 +37,7 @@ struct ElementPropertyTransition : public dom::KeyframeEffectReadOnly { ElementPropertyTransition(nsIDocument* aDocument, dom::Element* aTarget, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, const TimingParams &aTiming, StyleAnimationValue aStartForReversingTest, double aReversePortion) @@ -216,7 +216,7 @@ struct TransitionEventInfo { TimeStamp mTimeStamp; TransitionEventInfo(dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + CSSPseudoElementType aPseudoType, nsCSSProperty aProperty, StickyTimeDuration aDuration, const TimeStamp& aTimeStamp, @@ -289,7 +289,7 @@ public: * new style. */ void PruneCompletedTransitions(mozilla::dom::Element* aElement, - nsCSSPseudoElements::Type aPseudoType, + mozilla::CSSPseudoElementType aPseudoType, nsStyleContext* aNewStyleContext); void SetInAnimationOnlyStyleUpdate(bool aInAnimationOnlyUpdate) { From f9b04f2758ecd7038fcbe2a7b576d73c6b76dd69 Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Wed, 17 Feb 2016 22:04:00 +0100 Subject: [PATCH 027/115] Bug 1244049 - Part 3: Replace the type of nsCSSSelector::mPseudoType. r=dbaron --HG-- extra : rebase_source : 4bb852ab13bd448da20f9af4a3f13c5704e3a007 --- layout/style/StyleRule.cpp | 6 ++---- layout/style/StyleRule.h | 12 ++++++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/layout/style/StyleRule.cpp b/layout/style/StyleRule.cpp index 3bb5169cf3fd..57dbea4bd1d7 100644 --- a/layout/style/StyleRule.cpp +++ b/layout/style/StyleRule.cpp @@ -314,11 +314,9 @@ nsCSSSelector::nsCSSSelector(void) mNext(nullptr), mNameSpace(kNameSpaceID_Unknown), mOperator(0), - mPseudoType(static_cast(CSSPseudoElementType::NotPseudo)) + mPseudoType(CSSPseudoElementType::NotPseudo) { MOZ_COUNT_CTOR(nsCSSSelector); - static_assert(static_cast(CSSPseudoElementType::MAX) < INT16_MAX, - "CSSPseudoElementType values overflow mPseudoType"); } nsCSSSelector* @@ -333,7 +331,7 @@ nsCSSSelector::Clone(bool aDeepNext, bool aDeepNegations) const result->mCasedTag = mCasedTag; result->mOperator = mOperator; result->mPseudoType = mPseudoType; - + NS_IF_CLONE(mIDList); NS_IF_CLONE(mClassList); NS_IF_CLONE(mPseudoClassList); diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index 20775c379588..9610b660ec48 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -25,6 +25,7 @@ class nsIAtom; struct nsCSSSelectorList; namespace mozilla { +enum class CSSPseudoElementType : uint8_t; class CSSStyleSheet; } // namespace mozilla @@ -208,11 +209,9 @@ private: public: // Get and set the selector's pseudo type - mozilla::CSSPseudoElementType PseudoType() const { - return static_cast(mPseudoType); - } + mozilla::CSSPseudoElementType PseudoType() const { return mPseudoType; } void SetPseudoType(mozilla::CSSPseudoElementType aType) { - mPseudoType = static_cast(aType); + mPseudoType = aType; } size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; @@ -233,8 +232,9 @@ public: int32_t mNameSpace; char16_t mOperator; private: - // int16_t to make sure it packs well with mOperator - int16_t mPseudoType; + // The underlying type of CSSPseudoElementType is uint8_t and + // it packs well with mOperator. (char16_t + uint8_t is less than 32bits.) + mozilla::CSSPseudoElementType mPseudoType; nsCSSSelector(const nsCSSSelector& aCopy) = delete; nsCSSSelector& operator=(const nsCSSSelector& aCopy) = delete; From 83b2b79f9d3dc57d89448ef93bbd034379770d47 Mon Sep 17 00:00:00 2001 From: Michal Novotny Date: Thu, 18 Feb 2016 11:43:20 +0100 Subject: [PATCH 028/115] Bug 1248958 - CacheIndex mRWBuf ownership too fragile, read-after-free, r=honzab --- netwerk/cache2/CacheIndex.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/netwerk/cache2/CacheIndex.cpp b/netwerk/cache2/CacheIndex.cpp index 64e38c1d3205..3c46edd240ba 100644 --- a/netwerk/cache2/CacheIndex.cpp +++ b/netwerk/cache2/CacheIndex.cpp @@ -347,13 +347,15 @@ CacheIndex::PreShutdown() nsCOMPtr event; event = NS_NewRunnableMethod(index, &CacheIndex::PreShutdownInternal); - nsCOMPtr ioTarget = CacheFileIOManager::IOTarget(); - MOZ_ASSERT(ioTarget); + RefPtr ioThread = CacheFileIOManager::IOThread(); + MOZ_ASSERT(ioThread); - // PreShutdownInternal() will be executed before any queued event on INDEX - // level. That's OK since we don't want to wait for any operation in progess. - // We need to interrupt it and save journal as quickly as possible. - rv = ioTarget->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL); + // Executing PreShutdownInternal() on WRITE level ensures that read/write + // events holding pointer to mRWBuf will be executed before we release the + // buffer by calling FinishRead()/FinishWrite() in PreShutdownInternal(), but + // it will be executed before any queued event on INDEX level. That's OK since + // we don't want to wait until updating of the index finishes. + rv = ioThread->Dispatch(event, CacheIOThread::WRITE); if (NS_FAILED(rv)) { NS_WARNING("CacheIndex::PreShutdown() - Can't dispatch event"); LOG(("CacheIndex::PreShutdown() - Can't dispatch event" )); From cb99502b791a8f5ae7960a21d81510c95c90ad79 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Thu, 18 Feb 2016 10:46:16 +0000 Subject: [PATCH 029/115] Bug 1247335 - patch 1 - Provide a desktop-pixel variant of SetPosition on nsIBaseWindow and its implementations. r=emk --- docshell/base/nsDocShell.cpp | 9 +++++++++ dom/base/nsGlobalWindow.cpp | 16 +++++++--------- embedding/browser/nsDocShellTreeOwner.cpp | 9 +++++++++ embedding/browser/nsWebBrowser.cpp | 9 +++++++++ widget/nsIBaseWindow.idl | 6 ++++++ xpfe/appshell/nsChromeTreeOwner.cpp | 6 ++++++ xpfe/appshell/nsContentTreeOwner.cpp | 6 ++++++ xpfe/appshell/nsXULWindow.cpp | 15 +++++++++++++++ 8 files changed, 67 insertions(+), 9 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 3df3473a3ca0..2e5ce9e73ff4 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -5814,6 +5814,15 @@ nsDocShell::SetPosition(int32_t aX, int32_t aY) return NS_OK; } +NS_IMETHODIMP +nsDocShell::SetPositionDesktopPix(int32_t aX, int32_t aY) +{ + // Added to nsIBaseWindow in bug 1247335; + // implement if a use-case is found. + NS_ASSERTION(false, "implement me!"); + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP nsDocShell::GetPosition(int32_t* aX, int32_t* aY) { diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 145f4c31ac1d..97143f2ad223 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -7063,7 +7063,6 @@ nsGlobalWindow::MoveToOuter(int32_t aXPos, int32_t aYPos, ErrorResult& aError, b getter_AddRefs(screen)); } - LayoutDevicePoint devPos; if (screen) { int32_t screenLeftDeskPx, screenTopDeskPx, w, h; screen->GetRectDisplayPix(&screenLeftDeskPx, &screenTopDeskPx, &w, &h); @@ -7072,20 +7071,19 @@ nsGlobalWindow::MoveToOuter(int32_t aXPos, int32_t aYPos, ErrorResult& aError, b double scale; screen->GetDefaultCSSScaleFactor(&scale); - devPos = cssPos * CSSToLayoutDeviceScale(scale); + LayoutDevicePoint devPos = cssPos * CSSToLayoutDeviceScale(scale); - int32_t screenLeftDevPx, screenTopDevPx; - screen->GetRect(&screenLeftDevPx, &screenTopDevPx, &w, &h); - devPos.x += screenLeftDevPx; - devPos.y += screenTopDevPx; + screen->GetContentsScaleFactor(&scale); + DesktopPoint deskPos = devPos / DesktopToLayoutDeviceScale(scale); + aError = treeOwnerAsWin->SetPositionDesktopPix(screenLeftDeskPx + deskPos.x, + screenTopDeskPx + deskPos.y); } else { // We couldn't find a screen? Just assume a 1:1 mapping. CSSIntPoint cssPos(aXPos, aXPos); CheckSecurityLeftAndTop(&cssPos.x, &cssPos.y, aCallerIsChrome); - devPos = cssPos * CSSToLayoutDeviceScale(1.0); + LayoutDevicePoint devPos = cssPos * CSSToLayoutDeviceScale(1.0); + aError = treeOwnerAsWin->SetPosition(devPos.x, devPos.y); } - - aError = treeOwnerAsWin->SetPosition(devPos.x, devPos.y); } void diff --git a/embedding/browser/nsDocShellTreeOwner.cpp b/embedding/browser/nsDocShellTreeOwner.cpp index eb040ee8cc1c..dfe990e498f4 100644 --- a/embedding/browser/nsDocShellTreeOwner.cpp +++ b/embedding/browser/nsDocShellTreeOwner.cpp @@ -570,6 +570,15 @@ nsDocShellTreeOwner::GetDevicePixelsPerDesktopPixel(double* aScale) return NS_OK; } +NS_IMETHODIMP +nsDocShellTreeOwner::SetPositionDesktopPix(int32_t aX, int32_t aY) +{ + // Added to nsIBaseWindow in bug 1247335; + // implement if a use-case is found. + NS_ASSERTION(false, "implement me!"); + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP nsDocShellTreeOwner::SetPosition(int32_t aX, int32_t aY) { diff --git a/embedding/browser/nsWebBrowser.cpp b/embedding/browser/nsWebBrowser.cpp index 601e26b38ef3..d656503d394b 100644 --- a/embedding/browser/nsWebBrowser.cpp +++ b/embedding/browser/nsWebBrowser.cpp @@ -1302,6 +1302,15 @@ nsWebBrowser::GetDevicePixelsPerDesktopPixel(double* aScale) return NS_OK; } +NS_IMETHODIMP +nsWebBrowser::SetPositionDesktopPix(int32_t aX, int32_t aY) +{ + // Added to nsIBaseWindow in bug 1247335; + // implement if a use-case is found. + NS_ASSERTION(false, "implement me!"); + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP nsWebBrowser::SetPosition(int32_t aX, int32_t aY) { diff --git a/widget/nsIBaseWindow.idl b/widget/nsIBaseWindow.idl index 88160bce0a3c..24289a70b38a 100644 --- a/widget/nsIBaseWindow.idl +++ b/widget/nsIBaseWindow.idl @@ -91,6 +91,12 @@ interface nsIBaseWindow : nsISupports */ void setPosition(in long x, in long y); + /* + Ditto, with arguments in global desktop pixels rather than (potentially + ambiguous) device pixels + */ + void setPositionDesktopPix(in long x, in long y); + /* Gets the current x and y coordinates of the control. This is relatie to the parent window. diff --git a/xpfe/appshell/nsChromeTreeOwner.cpp b/xpfe/appshell/nsChromeTreeOwner.cpp index 969012028e7c..b5182535a7ee 100644 --- a/xpfe/appshell/nsChromeTreeOwner.cpp +++ b/xpfe/appshell/nsChromeTreeOwner.cpp @@ -388,6 +388,12 @@ NS_IMETHODIMP nsChromeTreeOwner::GetDevicePixelsPerDesktopPixel(double *aScale) return mXULWindow->GetDevicePixelsPerDesktopPixel(aScale); } +NS_IMETHODIMP nsChromeTreeOwner::SetPositionDesktopPix(int32_t x, int32_t y) +{ + NS_ENSURE_STATE(mXULWindow); + return mXULWindow->SetPositionDesktopPix(x, y); +} + NS_IMETHODIMP nsChromeTreeOwner::SetPosition(int32_t x, int32_t y) { NS_ENSURE_STATE(mXULWindow); diff --git a/xpfe/appshell/nsContentTreeOwner.cpp b/xpfe/appshell/nsContentTreeOwner.cpp index 522b1d5bf977..b7c7aee81e31 100644 --- a/xpfe/appshell/nsContentTreeOwner.cpp +++ b/xpfe/appshell/nsContentTreeOwner.cpp @@ -628,6 +628,12 @@ NS_IMETHODIMP nsContentTreeOwner::GetDevicePixelsPerDesktopPixel(double* aScale) return mXULWindow->GetDevicePixelsPerDesktopPixel(aScale); } +NS_IMETHODIMP nsContentTreeOwner::SetPositionDesktopPix(int32_t aX, int32_t aY) +{ + NS_ENSURE_STATE(mXULWindow); + return mXULWindow->SetPositionDesktopPix(aX, aY); +} + NS_IMETHODIMP nsContentTreeOwner::SetPosition(int32_t aX, int32_t aY) { NS_ENSURE_STATE(mXULWindow); diff --git a/xpfe/appshell/nsXULWindow.cpp b/xpfe/appshell/nsXULWindow.cpp index d38dd445fcf5..6b457ff9b4dd 100644 --- a/xpfe/appshell/nsXULWindow.cpp +++ b/xpfe/appshell/nsXULWindow.cpp @@ -615,6 +615,21 @@ nsXULWindow::GetScaleForDestinationPosition(int32_t aX, int32_t aY) return scale; } +NS_IMETHODIMP nsXULWindow::SetPositionDesktopPix(int32_t aX, int32_t aY) +{ + nsresult rv = mWindow->Move(aX, aY); + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); + if (!mChromeLoaded) { + // If we're called before the chrome is loaded someone obviously wants this + // window at this position. We don't persist this one-time position. + mIgnoreXULPosition = true; + return NS_OK; + } + PersistentAttributesDirty(PAD_POSITION); + SavePersistentAttributes(); + return NS_OK; +} + NS_IMETHODIMP nsXULWindow::SetPosition(int32_t aX, int32_t aY) { // Don't reset the window's size mode here - platforms that don't want to move From c31d3ec45bb2f29a9a3201e5d860ca93b56d4fdd Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Thu, 18 Feb 2016 10:47:14 +0000 Subject: [PATCH 030/115] Bug 1247335 - patch 2 - Use desktop pixel coordinates when loading a nsXULWindow position. r=emk --- xpfe/appshell/nsXULWindow.cpp | 61 ++++------------------------------- xpfe/appshell/nsXULWindow.h | 3 -- 2 files changed, 6 insertions(+), 58 deletions(-) diff --git a/xpfe/appshell/nsXULWindow.cpp b/xpfe/appshell/nsXULWindow.cpp index 6b457ff9b4dd..650c454ea5ca 100644 --- a/xpfe/appshell/nsXULWindow.cpp +++ b/xpfe/appshell/nsXULWindow.cpp @@ -577,44 +577,6 @@ NS_IMETHODIMP nsXULWindow::GetUnscaledDevicePixelsPerCSSPixel(double *aScale) return NS_OK; } -DesktopToLayoutDeviceScale -nsXULWindow::GetScaleForDestinationPosition(int32_t aX, int32_t aY) -{ - DesktopToLayoutDeviceScale scale(nsIWidget::DefaultScaleOverride()); - if (scale.scale <= 0.0) { - // The destination monitor may have the different dpi from the source. - nsCOMPtr screenMgr(do_GetService( - "@mozilla.org/gfx/screenmanager;1")); - if (screenMgr) { - int32_t width, height; - // Use current size, converted to desktop pixels - GetSize(&width, &height); - DesktopToLayoutDeviceScale curr = mWindow->GetDesktopToDeviceScale(); - width /= curr.scale; - height /= curr.scale; - width = std::max(1, width); - height = std::max(1, height); - nsCOMPtr screen; - screenMgr->ScreenForRect(aX, aY, width, height, - getter_AddRefs(screen)); - if (screen) { - double contentsScaleFactor; - if (NS_SUCCEEDED(screen->GetContentsScaleFactor( - &contentsScaleFactor))) { - scale = DesktopToLayoutDeviceScale(contentsScaleFactor); - } else { - // Fallback to the scale from the widget. - scale = mWindow->GetDesktopToDeviceScale(); - } - } - } else { - // this fallback should never actually be needed - scale = mWindow->GetDesktopToDeviceScale(); - } - } - return scale; -} - NS_IMETHODIMP nsXULWindow::SetPositionDesktopPix(int32_t aX, int32_t aY) { nsresult rv = mWindow->Move(aX, aY); @@ -630,23 +592,15 @@ NS_IMETHODIMP nsXULWindow::SetPositionDesktopPix(int32_t aX, int32_t aY) return NS_OK; } +// The parameters here are device pixels; do the best we can to convert to +// desktop px, using the window's current scale factor (if available). NS_IMETHODIMP nsXULWindow::SetPosition(int32_t aX, int32_t aY) { // Don't reset the window's size mode here - platforms that don't want to move // maximized windows should reset it in their respective Move implementation. - DesktopToLayoutDeviceScale scale = GetScaleForDestinationPosition(aX, aY); - DesktopPoint pos = LayoutDeviceIntPoint(aX, aY) / scale; - nsresult rv = mWindow->Move(pos.x, pos.y); - NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); - if (!mChromeLoaded) { - // If we're called before the chrome is loaded someone obviously wants this - // window at this position. We don't persist this one-time position. - mIgnoreXULPosition = true; - return NS_OK; - } - PersistentAttributesDirty(PAD_POSITION); - SavePersistentAttributes(); - return NS_OK; + DesktopToLayoutDeviceScale currScale = mWindow->GetDesktopToDeviceScale(); + DesktopPoint pos = LayoutDeviceIntPoint(aX, aY) / currScale; + return SetPositionDesktopPix(pos.x, pos.y); } NS_IMETHODIMP nsXULWindow::GetPosition(int32_t* aX, int32_t* aY) @@ -1205,10 +1159,7 @@ bool nsXULWindow::LoadPositionFromXUL() } mWindow->ConstrainPosition(false, &specX, &specY); if (specX != currX || specY != currY) { - DesktopToLayoutDeviceScale destScale = - GetScaleForDestinationPosition(specX, specY); - LayoutDevicePoint devPos = DesktopIntPoint(specX, specY) * destScale; - SetPosition(devPos.x, devPos.y); + SetPositionDesktopPix(specX, specY); } return gotPosition; diff --git a/xpfe/appshell/nsXULWindow.h b/xpfe/appshell/nsXULWindow.h index 87f01d2d9887..3d503ad14bfb 100644 --- a/xpfe/appshell/nsXULWindow.h +++ b/xpfe/appshell/nsXULWindow.h @@ -90,9 +90,6 @@ protected: NS_IMETHOD EnsurePrompter(); NS_IMETHOD EnsureAuthPrompter(); - mozilla::DesktopToLayoutDeviceScale - GetScaleForDestinationPosition(int32_t aX, int32_t aY); - void OnChromeLoaded(); void StaggerPosition(int32_t &aRequestedX, int32_t &aRequestedY, int32_t aSpecWidth, int32_t aSpecHeight); From badce210e1b9a3810d1e3831d181518e65583df6 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Thu, 18 Feb 2016 10:47:47 +0000 Subject: [PATCH 031/115] Bug 1247335 - patch 3 - Check for potential DPI change after moving or resizing nsGlobalWindow. r=emk --- dom/base/nsGlobalWindow.cpp | 35 +++++++++++++++++++++++++++++++++++ dom/base/nsGlobalWindow.h | 4 ++++ 2 files changed, 39 insertions(+) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 97143f2ad223..f1eb070729d0 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -5002,6 +5002,8 @@ nsGlobalWindow::SetOuterSize(int32_t aLengthCSSPixels, bool aIsWidth, height = lengthDevPixels; } aError = treeOwnerAsWin->SetSize(width, height, true); + + CheckForDPIChange(); } void @@ -5323,6 +5325,8 @@ nsGlobalWindow::SetScreenXOuter(int32_t aScreenX, ErrorResult& aError, bool aCal x = CSSToDevIntPixels(aScreenX); aError = treeOwnerAsWin->SetPosition(x, y); + + CheckForDPIChange(); } void @@ -5383,6 +5387,8 @@ nsGlobalWindow::SetScreenYOuter(int32_t aScreenY, ErrorResult& aError, bool aCal y = CSSToDevIntPixels(aScreenY); aError = treeOwnerAsWin->SetPosition(x, y); + + CheckForDPIChange(); } void @@ -7064,6 +7070,10 @@ nsGlobalWindow::MoveToOuter(int32_t aXPos, int32_t aYPos, ErrorResult& aError, b } if (screen) { + // On secondary displays, the "CSS px" coordinates are offset so that they + // share their origin with global desktop pixels, to avoid ambiguities in + // the coordinate space when there are displays with different DPIs. + // (See the corresponding code in GetScreenXY() above.) int32_t screenLeftDeskPx, screenTopDeskPx, w, h; screen->GetRectDisplayPix(&screenLeftDeskPx, &screenTopDeskPx, &w, &h); CSSIntPoint cssPos(aXPos - screenLeftDeskPx, aYPos - screenTopDeskPx); @@ -7084,6 +7094,8 @@ nsGlobalWindow::MoveToOuter(int32_t aXPos, int32_t aYPos, ErrorResult& aError, b LayoutDevicePoint devPos = cssPos * CSSToLayoutDeviceScale(1.0); aError = treeOwnerAsWin->SetPosition(devPos.x, devPos.y); } + + CheckForDPIChange(); } void @@ -7133,6 +7145,8 @@ nsGlobalWindow::MoveByOuter(int32_t aXDif, int32_t aYDif, ErrorResult& aError, b nsIntSize newDevPos(CSSToDevIntPixels(cssPos)); aError = treeOwnerAsWin->SetPosition(newDevPos.width, newDevPos.height); + + CheckForDPIChange(); } void @@ -7191,6 +7205,8 @@ nsGlobalWindow::ResizeToOuter(int32_t aWidth, int32_t aHeight, ErrorResult& aErr nsIntSize devSz(CSSToDevIntPixels(cssSize)); aError = treeOwnerAsWin->SetSize(devSz.width, devSz.height, true); + + CheckForDPIChange(); } void @@ -7260,6 +7276,8 @@ nsGlobalWindow::ResizeByOuter(int32_t aWidthDif, int32_t aHeightDif, nsIntSize newDevSize(CSSToDevIntPixels(cssSize)); aError = treeOwnerAsWin->SetSize(newDevSize.width, newDevSize.height, true); + + CheckForDPIChange(); } void @@ -13956,6 +13974,23 @@ nsGlobalWindow::CreateImageBitmap(const ImageBitmapSource& aImage, return ImageBitmap::Create(this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv); } +// Helper called by methods that move/resize the window, +// to ensure the presContext (if any) is aware of resolution +// change that may happen in multi-monitor configuration. +void +nsGlobalWindow::CheckForDPIChange() +{ + if (mDocShell) { + RefPtr presContext; + mDocShell->GetPresContext(getter_AddRefs(presContext)); + if (presContext) { + if (presContext->DeviceContext()->CheckDPIChange()) { + presContext->UIResolutionChanged(); + } + } + } +} + template class nsPIDOMWindow; template class nsPIDOMWindow; template class nsPIDOMWindow; diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index f4ae24cc52fb..0c7848e34a14 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -1652,6 +1652,10 @@ protected: // show, in that case we show a separate dialog to ask this question. bool ConfirmDialogIfNeeded(); + // Helper called after moving/resizing, to update docShell's presContext + // if we have caused a resolution change by moving across monitors. + void CheckForDPIChange(); + private: // Fire the JS engine's onNewGlobalObject hook. Only used on inner windows. void FireOnNewGlobalObject(); From 31705a1450051b6273ed1434c0204f88615799da Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Thu, 18 Feb 2016 18:52:37 +0800 Subject: [PATCH 032/115] Bug 1249244 - Add missing argument to MediaEngineGonkVideoSource::Allocate. r=cyu MozReview-Commit-ID: 5va5cHFqlja --HG-- extra : rebase_source : ca16b27f315b06468c93dcfd25ad9fc739dc1021 --- dom/media/webrtc/MediaEngineGonkVideoSource.cpp | 3 ++- dom/media/webrtc/MediaEngineGonkVideoSource.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp index 5e1c8696a6b2..4e1eaa3bf5d2 100644 --- a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp +++ b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp @@ -148,7 +148,8 @@ MediaEngineGonkVideoSource::NumCapabilities() nsresult MediaEngineGonkVideoSource::Allocate(const dom::MediaTrackConstraints& aConstraints, const MediaEnginePrefs& aPrefs, - const nsString& aDeviceId) + const nsString& aDeviceId, + const nsACString& aOrigin) { LOG((__FUNCTION__)); diff --git a/dom/media/webrtc/MediaEngineGonkVideoSource.h b/dom/media/webrtc/MediaEngineGonkVideoSource.h index 203e6d82e1eb..0aad56745cf4 100644 --- a/dom/media/webrtc/MediaEngineGonkVideoSource.h +++ b/dom/media/webrtc/MediaEngineGonkVideoSource.h @@ -62,7 +62,8 @@ public: nsresult Allocate(const dom::MediaTrackConstraints &aConstraints, const MediaEnginePrefs &aPrefs, - const nsString& aDeviceId) override; + const nsString& aDeviceId, + const nsACString& aOrigin) override; nsresult Deallocate() override; nsresult Start(SourceMediaStream* aStream, TrackID aID) override; nsresult Stop(SourceMediaStream* aSource, TrackID aID) override; From 39658a1669d39ceaa9737c16d1d8ac0a2b657393 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Thu, 18 Feb 2016 18:59:38 +0800 Subject: [PATCH 033/115] Bug 1249245 - Add missing header gfxPrefs.h to GrallocTextureClient.cpp. r=cyu MozReview-Commit-ID: ILck1Eh6XGU --HG-- extra : rebase_source : 48aeac8b7b8ee1b9abfd2a36de681cfc12994867 --- gfx/layers/opengl/GrallocTextureClient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gfx/layers/opengl/GrallocTextureClient.cpp b/gfx/layers/opengl/GrallocTextureClient.cpp index 44f5b34e63b7..fbb7ba7c4eb0 100644 --- a/gfx/layers/opengl/GrallocTextureClient.cpp +++ b/gfx/layers/opengl/GrallocTextureClient.cpp @@ -12,6 +12,7 @@ #include "mozilla/layers/ISurfaceAllocator.h" #include "mozilla/layers/ShadowLayerUtilsGralloc.h" #include "gfx2DGlue.h" +#include "gfxPrefs.h" // for gfxPrefs #include "SharedSurfaceGralloc.h" #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 From 46f9b7e0d4e5f36fa139664d6a673379877b2e12 Mon Sep 17 00:00:00 2001 From: Bogdan Postelnicu Date: Thu, 18 Feb 2016 14:31:16 +0200 Subject: [PATCH 034/115] Bug 1248908 - ToolbarDisplayLayout: Remove unnecessary null checks. r=sebastian MozReview-Commit-ID: LBtVN8F0oO4 --HG-- extra : rebase_source : 2dd6627edcc73e673fadad92fddd650ee71779c5 --- .../mozilla/gecko/toolbar/BrowserToolbar.java | 5 ++-- .../gecko/toolbar/ToolbarDisplayLayout.java | 25 ++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java index 2fdbfaba850b..9a2d26f6bd20 100644 --- a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java +++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java @@ -56,6 +56,7 @@ import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.LinearLayout; import android.widget.PopupWindow; +import android.support.annotation.NonNull; /** * {@code BrowserToolbar} is single entry point for users of the toolbar @@ -402,7 +403,7 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout } @Override - public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) { + public void onTabChanged(@NonNull Tab tab, Tabs.TabEvents msg, Object data) { Log.d(LOGTAG, "onTabChanged: " + msg); final Tabs tabs = Tabs.getInstance(); @@ -591,7 +592,7 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout activity.getString(R.string.one_tab)); } - private void updateDisplayLayout(Tab tab, EnumSet flags) { + private void updateDisplayLayout(@NonNull Tab tab, EnumSet flags) { if (isSwitchingTabs) { flags.add(UpdateFlags.DISABLE_ANIMATIONS); } diff --git a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarDisplayLayout.java b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarDisplayLayout.java index 6d554353ab84..efd4dab1dc4e 100644 --- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarDisplayLayout.java +++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarDisplayLayout.java @@ -29,6 +29,7 @@ import org.mozilla.gecko.widget.themed.ThemedTextView; import android.content.Context; import android.os.SystemClock; import android.support.annotation.Nullable; +import android.support.annotation.NonNull; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.TextUtils; @@ -190,7 +191,7 @@ public class ToolbarDisplayLayout extends ThemedLinearLayout { mPrefs = prefs; } - void updateFromTab(Tab tab, EnumSet flags) { + void updateFromTab(@NonNull Tab tab, EnumSet flags) { // Several parts of ToolbarDisplayLayout's state depends // on the views being attached to the view tree. if (!mIsAttached) { @@ -210,7 +211,7 @@ public class ToolbarDisplayLayout extends ThemedLinearLayout { } if (flags.contains(UpdateFlags.PRIVATE_MODE)) { - mTitle.setPrivateMode(tab != null && tab.isPrivate()); + mTitle.setPrivateMode(tab.isPrivate()); } } @@ -222,10 +223,10 @@ public class ToolbarDisplayLayout extends ThemedLinearLayout { } } - private void updateTitle(Tab tab) { + private void updateTitle(@NonNull Tab tab) { // Keep the title unchanged if there's no selected tab, // or if the tab is entering reader mode. - if (tab == null || tab.isEnteringReaderMode()) { + if (tab.isEnteringReaderMode()) { return; } @@ -279,13 +280,8 @@ public class ToolbarDisplayLayout extends ThemedLinearLayout { return ReaderModeUtils.getUrlFromAboutReader(url); } - private void updateSiteIdentity(Tab tab) { - final SiteIdentity siteIdentity; - if (tab == null) { - siteIdentity = null; - } else { - siteIdentity = tab.getSiteIdentity(); - } + private void updateSiteIdentity(@NonNull Tab tab) { + final SiteIdentity siteIdentity = tab.getSiteIdentity(); mSiteIdentityPopup.setSiteIdentity(siteIdentity); @@ -342,13 +338,12 @@ public class ToolbarDisplayLayout extends ThemedLinearLayout { mTrackingProtectionEnabled = trackingMode == TrackingMode.TRACKING_CONTENT_BLOCKED; } - private void updateProgress(@Nullable Tab tab) { - final boolean shouldShowThrobber = (tab != null && - tab.getState() == Tab.STATE_LOADING); + private void updateProgress(@NonNull Tab tab) { + final boolean shouldShowThrobber = tab.getState() == Tab.STATE_LOADING; updateUiMode(shouldShowThrobber ? UIMode.PROGRESS : UIMode.DISPLAY); - if (tab != null && Tab.STATE_SUCCESS == tab.getState() && mTrackingProtectionEnabled) { + if (Tab.STATE_SUCCESS == tab.getState() && mTrackingProtectionEnabled) { mActivity.showTrackingProtectionPromptIfApplicable(); } } From 6dc7388b9f365628c78b372ec6cf28ee96a63d8c Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Thu, 18 Feb 2016 14:18:07 +0100 Subject: [PATCH 035/115] Bug 1246658 part 5 - Support int64 constants, add MIRType_Int64. r=luke --- js/src/jit/IonAnalysis.cpp | 9 +- js/src/jit/IonTypes.h | 16 +++- js/src/jit/MCallOptimize.cpp | 4 +- js/src/jit/MIR.cpp | 94 ++++++++++++-------- js/src/jit/MIR.h | 15 +++- js/src/jit/RangeAnalysis.cpp | 14 +-- js/src/jit/shared/CodeGenerator-shared-inl.h | 2 +- js/src/jsapi-tests/testJitDCEinGVN.cpp | 2 +- js/src/jsapi-tests/testJitFoldsTo.cpp | 6 +- 9 files changed, 106 insertions(+), 56 deletions(-) diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index d2447a19a785..885767b9e985 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -1269,7 +1269,9 @@ GuessPhiType(MPhi* phi, bool* hasInputsWithEmptyTypes) // If we only saw definitions that can be converted into Float32 before and // encounter a Float32 value, promote previous values to Float32 type = MIRType_Float32; - } else if (IsNumberType(type) && IsNumberType(in->type())) { + } else if (IsTypeRepresentableAsDouble(type) && + IsTypeRepresentableAsDouble(in->type())) + { // Specialize phis with int32 and double operands as double. type = MIRType_Double; convertibleToFloat32 &= in->canProduceFloat32(); @@ -1329,7 +1331,9 @@ TypeAnalyzer::propagateSpecialization(MPhi* phi) } // Specialize phis with int32 and double operands as double. - if (IsNumberType(use->type()) && IsNumberType(phi->type())) { + if (IsTypeRepresentableAsDouble(use->type()) && + IsTypeRepresentableAsDouble(phi->type())) + { if (!respecialize(use, MIRType_Double)) return false; continue; @@ -2501,6 +2505,7 @@ IsResumableMIRType(MIRType type) case MIRType_ObjectGroup: case MIRType_Doublex2: // NYI, see also RSimdBox::recover case MIRType_SinCosDouble: + case MIRType_Int64: return false; } MOZ_CRASH("Unknown MIRType."); diff --git a/js/src/jit/IonTypes.h b/js/src/jit/IonTypes.h index ddf388479c1a..a78e1ab8bd8e 100644 --- a/js/src/jit/IonTypes.h +++ b/js/src/jit/IonTypes.h @@ -399,6 +399,7 @@ enum MIRType MIRType_Null, MIRType_Boolean, MIRType_Int32, + MIRType_Int64, MIRType_Double, MIRType_Float32, MIRType_String, @@ -504,6 +505,8 @@ StringFromMIRType(MIRType type) return "Bool"; case MIRType_Int32: return "Int32"; + case MIRType_Int64: + return "Int64"; case MIRType_Double: return "Double"; case MIRType_Float32: @@ -557,7 +560,18 @@ StringFromMIRType(MIRType type) static inline bool IsNumberType(MIRType type) { - return type == MIRType_Int32 || type == MIRType_Double || type == MIRType_Float32; + return type == MIRType_Int32 || + type == MIRType_Double || + type == MIRType_Float32 || + type == MIRType_Int64; +} + +static inline bool +IsTypeRepresentableAsDouble(MIRType type) +{ + return type == MIRType_Int32 || + type == MIRType_Double || + type == MIRType_Float32; } static inline bool diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index e50588db6d58..563f6aad3f36 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -1280,7 +1280,7 @@ IonBuilder::inlineMathPowHelper(MDefinition* lhs, MDefinition* rhs, MIRType outp // Optimize some constant powers. if (rhs->isConstant()) { - double pow = rhs->toConstant()->toNumber(); + double pow = rhs->toConstant()->numberToDouble(); // Math.pow(x, 0.5) is a sqrt with edge-case detection. if (pow == 0.5) { @@ -1486,7 +1486,7 @@ IonBuilder::inlineMathMinMax(CallInfo& callInfo, bool max) // Don't force a double MMinMax for arguments that would be a NOP // when doing an integer MMinMax. if (arg->isConstant()) { - double cte = arg->toConstant()->toNumber(); + double cte = arg->toConstant()->numberToDouble(); // min(int32, cte >= INT32_MAX) = int32 if (cte >= INT32_MAX && !max) break; diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index a76370a55fe9..5f633373609a 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -85,7 +85,8 @@ EvaluateConstantOperands(TempAllocator& alloc, MBinaryInstruction* ins, bool* pt MDefinition* left = ins->getOperand(0); MDefinition* right = ins->getOperand(1); - MOZ_ASSERT(IsNumberType(left->type()) && IsNumberType(right->type())); + MOZ_ASSERT(IsTypeRepresentableAsDouble(left->type())); + MOZ_ASSERT(IsTypeRepresentableAsDouble(right->type())); if (!left->isConstant() || !right->isConstant()) return nullptr; @@ -114,25 +115,25 @@ EvaluateConstantOperands(TempAllocator& alloc, MBinaryInstruction* ins, bool* pt ret.setNumber(uint32_t(lhs->toInt32()) >> (rhs->toInt32() & 0x1F)); break; case MDefinition::Op_Add: - ret.setNumber(lhs->toNumber() + rhs->toNumber()); + ret.setNumber(lhs->numberToDouble() + rhs->numberToDouble()); break; case MDefinition::Op_Sub: - ret.setNumber(lhs->toNumber() - rhs->toNumber()); + ret.setNumber(lhs->numberToDouble() - rhs->numberToDouble()); break; case MDefinition::Op_Mul: - ret.setNumber(lhs->toNumber() * rhs->toNumber()); + ret.setNumber(lhs->numberToDouble() * rhs->numberToDouble()); break; case MDefinition::Op_Div: if (ins->toDiv()->isUnsigned()) ret.setInt32(rhs->isInt32(0) ? 0 : uint32_t(lhs->toInt32()) / uint32_t(rhs->toInt32())); else - ret.setNumber(NumberDiv(lhs->toNumber(), rhs->toNumber())); + ret.setNumber(NumberDiv(lhs->numberToDouble(), rhs->numberToDouble())); break; case MDefinition::Op_Mod: if (ins->toMod()->isUnsigned()) ret.setInt32(rhs->isInt32(0) ? 0 : uint32_t(lhs->toInt32()) % uint32_t(rhs->toInt32())); else - ret.setNumber(NumberMod(lhs->toNumber(), rhs->toNumber())); + ret.setNumber(NumberMod(lhs->numberToDouble(), rhs->numberToDouble())); break; default: MOZ_CRASH("NYI"); @@ -166,7 +167,7 @@ EvaluateExactReciprocal(TempAllocator& alloc, MDiv* ins) return nullptr; int32_t num; - if (!mozilla::NumberIsInt32(right->toConstant()->toNumber(), &num)) + if (!mozilla::NumberIsInt32(right->toConstant()->numberToDouble(), &num)) return nullptr; // check if rhs is a power of two @@ -670,6 +671,12 @@ MConstant::NewFloat32(TempAllocator& alloc, double d) return new(alloc) MConstant(float(d)); } +MConstant* +MConstant::NewInt64(TempAllocator& alloc, int64_t i) +{ + return new(alloc) MConstant(i); +} + MConstant* MConstant::NewAsmJS(TempAllocator& alloc, const Value& v, MIRType type) { @@ -809,6 +816,13 @@ MConstant::MConstant(float f) setMovable(); } +MConstant::MConstant(int64_t i) +{ + setResultType(MIRType_Int64); + payload_.i64 = i; + setMovable(); +} + #ifdef DEBUG void MConstant::assertInitializedPayload() const @@ -825,6 +839,7 @@ MConstant::assertInitializedPayload() const MOZ_ASSERT((payload_.asBits >> 1) == 0); break; case MIRType_Double: + case MIRType_Int64: break; case MIRType_String: case MIRType_Object: @@ -941,7 +956,7 @@ MConstant::printOpcode(GenericPrinter& out) const bool MConstant::canProduceFloat32() const { - if (!IsNumberType(type())) + if (!isTypeRepresentableAsDouble()) return false; if (type() == MIRType_Int32) @@ -1067,7 +1082,7 @@ MSimdValueX4::foldsTo(TempAllocator& alloc) case MIRType_Float32x4: { float a[4]; for (size_t i = 0; i < 4; ++i) - a[i] = getOperand(i)->toConstant()->toNumber(); + a[i] = getOperand(i)->toConstant()->numberToDouble(); cst = SimdConstant::CreateX4(a); break; } @@ -1103,7 +1118,7 @@ MSimdSplatX4::foldsTo(TempAllocator& alloc) break; } case MIRType_Float32x4: { - float v = op->toConstant()->toNumber(); + float v = op->toConstant()->numberToDouble(); cst = SimdConstant::SplatX4(v); break; } @@ -1446,10 +1461,10 @@ MDefinition* MMathFunction::foldsTo(TempAllocator& alloc) { MDefinition* input = getOperand(0); - if (!input->isConstant() || !input->toConstant()->isNumber()) + if (!input->isConstant() || !input->toConstant()->isTypeRepresentableAsDouble()) return this; - double in = input->toConstant()->toNumber(); + double in = input->toConstant()->numberToDouble(); double out; switch (function_) { case Log: @@ -2017,7 +2032,7 @@ MPhi::foldsTernary() // If testArg is an int32 type we can: // - fold testArg ? testArg : 0 to testArg // - fold testArg ? 0 : testArg to 0 - if (testArg->type() == MIRType_Int32 && c->toNumber() == 0) { + if (testArg->type() == MIRType_Int32 && c->numberToDouble() == 0) { // When folding to the constant we need to hoist it. if (trueDef == c && !c->block()->dominates(block())) c->block()->moveBefore(pred->lastIns(), c); @@ -2159,7 +2174,7 @@ jit::MergeTypes(MIRType* ptype, TemporaryTypeSet** ptypeSet, if (newTypeSet && newTypeSet->empty()) return true; if (newType != *ptype) { - if (IsNumberType(newType) && IsNumberType(*ptype)) { + if (IsTypeRepresentableAsDouble(newType) && IsTypeRepresentableAsDouble(*ptype)) { *ptype = MIRType_Double; } else if (*ptype != MIRType_Value) { if (!*ptypeSet) { @@ -2393,7 +2408,7 @@ IsConstant(MDefinition* def, double v) if (!def->isConstant()) return false; - return NumbersAreIdentical(def->toConstant()->toNumber(), v); + return NumbersAreIdentical(def->toConstant()->numberToDouble(), v); } MDefinition* @@ -2807,11 +2822,14 @@ MMinMax::foldsTo(TempAllocator& alloc) // Directly apply math utility to compare the rhs() and lhs() when // they are both constants. if (lhs()->isConstant() && rhs()->isConstant()) { - if (!lhs()->toConstant()->isNumber() || !rhs()->toConstant()->isNumber()) + if (!lhs()->toConstant()->isTypeRepresentableAsDouble() || + !rhs()->toConstant()->isTypeRepresentableAsDouble()) + { return this; + } - double lnum = lhs()->toConstant()->toNumber(); - double rnum = rhs()->toConstant()->toNumber(); + double lnum = lhs()->toConstant()->numberToDouble(); + double rnum = rhs()->toConstant()->numberToDouble(); double result; if (isMax()) result = js::math_max_impl(lnum, rnum); @@ -2837,7 +2855,10 @@ MMinMax::foldsTo(TempAllocator& alloc) if (operand->isToDouble() && operand->getOperand(0)->type() == MIRType_Int32) { // min(int32, cte >= INT32_MAX) = int32 - if (constant->isNumber() && constant->toNumber() >= INT32_MAX && !isMax()) { + if (!isMax() && + constant->isTypeRepresentableAsDouble() && + constant->numberToDouble() >= INT32_MAX) + { MLimitedTruncate* limit = MLimitedTruncate::New(alloc, operand->getOperand(0), MDefinition::NoTruncate); block()->insertBefore(this, limit); @@ -2846,7 +2867,10 @@ MMinMax::foldsTo(TempAllocator& alloc) } // max(int32, cte <= INT32_MIN) = int32 - if (constant->isNumber() && constant->toNumber() <= INT32_MIN && isMax()) { + if (isMax() && + constant->isTypeRepresentableAsDouble() && + constant->numberToDouble() <= INT32_MIN) + { MLimitedTruncate* limit = MLimitedTruncate::New(alloc, operand->getOperand(0), MDefinition::NoTruncate); block()->insertBefore(this, limit); @@ -3238,7 +3262,7 @@ MCompare::determineCompareType(JSOp op, MDefinition* left, MDefinition* right) } // Numeric comparisons against a double coerce to double. - if (IsNumberType(lhs) && IsNumberType(rhs)) + if (IsTypeRepresentableAsDouble(lhs) && IsTypeRepresentableAsDouble(rhs)) return Compare_Double; // Any comparison is allowed except strict eq. @@ -3648,7 +3672,7 @@ MToInt32::foldsTo(TempAllocator& alloc) case MIRType_Double: int32_t ival; // Only the value within the range of Int32 can be substituted as constant. - if (mozilla::NumberEqualsInt32(input->toConstant()->toNumber(), &ival)) + if (mozilla::NumberEqualsInt32(input->toConstant()->numberToDouble(), &ival)) return MConstant::New(alloc, Int32Value(ival)); break; default: @@ -3696,8 +3720,8 @@ MToDouble::foldsTo(TempAllocator& alloc) if (input->type() == MIRType_Double) return input; - if (input->isConstant() && input->toConstant()->isNumber()) { - double out = input->toConstant()->toNumber(); + if (input->isConstant() && input->toConstant()->isTypeRepresentableAsDouble()) { + double out = input->toConstant()->numberToDouble(); return MConstant::New(alloc, DoubleValue(out)); } @@ -3718,8 +3742,8 @@ MToFloat32::foldsTo(TempAllocator& alloc) if (input->isToDouble() && input->toToDouble()->input()->type() == MIRType_Float32) return input->toToDouble()->input(); - if (input->isConstant() && input->toConstant()->isNumber()) - return MConstant::NewFloat32(alloc, float(input->toConstant()->toNumber())); + if (input->isConstant() && input->toConstant()->isTypeRepresentableAsDouble()) + return MConstant::NewFloat32(alloc, float(input->toConstant()->numberToDouble())); return this; } @@ -3740,8 +3764,8 @@ MDefinition* MClampToUint8::foldsTo(TempAllocator& alloc) { if (MConstant* inputConst = input()->maybeConstantValue()) { - if (inputConst->isNumber()) { - int32_t clamped = ClampDoubleToUint8(inputConst->toNumber()); + if (inputConst->isTypeRepresentableAsDouble()) { + int32_t clamped = ClampDoubleToUint8(inputConst->numberToDouble()); return MConstant::New(alloc, Int32Value(clamped)); } } @@ -4083,29 +4107,29 @@ MCompare::evaluateConstantOperands(TempAllocator& alloc, bool* result) return true; } - if (!lhs->isNumber() || !rhs->isNumber()) + if (!lhs->isTypeRepresentableAsDouble() || !rhs->isTypeRepresentableAsDouble()) return false; switch (jsop_) { case JSOP_LT: - *result = (lhs->toNumber() < rhs->toNumber()); + *result = (lhs->numberToDouble() < rhs->numberToDouble()); break; case JSOP_LE: - *result = (lhs->toNumber() <= rhs->toNumber()); + *result = (lhs->numberToDouble() <= rhs->numberToDouble()); break; case JSOP_GT: - *result = (lhs->toNumber() > rhs->toNumber()); + *result = (lhs->numberToDouble() > rhs->numberToDouble()); break; case JSOP_GE: - *result = (lhs->toNumber() >= rhs->toNumber()); + *result = (lhs->numberToDouble() >= rhs->numberToDouble()); break; case JSOP_STRICTEQ: // Fall through. case JSOP_EQ: - *result = (lhs->toNumber() == rhs->toNumber()); + *result = (lhs->numberToDouble() == rhs->numberToDouble()); break; case JSOP_STRICTNE: // Fall through. case JSOP_NE: - *result = (lhs->toNumber() != rhs->toNumber()); + *result = (lhs->numberToDouble() != rhs->numberToDouble()); break; default: return false; diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 5cabe59a3f75..5f5faf890b29 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -1371,6 +1371,7 @@ class MConstant : public MNullaryInstruction union { bool b; int32_t i32; + int64_t i64; float f; double d; JSString* str; @@ -1396,12 +1397,14 @@ class MConstant : public MNullaryInstruction MConstant(const Value& v, CompilerConstraintList* constraints); explicit MConstant(JSObject* obj); explicit MConstant(float f); + explicit MConstant(int64_t i); public: INSTRUCTION_HEADER(Constant) static MConstant* New(TempAllocator& alloc, const Value& v, CompilerConstraintList* constraints = nullptr); static MConstant* NewFloat32(TempAllocator& alloc, double d); + static MConstant* NewInt64(TempAllocator& alloc, int64_t i); static MConstant* NewAsmJS(TempAllocator& alloc, const Value& v, MIRType type); static MConstant* NewConstraintlessObject(TempAllocator& alloc, JSObject* v); @@ -1458,6 +1461,10 @@ class MConstant : public MNullaryInstruction MOZ_ASSERT(type() == MIRType_Int32); return payload_.i32; } + int64_t toInt64() const { + MOZ_ASSERT(type() == MIRType_Int64); + return payload_.i64; + } bool isInt32(int32_t i) const { return type() == MIRType_Int32 && payload_.i32 == i; } @@ -1488,15 +1495,15 @@ class MConstant : public MNullaryInstruction return nullptr; } - bool isNumber() const { - return IsNumberType(type()); + bool isTypeRepresentableAsDouble() const { + return IsTypeRepresentableAsDouble(type()); } - double toNumber() const { + double numberToDouble() const { + MOZ_ASSERT(isTypeRepresentableAsDouble()); if (type() == MIRType_Int32) return toInt32(); if (type() == MIRType_Double) return toDouble(); - MOZ_ASSERT(type() == MIRType_Float32); return toFloat32(); } diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index b193eee4e307..f3c7d0ca99f9 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -198,12 +198,12 @@ RangeAnalysis::addBetaNodes() MConstant* leftConst = left->maybeConstantValue(); MConstant* rightConst = right->maybeConstantValue(); - if (leftConst && leftConst->isNumber()) { - bound = leftConst->toNumber(); + if (leftConst && leftConst->isTypeRepresentableAsDouble()) { + bound = leftConst->numberToDouble(); val = right; jsop = ReverseCompareOp(jsop); - } else if (rightConst && rightConst->isNumber()) { - bound = rightConst->toNumber(); + } else if (rightConst && rightConst->isTypeRepresentableAsDouble()) { + bound = rightConst->numberToDouble(); val = left; } else if (left->type() == MIRType_Int32 && right->type() == MIRType_Int32) { MDefinition* smaller = nullptr; @@ -1291,8 +1291,8 @@ MBeta::computeRange(TempAllocator& alloc) void MConstant::computeRange(TempAllocator& alloc) { - if (isNumber()) { - double d = toNumber(); + if (isTypeRepresentableAsDouble()) { + double d = numberToDouble(); setRange(Range::NewDoubleSingletonRange(alloc, d)); } else if (type() == MIRType_Boolean) { bool b = toBoolean(); @@ -2416,7 +2416,7 @@ MConstant::truncate() MOZ_ASSERT(needTruncation(Truncate)); // Truncate the double to int, since all uses truncates it. - int32_t res = ToInt32(toNumber()); + int32_t res = ToInt32(numberToDouble()); payload_.asBits = 0; payload_.i32 = res; setResultType(MIRType_Int32); diff --git a/js/src/jit/shared/CodeGenerator-shared-inl.h b/js/src/jit/shared/CodeGenerator-shared-inl.h index 170875fbd0c2..228365344247 100644 --- a/js/src/jit/shared/CodeGenerator-shared-inl.h +++ b/js/src/jit/shared/CodeGenerator-shared-inl.h @@ -28,7 +28,7 @@ ToInt32(const LAllocation* a) static inline double ToDouble(const LAllocation* a) { - return a->toConstant()->toNumber(); + return a->toConstant()->numberToDouble(); } static inline Register diff --git a/js/src/jsapi-tests/testJitDCEinGVN.cpp b/js/src/jsapi-tests/testJitDCEinGVN.cpp index 9d6b13ab44f4..9d3a94921056 100644 --- a/js/src/jsapi-tests/testJitDCEinGVN.cpp +++ b/js/src/jsapi-tests/testJitDCEinGVN.cpp @@ -136,7 +136,7 @@ BEGIN_TEST(testJitDCEinGVN_phi) // c1 should be deleted. for (MInstructionIterator ins = block->begin(); ins != block->end(); ins++) { - CHECK(!ins->isConstant() || (ins->toConstant()->toNumber() != 1.0)); + CHECK(!ins->isConstant() || (ins->toConstant()->numberToDouble() != 1.0)); } return true; } diff --git a/js/src/jsapi-tests/testJitFoldsTo.cpp b/js/src/jsapi-tests/testJitFoldsTo.cpp index ba5278c793bd..4b5e2c0f1a56 100644 --- a/js/src/jsapi-tests/testJitFoldsTo.cpp +++ b/js/src/jsapi-tests/testJitFoldsTo.cpp @@ -42,7 +42,7 @@ BEGIN_TEST(testJitFoldsTo_DivReciprocal) CHECK(op->isMul()); CHECK(op->getOperand(0) == left); CHECK(op->getOperand(1)->isConstant()); - CHECK(op->getOperand(1)->toConstant()->toNumber() == 0.25); + CHECK(op->getOperand(1)->toConstant()->numberToDouble() == 0.25); return true; } END_TEST(testJitFoldsTo_DivReciprocal) @@ -229,7 +229,7 @@ BEGIN_TEST(testJitFoldsTo_UnsignedDiv) // Test that the div got folded to 0. MConstant* op = ret->getOperand(0)->toConstant(); - CHECK(mozilla::NumbersAreIdentical(op->toNumber(), 0.0)); + CHECK(mozilla::NumbersAreIdentical(op->numberToDouble(), 0.0)); return true; } END_TEST(testJitFoldsTo_UnsignedDiv) @@ -254,7 +254,7 @@ BEGIN_TEST(testJitFoldsTo_UnsignedMod) // Test that the mod got folded to 1. MConstant* op = ret->getOperand(0)->toConstant(); - CHECK(mozilla::NumbersAreIdentical(op->toNumber(), 1.0)); + CHECK(mozilla::NumbersAreIdentical(op->numberToDouble(), 1.0)); return true; } END_TEST(testJitFoldsTo_UnsignedMod) From 0048e20de02cf6c1f53ae2c3d12b11a74f1a4a61 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Thu, 18 Feb 2016 14:19:21 +0100 Subject: [PATCH 036/115] Bug 1248598 part 1 - Some code changes required for the i64.const instruction. r=luke --- js/src/asmjs/WasmBinary.h | 22 ++++++++++++++++------ js/src/asmjs/WasmIonCompile.cpp | 18 ++++++++++++++++-- js/src/asmjs/WasmText.cpp | 2 +- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/js/src/asmjs/WasmBinary.h b/js/src/asmjs/WasmBinary.h index 091850c3cd85..a39faa96374f 100644 --- a/js/src/asmjs/WasmBinary.h +++ b/js/src/asmjs/WasmBinary.h @@ -704,19 +704,29 @@ class Decoder double uncheckedReadFixedF64() { return uncheckedRead(); } - uint32_t uncheckedReadVarU32() { - uint32_t decoded = 0; + template + UInt uncheckedReadVarU() { + static const unsigned numBits = sizeof(UInt) * CHAR_BIT; + static const unsigned remainderBits = numBits % 7; + static const unsigned numBitsInSevens = numBits - remainderBits; + UInt decoded = 0; uint32_t shift = 0; do { uint8_t byte = *cur_++; if (!(byte & 0x80)) - return decoded | (uint32_t(byte) << shift); - decoded |= uint32_t(byte & 0x7f) << shift; + return decoded | (UInt(byte) << shift); + decoded |= UInt(byte & 0x7f) << shift; shift += 7; - } while (shift != 28); + } while (shift != numBitsInSevens); uint8_t byte = *cur_++; MOZ_ASSERT(!(byte & 0xf0)); - return decoded | (uint32_t(byte) << 28); + return decoded | (UInt(byte) << numBitsInSevens); + } + uint32_t uncheckedReadVarU32() { + return uncheckedReadVarU(); + } + uint64_t uncheckedReadVarU64() { + return uncheckedReadVarU(); } Expr uncheckedReadExpr() { return uncheckedReadEnum(); diff --git a/js/src/asmjs/WasmIonCompile.cpp b/js/src/asmjs/WasmIonCompile.cpp index 037aefd68fe6..7652510ee5c5 100644 --- a/js/src/asmjs/WasmIonCompile.cpp +++ b/js/src/asmjs/WasmIonCompile.cpp @@ -198,6 +198,15 @@ class FunctionCompiler return constant; } + MDefinition* constant(int64_t i) + { + if (inDeadCode()) + return nullptr; + MConstant* constant = MConstant::NewInt64(alloc(), i); + curBlock_->add(constant); + return constant; + } + template MDefinition* unary(MDefinition* op) { @@ -1214,6 +1223,7 @@ class FunctionCompiler uint8_t readU8() { return decoder_.uncheckedReadFixedU8(); } uint32_t readVarU32() { return decoder_.uncheckedReadVarU32(); } + uint64_t readVarU64() { return decoder_.uncheckedReadVarU64(); } float readF32() { return decoder_.uncheckedReadFixedF32(); } double readF64() { return decoder_.uncheckedReadFixedF64(); } Expr readExpr() { return decoder_.uncheckedReadExpr(); } @@ -1344,7 +1354,9 @@ EmitLiteral(FunctionCompiler& f, ExprType type, MDefinition** def) return true; } case ExprType::I64: { - MOZ_CRASH("int64"); + int64_t val = f.readVarU64(); + *def = f.constant(val); + return true; } case ExprType::F32: { float val = f.readF32(); @@ -2808,6 +2820,9 @@ EmitExpr(FunctionCompiler& f, ExprType type, MDefinition** def, LabelVector* may return EmitAtomicsStore(f, def); case Expr::I32AtomicsBinOp: return EmitAtomicsBinOp(f, def); + // I64 + case Expr::I64Const: + return EmitLiteral(f, ExprType::I64, def); // F32 case Expr::F32Const: return EmitLiteral(f, ExprType::F32, def); @@ -2929,7 +2944,6 @@ EmitExpr(FunctionCompiler& f, ExprType type, MDefinition** def, LabelVector* may case Expr::F64Nearest: case Expr::F64Trunc: case Expr::I32WrapI64: - case Expr::I64Const: case Expr::I64ExtendSI32: case Expr::I64ExtendUI32: case Expr::I64TruncSF32: diff --git a/js/src/asmjs/WasmText.cpp b/js/src/asmjs/WasmText.cpp index 685b96604ab2..7da345f924aa 100644 --- a/js/src/asmjs/WasmText.cpp +++ b/js/src/asmjs/WasmText.cpp @@ -2074,7 +2074,7 @@ ParseConst(WasmParseContext& c, WasmToken constToken) case ValType::I64: { switch (val.kind()) { case WasmToken::Index: - return new(c.lifo) WasmAstConst(Val(val.index())); + return new(c.lifo) WasmAstConst(Val(uint64_t(val.index()))); case WasmToken::UnsignedInteger: return new(c.lifo) WasmAstConst(Val(val.uint())); case WasmToken::SignedInteger: From 1e87d62a03b4ed8c4e023ed235393d0a2960d480 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Thu, 18 Feb 2016 14:53:40 +0100 Subject: [PATCH 037/115] Bug 1248949 - Optimize Arena::thingsPerArena. r=terrence --- js/src/gc/Heap.h | 14 +++---- js/src/jsgc.cpp | 80 +++++++++++++++++++++++++++---------- js/src/vm/MemoryMetrics.cpp | 2 +- 3 files changed, 66 insertions(+), 30 deletions(-) diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index 5f8a2353528d..30a8f646cd13 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -744,6 +744,7 @@ struct Arena private: static JS_FRIEND_DATA(const uint32_t) ThingSizes[]; static JS_FRIEND_DATA(const uint32_t) FirstThingOffsets[]; + static const uint32_t ThingsPerArena[]; public: static void staticAsserts(); @@ -756,17 +757,12 @@ struct Arena return FirstThingOffsets[size_t(kind)]; } - static size_t thingsPerArena(size_t thingSize) { - MOZ_ASSERT(thingSize % CellSize == 0); - - /* We should be able to fit FreeSpan in any GC thing. */ - MOZ_ASSERT(thingSize >= sizeof(FreeSpan)); - - return (ArenaSize - sizeof(ArenaHeader)) / thingSize; + static size_t thingsPerArena(AllocKind kind) { + return ThingsPerArena[size_t(kind)]; } - static size_t thingsSpan(size_t thingSize) { - return thingsPerArena(thingSize) * thingSize; + static size_t thingsSpan(AllocKind kind) { + return thingsPerArena(kind) * thingSize(kind); } static bool isAligned(uintptr_t thing, size_t thingSize) { diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 6cf8e10cf046..5e9ff235a65a 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -261,14 +261,20 @@ const AllocKind gc::slotsToThingKind[] = { static_assert(JS_ARRAY_LENGTH(slotsToThingKind) == SLOTS_TO_THING_KIND_LIMIT, "We have defined a slot count for each kind."); -// Assert that SortedArenaList::MinThingSize is <= the real minimum thing size. -#define CHECK_MIN_THING_SIZE_INNER(x_) \ +// Assert that SortedArenaList::MinThingSize and sizeof(FreeSpan) are <= the +// real minimum thing size. Also assert each size is a multiple of CellSize. +#define CHECK_THING_SIZE_INNER(x_) \ static_assert(x_ >= SortedArenaList::MinThingSize, \ - #x_ " is less than SortedArenaList::MinThingSize!"); -#define CHECK_MIN_THING_SIZE(...) { __VA_ARGS__ }; /* Define the array. */ \ - MOZ_FOR_EACH(CHECK_MIN_THING_SIZE_INNER, (), (__VA_ARGS__ UINT32_MAX)) + #x_ " is less than SortedArenaList::MinThingSize!"); \ + static_assert(x_ >= sizeof(FreeSpan), \ + #x_ " is less than sizeof(FreeSpan)"); \ + static_assert(x_ % CellSize == 0, \ + #x_ " not a multiple of CellSize"); -const uint32_t Arena::ThingSizes[] = CHECK_MIN_THING_SIZE( +#define CHECK_THING_SIZE(...) { __VA_ARGS__ }; /* Define the array. */ \ + MOZ_FOR_EACH(CHECK_THING_SIZE_INNER, (), (__VA_ARGS__ 0x20)) + +const uint32_t Arena::ThingSizes[] = CHECK_THING_SIZE( sizeof(JSFunction), /* AllocKind::FUNCTION */ sizeof(FunctionExtended), /* AllocKind::FUNCTION_EXTENDED */ sizeof(JSObject_Slots0), /* AllocKind::OBJECT0 */ @@ -296,8 +302,8 @@ const uint32_t Arena::ThingSizes[] = CHECK_MIN_THING_SIZE( sizeof(jit::JitCode), /* AllocKind::JITCODE */ ); -#undef CHECK_MIN_THING_SIZE_INNER -#undef CHECK_MIN_THING_SIZE +#undef CHECK_THING_SIZE_INNER +#undef CHECK_THING_SIZE #define OFFSET(type) uint32_t(sizeof(ArenaHeader) + (ArenaSize - sizeof(ArenaHeader)) % sizeof(type)) @@ -331,6 +337,38 @@ const uint32_t Arena::FirstThingOffsets[] = { #undef OFFSET +#define COUNT(type) uint32_t((ArenaSize - sizeof(ArenaHeader)) / sizeof(type)) + +const uint32_t Arena::ThingsPerArena[] = { + COUNT(JSFunction), /* AllocKind::FUNCTION */ + COUNT(FunctionExtended), /* AllocKind::FUNCTION_EXTENDED */ + COUNT(JSObject_Slots0), /* AllocKind::OBJECT0 */ + COUNT(JSObject_Slots0), /* AllocKind::OBJECT0_BACKGROUND */ + COUNT(JSObject_Slots2), /* AllocKind::OBJECT2 */ + COUNT(JSObject_Slots2), /* AllocKind::OBJECT2_BACKGROUND */ + COUNT(JSObject_Slots4), /* AllocKind::OBJECT4 */ + COUNT(JSObject_Slots4), /* AllocKind::OBJECT4_BACKGROUND */ + COUNT(JSObject_Slots8), /* AllocKind::OBJECT8 */ + COUNT(JSObject_Slots8), /* AllocKind::OBJECT8_BACKGROUND */ + COUNT(JSObject_Slots12), /* AllocKind::OBJECT12 */ + COUNT(JSObject_Slots12), /* AllocKind::OBJECT12_BACKGROUND */ + COUNT(JSObject_Slots16), /* AllocKind::OBJECT16 */ + COUNT(JSObject_Slots16), /* AllocKind::OBJECT16_BACKGROUND */ + COUNT(JSScript), /* AllocKind::SCRIPT */ + COUNT(LazyScript), /* AllocKind::LAZY_SCRIPT */ + COUNT(Shape), /* AllocKind::SHAPE */ + COUNT(AccessorShape), /* AllocKind::ACCESSOR_SHAPE */ + COUNT(BaseShape), /* AllocKind::BASE_SHAPE */ + COUNT(ObjectGroup), /* AllocKind::OBJECT_GROUP */ + COUNT(JSFatInlineString), /* AllocKind::FAT_INLINE_STRING */ + COUNT(JSString), /* AllocKind::STRING */ + COUNT(JSExternalString), /* AllocKind::EXTERNAL_STRING */ + COUNT(JS::Symbol), /* AllocKind::SYMBOL */ + COUNT(jit::JitCode), /* AllocKind::JITCODE */ +}; + +#undef COUNT + struct js::gc::FinalizePhase { size_t length; @@ -455,9 +493,11 @@ ArenaHeader::unmarkAll() Arena::staticAsserts() { static_assert(JS_ARRAY_LENGTH(ThingSizes) == size_t(AllocKind::LIMIT), - "We haven't defined all thing sizes."); + "We haven't defined all thing sizes."); static_assert(JS_ARRAY_LENGTH(FirstThingOffsets) == size_t(AllocKind::LIMIT), - "We haven't defined all offsets."); + "We haven't defined all offsets."); + static_assert(JS_ARRAY_LENGTH(ThingsPerArena) == size_t(AllocKind::LIMIT), + "We haven't defined all counts."); } void @@ -542,7 +582,7 @@ Arena::finalize(FreeOp* fop, AllocKind thingKind, size_t thingSize) size_t nfree = 0; for (const FreeSpan* span = &newListHead; !span->isEmpty(); span = span->nextSpan()) nfree += span->length(thingSize); - MOZ_ASSERT(nfree + nmarked == thingsPerArena(thingSize)); + MOZ_ASSERT(nfree + nmarked == thingsPerArena(thingKind)); #endif aheader.setFirstFreeSpan(&newListHead); return nmarked; @@ -570,7 +610,7 @@ FinalizeTypedArenas(FreeOp* fop, MOZ_ASSERT_IF(fop->onBackgroundThread(), keepArenas == ArenaLists::KEEP_ARENAS); size_t thingSize = Arena::thingSize(thingKind); - size_t thingsPerArena = Arena::thingsPerArena(thingSize); + size_t thingsPerArena = Arena::thingsPerArena(thingKind); while (ArenaHeader* aheader = *src) { *src = aheader->next; @@ -2033,7 +2073,7 @@ size_t ArenaHeader::countFreeCells() size_t ArenaHeader::countUsedCells() { - return Arena::thingsPerArena(getThingSize()) - countFreeCells(); + return Arena::thingsPerArena(getAllocKind()) - countFreeCells(); } ArenaHeader* @@ -2095,7 +2135,7 @@ ArenaList::pickArenasToRelocate(size_t& arenaTotalOut, size_t& relocTotalOut) } mozilla::DebugOnly lastFreeCells(0); - size_t cellsPerArena = Arena::thingsPerArena((*arenap)->getThingSize()); + size_t cellsPerArena = Arena::thingsPerArena((*arenap)->getAllocKind()); while (*arenap) { ArenaHeader* arena = *arenap; @@ -2366,7 +2406,7 @@ GCRuntime::relocateArenas(Zone* zone, JS::gcreason::Reason reason, ArenaHeader*& // Check that we did as much compaction as we should have. There // should always be less than one arena's worth of free cells. for (auto i : AllAllocKinds()) { - size_t thingsPerArena = Arena::thingsPerArena(Arena::thingSize(i)); + size_t thingsPerArena = Arena::thingsPerArena(i); if (CanRelocateAllocKind(i)) { ArenaList& al = zone->arenas.arenaLists[i]; size_t freeCells = 0; @@ -2854,7 +2894,7 @@ GCRuntime::releaseRelocatedArenasWithoutUnlocking(ArenaHeader* arenaList, const #if defined(JS_CRASH_DIAGNOSTICS) || defined(JS_GC_ZEAL) JS_POISON(reinterpret_cast(arena->thingsStart(thingKind)), - JS_MOVED_TENURED_PATTERN, Arena::thingsSpan(thingSize)); + JS_MOVED_TENURED_PATTERN, Arena::thingsSpan(thingKind)); #endif releaseArena(aheader, lock); @@ -2940,7 +2980,7 @@ ArenaLists::forceFinalizeNow(FreeOp* fop, AllocKind thingKind, KeepArenasEnum ke return; arenaLists[thingKind].clear(); - size_t thingsPerArena = Arena::thingsPerArena(Arena::thingSize(thingKind)); + size_t thingsPerArena = Arena::thingsPerArena(thingKind); SortedArenaList finalizedSorted(thingsPerArena); auto unlimited = SliceBudget::unlimited(); @@ -3009,7 +3049,7 @@ ArenaLists::backgroundFinalize(FreeOp* fop, ArenaHeader* listHead, ArenaHeader** AllocKind thingKind = listHead->getAllocKind(); Zone* zone = listHead->zone; - size_t thingsPerArena = Arena::thingsPerArena(Arena::thingSize(thingKind)); + size_t thingsPerArena = Arena::thingsPerArena(thingKind); SortedArenaList finalizedSorted(thingsPerArena); auto unlimited = SliceBudget::unlimited(); @@ -5447,7 +5487,7 @@ SweepArenaList(ArenaHeader** arenasToSweep, SliceBudget& sliceBudget, Args... ar *arenasToSweep = (*arenasToSweep)->next; AllocKind kind = MapTypeToFinalizeKind::kind; - sliceBudget.step(Arena::thingsPerArena(Arena::thingSize(kind))); + sliceBudget.step(Arena::thingsPerArena(kind)); if (sliceBudget.isOverBudget()) return false; } @@ -5520,7 +5560,7 @@ GCRuntime::sweepPhase(SliceBudget& sliceBudget) AllocKind kind = IncrementalFinalizePhases[finalizePhase].kinds[sweepKindIndex]; /* Set the number of things per arena for this AllocKind. */ - size_t thingsPerArena = Arena::thingsPerArena(Arena::thingSize(kind)); + size_t thingsPerArena = Arena::thingsPerArena(kind); incrementalSweepList.setThingsPerArena(thingsPerArena); if (!zone->arenas.foregroundFinalize(&fop, kind, sliceBudget, diff --git a/js/src/vm/MemoryMetrics.cpp b/js/src/vm/MemoryMetrics.cpp index 6af6f463c730..6be0fde81c14 100644 --- a/js/src/vm/MemoryMetrics.cpp +++ b/js/src/vm/MemoryMetrics.cpp @@ -356,7 +356,7 @@ StatsArenaCallback(JSRuntime* rt, void* data, gc::Arena* arena, // The admin space includes (a) the header and (b) the padding between the // end of the header and the start of the first GC thing. - size_t allocationSpace = arena->thingsSpan(thingSize); + size_t allocationSpace = Arena::thingsSpan(arena->aheader.getAllocKind()); rtStats->currZoneStats->gcHeapArenaAdmin += gc::ArenaSize - allocationSpace; // We don't call the callback on unused things. So we compute the From df9401a677c64a45954c5075b2c2700095e92017 Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Thu, 18 Feb 2016 09:31:42 -0500 Subject: [PATCH 038/115] Bug 1242989 - keep content insertions in a hash, r=tbsaunde --- accessible/base/NotificationController.cpp | 100 ++++++++------------- accessible/base/NotificationController.h | 42 +-------- 2 files changed, 39 insertions(+), 103 deletions(-) diff --git a/accessible/base/NotificationController.cpp b/accessible/base/NotificationController.cpp index 1c078a16e08e..ef024cb333b0 100644 --- a/accessible/base/NotificationController.cpp +++ b/accessible/base/NotificationController.cpp @@ -52,7 +52,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(NotificationController) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHangingChildDocuments) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContentInsertions) + for (auto it = tmp->mContentInsertions.ConstIter(); !it.Done(); it.Next()) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mContentInsertions key"); + cb.NoteXPCOMChild(it.Key()); + nsTArray>* list = it.UserData(); + for (uint32_t i = 0; i < list->Length(); i++) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, + "mContentInsertions value item"); + cb.NoteXPCOMChild(list->ElementAt(i)); + } + } NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvents) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelocations) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END @@ -103,10 +112,23 @@ NotificationController::ScheduleContentInsertion(Accessible* aContainer, nsIContent* aStartChildNode, nsIContent* aEndChildNode) { - RefPtr insertion = new ContentInsertion(mDocument, - aContainer); - if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) && - mContentInsertions.AppendElement(insertion)) { + nsTArray>* list = + mContentInsertions.LookupOrAdd(aContainer); + + bool needsProcessing = false; + nsIContent* node = aStartChildNode; + while (node != aEndChildNode) { + // Notification triggers for content insertion even if no content was + // actually inserted, check if the given content has a frame to discard + // this case early. + if (node->GetPrimaryFrame()) { + if (list->AppendElement(node)) + needsProcessing = true; + } + node = node->GetNextSibling(); + } + + if (needsProcessing) { ScheduleProcessing(); } } @@ -130,7 +152,7 @@ NotificationController::IsUpdatePending() { return mPresShell->IsLayoutFlushObserver() || mObservingState == eRefreshProcessingForUpdate || - mContentInsertions.Length() != 0 || mNotifications.Length() != 0 || + mContentInsertions.Count() != 0 || mNotifications.Length() != 0 || mTextHash.Count() != 0 || !mDocument->HasLoadState(DocAccessible::eTreeConstructed); } @@ -178,7 +200,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) mDocument->DoInitialUpdate(); - NS_ASSERTION(mContentInsertions.Length() == 0, + NS_ASSERTION(mContentInsertions.Count() == 0, "Pending content insertions while initial accessible tree isn't created!"); } @@ -196,15 +218,13 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) // document accessible. // Process only currently queued content inserted notifications. - nsTArray > contentInsertions; - contentInsertions.SwapElements(mContentInsertions); - - uint32_t insertionCount = contentInsertions.Length(); - for (uint32_t idx = 0; idx < insertionCount; idx++) { - contentInsertions[idx]->Process(); - if (!mDocument) + for (auto iter = mContentInsertions.ConstIter(); !iter.Done(); iter.Next()) { + mDocument->ProcessContentInserted(iter.Key(), iter.UserData()); + if (!mDocument) { return; + } } + mContentInsertions.Clear(); // Process rendered text change notifications. for (auto iter = mTextHash.Iter(); !iter.Done(); iter.Next()) { @@ -403,7 +423,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) // Stop further processing if there are no new notifications of any kind or // events and document load is processed. - if (mContentInsertions.IsEmpty() && mNotifications.IsEmpty() && + if (mContentInsertions.Count() == 0 && mNotifications.IsEmpty() && mEvents.IsEmpty() && mTextHash.Count() == 0 && mHangingChildDocuments.IsEmpty() && mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) && @@ -411,53 +431,3 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) mObservingState = eNotObservingRefresh; } } - -//////////////////////////////////////////////////////////////////////////////// -// NotificationController: content inserted notification - -NotificationController::ContentInsertion:: - ContentInsertion(DocAccessible* aDocument, Accessible* aContainer) : - mDocument(aDocument), mContainer(aContainer) -{ -} - -bool -NotificationController::ContentInsertion:: - InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode) -{ - bool haveToUpdate = false; - - nsIContent* node = aStartChildNode; - while (node != aEndChildNode) { - // Notification triggers for content insertion even if no content was - // actually inserted, check if the given content has a frame to discard - // this case early. - if (node->GetPrimaryFrame()) { - if (mInsertedContent.AppendElement(node)) - haveToUpdate = true; - } - - node = node->GetNextSibling(); - } - - return haveToUpdate; -} - -NS_IMPL_CYCLE_COLLECTION(NotificationController::ContentInsertion, - mContainer) - -NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(NotificationController::ContentInsertion, - AddRef) -NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(NotificationController::ContentInsertion, - Release) - -void -NotificationController::ContentInsertion::Process() -{ - mDocument->ProcessContentInserted(mContainer, &mInsertedContent); - - mDocument = nullptr; - mContainer = nullptr; - mInsertedContent.Clear(); -} - diff --git a/accessible/base/NotificationController.h b/accessible/base/NotificationController.h index 14f7b3af527a..666ddcc4a3f4 100644 --- a/accessible/base/NotificationController.h +++ b/accessible/base/NotificationController.h @@ -247,44 +247,10 @@ private: nsTArray > mHangingChildDocuments; /** - * Storage for content inserted notification information. + * Pending accessible tree update notifications for content insertions. */ - class ContentInsertion - { - public: - ContentInsertion(DocAccessible* aDocument, Accessible* aContainer); - - NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ContentInsertion) - NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(ContentInsertion) - - bool InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode); - void Process(); - - protected: - virtual ~ContentInsertion() { mDocument = nullptr; } - - private: - ContentInsertion(); - ContentInsertion(const ContentInsertion&); - ContentInsertion& operator = (const ContentInsertion&); - - // The document used to process content insertion, matched to document of - // the notification controller that this notification belongs to, therefore - // it's ok to keep it as weak ref. - DocAccessible* mDocument; - - // The container accessible that content insertion occurs within. - RefPtr mContainer; - - // Array of inserted contents. - nsTArray > mInsertedContent; - }; - - /** - * A pending accessible tree update notifications for content insertions. - * Don't make this an AutoTArray; we use SwapElements() on it. - */ - nsTArray > mContentInsertions; + nsClassHashtable, + nsTArray>> mContentInsertions; template class nsCOMPtrHashKey : public PLDHashEntryHdr @@ -311,7 +277,7 @@ private: }; /** - * A pending accessible tree update notifications for rendered text changes. + * Pending accessible tree update notifications for rendered text changes. */ nsTHashtable > mTextHash; From d75a7f55afc3c3496587b4700ca678a2ed1a91c5 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Wed, 17 Feb 2016 15:17:21 -0500 Subject: [PATCH 039/115] Bug 1249103 - remove support for MOZ_POST_DSO_LIB_COMMAND; r=mshal Nothing uses this variable. blame suggests that it was used for HP-UX once upon a time. The companion variable, MOZ_POST_PROGRAM_COMMAND, is only used by HP-UX, but as we're not wholesale removing HP-UX support (yet), we should leave MOZ_POST_PROGRAM_COMMAND alone. --- config/rules.mk | 3 --- configure.in | 1 - js/src/configure.in | 1 - 3 files changed, 5 deletions(-) diff --git a/config/rules.mk b/config/rules.mk index ca2a58f3d4e9..e40e1792b5d2 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -863,9 +863,6 @@ endif # WINNT && !GCC ifdef ENABLE_STRIP $(STRIP) $(STRIP_FLAGS) $@ endif -ifdef MOZ_POST_DSO_LIB_COMMAND - $(MOZ_POST_DSO_LIB_COMMAND) $@ -endif ifeq ($(SOLARIS_SUNPRO_CC),1) _MDDEPFILE = $(MDDEPDIR)/$(@F).pp diff --git a/configure.in b/configure.in index bef32fce9faa..d74d2f43ec83 100644 --- a/configure.in +++ b/configure.in @@ -8475,7 +8475,6 @@ AC_SUBST(USE_DEPENDENT_LIBS) AC_SUBST(MOZ_BUILD_ROOT) -AC_SUBST(MOZ_POST_DSO_LIB_COMMAND) AC_SUBST(MOZ_POST_PROGRAM_COMMAND) AC_SUBST(MOZ_LINKER_EXTRACT) diff --git a/js/src/configure.in b/js/src/configure.in index d6a80a99a727..fa85cf44588a 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -3467,7 +3467,6 @@ AC_SUBST(USE_DEPENDENT_LIBS) AC_SUBST(MOZ_BUILD_ROOT) -AC_SUBST(MOZ_POST_DSO_LIB_COMMAND) AC_SUBST(MOZ_POST_PROGRAM_COMMAND) AC_SUBST(MOZ_APP_NAME) From 746ba1a2f52e8fc8c0a759d58c0847113b956697 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Tue, 16 Feb 2016 21:09:34 -0500 Subject: [PATCH 040/115] Bug 1248770 - change sdp_unittests to cope with diverse c++ standard interpretations; r=jesup The C++ standard, [facet.num.get.virtuals], defines the method to be used for reading numeric values from an iterator. The core loop is defined thusly in N3242 (the draft for the C++11 standard): Stage 2: If in==end then stage 2 terminates. Otherwise a charT is taken from in and local variables are initialized as if by char_type ct = *in; char c = src[find(atoms, atoms + sizeof(src) - 1, ct) - atoms]; if (ct == use_facet >(loc).decimal_point()) c = '.'; bool discard = ct == use_facet >(loc).thousands_sep() && use_facet >(loc).grouping().length() != 0; where the values src and atoms are defined as if by: static const char src[] = "0123456789abcdefxABCDEFX+-"; char_type atoms[sizeof(src)]; use_facet >(loc).widen(src, src + sizeof(src), atoms); for this value of loc. If discard is true, then if '.' has not yet been accumulated, then the position of the character is remembered, but the character is otherwise ignored. Otherwise, if '.' has already been accumulated, the character is discarded and Stage 2 terminates. If the character is either discarded or accumulated then in is advanced by ++in and processing returns to the beginning of stage 2. Stage 3: The sequence of chars accumulated in stage 2 (the field) is converted to a numeric value by the rules of one of the functions declared in the header : - For a signed integer value, the function strtoll. - For an unsigned integer value, the function strtoull. - For a floating-point value, the function strtold. The important part for our purposes here is the line: char c = src[find(atoms, atoms + sizeof(src) - 1, ct) - atoms]; which implies that we are to accumulate any and all characters that might be numerical constituents. According to the spec text, we might accumulate a long run of numeric constituents, only to decide in stage 3 that our accumulated string cannot be a valid number. Please note that this includes characters like 'x' and 'X' which are only valid as part of a hexadecimal prefix. sdp_unittests has a number of tests that look like: ParseInvalid("[x", 1); The test converts the input string to a stringstream, and attempts to read an integer from the stream starting after the '[' character. The test expects that no input from the string stream will be consumed, as the character 'x' cannot begin any number, and thus the position of the stream after failure will be 1. This behavior is consistent with MSVC's standard library, libstdc++, and stlport. However, libc++ uses a different algorithm that appears to hew more closely to the letter of the spec, and consumes the 'x' character as being a valid constituent character ("accumulates" in the above text). The string is rejected as an invalid integer, yet the position of the string stream afterwards is different from what the test expects, and we therefore fail. This patch therefore alters a number of tests to use a different invalid character, 'v', that both the incremental algorithm (MSVC, libstdc++, stlport) and the all-at-once algorithm (libc++) will recognize as not being a valid constituent character and stop the parsing early, as expected. You might think that specifying the base for numeric input as std::dec would work, and it partially does, but reading floating-point numbers still reads the 'x' characters (!). --- media/webrtc/signaling/test/sdp_unittests.cpp | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/media/webrtc/signaling/test/sdp_unittests.cpp b/media/webrtc/signaling/test/sdp_unittests.cpp index fc4e58970c94..51eb6c0ff344 100644 --- a/media/webrtc/signaling/test/sdp_unittests.cpp +++ b/media/webrtc/signaling/test/sdp_unittests.cpp @@ -2825,16 +2825,16 @@ TEST(NewSdpTestNoFixture, CheckImageattrXYRangeParseInvalid) { ParseInvalid("[-1", 1); ParseInvalid("[-", 1); - ParseInvalid("[-x", 1); + ParseInvalid("[-v", 1); ParseInvalid("[640:-1", 5); ParseInvalid("[640:16:-1", 8); ParseInvalid("[640,-1", 5); ParseInvalid("[640,-]", 5); - ParseInvalid("-x", 0); + ParseInvalid("-v", 0); ParseInvalid("-1", 0); ParseInvalid("", 0); ParseInvalid("[", 1); - ParseInvalid("[x", 1); + ParseInvalid("[v", 1); ParseInvalid("[", 1); ParseInvalid("[ 640", 1); // It looks like the overflow detection only happens once the whole number @@ -2842,23 +2842,23 @@ TEST(NewSdpTestNoFixture, CheckImageattrXYRangeParseInvalid) ParseInvalid("[99999999999999999:", 18); ParseInvalid("[640", 4); ParseInvalid("[640:", 5); - ParseInvalid("[640:x", 5); + ParseInvalid("[640:v", 5); ParseInvalid("[640:16", 7); ParseInvalid("[640:16:", 8); - ParseInvalid("[640:16:x", 8); + ParseInvalid("[640:16:v", 8); ParseInvalid("[640:16:320]", 11); ParseInvalid("[640:16:320", 11); - ParseInvalid("[640:16:320x", 11); + ParseInvalid("[640:16:320v", 11); ParseInvalid("[640:1024", 9); ParseInvalid("[640:320]", 8); - ParseInvalid("[640:1024x", 9); + ParseInvalid("[640:1024v", 9); ParseInvalid("[640,", 5); - ParseInvalid("[640,x", 5); + ParseInvalid("[640,v", 5); ParseInvalid("[640]", 4); ParseInvalid("[640x", 4); ParseInvalid("[640,]", 5); ParseInvalid(" ", 0); - ParseInvalid("x", 0); + ParseInvalid("v", 0); } static SdpImageattrAttributeList::SRange @@ -2908,31 +2908,31 @@ TEST(NewSdpTestNoFixture, CheckImageattrSRangeParseInvalid) { ParseInvalid("", 0); ParseInvalid("[", 1); - ParseInvalid("[x", 1); + ParseInvalid("[v", 1); ParseInvalid("[-1", 1); ParseInvalid("[", 1); ParseInvalid("[-", 1); - ParseInvalid("[x", 1); + ParseInvalid("[v", 1); ParseInvalid("[ 0.2", 1); ParseInvalid("[10.1-", 5); ParseInvalid("[0.08-", 5); ParseInvalid("[0.2", 4); ParseInvalid("[0.2-", 5); - ParseInvalid("[0.2-x", 5); + ParseInvalid("[0.2-v", 5); ParseInvalid("[0.2--1", 5); ParseInvalid("[0.2-0.3", 8); ParseInvalid("[0.2-0.1]", 8); - ParseInvalid("[0.2-0.3x", 8); + ParseInvalid("[0.2-0.3v", 8); ParseInvalid("[0.2,", 5); - ParseInvalid("[0.2,x", 5); + ParseInvalid("[0.2,v", 5); ParseInvalid("[0.2,-1", 5); ParseInvalid("[0.2]", 4); - ParseInvalid("[0.2x", 4); + ParseInvalid("[0.2v", 4); ParseInvalid("[0.2,]", 5); ParseInvalid("[0.2,-]", 5); ParseInvalid(" ", 0); - ParseInvalid("x", 0); - ParseInvalid("-x", 0); + ParseInvalid("v", 0); + ParseInvalid("-v", 0); ParseInvalid("-1", 0); } @@ -2959,27 +2959,27 @@ TEST(NewSdpTestNoFixture, CheckImageattrPRangeParseInvalid) { ParseInvalid("", 0); ParseInvalid("[", 1); - ParseInvalid("[x", 1); + ParseInvalid("[v", 1); ParseInvalid("[-1", 1); ParseInvalid("[", 1); ParseInvalid("[-", 1); - ParseInvalid("[x", 1); + ParseInvalid("[v", 1); ParseInvalid("[ 0.2", 1); ParseInvalid("[10.1-", 5); ParseInvalid("[0.08-", 5); ParseInvalid("[0.2", 4); ParseInvalid("[0.2-", 5); - ParseInvalid("[0.2-x", 5); + ParseInvalid("[0.2-v", 5); ParseInvalid("[0.2--1", 5); ParseInvalid("[0.2-0.3", 8); ParseInvalid("[0.2-0.1]", 8); - ParseInvalid("[0.2-0.3x", 8); + ParseInvalid("[0.2-0.3v", 8); ParseInvalid("[0.2,", 4); ParseInvalid("[0.2:", 4); ParseInvalid("[0.2]", 4); - ParseInvalid("[0.2x", 4); + ParseInvalid("[0.2v", 4); ParseInvalid(" ", 0); - ParseInvalid("x", 0); + ParseInvalid("v", 0); ParseInvalid("-x", 0); ParseInvalid("-1", 0); } @@ -3131,7 +3131,7 @@ TEST(NewSdpTestNoFixture, CheckImageattrSetParseInvalid) ParseInvalid("[y=", 3); ParseInvalid("[x=[", 4); ParseInvalid("[x=320", 6); - ParseInvalid("[x=320x", 6); + ParseInvalid("[x=320v", 6); ParseInvalid("[x=320,", 7); ParseInvalid("[x=320,=", 8); ParseInvalid("[x=320,x", 8); @@ -3141,15 +3141,15 @@ TEST(NewSdpTestNoFixture, CheckImageattrSetParseInvalid) ParseInvalid("[x=320,y=240x", 12); ParseInvalid("[x=320,y=240,", 13); ParseInvalid("[x=320,y=240,q=", 15); - ParseInvalid("[x=320,y=240,q=x", 15); + ParseInvalid("[x=320,y=240,q=v", 15); ParseInvalid("[x=320,y=240,q=0.5", 18); ParseInvalid("[x=320,y=240,q=0.5,", 19); ParseInvalid("[x=320,y=240,q=0.5,]", 20); ParseInvalid("[x=320,y=240,q=0.5,=]", 20); - ParseInvalid("[x=320,y=240,q=0.5,sar=x]", 23); + ParseInvalid("[x=320,y=240,q=0.5,sar=v]", 23); ParseInvalid("[x=320,y=240,q=0.5,q=0.4", 21); ParseInvalid("[x=320,y=240,sar=", 17); - ParseInvalid("[x=320,y=240,sar=x", 17); + ParseInvalid("[x=320,y=240,sar=v", 17); ParseInvalid( "[x=320,y=240,sar=[0.5-0.6],sar=[0.7-0.8]", 31); ParseInvalid("[x=320,y=240,par=", 17); From a88f23c105e0b22ed722f07039eac65003fbc50d Mon Sep 17 00:00:00 2001 From: Michael Bebenita Date: Thu, 11 Feb 2016 23:49:05 -0800 Subject: [PATCH 041/115] Bug 1247855: Resolve named functions and locals (r=luke) MozReview-Commit-ID: 8yzOQrR2Idj --HG-- extra : rebase_source : e629e389fd0e19fd73fc1d49aa94d465bcad8f36 --- js/src/asmjs/WasmText.cpp | 664 +++++++++++++++++++++++----- js/src/jit-test/tests/wasm/basic.js | 41 ++ 2 files changed, 606 insertions(+), 99 deletions(-) diff --git a/js/src/asmjs/WasmText.cpp b/js/src/asmjs/WasmText.cpp index 7da345f924aa..468a50c29d41 100644 --- a/js/src/asmjs/WasmText.cpp +++ b/js/src/asmjs/WasmText.cpp @@ -44,6 +44,7 @@ using mozilla::PositiveInfinity; using mozilla::SpecificNaN; static const unsigned AST_LIFO_DEFAULT_CHUNK_SIZE = 4096; +static const uint32_t WasmNoIndex = UINT32_MAX; /*****************************************************************************/ // wasm AST @@ -58,8 +59,72 @@ using WasmAstVector = mozilla::Vector>; template using WasmAstHashMap = HashMap>; +class WasmName +{ + const char16_t* begin_; + const char16_t* end_; + public: + WasmName(const char16_t* begin, size_t length) : begin_(begin), end_(begin + length) {} + WasmName() : begin_(nullptr), end_(nullptr) {} + const char16_t* begin() const { return begin_; } + const char16_t* end() const { return end_; } + size_t length() const { MOZ_ASSERT(begin_ != nullptr); return end_ - begin_; } + bool isEmpty() const { return begin_ == nullptr; } +}; + +class WasmRef +{ + WasmName name_; + uint32_t index_; + + public: + WasmRef() + : index_(WasmNoIndex) + { + MOZ_ASSERT(isInvalid()); + } + WasmRef(WasmName name, uint32_t index) + : name_(name), index_(index) + { + MOZ_ASSERT(name.isEmpty() ^ (index == WasmNoIndex)); + MOZ_ASSERT(!isInvalid()); + } + bool isInvalid() const { + return name_.isEmpty() && index_ == WasmNoIndex; + } + WasmName name() const { + return name_; + } + size_t index() const { + MOZ_ASSERT(index_ != WasmNoIndex); + return index_; + } + void setIndex(uint32_t index) { + MOZ_ASSERT(index_ == WasmNoIndex); + index_ = index; + } +}; + +struct WasmNameHasher +{ + typedef const WasmName Lookup; + static js::HashNumber hash(Lookup l) { + return mozilla::HashString(l.begin(), l.length()); + } + static bool match(const WasmName key, Lookup lookup) { + if (key.length() != lookup.length()) + return false; + if (key.begin() == lookup.begin()) + return true; + return EqualChars(key.begin(), lookup.begin(), key.length()); + } +}; + +using WasmNameMap = HashMap; + typedef WasmAstVector WasmAstValTypeVector; typedef WasmAstVector WasmAstExprVector; +typedef mozilla::Vector> WasmNameVector; struct WasmAstBase { @@ -70,6 +135,7 @@ struct WasmAstBase class WasmAstSig : public WasmAstBase { + WasmName name_; WasmAstValTypeVector args_; ExprType ret_; @@ -82,8 +148,9 @@ class WasmAstSig : public WasmAstBase : args_(Move(args)), ret_(ret) {} - WasmAstSig(WasmAstSig&& rhs) - : args_(Move(rhs.args_)), + WasmAstSig(WasmName name, WasmAstSig&& rhs) + : name_(name), + args_(Move(rhs.args_)), ret_(rhs.ret_) {} void operator=(WasmAstSig&& rhs) { @@ -96,6 +163,9 @@ class WasmAstSig : public WasmAstBase ExprType ret() const { return ret_; } + WasmName name() const { + return name_; + } bool operator==(const WasmAstSig& rhs) const { return ret() == rhs.ret() && EqualContainers(args(), rhs.args()); } @@ -171,33 +241,33 @@ class WasmAstConst : public WasmAstExpr class WasmAstGetLocal : public WasmAstExpr { - uint32_t localIndex_; + WasmRef local_; public: static const WasmAstExprKind Kind = WasmAstExprKind::GetLocal; - explicit WasmAstGetLocal(uint32_t localIndex) + explicit WasmAstGetLocal(WasmRef local) : WasmAstExpr(Kind), - localIndex_(localIndex) + local_(local) {} - uint32_t localIndex() const { - return localIndex_; + WasmRef& local() { + return local_; } }; class WasmAstSetLocal : public WasmAstExpr { - uint32_t localIndex_; + WasmRef local_; WasmAstExpr& value_; public: static const WasmAstExprKind Kind = WasmAstExprKind::SetLocal; - WasmAstSetLocal(uint32_t localIndex, WasmAstExpr& value) + WasmAstSetLocal(WasmRef local, WasmAstExpr& value) : WasmAstExpr(Kind), - localIndex_(localIndex), + local_(local), value_(value) {} - uint32_t localIndex() const { - return localIndex_; + WasmRef& local() { + return local_; } WasmAstExpr& value() const { return value_; @@ -221,33 +291,32 @@ class WasmAstBlock : public WasmAstExpr class WasmAstCall : public WasmAstExpr { Expr expr_; - uint32_t index_; + WasmRef func_; WasmAstExprVector args_; public: static const WasmAstExprKind Kind = WasmAstExprKind::Call; - WasmAstCall(Expr expr, uint32_t index, WasmAstExprVector&& args) - : WasmAstExpr(Kind), expr_(expr), index_(index), args_(Move(args)) + WasmAstCall(Expr expr, WasmRef func, WasmAstExprVector&& args) + : WasmAstExpr(Kind), expr_(expr), func_(func), args_(Move(args)) {} Expr expr() const { return expr_; } - uint32_t index() const { return index_; } + WasmRef& func() { return func_; } const WasmAstExprVector& args() const { return args_; } }; class WasmAstCallIndirect : public WasmAstExpr { - uint32_t sigIndex_; + WasmRef sig_; WasmAstExpr* index_; WasmAstExprVector args_; public: static const WasmAstExprKind Kind = WasmAstExprKind::CallIndirect; - WasmAstCallIndirect(uint32_t sigIndex, WasmAstExpr* index, WasmAstExprVector&& args) - : WasmAstExpr(Kind), sigIndex_(sigIndex), index_(index), args_(Move(args)) + WasmAstCallIndirect(WasmRef sig, WasmAstExpr* index, WasmAstExprVector&& args) + : WasmAstExpr(Kind), sig_(sig), index_(index), args_(Move(args)) {} - - uint32_t sigIndex() const { return sigIndex_; } + WasmRef& sig() { return sig_; } WasmAstExpr* index() const { return index_; } const WasmAstExprVector& args() const { return args_; } }; @@ -336,33 +405,42 @@ class WasmAstStore : public WasmAstExpr class WasmAstFunc : public WasmAstNode { - const uint32_t sigIndex_; + WasmName name_; + WasmRef sig_; WasmAstValTypeVector varTypes_; + WasmNameVector varNames_; WasmAstExprVector body_; public: - WasmAstFunc(uint32_t sigIndex, WasmAstValTypeVector&& varTypes, WasmAstExprVector&& body) - : sigIndex_(sigIndex), + WasmAstFunc(WasmName name, WasmRef sig, WasmAstValTypeVector&& varTypes, + WasmNameVector&& varNames, WasmAstExprVector&& body) + : name_(name), + sig_(sig), varTypes_(Move(varTypes)), + varNames_(Move(varNames)), body_(Move(body)) {} - uint32_t sigIndex() const { return sigIndex_; } + WasmRef& sig() { return sig_; } const WasmAstValTypeVector& varTypes() const { return varTypes_; } + const WasmNameVector& varNames() const { return varNames_; } const WasmAstExprVector& body() const { return body_; } + WasmName name() const { return name_; } }; class WasmAstImport : public WasmAstNode { - TwoByteChars module_; - TwoByteChars func_; + WasmName name_; + WasmName module_; + WasmName func_; uint32_t sigIndex_; public: - WasmAstImport(TwoByteChars module, TwoByteChars func, uint32_t sigIndex) - : module_(module), func_(func), sigIndex_(sigIndex) + WasmAstImport(WasmName name, WasmName module, WasmName func, uint32_t sigIndex) + : name_(name), module_(module), func_(func), sigIndex_(sigIndex) {} - TwoByteChars module() const { return module_; } - TwoByteChars func() const { return func_; } + WasmName name() const { return name_; } + WasmName module() const { return module_; } + WasmName func() const { return func_; } uint32_t sigIndex() const { return sigIndex_; } }; @@ -370,27 +448,23 @@ enum class WasmAstExportKind { Func, Memory }; class WasmAstExport : public WasmAstNode { - TwoByteChars name_; + WasmName name_; WasmAstExportKind kind_; - union { - uint32_t funcIndex_; - } u; + WasmRef func_; public: - WasmAstExport(TwoByteChars name, uint32_t funcIndex) - : name_(name), kind_(WasmAstExportKind::Func) - { - u.funcIndex_ = funcIndex; - } - explicit WasmAstExport(TwoByteChars name) + WasmAstExport(WasmName name, WasmRef func) + : name_(name), kind_(WasmAstExportKind::Func), func_(func) + {} + explicit WasmAstExport(WasmName name) : name_(name), kind_(WasmAstExportKind::Memory) {} - TwoByteChars name() const { return name_; } + WasmName name() const { return name_; } WasmAstExportKind kind() const { return kind_; } - size_t funcIndex() const { MOZ_ASSERT(kind_ == WasmAstExportKind::Func); return u.funcIndex_; } + WasmRef& func() { return func_; } }; -typedef WasmAstVector WasmAstTableElemVector; +typedef WasmAstVector WasmAstTableElemVector; class WasmAstTable : public WasmAstNode { @@ -398,20 +472,20 @@ class WasmAstTable : public WasmAstNode public: explicit WasmAstTable(WasmAstTableElemVector&& elems) : elems_(Move(elems)) {} - const WasmAstTableElemVector& elems() const { return elems_; } + WasmAstTableElemVector& elems() { return elems_; } }; class WasmAstSegment : public WasmAstNode { uint32_t offset_; - TwoByteChars text_; + WasmName text_; public: - WasmAstSegment(uint32_t offset, TwoByteChars text) + WasmAstSegment(uint32_t offset, WasmName text) : offset_(offset), text_(text) {} uint32_t offset() const { return offset_; } - TwoByteChars text() const { return text_; } + WasmName text() const { return text_; } }; typedef WasmAstVector WasmAstSegmentVector; @@ -477,7 +551,7 @@ class WasmAstModule : public WasmAstNode return true; } *sigIndex = sigs_.length(); - return sigs_.append(new (lifo_) WasmAstSig(Move(sig))) && + return sigs_.append(new (lifo_) WasmAstSig(WasmName(), Move(sig))) && sigMap_.add(p, sigs_.back(), *sigIndex); } bool append(WasmAstSig* sig) { @@ -514,7 +588,7 @@ class WasmAstModule : public WasmAstNode table_ = table; return true; } - const WasmAstTable* maybeTable() const { + WasmAstTable* maybeTable() const { return table_; } }; @@ -737,12 +811,15 @@ class WasmToken const char16_t* end() const { return end_; } - TwoByteChars text() const { + WasmName text() const { MOZ_ASSERT(kind_ == Text); MOZ_ASSERT(begin_[0] == '"'); MOZ_ASSERT(end_[-1] == '"'); MOZ_ASSERT(end_ - begin_ >= 2); - return TwoByteChars(begin_ + 1, end_ - begin_ - 2); + return WasmName(begin_ + 1, end_ - begin_ - 2); + } + WasmName name() const { + return WasmName(begin_, end_ - begin_); } uint32_t index() const { MOZ_ASSERT(kind_ == Index); @@ -985,7 +1062,6 @@ class WasmTokenStream unsigned column = token.begin() - lineStart_ + 1; error->reset(JS_smprintf("parsing wasm text at %u:%u", line_, column)); } - WasmToken peek() { if (!lookaheadDepth_) { lookahead_[lookaheadIndex_] = next(); @@ -1020,7 +1096,35 @@ class WasmTokenStream } bool getIf(WasmToken::Kind kind) { WasmToken token; - return getIf(kind, &token); + if (getIf(kind, &token)) + return true; + return false; + } + WasmName getIfName() { + WasmToken token; + if (getIf(WasmToken::Name, &token)) + return token.name(); + return WasmName(); + } + bool getRef(WasmRef* ref) { + WasmToken token = get(); + switch (token.kind()) { + case WasmToken::Name: + *ref = WasmRef(token.name(), WasmNoIndex); + break; + case WasmToken::Index: + *ref = WasmRef(WasmName(), token.index()); + break; + default: + return false; + } + return true; + } + bool getIfRef(WasmRef* ref) { + WasmToken token = peek(); + if (token.kind() == WasmToken::Name || token.kind() == WasmToken::Index) + return getRef(ref); + return false; } bool match(WasmToken::Kind expect, WasmToken* token, UniqueChars* error) { *token = get(); @@ -1719,6 +1823,10 @@ struct WasmParseContext dtoaState(NewDtoaState()) {} + bool fail(const char* message) { + error->reset(JS_smprintf(message)); + return false; + } ~WasmParseContext() { DestroyDtoaState(dtoaState); } @@ -1778,22 +1886,22 @@ ParseCall(WasmParseContext& c, Expr expr) { MOZ_ASSERT(expr == Expr::Call || expr == Expr::CallImport); - WasmToken index; - if (!c.ts.match(WasmToken::Index, &index, c.error)) + WasmRef func; + if (!c.ts.getRef(&func)) return nullptr; WasmAstExprVector args(c.lifo); if (!ParseArgs(c, &args)) return nullptr; - return new(c.lifo) WasmAstCall(expr, index.index(), Move(args)); + return new(c.lifo) WasmAstCall(expr, func, Move(args)); } static WasmAstCallIndirect* ParseCallIndirect(WasmParseContext& c) { - WasmToken sigIndex; - if (!c.ts.match(WasmToken::Index, &sigIndex, c.error)) + WasmRef sig; + if (!c.ts.getRef(&sig)) return nullptr; WasmAstExpr* index = ParseExpr(c); @@ -1804,7 +1912,7 @@ ParseCallIndirect(WasmParseContext& c) if (!ParseArgs(c, &args)) return nullptr; - return new(c.lifo) WasmAstCallIndirect(sigIndex.index(), index, Move(args)); + return new(c.lifo) WasmAstCallIndirect(sig, index, Move(args)); } static uint_fast8_t @@ -2110,25 +2218,25 @@ ParseConst(WasmParseContext& c, WasmToken constToken) static WasmAstGetLocal* ParseGetLocal(WasmParseContext& c) { - WasmToken localIndex; - if (!c.ts.match(WasmToken::Index, &localIndex, c.error)) + WasmRef local; + if (!c.ts.getRef(&local)) return nullptr; - return new(c.lifo) WasmAstGetLocal(localIndex.index()); + return new(c.lifo) WasmAstGetLocal(local); } static WasmAstSetLocal* ParseSetLocal(WasmParseContext& c) { - WasmToken localIndex; - if (!c.ts.match(WasmToken::Index, &localIndex, c.error)) + WasmRef local; + if (!c.ts.getRef(&local)) return nullptr; WasmAstExpr* value = ParseExpr(c); if (!value) return nullptr; - return new(c.lifo) WasmAstSetLocal(localIndex.index(), *value); + return new(c.lifo) WasmAstSetLocal(local, *value); } static WasmAstUnaryOperator* @@ -2397,24 +2505,22 @@ ParseResult(WasmParseContext& c, ExprType* result) return true; } -static const uint32_t BadSigIndex = UINT32_MAX; - static WasmAstFunc* ParseFunc(WasmParseContext& c, WasmAstModule* module) { WasmAstValTypeVector vars(c.lifo); WasmAstValTypeVector args(c.lifo); - ExprType result = ExprType::Void; + WasmNameVector varNames(c.lifo); - uint32_t sigIndex = BadSigIndex; + WasmName funcName = c.ts.getIfName(); + + WasmRef sig; WasmToken openParen; if (c.ts.getIf(WasmToken::OpenParen, &openParen)) { if (c.ts.getIf(WasmToken::Type)) { - WasmToken sigToken; - if (!c.ts.match(WasmToken::Index, &sigToken, c.error)) + if (!c.ts.getRef(&sig)) return nullptr; - sigIndex = sigToken.index(); if (!c.ts.match(WasmToken::CloseParen, c.error)) return nullptr; } else { @@ -2423,18 +2529,20 @@ ParseFunc(WasmParseContext& c, WasmAstModule* module) } WasmAstExprVector body(c.lifo); + ExprType result = ExprType::Void; while (c.ts.getIf(WasmToken::OpenParen)) { WasmToken token = c.ts.get(); switch (token.kind()) { case WasmToken::Local: - if (!ParseValueType(c, &vars)) - return nullptr; - break; - case WasmToken::Param: - if (!ParseValueType(c, &args)) + case WasmToken::Param: { + WasmName name = c.ts.getIfName(); + if (!varNames.append(name)) + return nullptr; + if (!ParseValueType(c, token.kind() == WasmToken::Local ? &vars : &args)) return nullptr; break; + } case WasmToken::Result: if (!ParseResult(c, &result)) return nullptr; @@ -2450,12 +2558,14 @@ ParseFunc(WasmParseContext& c, WasmAstModule* module) return nullptr; } - if (sigIndex == BadSigIndex) { + if (sig.isInvalid()) { + uint32_t sigIndex; if (!module->declare(WasmAstSig(Move(args), result), &sigIndex)) return nullptr; + sig.setIndex(sigIndex); } - return new(c.lifo) WasmAstFunc(sigIndex, Move(vars), Move(body)); + return new(c.lifo) WasmAstFunc(funcName, sig, Move(vars), Move(varNames), Move(body)); } static bool @@ -2490,6 +2600,8 @@ ParseFuncType(WasmParseContext& c, WasmAstSig* sig) static WasmAstSig* ParseTypeDef(WasmParseContext& c) { + WasmName name = c.ts.getIfName(); + if (!c.ts.match(WasmToken::OpenParen, c.error)) return nullptr; if (!c.ts.match(WasmToken::Func, c.error)) @@ -2502,7 +2614,7 @@ ParseTypeDef(WasmParseContext& c) if (!c.ts.match(WasmToken::CloseParen, c.error)) return nullptr; - return new(c.lifo) WasmAstSig(Move(sig)); + return new(c.lifo) WasmAstSig(name, Move(sig)); } static WasmAstSegment* @@ -2544,6 +2656,8 @@ ParseMemory(WasmParseContext& c) static WasmAstImport* ParseImport(WasmParseContext& c, WasmAstModule* module) { + WasmName name = c.ts.getIfName(); + WasmToken moduleName; if (!c.ts.match(WasmToken::Text, &moduleName, c.error)) return nullptr; @@ -2560,7 +2674,7 @@ ParseImport(WasmParseContext& c, WasmAstModule* module) if (!module->declare(Move(sig), &sigIndex)) return nullptr; - return new(c.lifo) WasmAstImport(moduleName.text(), funcName.text(), sigIndex); + return new(c.lifo) WasmAstImport(name, moduleName.text(), funcName.text(), sigIndex); } static WasmAstExport* @@ -2573,7 +2687,9 @@ ParseExport(WasmParseContext& c) WasmToken exportee = c.ts.get(); switch (exportee.kind()) { case WasmToken::Index: - return new(c.lifo) WasmAstExport(name.text(), exportee.index()); + return new(c.lifo) WasmAstExport(name.text(), WasmRef(WasmName(), exportee.index())); + case WasmToken::Name: + return new(c.lifo) WasmAstExport(name.text(), WasmRef(exportee.name(), WasmNoIndex)); case WasmToken::Memory: return new(c.lifo) WasmAstExport(name.text()); default: @@ -2590,9 +2706,9 @@ ParseTable(WasmParseContext& c) { WasmAstTableElemVector elems(c.lifo); - WasmToken token; - while (c.ts.getIf(WasmToken::Index, &token)) { - if (!elems.append(token.index())) + WasmRef elem; + while (c.ts.getIfRef(&elem)) { + if (!elems.append(elem)) return nullptr; } @@ -2680,6 +2796,352 @@ ParseModule(const char16_t* text, LifoAlloc& lifo, UniqueChars* error) } // end anonymous namespace +/*****************************************************************************/ +// wasm name resolution + +namespace { + +class Resolver +{ + UniqueChars* error_; + WasmNameMap varMap_; + WasmNameMap sigMap_; + WasmNameMap funcMap_; + WasmNameMap importMap_; + + bool registerName(WasmNameMap& map, WasmName name, size_t index) { + WasmNameMap::AddPtr p = map.lookupForAdd(name); + if (!p) { + if (!map.add(p, name, index)) + return false; + } else { + return false; + } + return true; + } + bool resolveName(WasmNameMap& map, WasmName name, size_t* index) { + WasmNameMap::Ptr p = map.lookup(name); + if (p) { + *index = p->value(); + return true; + } + return false; + } + bool resolveRef(WasmNameMap& map, WasmRef& ref) { + WasmNameMap::Ptr p = map.lookup(ref.name()); + if (p) { + ref.setIndex(p->value()); + return true; + } + return false; + } + + public: + explicit Resolver(UniqueChars* error) + : error_(error) + {} + bool init() { + return sigMap_.init() && funcMap_.init() && importMap_.init() && varMap_.init(); + } + void beginFunc() { + varMap_.clear(); + } + bool registerSigName(WasmName name, size_t index) { + return registerName(sigMap_, name, index); + } + bool registerFuncName(WasmName name, size_t index) { + return registerName(funcMap_, name, index); + } + bool registerImportName(WasmName name, size_t index) { + return registerName(importMap_, name, index); + } + bool registerVarName(WasmName name, size_t index) { + return registerName(varMap_, name, index); + } + bool resolveSigRef(WasmRef& ref) { + return resolveRef(sigMap_, ref); + } + bool resolveFuncRef(WasmRef& ref) { + return resolveRef(funcMap_, ref); + } + bool resolveImportRef(WasmRef& ref) { + return resolveRef(importMap_, ref); + } + bool resolveVarRef(WasmRef& ref) { + return resolveRef(varMap_, ref); + } + bool fail(const char*message) { + error_->reset(JS_smprintf("%s", message)); + return false; + } +}; + +} // end anonymous namespace + +static bool +ResolveExpr(Resolver& r, WasmAstExpr& expr); + +static bool +ResolveBlock(Resolver& r, WasmAstBlock& b) +{ + size_t numExprs = b.exprs().length(); + for (size_t i = 0; i < numExprs; i++) { + if (!ResolveExpr(r, *b.exprs()[i])) + return false; + } + + return true; +} + +static bool +ResolveArgs(Resolver& r, const WasmAstExprVector& args) +{ + for (WasmAstExpr* arg : args) { + if (!ResolveExpr(r, *arg)) + return false; + } + + return true; +} + +static bool +ResolveCall(Resolver& r, WasmAstCall& c) +{ + if (!ResolveArgs(r, c.args())) + return false; + + if (c.func().name().isEmpty()) + return true; + + if (c.expr() == Expr::Call ? !r.resolveFuncRef(c.func()) + : !r.resolveImportRef(c.func())) { + return r.fail("function not found"); + } + + return true; +} + +static bool +ResolveCallIndirect(Resolver& r, WasmAstCallIndirect& c) +{ + if (!ResolveExpr(r, *c.index())) + return false; + + if (!ResolveArgs(r, c.args())) + return false; + + if (c.sig().name().isEmpty()) + return true; + + if (!r.resolveSigRef(c.sig())) + return r.fail("signature not found"); + + return true; +} + +static bool +ResolveGetLocal(Resolver& r, WasmAstGetLocal& gl) +{ + if (gl.local().name().isEmpty()) + return true; + + if (!r.resolveVarRef(gl.local())) + return r.fail("local not found"); + + return true; +} + +static bool +ResolveSetLocal(Resolver& r, WasmAstSetLocal& sl) +{ + if (!ResolveExpr(r, sl.value())) + return false; + + if (sl.local().name().isEmpty()) + return true; + + if (!r.resolveVarRef(sl.local())) + return r.fail("local not found"); + + return true; +} + +static bool +ResolveUnaryOperator(Resolver& r, WasmAstUnaryOperator& b) +{ + return ResolveExpr(r, *b.op()); +} + +static bool +ResolveBinaryOperator(Resolver& r, WasmAstBinaryOperator& b) +{ + return ResolveExpr(r, *b.lhs()) && + ResolveExpr(r, *b.rhs()); +} + +static bool +ResolveComparisonOperator(Resolver& r, WasmAstComparisonOperator& b) +{ + return ResolveExpr(r, *b.lhs()) && + ResolveExpr(r, *b.rhs()); +} + +static bool +ResolveConversionOperator(Resolver& r, WasmAstConversionOperator& b) +{ + return ResolveExpr(r, *b.op()); +} + +static bool +ResolveIfElse(Resolver& r, WasmAstIfElse& ie) +{ + return ResolveExpr(r, ie.cond()) && + ResolveExpr(r, ie.ifBody()) && + (!ie.hasElse() || ResolveExpr(r, ie.elseBody())); +} + +static bool +ResolveLoadStoreAddress(Resolver& r, const WasmAstLoadStoreAddress &address) +{ + return ResolveExpr(r, address.base()); +} + +static bool +ResolveLoad(Resolver& r, WasmAstLoad& l) +{ + return ResolveLoadStoreAddress(r, l.address()); +} + +static bool +ResolveStore(Resolver& r, WasmAstStore& s) +{ + return ResolveLoadStoreAddress(r, s.address()) && + ResolveExpr(r, s.value()); +} + +static bool +ResolveExpr(Resolver& r, WasmAstExpr& expr) +{ + switch (expr.kind()) { + case WasmAstExprKind::Nop: + return true; + case WasmAstExprKind::BinaryOperator: + return ResolveBinaryOperator(r, expr.as()); + case WasmAstExprKind::Block: + return ResolveBlock(r, expr.as()); + case WasmAstExprKind::Call: + return ResolveCall(r, expr.as()); + case WasmAstExprKind::CallIndirect: + return ResolveCallIndirect(r, expr.as()); + case WasmAstExprKind::ComparisonOperator: + return ResolveComparisonOperator(r, expr.as()); + case WasmAstExprKind::Const: + return true; + case WasmAstExprKind::ConversionOperator: + return ResolveConversionOperator(r, expr.as()); + case WasmAstExprKind::GetLocal: + return ResolveGetLocal(r, expr.as()); + case WasmAstExprKind::IfElse: + return ResolveIfElse(r, expr.as()); + case WasmAstExprKind::Load: + return ResolveLoad(r, expr.as()); + case WasmAstExprKind::SetLocal: + return ResolveSetLocal(r, expr.as()); + case WasmAstExprKind::Store: + return ResolveStore(r, expr.as()); + case WasmAstExprKind::UnaryOperator: + return ResolveUnaryOperator(r, expr.as()); + default:; + } + MOZ_CRASH("Bad expr kind"); +} + +static bool +ResolveFunc(Resolver& r, WasmAstFunc& func) +{ + r.beginFunc(); + + size_t numVars = func.varNames().length(); + for (size_t i = 0; i < numVars; i++) { + WasmName name = func.varNames()[i]; + if (name.isEmpty()) + continue; + if (!r.registerVarName(name, i)) + return r.fail("duplicate var"); + } + + for (WasmAstExpr* expr : func.body()) { + if (!ResolveExpr(r, *expr)) + return false; + } + return true; +} + +static bool +ResolveModule(LifoAlloc& lifo, WasmAstModule* module, UniqueChars* error) +{ + Resolver r(error); + + if (!r.init()) + return false; + + size_t numSigs = module->sigs().length(); + for (size_t i = 0; i < numSigs; i++) { + WasmAstSig* sig = module->sigs()[i]; + if (sig->name().isEmpty()) + continue; + if (!r.registerSigName(sig->name(), i)) + return r.fail("duplicate signature"); + } + + size_t numFuncs = module->funcs().length(); + for (size_t i = 0; i < numFuncs; i++) { + WasmAstFunc* func = module->funcs()[i]; + if (!func->sig().name().isEmpty()) { + if (!r.resolveSigRef(func->sig())) + return r.fail("signature not found"); + } + if (func->name().isEmpty()) + continue; + if (!r.registerFuncName(func->name(), i)) + return r.fail("duplicate function"); + } + + if (module->maybeTable()) { + for (WasmRef& ref : module->maybeTable()->elems()) { + if (ref.name().isEmpty()) + continue; + if (!r.resolveFuncRef(ref)) + return r.fail("function not found"); + } + } + + size_t numImports = module->imports().length(); + for (size_t i = 0; i < numImports; i++) { + WasmAstImport* imp = module->imports()[i]; + if (imp->name().isEmpty()) + continue; + if (!r.registerImportName(imp->name(), i)) + return r.fail("duplicate import"); + } + + for (WasmAstExport* export_ : module->exports()) { + if (export_->kind() != WasmAstExportKind::Func) + continue; + if (export_->func().name().isEmpty()) + continue; + if (!r.resolveFuncRef(export_->func())) + return r.fail("function not found"); + } + + for (WasmAstFunc* func : module->funcs()) { + if (!ResolveFunc(r, *func)) + return false; + } + + return true; +} + /*****************************************************************************/ // wasm function body serialization @@ -2721,7 +3183,7 @@ EncodeCall(Encoder& e, WasmAstCall& c) if (!e.writeExpr(c.expr())) return false; - if (!e.writeVarU32(c.index())) + if (!e.writeVarU32(c.func().index())) return false; if (!EncodeArgs(e, c.args())) @@ -2736,7 +3198,7 @@ EncodeCallIndirect(Encoder& e, WasmAstCallIndirect& c) if (!e.writeExpr(Expr::CallIndirect)) return false; - if (!e.writeVarU32(c.sigIndex())) + if (!e.writeVarU32(c.sig().index())) return false; if (!EncodeExpr(e, *c.index())) @@ -2774,14 +3236,14 @@ static bool EncodeGetLocal(Encoder& e, WasmAstGetLocal& gl) { return e.writeExpr(Expr::GetLocal) && - e.writeVarU32(gl.localIndex()); + e.writeVarU32(gl.local().index()); } static bool EncodeSetLocal(Encoder& e, WasmAstSetLocal& sl) { return e.writeExpr(Expr::SetLocal) && - e.writeVarU32(sl.localIndex()) && + e.writeVarU32(sl.local().index()) && EncodeExpr(e, sl.value()); } @@ -2937,7 +3399,7 @@ EncodeDeclarationSection(Encoder& e, WasmAstModule& module) return false; for (WasmAstFunc* func : module.funcs()) { - if (!e.writeVarU32(func->sigIndex())) + if (!e.writeVarU32(func->sig().index())) return false; } @@ -2946,9 +3408,10 @@ EncodeDeclarationSection(Encoder& e, WasmAstModule& module) } static bool -EncodeCString(Encoder& e, TwoByteChars twoByteChars) +EncodeCString(Encoder& e, WasmName wasmName) { - UniqueChars utf8(JS::CharsToNewUTF8CharsZ(nullptr, twoByteChars).c_str()); + TwoByteChars range(wasmName.begin(), wasmName.length()); + UniqueChars utf8(JS::CharsToNewUTF8CharsZ(nullptr, range).c_str()); return utf8 && e.writeCString(utf8.get()); } @@ -3025,7 +3488,7 @@ EncodeMemorySection(Encoder& e, WasmAstModule& module) static bool EncodeFunctionExport(Encoder& e, WasmAstExport& exp) { - if (!e.writeVarU32(exp.funcIndex())) + if (!e.writeVarU32(exp.func().index())) return false; if (!EncodeCString(e, exp.name())) @@ -3096,8 +3559,8 @@ EncodeTableSection(Encoder& e, WasmAstModule& module) if (!e.writeVarU32(module.maybeTable()->elems().length())) return false; - for (uint32_t index : module.maybeTable()->elems()) { - if (!e.writeVarU32(index)) + for (WasmRef& ref : module.maybeTable()->elems()) { + if (!e.writeVarU32(ref.index())) return false; } @@ -3142,14 +3605,14 @@ EncodeDataSegment(Encoder& e, WasmAstSegment& segment) if (!e.writeVarU32(segment.offset())) return false; - TwoByteChars text = segment.text(); + WasmName text = segment.text(); Vector bytes; if (!bytes.reserve(text.length())) return false; - const char16_t* cur = text.start().get(); - const char16_t* end = text.end().get(); + const char16_t* cur = text.begin(); + const char16_t* end = text.end(); while (cur != end) { uint8_t byte; MOZ_ALWAYS_TRUE(ConsumeTextByte(&cur, end, &byte)); @@ -3251,5 +3714,8 @@ wasm::TextToBinary(const char16_t* text, UniqueChars* error) if (!module) return nullptr; + if (!ResolveModule(lifo, module, error)) + return nullptr; + return EncodeModule(*module); } diff --git a/js/src/jit-test/tests/wasm/basic.js b/js/src/jit-test/tests/wasm/basic.js index b1de3f9bb36a..3db98b4a1d17 100644 --- a/js/src/jit-test/tests/wasm/basic.js +++ b/js/src/jit-test/tests/wasm/basic.js @@ -46,6 +46,11 @@ assertEq(desc.value(), undefined); wasmEvalText('(module (func) (func) (export "a" 0))'); wasmEvalText('(module (func) (func) (export "a" 1))'); +wasmEvalText('(module (func $a) (func $b) (export "a" $a) (export "b" $b))'); +wasmEvalText('(module (func $a) (func $b) (export "a" $a) (export "b" $b))'); +assertErrorMessage(() => wasmEvalText('(module (func $a) (func) (export "a" $a) (export "b" $b))'), SyntaxError, /function not found/); +assertErrorMessage(() => wasmEvalText('(module (func $foo) (func $foo))'), SyntaxError, /duplicate function/); + assertErrorMessage(() => wasmEvalText('(module (func) (export "a" 1))'), TypeError, /export function index out of range/); assertErrorMessage(() => wasmEvalText('(module (func) (func) (export "a" 2))'), TypeError, /export function index out of range/); @@ -92,6 +97,7 @@ assertErrorMessage(() => wasmEvalText('(module (func (result i64)))'), TypeError assertErrorMessage(() => wasmEvalText('(module (import "a" "b"))', 1), Error, /Second argument, if present, must be an Object/); assertErrorMessage(() => wasmEvalText('(module (import "a" "b"))', null), Error, /Second argument, if present, must be an Object/); +assertErrorMessage(() => wasmEvalText('(module (import $foo "a" "b") (import $foo "a" "b"))'), SyntaxError, /duplicate import/); const noImportObj = /no import object given/; const notObject = /import object field is not an Object/; @@ -121,6 +127,7 @@ wasmEvalText(code, {a:()=>{}, b:{c:()=>{}}, c:()=>{}}); wasmEvalText('(module (import "a" "" (result i32)))', {a: ()=> {}}); wasmEvalText('(module (import "a" "" (result f32)))', {a: ()=> {}}); wasmEvalText('(module (import "a" "" (result f64)))', {a: ()=> {}}); +wasmEvalText('(module (import $foo "a" "" (result f64)))', {a: ()=> {}}); // ---------------------------------------------------------------------------- // memory @@ -221,6 +228,11 @@ assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (get_ assertErrorMessage(() => wasmEvalText('(module (func (local i64)))'), TypeError, /NYI/); +assertEq(wasmEvalText('(module (func (param $a i32) (result i32) (get_local $a)) (export "" 0))')(), 0); +assertEq(wasmEvalText('(module (func (param $a i32) (local $b i32) (result i32) (block (set_local $b (get_local $a)) (get_local $b))) (export "" 0))')(42), 42); +assertErrorMessage(() => wasmEvalText('(module (func (param $a i32) (local $a i32)))'), SyntaxError, /duplicate var/); +assertErrorMessage(() => wasmEvalText('(module (func (get_local $a)))'), SyntaxError, /local not found/); + // ---------------------------------------------------------------------------- // blocks @@ -336,3 +348,32 @@ for (bad of [6, 7, 100, Math.pow(2,31)-1, Math.pow(2,31), Math.pow(2,31)+1, Math assertThrowsInstanceOf(() => i2i(bad, 0), RangeError); assertThrowsInstanceOf(() => i2v(bad, 0), RangeError); } + +assertErrorMessage(() => wasmEvalText('(module (type $a (func)) (type $a (func (param i32))))'), SyntaxError, /duplicate signature/); +assertErrorMessage(() => wasmEvalText('(module (type $a (func)) (func (type $b) (i32.const 13)))'), SyntaxError, /signature not found/); +assertErrorMessage(() => wasmEvalText('(module (type $a (func)) (func (call_indirect $c (get_local 0) (i32.const 0))))'), SyntaxError, /signature not found/); + +var {v2i, i2i, i2v} = wasmEvalText(`(module + (type $a (func (result i32))) + (type $b (func (param i32) (result i32))) + (type $c (func (param i32))) + (func $a (type $a) (i32.const 13)) + (func $b (type $a) (i32.const 42)) + (func $c (type $b) (i32.add (get_local 0) (i32.const 1))) + (func $d (type $b) (i32.add (get_local 0) (i32.const 2))) + (func $e (type $b) (i32.add (get_local 0) (i32.const 3))) + (func $f (type $b) (i32.add (get_local 0) (i32.const 4))) + (table $a $b $c $d $e $f) + (func (param i32) (result i32) (call_indirect $a (get_local 0))) + (func (param i32) (param i32) (result i32) (call_indirect $b (get_local 0) (get_local 1))) + (func (param i32) (call_indirect $c (get_local 0) (i32.const 0))) + (export "v2i" 6) + (export "i2i" 7) + (export "i2v" 8) +)`); + +wasmEvalText('(module (func $foo (nop)) (func (call $foo)))'); +wasmEvalText('(module (func (call $foo)) (func $foo (nop)))'); +wasmEvalText('(module (import $bar "a" "") (func (call_import $bar)) (func $foo (nop)))', {a:()=>{}}); +assertErrorMessage(() => wasmEvalText('(module (import "a" "") (func (call_import $abc)))'), SyntaxError, /function not found/); + From ab744ac5a1cbf69d2c0070e195410c316e621538 Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Thu, 11 Feb 2016 15:00:22 -0500 Subject: [PATCH 042/115] Bug 698882 - mozilla::net::PollableEvent r=dragana r=mayhemer --- netwerk/base/PollableEvent.cpp | 163 +++++++++++++++++++++ netwerk/base/PollableEvent.h | 38 +++++ netwerk/base/moz.build | 1 + netwerk/base/nsSocketTransportService2.cpp | 122 +++++++-------- netwerk/base/nsSocketTransportService2.h | 20 +-- netwerk/standalone/moz.build | 1 + 6 files changed, 272 insertions(+), 73 deletions(-) create mode 100644 netwerk/base/PollableEvent.cpp create mode 100644 netwerk/base/PollableEvent.h diff --git a/netwerk/base/PollableEvent.cpp b/netwerk/base/PollableEvent.cpp new file mode 100644 index 000000000000..825977bd5c99 --- /dev/null +++ b/netwerk/base/PollableEvent.cpp @@ -0,0 +1,163 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsSocketTransportService2.h" +#include "PollableEvent.h" +#include "mozilla/Assertions.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/Logging.h" +#include "prerror.h" +#include "prio.h" +#include "private/pprio.h" + +#ifdef XP_WIN +#include "ShutdownLayer.h" +#else +#include +#define USEPIPE 1 +#endif + +namespace mozilla { +namespace net { + +PollableEvent::PollableEvent() + : mWriteFD(nullptr) + , mReadFD(nullptr) + , mSignaled(false) +{ + // create pair of prfiledesc that can be used as a poll()ble + // signal. on windows use a localhost socket pair, and on + // unix use a pipe. +#ifdef USEPIPE + if (PR_CreatePipe(&mReadFD, &mWriteFD) == PR_SUCCESS) { + // make the pipe non blocking. NSPR asserts at + // trying to use SockOpt here + PROsfd fd = PR_FileDesc2NativeHandle(mReadFD); + int flags = fcntl(fd, F_GETFL, 0); + (void)fcntl(fd, F_SETFL, flags | O_NONBLOCK); + fd = PR_FileDesc2NativeHandle(mWriteFD); + flags = fcntl(fd, F_GETFL, 0); + (void)fcntl(fd, F_SETFL, flags | O_NONBLOCK); + } else { + mReadFD = nullptr; + mWriteFD = nullptr; + SOCKET_LOG(("PollableEvent() pipe failed\n")); + } +#else + PRFileDesc *fd[2]; + if (PR_NewTCPSocketPair(fd) == PR_SUCCESS) { + mReadFD = fd[0]; + mWriteFD = fd[1]; + + PRSocketOptionData opt; + DebugOnly status; + opt.option = PR_SockOpt_NoDelay; + opt.value.no_delay = true; + PR_SetSocketOption(mWriteFD, &opt); + PR_SetSocketOption(mReadFD, &opt); + opt.option = PR_SockOpt_Nonblocking; + opt.value.non_blocking = true; + status = PR_SetSocketOption(mWriteFD, &opt); + MOZ_ASSERT(status == PR_SUCCESS); + status = PR_SetSocketOption(mReadFD, &opt); + MOZ_ASSERT(status == PR_SUCCESS); + } else { + SOCKET_LOG(("PollableEvent() socketpair failed\n")); + } +#endif + + if (mReadFD && mWriteFD) { + // prime the system to deal with races invovled in [dc]tor cycle + SOCKET_LOG(("PollableEvent() ctor ok\n")); + mSignaled = true; + PR_Write(mWriteFD, "I", 1); + } +} + +PollableEvent::~PollableEvent() +{ + if (mWriteFD) { +#if defined(XP_WIN) + mozilla::net::AttachShutdownLayer(mWriteFD); +#endif + PR_Close(mWriteFD); + } + if (mReadFD) { +#if defined(XP_WIN) + mozilla::net::AttachShutdownLayer(mReadFD); +#endif + PR_Close(mReadFD); + } +} + +// we do not record signals on the socket thread +// because the socket thread can reliably look at its +// own runnable queue before selecting a poll time +// this is the "service the network without blocking" comment in +// nsSocketTransportService2.cpp +bool +PollableEvent::Signal() +{ + SOCKET_LOG(("PollableEvent::Signal\n")); + + if (!mWriteFD) { + SOCKET_LOG(("PollableEvent::Signal Failed on no FD\n")); + return false; + } + if (PR_GetCurrentThread() == gSocketThread) { + SOCKET_LOG(("PollableEvent::Signal OnSocketThread nop\n")); + return true; + } + if (mSignaled) { + return true; + } + mSignaled = true; + int32_t status = PR_Write(mWriteFD, "M", 1); + if (status != 1) { + NS_WARNING("PollableEvent::Signal Failed\n"); + SOCKET_LOG(("PollableEvent::Signal Failed\n")); + } + return (status == 1); +} + +bool +PollableEvent::Clear() +{ + // necessary because of the "dont signal on socket thread" optimization + MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); + + SOCKET_LOG(("PollableEvent::Clear\n")); + mSignaled = false; + if (!mReadFD) { + SOCKET_LOG(("PollableEvent::Clear mReadFD is null\n")); + return false; + } + char buf[2048]; + int32_t status = PR_Read(mReadFD, buf, 2048); + + if (status == 1) { + return true; + } + if (status == 0) { + SOCKET_LOG(("PollableEvent::Clear EOF!\n")); + return false; + } + if (status > 1) { + MOZ_ASSERT(false); + SOCKET_LOG(("PollableEvent::Clear Unexpected events\n")); + Clear(); + return true; + } + PRErrorCode code = PR_GetError(); + if (code == PR_WOULD_BLOCK_ERROR) { + return true; + } + SOCKET_LOG(("PollableEvent::Clear unexpected error %d\n", code)); + return false; +} + +} // namespace net +} // namespace mozilla diff --git a/netwerk/base/PollableEvent.h b/netwerk/base/PollableEvent.h new file mode 100644 index 000000000000..80007993200d --- /dev/null +++ b/netwerk/base/PollableEvent.h @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef PollableEvent_h__ +#define PollableEvent_h__ + +#include "mozilla/Mutex.h" + +namespace mozilla { +namespace net { + +// class must be called locked +class PollableEvent +{ +public: + PollableEvent(); + ~PollableEvent(); + + // Signal/Clear return false only if they fail + bool Signal(); + bool Clear(); + bool Valid() { return mWriteFD && mReadFD; } + + PRFileDesc *PollableFD() { return mReadFD; } + +private: + PRFileDesc *mWriteFD; + PRFileDesc *mReadFD; + bool mSignaled; +}; + +} // namespace net +} // namespace mozilla + +#endif diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index 3426159ddae9..da47fe601825 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -249,6 +249,7 @@ UNIFIED_SOURCES += [ 'nsURLHelper.cpp', 'nsURLParsers.cpp', 'OfflineObserver.cpp', + 'PollableEvent.cpp', 'Predictor.cpp', 'ProxyAutoConfig.cpp', 'RedirectChannelRegistrar.cpp', diff --git a/netwerk/base/nsSocketTransportService2.cpp b/netwerk/base/nsSocketTransportService2.cpp index 6f036616fbf0..17f9ee39fa91 100644 --- a/netwerk/base/nsSocketTransportService2.cpp +++ b/netwerk/base/nsSocketTransportService2.cpp @@ -89,13 +89,13 @@ DebugMutexAutoLock::~DebugMutexAutoLock() nsSocketTransportService::nsSocketTransportService() : mThread(nullptr) - , mThreadEvent(nullptr) , mAutodialEnabled(false) , mLock("nsSocketTransportService::mLock") , mInitialized(false) , mShuttingDown(false) , mOffline(false) , mGoingOffline(false) + , mRawThread(nullptr) , mActiveListSize(SOCKET_LIMIT_MIN) , mIdleListSize(SOCKET_LIMIT_MIN) , mActiveCount(0) @@ -133,9 +133,6 @@ nsSocketTransportService::~nsSocketTransportService() { NS_ASSERTION(NS_IsMainThread(), "wrong thread"); NS_ASSERTION(!mInitialized, "not shutdown properly"); - - if (mThreadEvent) - PR_DestroyPollableEvent(mThreadEvent); free(mActiveList); free(mIdleList); @@ -437,7 +434,7 @@ nsSocketTransportService::PollTimeout() } int32_t -nsSocketTransportService::Poll(bool wait, uint32_t *interval, +nsSocketTransportService::Poll(uint32_t *interval, TimeDuration *pollDuration) { PRPollDesc *pollList; @@ -445,11 +442,16 @@ nsSocketTransportService::Poll(bool wait, uint32_t *interval, PRIntervalTime pollTimeout; *pollDuration = 0; + // If there are pending events for this thread then + // DoPollIteration() should service the network without blocking. + bool pendingEvents = false; + mRawThread->HasPendingEvents(&pendingEvents); + if (mPollList[0].fd) { mPollList[0].out_flags = 0; pollList = mPollList; pollCount = mActiveCount + 1; - pollTimeout = PollTimeout(); + pollTimeout = pendingEvents ? PR_INTERVAL_NO_WAIT : PollTimeout(); } else { // no pollable event, so busy wait... @@ -458,12 +460,10 @@ nsSocketTransportService::Poll(bool wait, uint32_t *interval, pollList = &mPollList[1]; else pollList = nullptr; - pollTimeout = PR_MillisecondsToInterval(25); + pollTimeout = + pendingEvents ? PR_INTERVAL_NO_WAIT : PR_MillisecondsToInterval(25); } - if (!wait) - pollTimeout = PR_INTERVAL_NO_WAIT; - PRIntervalTime ts = PR_IntervalNow(); TimeStamp pollStart; @@ -515,19 +515,20 @@ nsSocketTransportService::Init() if (mShuttingDown) return NS_ERROR_UNEXPECTED; - if (!mThreadEvent) { - mThreadEvent = PR_NewPollableEvent(); + if (!mPollableEvent) { + mPollableEvent.reset(new PollableEvent()); // // NOTE: per bug 190000, this failure could be caused by Zone-Alarm // or similar software. // // NOTE: per bug 191739, this failure could also be caused by lack - // of a loopback device on Windows and OS/2 platforms (NSPR creates + // of a loopback device on Windows and OS/2 platforms (it creates // a loopback socket pair on these platforms to implement a pollable // event object). if we can't create a pollable event, then we'll // have to "busy wait" to implement the socket event queue :-( // - if (!mThreadEvent) { + if (!mPollableEvent->Valid()) { + mPollableEvent = nullptr; NS_WARNING("running socket transport thread without a pollable event"); SOCKET_LOG(("running socket transport thread without a pollable event")); } @@ -586,9 +587,9 @@ nsSocketTransportService::Shutdown() // signal the socket thread to shutdown mShuttingDown = true; - if (mThreadEvent) - PR_SetPollableEvent(mThreadEvent); - // else wait for Poll timeout + if (mPollableEvent) { + mPollableEvent->Signal(); + } } // join with thread @@ -639,8 +640,9 @@ nsSocketTransportService::SetOffline(bool offline) else if (mOffline && !offline) { mOffline = false; } - if (mThreadEvent) - PR_SetPollableEvent(mThreadEvent); + if (mPollableEvent) { + mPollableEvent->Signal(); + } return NS_OK; } @@ -763,9 +765,19 @@ nsSocketTransportService::SetAutodialEnabled(bool value) NS_IMETHODIMP nsSocketTransportService::OnDispatchedEvent(nsIThreadInternal *thread) { + if (PR_GetCurrentThread() == gSocketThread) { + // this check is redundant to one done inside ::Signal(), but + // we can do it here and skip obtaining the lock - given that + // this is a relatively common occurance its worth the + // redundant code + SOCKET_LOG(("OnDispatchedEvent Same Thread Skip Signal\n")); + return NS_OK; + } + DebugMutexAutoLock lock(mLock); - if (mThreadEvent) - PR_SetPollableEvent(mThreadEvent); + if (mPollableEvent) { + mPollableEvent->Signal(); + } return NS_OK; } @@ -812,15 +824,15 @@ nsSocketTransportService::Run() gSocketThread = PR_GetCurrentThread(); - // add thread event to poll list (mThreadEvent may be nullptr) - mPollList[0].fd = mThreadEvent; - mPollList[0].in_flags = PR_POLL_READ; + // add thread event to poll list (mPollableEvent may be nullptr) + mPollList[0].fd = mPollableEvent ? mPollableEvent->PollableFD() : nullptr; + mPollList[0].in_flags = PR_POLL_READ | PR_POLL_EXCEPT; mPollList[0].out_flags = 0; - nsIThread *thread = NS_GetCurrentThread(); + mRawThread = NS_GetCurrentThread(); // hook ourselves up to observe event processing for this thread - nsCOMPtr threadInt = do_QueryInterface(thread); + nsCOMPtr threadInt = do_QueryInterface(mRawThread); threadInt->SetObserver(this); // make sure the pseudo random number generator is seeded on this thread @@ -849,7 +861,6 @@ nsSocketTransportService::Run() for (;;) { bool pendingEvents = false; - thread->HasPendingEvents(&pendingEvents); numberOfPendingEvents = 0; numberOfPendingEventsLastCycle = 0; @@ -864,9 +875,7 @@ nsSocketTransportService::Run() pollCycleStart = TimeStamp::NowLoRes(); } - // If there are pending events for this thread then - // DoPollIteration() should service the network without blocking. - DoPollIteration(!pendingEvents, &singlePollDuration); + DoPollIteration(&singlePollDuration); if (mTelemetryEnabledPref && !pollCycleStart.IsNull()) { Telemetry::Accumulate(Telemetry::STS_POLL_BLOCK_TIME, @@ -878,11 +887,7 @@ nsSocketTransportService::Run() pollDuration += singlePollDuration; } - // If nothing was pending before the poll, it might be now - if (!pendingEvents) { - thread->HasPendingEvents(&pendingEvents); - } - + mRawThread->HasPendingEvents(&pendingEvents); if (pendingEvents) { if (!mServingPendingQueue) { nsresult rv = Dispatch(NS_NewRunnableMethod(this, @@ -906,10 +911,10 @@ nsSocketTransportService::Run() } TimeStamp eventQueueStart = TimeStamp::NowLoRes(); do { - NS_ProcessNextEvent(thread); + NS_ProcessNextEvent(mRawThread); numberOfPendingEvents++; pendingEvents = false; - thread->HasPendingEvents(&pendingEvents); + mRawThread->HasPendingEvents(&pendingEvents); } while (pendingEvents && mServingPendingQueue && ((TimeStamp::NowLoRes() - eventQueueStart).ToMilliseconds() < @@ -967,7 +972,7 @@ nsSocketTransportService::Run() // Final pass over the event queue. This makes sure that events posted by // socket detach handlers get processed. - NS_ProcessPendingEvents(thread); + NS_ProcessPendingEvents(mRawThread); gSocketThread = nullptr; @@ -1008,12 +1013,11 @@ nsSocketTransportService::Reset(bool aGuardLocals) } nsresult -nsSocketTransportService::DoPollIteration(bool wait, TimeDuration *pollDuration) +nsSocketTransportService::DoPollIteration(TimeDuration *pollDuration) { - SOCKET_LOG(("STS poll iter [%d]\n", wait)); + SOCKET_LOG(("STS poll iter\n")); int32_t i, count; - // // poll loop // @@ -1068,15 +1072,14 @@ nsSocketTransportService::DoPollIteration(bool wait, TimeDuration *pollDuration) // Measures seconds spent while blocked on PR_Poll uint32_t pollInterval; - int32_t n = 0; #if !defined(MOZILLA_XPCOMRT_API) if (!gIOService->IsNetTearingDown()) { // Let's not do polling during shutdown. - n = Poll(wait, &pollInterval, pollDuration); + n = Poll(&pollInterval, pollDuration); } #else - n = Poll(wait, &pollInterval, pollDuration); + n = Poll(&pollInterval, pollDuration); #endif // defined(MOZILLA_XPCOMRT_API) if (n < 0) { @@ -1132,29 +1135,28 @@ nsSocketTransportService::DoPollIteration(bool wait, TimeDuration *pollDuration) DetachSocket(mActiveList, &mActiveList[i]); } - if (n != 0 && mPollList[0].out_flags == PR_POLL_READ) { - // acknowledge pollable event (wait should not block) - if (PR_WaitForPollableEvent(mThreadEvent) != PR_SUCCESS) { + if (n != 0 && (mPollList[0].out_flags & (PR_POLL_READ | PR_POLL_EXCEPT))) { + DebugMutexAutoLock lock(mLock); + + // acknowledge pollable event (should not block) + if (mPollableEvent && + ((mPollList[0].out_flags & PR_POLL_EXCEPT) || + !mPollableEvent->Clear())) { // On Windows, the TCP loopback connection in the // pollable event may become broken when a laptop // switches between wired and wireless networks or // wakes up from hibernation. We try to create a // new pollable event. If that fails, we fall back // on "busy wait". - { - DebugMutexAutoLock lock(mLock); - PR_DestroyPollableEvent(mThreadEvent); - mThreadEvent = PR_NewPollableEvent(); + NS_WARNING("Trying to repair mPollableEvent"); + mPollableEvent.reset(new PollableEvent()); + if (!mPollableEvent->Valid()) { + mPollableEvent = nullptr; } - if (!mThreadEvent) { - NS_WARNING("running socket transport thread without " - "a pollable event"); - SOCKET_LOG(("running socket transport thread without " - "a pollable event")); - } - mPollList[0].fd = mThreadEvent; - // mPollList[0].in_flags was already set to PR_POLL_READ - // in Run(). + SOCKET_LOG(("running socket transport thread without " + "a pollable event now valid=%d", mPollableEvent->Valid())); + mPollList[0].fd = mPollableEvent ? mPollableEvent->PollableFD() : nullptr; + mPollList[0].in_flags = PR_POLL_READ | PR_POLL_EXCEPT; mPollList[0].out_flags = 0; } } diff --git a/netwerk/base/nsSocketTransportService2.h b/netwerk/base/nsSocketTransportService2.h index 44f514740d50..d1c9ef722824 100644 --- a/netwerk/base/nsSocketTransportService2.h +++ b/netwerk/base/nsSocketTransportService2.h @@ -19,6 +19,8 @@ #include "mozilla/net/DashboardTypes.h" #include "mozilla/Atomics.h" #include "mozilla/TimeStamp.h" +#include "mozilla/UniquePtr.h" +#include "PollableEvent.h" class nsASocketHandler; struct PRPollDesc; @@ -124,14 +126,7 @@ private: //------------------------------------------------------------------------- nsCOMPtr mThread; // protected by mLock - PRFileDesc *mThreadEvent; - // protected by mLock. mThreadEvent may change - // if the old pollable event is broken. only - // the socket thread may change mThreadEvent; - // it needs to lock mLock only when it changes - // mThreadEvent. other threads don't change - // mThreadEvent; they need to lock mLock - // whenever they access mThreadEvent. + mozilla::UniquePtr mPollableEvent; bool mAutodialEnabled; // pref to control autodial code @@ -173,6 +168,7 @@ private: SocketContext *mActiveList; /* mListSize entries */ SocketContext *mIdleList; /* mListSize entries */ + nsIThread *mRawThread; uint32_t mActiveListSize; uint32_t mIdleListSize; @@ -197,18 +193,16 @@ private: //------------------------------------------------------------------------- // poll list (socket thread only) // - // first element of the poll list is mThreadEvent (or null if the pollable + // first element of the poll list is mPollableEvent (or null if the pollable // event cannot be created). //------------------------------------------------------------------------- PRPollDesc *mPollList; /* mListSize + 1 entries */ PRIntervalTime PollTimeout(); // computes ideal poll timeout - nsresult DoPollIteration(bool wait, - mozilla::TimeDuration *pollDuration); + nsresult DoPollIteration(mozilla::TimeDuration *pollDuration); // perfoms a single poll iteration - int32_t Poll(bool wait, - uint32_t *interval, + int32_t Poll(uint32_t *interval, mozilla::TimeDuration *pollDuration); // calls PR_Poll. the out param // interval indicates the poll diff --git a/netwerk/standalone/moz.build b/netwerk/standalone/moz.build index 60a16aa26783..1fd8b8992be2 100644 --- a/netwerk/standalone/moz.build +++ b/netwerk/standalone/moz.build @@ -12,6 +12,7 @@ src_list = [ ] netwerk_base_src = [ + 'PollableEvent.cpp', 'nsDNSPrefetch.cpp', 'nsNetAddr.cpp', 'nsSocketTransportService2.cpp', From 41d307c324691d021d83a1d200d975f13af9bd2a Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 18 Feb 2016 10:56:15 -0500 Subject: [PATCH 043/115] Bug 1245241 - part 1 - Close Shmem file handles after mapping them when possible to reduce exhaustion issues. r=billm --- gfx/layers/ipc/CompositorChild.cpp | 3 +- ipc/chromium/src/base/shared_memory.h | 17 +- ipc/chromium/src/base/shared_memory_posix.cc | 47 ++-- ipc/chromium/src/base/shared_memory_win.cc | 37 +-- ipc/glue/CrossProcessMutex_posix.cpp | 8 +- ipc/glue/SharedMemory.h | 37 +++ ipc/glue/SharedMemoryBasic_android.cpp | 17 +- ipc/glue/SharedMemoryBasic_android.h | 15 +- ipc/glue/SharedMemoryBasic_chromium.h | 20 +- ipc/glue/SharedMemoryBasic_mach.h | 15 +- ipc/glue/SharedMemoryBasic_mach.mm | 27 +- ipc/glue/SharedMemorySysV.h | 32 ++- ipc/glue/Shmem.cpp | 273 +++++-------------- 13 files changed, 225 insertions(+), 323 deletions(-) diff --git a/gfx/layers/ipc/CompositorChild.cpp b/gfx/layers/ipc/CompositorChild.cpp index f1600052ab0d..742a3d5faf43 100644 --- a/gfx/layers/ipc/CompositorChild.cpp +++ b/gfx/layers/ipc/CompositorChild.cpp @@ -450,7 +450,8 @@ CompositorChild::SharedFrameMetricsData::SharedFrameMetricsData( , mLayersId(aLayersId) , mAPZCId(aAPZCId) { - mBuffer = new ipc::SharedMemoryBasic(metrics); + mBuffer = new ipc::SharedMemoryBasic; + mBuffer->SetHandle(metrics); mBuffer->Map(sizeof(FrameMetrics)); mMutex = new CrossProcessMutex(handle); MOZ_COUNT_CTOR(SharedFrameMetricsData); diff --git a/ipc/chromium/src/base/shared_memory.h b/ipc/chromium/src/base/shared_memory.h index a1b6d927139a..49291cd601c3 100644 --- a/ipc/chromium/src/base/shared_memory.h +++ b/ipc/chromium/src/base/shared_memory.h @@ -43,17 +43,18 @@ class SharedMemory { // Create a new SharedMemory object from an existing, open // shared memory file. - SharedMemory(SharedMemoryHandle handle, bool read_only); - - // Create a new SharedMemory object from an existing, open - // shared memory file that was created by a remote process and not shared - // to the current process. - SharedMemory(SharedMemoryHandle handle, bool read_only, - base::ProcessHandle process); + SharedMemory(SharedMemoryHandle init_handle, bool read_only) + : SharedMemory() { + SetHandle(init_handle, read_only); + } // Destructor. Will close any open files. ~SharedMemory(); + // Initialize a new SharedMemory object from an existing, open + // shared memory file. + bool SetHandle(SharedMemoryHandle handle, bool read_only); + // Return true iff the given handle is valid (i.e. not the distingished // invalid value; NULL for a HANDLE and -1 for a file descriptor) static bool IsHandleValid(const SharedMemoryHandle& handle); @@ -116,7 +117,7 @@ class SharedMemory { // Closes the open shared memory segment. // It is safe to call Close repeatedly. - void Close(); + void Close(bool unmap_view = true); // Share the shared memory to another process. Attempts // to create a platform-specific new_handle which can be diff --git a/ipc/chromium/src/base/shared_memory_posix.cc b/ipc/chromium/src/base/shared_memory_posix.cc index dc8732017374..bc8238555bd1 100644 --- a/ipc/chromium/src/base/shared_memory_posix.cc +++ b/ipc/chromium/src/base/shared_memory_posix.cc @@ -26,35 +26,24 @@ SharedMemory::SharedMemory() max_size_(0) { } -SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only) - : mapped_file_(handle.fd), - inode_(0), - memory_(NULL), - read_only_(read_only), - max_size_(0) { - struct stat st; - if (fstat(handle.fd, &st) == 0) { - // If fstat fails, then the file descriptor is invalid and we'll learn this - // fact when Map() fails. - inode_ = st.st_ino; - } -} - -SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only, - ProcessHandle process) - : mapped_file_(handle.fd), - memory_(NULL), - read_only_(read_only), - max_size_(0) { - // We don't handle this case yet (note the ignored parameter); let's die if - // someone comes calling. - NOTREACHED(); -} - SharedMemory::~SharedMemory() { Close(); } +bool SharedMemory::SetHandle(SharedMemoryHandle handle, bool read_only) { + DCHECK(mapped_file_ == -1); + + struct stat st; + if (fstat(handle.fd, &st) < 0) { + return false; + } + + mapped_file_ = handle.fd; + inode_ = st.st_ino; + read_only_ = read_only; + return true; +} + // static bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) { return handle.fd >= 0; @@ -268,10 +257,12 @@ bool SharedMemory::ShareToProcessCommon(ProcessId processId, } -void SharedMemory::Close() { - Unmap(); +void SharedMemory::Close(bool unmap_view) { + if (unmap_view) { + Unmap(); + } - if (mapped_file_ > 0) { + if (mapped_file_ >= 0) { close(mapped_file_); mapped_file_ = -1; } diff --git a/ipc/chromium/src/base/shared_memory_win.cc b/ipc/chromium/src/base/shared_memory_win.cc index 02d90bd2a51d..757443a718fa 100644 --- a/ipc/chromium/src/base/shared_memory_win.cc +++ b/ipc/chromium/src/base/shared_memory_win.cc @@ -19,34 +19,20 @@ SharedMemory::SharedMemory() lock_(NULL) { } -SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only) - : mapped_file_(handle), - memory_(NULL), - read_only_(read_only), - max_size_(0), - lock_(NULL) { -} - -SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only, - ProcessHandle process) - : mapped_file_(NULL), - memory_(NULL), - read_only_(read_only), - max_size_(0), - lock_(NULL) { - ::DuplicateHandle(process, handle, - GetCurrentProcess(), &mapped_file_, - STANDARD_RIGHTS_REQUIRED | - (read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS), - FALSE, 0); -} - SharedMemory::~SharedMemory() { Close(); if (lock_ != NULL) CloseHandle(lock_); } +bool SharedMemory::SetHandle(SharedMemoryHandle handle, bool read_only) { + DCHECK(mapped_file_ == NULL); + + mapped_file_ = handle; + read_only_ = read_only; + return true; +} + // static bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) { return handle != NULL; @@ -151,10 +137,9 @@ bool SharedMemory::ShareToProcessCommon(ProcessId processId, } -void SharedMemory::Close() { - if (memory_ != NULL) { - UnmapViewOfFile(memory_); - memory_ = NULL; +void SharedMemory::Close(bool unmap_view) { + if (unmap_view) { + Unmap(); } if (mapped_file_ != NULL) { diff --git a/ipc/glue/CrossProcessMutex_posix.cpp b/ipc/glue/CrossProcessMutex_posix.cpp index 3418a785cc20..3a6108ecadab 100644 --- a/ipc/glue/CrossProcessMutex_posix.cpp +++ b/ipc/glue/CrossProcessMutex_posix.cpp @@ -82,11 +82,15 @@ CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle) : mMutex(nullptr) , mCount(nullptr) { - if (!ipc::SharedMemoryBasic::IsHandleValid(aHandle)) { + mSharedBuffer = new ipc::SharedMemoryBasic; + + if (!mSharedBuffer->IsHandleValid(aHandle)) { MOZ_CRASH(); } - mSharedBuffer = new ipc::SharedMemoryBasic(aHandle); + if (!mSharedBuffer->SetHandle(aHandle)) { + MOZ_CRASH(); + } if (!mSharedBuffer->Map(sizeof(MutexData))) { MOZ_CRASH(); diff --git a/ipc/glue/SharedMemory.h b/ipc/glue/SharedMemory.h index 6a36aed7e96f..73fc421e354d 100644 --- a/ipc/glue/SharedMemory.h +++ b/ipc/glue/SharedMemory.h @@ -12,6 +12,9 @@ #include "nsISupportsImpl.h" // NS_INLINE_DECL_REFCOUNTING #include "mozilla/Attributes.h" +#include "base/process.h" +#include "chrome/common/ipc_message_utils.h" + // // This is a low-level wrapper around platform shared memory. Don't // use it directly; use Shmem allocated through IPDL interfaces. @@ -55,8 +58,13 @@ public: virtual bool Create(size_t size) = 0; virtual bool Map(size_t nBytes) = 0; + virtual void CloseHandle() = 0; + virtual SharedMemoryType Type() const = 0; + virtual bool ShareHandle(base::ProcessId aProcessId, IPC::Message* aMessage) = 0; + virtual bool ReadHandle(const IPC::Message* aMessage, void** aIter) = 0; + void Protect(char* aAddr, size_t aSize, int aRights) { @@ -110,6 +118,35 @@ protected: size_t mMappedSize; }; +template +class SharedMemoryCommon : public SharedMemory +{ +public: + typedef HandleImpl Handle; + + virtual bool ShareToProcess(base::ProcessId aProcessId, Handle* aHandle) = 0; + virtual bool IsHandleValid(const Handle& aHandle) const = 0; + virtual bool SetHandle(const Handle& aHandle) = 0; + + virtual bool ShareHandle(base::ProcessId aProcessId, IPC::Message* aMessage) override + { + Handle handle; + if (!ShareToProcess(aProcessId, &handle)) { + return false; + } + IPC::WriteParam(aMessage, handle); + return true; + } + + virtual bool ReadHandle(const IPC::Message* aMessage, void** aIter) override + { + Handle handle; + return IPC::ReadParam(aMessage, aIter, &handle) && + IsHandleValid(handle) && + SetHandle(handle); + } +}; + } // namespace ipc } // namespace mozilla diff --git a/ipc/glue/SharedMemoryBasic_android.cpp b/ipc/glue/SharedMemoryBasic_android.cpp index 729023003f2f..eb91794b6ee7 100644 --- a/ipc/glue/SharedMemoryBasic_android.cpp +++ b/ipc/glue/SharedMemoryBasic_android.cpp @@ -40,15 +40,18 @@ SharedMemoryBasic::SharedMemoryBasic() , mMemory(nullptr) { } -SharedMemoryBasic::SharedMemoryBasic(const Handle& aHandle) - : mShmFd(aHandle.fd) - , mMemory(nullptr) -{ } - SharedMemoryBasic::~SharedMemoryBasic() { Unmap(); - Destroy(); + CloseHandle(); +} + +bool +SharedMemoryBasic::SetHandle(const Handle& aHandle) +{ + MOZ_ASSERT(-1 == mShmFd, "Already Create()d"); + mShmFd = aHandle.fd; + return true; } bool @@ -125,7 +128,7 @@ SharedMemoryBasic::Unmap() } void -SharedMemoryBasic::Destroy() +SharedMemoryBasic::CloseHandle() { if (mShmFd > 0) { close(mShmFd); diff --git a/ipc/glue/SharedMemoryBasic_android.h b/ipc/glue/SharedMemoryBasic_android.h index b10d8d769c57..3074f2d5b217 100644 --- a/ipc/glue/SharedMemoryBasic_android.h +++ b/ipc/glue/SharedMemoryBasic_android.h @@ -20,19 +20,19 @@ namespace mozilla { namespace ipc { -class SharedMemoryBasic final : public SharedMemory +class SharedMemoryBasic final : public SharedMemoryCommon { public: - typedef base::FileDescriptor Handle; - SharedMemoryBasic(); - SharedMemoryBasic(const Handle& aHandle); + virtual bool SetHandle(const Handle& aHandle) override; virtual bool Create(size_t aNbytes) override; virtual bool Map(size_t nBytes) override; + virtual void CloseHandle() override; + virtual void* memory() const override { return mMemory; @@ -48,19 +48,18 @@ public: return Handle(); } - static bool IsHandleValid(const Handle &aHandle) + virtual bool IsHandleValid(const Handle &aHandle) const override { return aHandle.fd >= 0; } - bool ShareToProcess(base::ProcessId aProcessId, - Handle* aNewHandle); + virtual bool ShareToProcess(base::ProcessId aProcessId, + Handle* aNewHandle) override; private: ~SharedMemoryBasic(); void Unmap(); - void Destroy(); // The /dev/ashmem fd we allocate. int mShmFd; diff --git a/ipc/glue/SharedMemoryBasic_chromium.h b/ipc/glue/SharedMemoryBasic_chromium.h index 97fd1ba623aa..6dfc6eafefbb 100644 --- a/ipc/glue/SharedMemoryBasic_chromium.h +++ b/ipc/glue/SharedMemoryBasic_chromium.h @@ -21,18 +21,15 @@ namespace mozilla { namespace ipc { -class SharedMemoryBasic final : public SharedMemory +class SharedMemoryBasic final : public SharedMemoryCommon { public: - typedef base::SharedMemoryHandle Handle; - SharedMemoryBasic() { } - explicit SharedMemoryBasic(const Handle& aHandle) - : mSharedMemory(aHandle, false) - { + virtual bool SetHandle(const Handle& aHandle) override { + return mSharedMemory.SetHandle(aHandle, false); } virtual bool Create(size_t aNbytes) override @@ -53,6 +50,11 @@ public: return ok; } + virtual void CloseHandle() override + { + mSharedMemory.Close(false); + } + virtual void* memory() const override { return mSharedMemory.memory(); @@ -68,13 +70,13 @@ public: return base::SharedMemory::NULLHandle(); } - static bool IsHandleValid(const Handle &aHandle) + virtual bool IsHandleValid(const Handle &aHandle) const override { return base::SharedMemory::IsHandleValid(aHandle); } - bool ShareToProcess(base::ProcessId aProcessId, - Handle* new_handle) + virtual bool ShareToProcess(base::ProcessId aProcessId, + Handle* new_handle) override { base::SharedMemoryHandle handle; bool ret = mSharedMemory.ShareToProcess(aProcessId, &handle); diff --git a/ipc/glue/SharedMemoryBasic_mach.h b/ipc/glue/SharedMemoryBasic_mach.h index bd0753fe10ef..708970fc0d6d 100644 --- a/ipc/glue/SharedMemoryBasic_mach.h +++ b/ipc/glue/SharedMemoryBasic_mach.h @@ -25,11 +25,9 @@ class ReceivePort; namespace mozilla { namespace ipc { -class SharedMemoryBasic final : public SharedMemory +class SharedMemoryBasic final : public SharedMemoryCommon { public: - typedef mach_port_t Handle; - static void SetupMachMemory(pid_t pid, ReceivePort* listen_port, MachPortSender* listen_port_ack, @@ -43,12 +41,14 @@ public: SharedMemoryBasic(); - explicit SharedMemoryBasic(Handle aHandle); + virtual bool SetHandle(const Handle& aHandle) override; virtual bool Create(size_t aNbytes) override; virtual bool Map(size_t nBytes) override; + virtual void CloseHandle() override; + virtual void* memory() const override { return mMemory; @@ -65,16 +65,15 @@ public: } - static bool IsHandleValid(const Handle &aHandle); + virtual bool IsHandleValid(const Handle &aHandle) const override; - bool ShareToProcess(base::ProcessId aProcessId, - Handle* aNewHandle); + virtual bool ShareToProcess(base::ProcessId aProcessId, + Handle* aNewHandle) override; private: ~SharedMemoryBasic(); void Unmap(); - void Destroy(); mach_port_t mPort; // Pointer to mapped region, null if unmapped. void *mMemory; diff --git a/ipc/glue/SharedMemoryBasic_mach.mm b/ipc/glue/SharedMemoryBasic_mach.mm index 79bce0ea0c83..35ebd979a10f 100644 --- a/ipc/glue/SharedMemoryBasic_mach.mm +++ b/ipc/glue/SharedMemoryBasic_mach.mm @@ -500,17 +500,19 @@ SharedMemoryBasic::SharedMemoryBasic() { } -SharedMemoryBasic::SharedMemoryBasic(Handle aHandle) - : mPort(MACH_PORT_NULL) - , mMemory(nullptr) -{ - mPort = aHandle; -} - SharedMemoryBasic::~SharedMemoryBasic() { Unmap(); - Destroy(); + CloseHandle(); +} + +bool +SharedMemoryBasic::SetHandle(const Handle& aHandle) +{ + MOZ_ASSERT(mPort == MACH_PORT_NULL, "already initialized"); + + mPort = aHandle; + return true; } static inline void* @@ -657,13 +659,16 @@ SharedMemoryBasic::Unmap() } void -SharedMemoryBasic::Destroy() +SharedMemoryBasic::CloseHandle() { - mach_port_deallocate(mach_task_self(), mPort); + if (mPort != MACH_PORT_NULL) { + mach_port_deallocate(mach_task_self(), mPort); + mPort = MACH_PORT_NULL; + } } bool -SharedMemoryBasic::IsHandleValid(const Handle& aHandle) +SharedMemoryBasic::IsHandleValid(const Handle& aHandle) const { return aHandle > 0; } diff --git a/ipc/glue/SharedMemorySysV.h b/ipc/glue/SharedMemorySysV.h index 934569300665..d853d85c5061 100644 --- a/ipc/glue/SharedMemorySysV.h +++ b/ipc/glue/SharedMemorySysV.h @@ -35,23 +35,15 @@ namespace mozilla { namespace ipc { -class SharedMemorySysV : public SharedMemory +class SharedMemorySysV : public SharedMemoryCommon { public: - typedef int Handle; - SharedMemorySysV() : mHandle(-1), mData(nullptr) { } - explicit SharedMemorySysV(Handle aHandle) : - mHandle(aHandle), - mData(nullptr) - { - } - virtual ~SharedMemorySysV() { shmdt(mData); @@ -59,6 +51,14 @@ public: mData = nullptr; } + virtual bool SetHandle(const Handle& aHandle) override + { + MOZ_ASSERT(mHandle == -1, "already initialized"); + + mHandle = aHandle; + return true; + } + virtual bool Create(size_t aNbytes) override { int id = shmget(IPC_PRIVATE, aNbytes, IPC_CREAT | 0600); @@ -132,11 +132,23 @@ public: return -1; } - static bool IsHandleValid(Handle aHandle) + virtual bool IsHandleValid(const Handle& aHandle) const override { return aHandle != -1; } + virtual void CloseHandle() override + { + } + + virtual bool ShareToProcess(base::ProcessId aProcessId, Handle* aHandle) override { + if (mHandle == -1) { + return false; + } + *aHandle = mHandle; + return true; + } + private: Handle mHandle; void* mData; diff --git a/ipc/glue/Shmem.cpp b/ipc/glue/Shmem.cpp index d14be9f2514f..9837530583dc 100644 --- a/ipc/glue/Shmem.cpp +++ b/ipc/glue/Shmem.cpp @@ -24,22 +24,16 @@ private: public: ShmemCreated(int32_t routingId, - const id_t& aIPDLId, - const size_t& aSize, - const SharedMemoryBasic::Handle& aHandle) : + id_t aIPDLId, + size_t aSize, + SharedMemory::SharedMemoryType aType) : IPC::Message(routingId, SHMEM_CREATED_MESSAGE_TYPE, PRIORITY_NORMAL) { IPC::WriteParam(this, aIPDLId); IPC::WriteParam(this, aSize); - IPC::WriteParam(this, int32_t(SharedMemory::TYPE_BASIC)), - IPC::WriteParam(this, aHandle); + IPC::WriteParam(this, int32_t(aType)); } - // Instead of a single Read() function, we have ReadInfo() and - // ReadHandle(). The reason is that the handle type is specific to - // the shmem type. These functions should only be called in the - // order ReadInfo(); ReadHandle();, and only once each. - static bool ReadInfo(const Message* msg, void** iter, id_t* aIPDLId, @@ -53,40 +47,6 @@ public: return true; } - static bool - ReadHandle(const Message* msg, void** iter, - SharedMemoryBasic::Handle* aHandle) - { - if (!IPC::ReadParam(msg, iter, aHandle)) - return false; - msg->EndRead(*iter); - return true; - } - -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV - ShmemCreated(int32_t routingId, - const id_t& aIPDLId, - const size_t& aSize, - const SharedMemorySysV::Handle& aHandle) : - IPC::Message(routingId, SHMEM_CREATED_MESSAGE_TYPE, PRIORITY_NORMAL) - { - IPC::WriteParam(this, aIPDLId); - IPC::WriteParam(this, aSize); - IPC::WriteParam(this, int32_t(SharedMemory::TYPE_SYSV)), - IPC::WriteParam(this, aHandle); - } - - static bool - ReadHandle(const Message* msg, void** iter, - SharedMemorySysV::Handle* aHandle) - { - if (!IPC::ReadParam(msg, iter, aHandle)) - return false; - msg->EndRead(*iter); - return true; - } -#endif - void Log(const std::string& aPrefix, FILE* aOutf) const { @@ -101,53 +61,69 @@ private: public: ShmemDestroyed(int32_t routingId, - const id_t& aIPDLId) : + id_t aIPDLId) : IPC::Message(routingId, SHMEM_DESTROYED_MESSAGE_TYPE, PRIORITY_NORMAL) { IPC::WriteParam(this, aIPDLId); } }; - -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV -static already_AddRefed -CreateSegment(size_t aNBytes, SharedMemorySysV::Handle aHandle) +static SharedMemory* +NewSegment(SharedMemory::SharedMemoryType aType) { - RefPtr segment; - - if (SharedMemorySysV::IsHandleValid(aHandle)) { - segment = new SharedMemorySysV(aHandle); - } - else { - segment = new SharedMemorySysV(); - - if (!segment->Create(aNBytes)) - return nullptr; - } - if (!segment->Map(aNBytes)) + if (SharedMemory::TYPE_BASIC == aType) { + return new SharedMemoryBasic; +#ifdef MOZ_HAVE_SHAREDMEMORYSYSV + } else if (SharedMemory::TYPE_SYSV == aType) { + return new SharedMemorySysV; +#endif + } else { + NS_ERROR("unknown Shmem type"); return nullptr; + } +} +static already_AddRefed +CreateSegment(SharedMemory::SharedMemoryType aType, size_t aNBytes, size_t aExtraSize) +{ + RefPtr segment = NewSegment(aType); + if (!segment) { + return nullptr; + } + size_t size = SharedMemory::PageAlignedSize(aNBytes + aExtraSize); + if (!segment->Create(size) || !segment->Map(size)) { + return nullptr; + } return segment.forget(); } -#endif -static already_AddRefed -CreateSegment(size_t aNBytes, SharedMemoryBasic::Handle aHandle) +static already_AddRefed +ReadSegment(const IPC::Message& aDescriptor, Shmem::id_t* aId, size_t* aNBytes, size_t aExtraSize) { - RefPtr segment; - - if (SharedMemoryBasic::IsHandleValid(aHandle)) { - segment = new SharedMemoryBasic(aHandle); - } - else { - segment = new SharedMemoryBasic(); - - if (!segment->Create(aNBytes)) - return nullptr; - } - if (!segment->Map(aNBytes)) + if (SHMEM_CREATED_MESSAGE_TYPE != aDescriptor.type()) { + NS_ERROR("expected 'shmem created' message"); return nullptr; - + } + SharedMemory::SharedMemoryType type; + void* iter = nullptr; + if (!ShmemCreated::ReadInfo(&aDescriptor, &iter, aId, aNBytes, &type)) { + return nullptr; + } + RefPtr segment = NewSegment(type); + if (!segment) { + return nullptr; + } + if (!segment->ReadHandle(&aDescriptor, &iter)) { + NS_ERROR("trying to open invalid handle"); + return nullptr; + } + aDescriptor.EndRead(iter); + size_t size = SharedMemory::PageAlignedSize(*aNBytes + aExtraSize); + if (!segment->Map(size)) { + return nullptr; + } + // close the handle to the segment after it is mapped + segment->CloseHandle(); return segment.forget(); } @@ -155,8 +131,9 @@ static void DestroySegment(SharedMemory* aSegment) { // the SharedMemory dtor closes and unmaps the actual OS shmem segment - if (aSegment) + if (aSegment) { aSegment->Release(); + } } @@ -357,24 +334,12 @@ Shmem::Alloc(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, MOZ_ASSERT(!aProtect || !aUnsafe, "protect => !unsafe"); size_t pageSize = SharedMemory::SystemPageSize(); - RefPtr segment; // |2*pageSize| is for the front and back sentinel - size_t segmentSize = SharedMemory::PageAlignedSize(aNBytes + 2*pageSize); - - if (aType == SharedMemory::TYPE_BASIC) - segment = CreateSegment(segmentSize, SharedMemoryBasic::NULLHandle()); -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV - else if (aType == SharedMemory::TYPE_SYSV) - segment = CreateSegment(segmentSize, SharedMemorySysV::NULLHandle()); -#endif - else { - NS_ERROR("unknown shmem type"); + RefPtr segment = CreateSegment(aType, aNBytes, 2*pageSize); + if (!segment) { return nullptr; } - if (!segment) - return nullptr; - Header* header; char *frontSentinel; char *data; @@ -405,54 +370,14 @@ Shmem::OpenExisting(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, id_t* aId, bool aProtect) { - if (SHMEM_CREATED_MESSAGE_TYPE != aDescriptor.type()) { - NS_ERROR("expected 'shmem created' message"); - return nullptr; - } - - void* iter = nullptr; - SharedMemory::SharedMemoryType type; size_t size; - if (!ShmemCreated::ReadInfo(&aDescriptor, &iter, aId, &size, &type)) - return nullptr; - - RefPtr segment; size_t pageSize = SharedMemory::SystemPageSize(); // |2*pageSize| is for the front and back sentinels - size_t segmentSize = SharedMemory::PageAlignedSize(size + 2*pageSize); - - if (SharedMemory::TYPE_BASIC == type) { - SharedMemoryBasic::Handle handle; - if (!ShmemCreated::ReadHandle(&aDescriptor, &iter, &handle)) - return nullptr; - - if (!SharedMemoryBasic::IsHandleValid(handle)) { - NS_ERROR("trying to open invalid handle"); - return nullptr; - } - segment = CreateSegment(segmentSize, handle); - } -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV - else if (SharedMemory::TYPE_SYSV == type) { - SharedMemorySysV::Handle handle; - if (!ShmemCreated::ReadHandle(&aDescriptor, &iter, &handle)) - return nullptr; - - if (!SharedMemorySysV::IsHandleValid(handle)) { - NS_ERROR("trying to open invalid handle"); - return nullptr; - } - segment = CreateSegment(segmentSize, handle); - } -#endif - else { - NS_ERROR("unknown shmem type"); + RefPtr segment = ReadSegment(aDescriptor, aId, &size, 2*pageSize); + if (!segment) { return nullptr; } - if (!segment) - return nullptr; - Header* header = GetHeader(segment); if (size != header->mSize) { @@ -508,23 +433,11 @@ Shmem::Alloc(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, bool /*unused*/, bool /*unused*/) { - RefPtr segment; - - if (aType == SharedMemory::TYPE_BASIC) - segment = CreateSegment(SharedMemory::PageAlignedSize(aNBytes + sizeof(uint32_t)), - SharedMemoryBasic::NULLHandle()); -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV - else if (aType == SharedMemory::TYPE_SYSV) - segment = CreateSegment(SharedMemory::PageAlignedSize(aNBytes + sizeof(uint32_t)), - SharedMemorySysV::NULLHandle()); -#endif - else { + RefPtr segment = CreateSegment(aType, aNBytes, sizeof(uint32_t)); + if (!segment) { return nullptr; } - if (!segment) - return nullptr; - *PtrToSize(segment) = static_cast(aNBytes); return segment.forget(); @@ -537,49 +450,12 @@ Shmem::OpenExisting(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, id_t* aId, bool /*unused*/) { - if (SHMEM_CREATED_MESSAGE_TYPE != aDescriptor.type()) { - return nullptr; - } - - SharedMemory::SharedMemoryType type; - void* iter = nullptr; size_t size; - if (!ShmemCreated::ReadInfo(&aDescriptor, &iter, aId, &size, &type)) - return nullptr; - - RefPtr segment; - size_t segmentSize = SharedMemory::PageAlignedSize(size + sizeof(uint32_t)); - - if (SharedMemory::TYPE_BASIC == type) { - SharedMemoryBasic::Handle handle; - if (!ShmemCreated::ReadHandle(&aDescriptor, &iter, &handle)) - return nullptr; - - if (!SharedMemoryBasic::IsHandleValid(handle)) { - return nullptr; - } - - segment = CreateSegment(segmentSize, handle); - } -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV - else if (SharedMemory::TYPE_SYSV == type) { - SharedMemorySysV::Handle handle; - if (!ShmemCreated::ReadHandle(&aDescriptor, &iter, &handle)) - return nullptr; - - if (!SharedMemorySysV::IsHandleValid(handle)) { - return nullptr; - } - segment = CreateSegment(segmentSize, handle); - } -#endif - else { + RefPtr segment = ReadSegment(aDescriptor, aId, &size, sizeof(uint32_t)); + if (!segment) { return nullptr; } - if (!segment) - return nullptr; - // this is the only validity check done in non-DEBUG builds if (size != static_cast(*PtrToSize(segment))) { return nullptr; @@ -624,26 +500,13 @@ Shmem::ShareTo(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, { AssertInvariants(); - if (SharedMemory::TYPE_BASIC == mSegment->Type()) { - SharedMemoryBasic* seg = static_cast(mSegment); - SharedMemoryBasic::Handle handle; - if (!seg->ShareToProcess(aTargetPid, &handle)) - return nullptr; - - return new ShmemCreated(routingId, mId, mSize, handle); - } -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV - else if (SharedMemory::TYPE_SYSV == mSegment->Type()) { - SharedMemorySysV* seg = static_cast(mSegment); - return new ShmemCreated(routingId, mId, mSize, seg->GetHandle()); - } -#endif - else { - MOZ_ASSERT(false, "unknown shmem type (here?!)"); + IPC::Message *msg = new ShmemCreated(routingId, mId, mSize, mSegment->Type()); + if (!mSegment->ShareHandle(aTargetPid, msg)) { return nullptr; } - - return nullptr; + // close the handle to the segment after it is shared + mSegment->CloseHandle(); + return msg; } IPC::Message* From d4c87aeb45f374b94c82801980062dbc5708e51c Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 18 Feb 2016 10:56:15 -0500 Subject: [PATCH 044/115] Bug 1245241 - part 2 - remove TYPE_SYSV Shmems from IPDL. r=billm --- ipc/glue/Shmem.cpp | 24 ------ ipc/glue/Shmem.h | 4 +- ipc/ipdl/test/cxx/PTestSysVShmem.ipdl | 22 ----- ipc/ipdl/test/cxx/TestSysVShmem.cpp | 120 -------------------------- ipc/ipdl/test/cxx/TestSysVShmem.h | 66 -------------- ipc/ipdl/test/cxx/moz.build | 6 -- 6 files changed, 1 insertion(+), 241 deletions(-) delete mode 100644 ipc/ipdl/test/cxx/PTestSysVShmem.ipdl delete mode 100644 ipc/ipdl/test/cxx/TestSysVShmem.cpp delete mode 100644 ipc/ipdl/test/cxx/TestSysVShmem.h diff --git a/ipc/glue/Shmem.cpp b/ipc/glue/Shmem.cpp index 9837530583dc..31d8af9b3dcf 100644 --- a/ipc/glue/Shmem.cpp +++ b/ipc/glue/Shmem.cpp @@ -9,7 +9,6 @@ #include "ProtocolUtils.h" #include "SharedMemoryBasic.h" -#include "SharedMemorySysV.h" #include "mozilla/unused.h" @@ -73,10 +72,6 @@ NewSegment(SharedMemory::SharedMemoryType aType) { if (SharedMemory::TYPE_BASIC == aType) { return new SharedMemoryBasic; -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV - } else if (SharedMemory::TYPE_SYSV == aType) { - return new SharedMemorySysV; -#endif } else { NS_ERROR("unknown Shmem type"); return nullptr; @@ -474,25 +469,6 @@ Shmem::Dealloc(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, #endif // if defined(DEBUG) -int -Shmem::GetSysVID() const -{ -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV - AssertInvariants(); - - if (mSegment->Type() != SharedMemory::TYPE_SYSV) { - NS_ERROR("Can't call GetSysVID() on a non-SysV Shmem!"); - return -1; - } - - SharedMemorySysV* seg = static_cast(mSegment); - return seg->GetHandle(); -#else - NS_ERROR("Can't call GetSysVID() with no support for SysV shared memory!"); - return -1; // not reached -#endif -} - IPC::Message* Shmem::ShareTo(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, base::ProcessId aTargetPid, diff --git a/ipc/glue/Shmem.h b/ipc/glue/Shmem.h index 6e7cd0f99a28..818dd015c3f0 100644 --- a/ipc/glue/Shmem.h +++ b/ipc/glue/Shmem.h @@ -36,7 +36,7 @@ * means is OS specific.) * * (4a) The child receives the special IPC message, and using the - * |SharedMemory{SysV,Basic}::Handle| it was passed, creates a + * |SharedMemory{Basic}::Handle| it was passed, creates a * |mozilla::ipc::SharedMemory| in the child * process. * @@ -175,8 +175,6 @@ public: return mSize / sizeof(T); } - int GetSysVID() const; - // These shouldn't be used directly, use the IPDL interface instead. id_t Id(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead) const { return mId; diff --git a/ipc/ipdl/test/cxx/PTestSysVShmem.ipdl b/ipc/ipdl/test/cxx/PTestSysVShmem.ipdl deleted file mode 100644 index 56c01c54a741..000000000000 --- a/ipc/ipdl/test/cxx/PTestSysVShmem.ipdl +++ /dev/null @@ -1,22 +0,0 @@ -namespace mozilla { -namespace _ipdltest { - -protocol PTestSysVShmem { -child: - async Give(Shmem mem, Shmem unsafe, size_t expectedSize); - -parent: - async Take(Shmem mem, Shmem unsafe, size_t expectedSize); - async __delete__(); - - -state GIVING: - send Give goto TAKING; - -state TAKING: - recv Take goto TAKING; - recv __delete__; -}; - -} -} diff --git a/ipc/ipdl/test/cxx/TestSysVShmem.cpp b/ipc/ipdl/test/cxx/TestSysVShmem.cpp deleted file mode 100644 index bd41c1f47a28..000000000000 --- a/ipc/ipdl/test/cxx/TestSysVShmem.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "TestSysVShmem.h" - -#include "IPDLUnitTests.h" // fail etc. - - -namespace mozilla { -namespace _ipdltest { - -//----------------------------------------------------------------------------- -// Parent - -void -TestSysVShmemParent::Main() -{ - Shmem mem; - Shmem unsafe; - - size_t size = 12345; - if (!AllocShmem(size, SharedMemory::TYPE_SYSV, &mem)) - fail("can't alloc shmem"); - if (!AllocUnsafeShmem(size, SharedMemory::TYPE_SYSV, &unsafe)) - fail("can't alloc shmem"); - - if (0 > mem.GetSysVID()) - fail("invalid shmem ID"); - if (0 > unsafe.GetSysVID()) - fail("invalid shmem ID"); - - if (mem.Size() != size) - fail("shmem is wrong size: expected %lu, got %lu", - size, mem.Size()); - if (unsafe.Size() != size) - fail("shmem is wrong size: expected %lu, got %lu", - size, unsafe.Size()); - - char* ptr = mem.get(); - memcpy(ptr, "Hello!", sizeof("Hello!")); - - char* unsafeptr = unsafe.get(); - memcpy(unsafeptr, "Hello!", sizeof("Hello!")); - - Shmem unsafecopy = unsafe; - if (!SendGive(mem, unsafe, size)) - fail("can't send Give()"); - - // uncomment the following line for a (nondeterministic) surprise! - //char c1 = *ptr; (void)c1; - - // uncomment the following line for a deterministic surprise! - //char c2 = *mem.get(); (void)c2; - - // unsafe shmem gets rid of those checks - char uc1 = *unsafeptr; (void)uc1; - char uc2 = *unsafecopy.get(); (void)uc2; -} - - -bool -TestSysVShmemParent::RecvTake(Shmem&& mem, Shmem&& unsafe, - const size_t& expectedSize) -{ - if (mem.Size() != expectedSize) - fail("expected shmem size %lu, but it has size %lu", - expectedSize, mem.Size()); - if (unsafe.Size() != expectedSize) - fail("expected shmem size %lu, but it has size %lu", - expectedSize, unsafe.Size()); - - if (strcmp(mem.get(), "And yourself!")) - fail("expected message was not written"); - if (strcmp(unsafe.get(), "And yourself!")) - fail("expected message was not written"); - - if (!DeallocShmem(mem)) - fail("DeallocShmem"); - if (!DeallocShmem(unsafe)) - fail("DeallocShmem"); - - Close(); - - return true; -} - -//----------------------------------------------------------------------------- -// Child - -bool -TestSysVShmemChild::RecvGive(Shmem&& mem, Shmem&& unsafe, const size_t& expectedSize) -{ - if (mem.Size() != expectedSize) - fail("expected shmem size %lu, but it has size %lu", - expectedSize, mem.Size()); - if (unsafe.Size() != expectedSize) - fail("expected shmem size %lu, but it has size %lu", - expectedSize, unsafe.Size()); - - if (strcmp(mem.get(), "Hello!")) - fail("expected message was not written"); - if (strcmp(unsafe.get(), "Hello!")) - fail("expected message was not written"); - - char* unsafeptr = unsafe.get(); - - memcpy(mem.get(), "And yourself!", sizeof("And yourself!")); - memcpy(unsafeptr, "And yourself!", sizeof("And yourself!")); - - Shmem unsafecopy = unsafe; - if (!SendTake(mem, unsafe, expectedSize)) - fail("can't send Take()"); - - // these checks also shouldn't fail in the child - char uc1 = *unsafeptr; (void)uc1; - char uc2 = *unsafecopy.get(); (void)uc2; - - return true; -} - - -} // namespace _ipdltest -} // namespace mozilla diff --git a/ipc/ipdl/test/cxx/TestSysVShmem.h b/ipc/ipdl/test/cxx/TestSysVShmem.h deleted file mode 100644 index bbba0a116653..000000000000 --- a/ipc/ipdl/test/cxx/TestSysVShmem.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef mozilla__ipdltest_TestSysVShmem_h -#define mozilla__ipdltest_TestSysVShmem_h - -#include "mozilla/_ipdltest/IPDLUnitTests.h" - -#include "mozilla/_ipdltest/PTestSysVShmemParent.h" -#include "mozilla/_ipdltest/PTestSysVShmemChild.h" - -namespace mozilla { -namespace _ipdltest { - - -class TestSysVShmemParent : - public PTestSysVShmemParent -{ -public: - TestSysVShmemParent() { } - virtual ~TestSysVShmemParent() { } - - static bool RunTestInProcesses() { return true; } - static bool RunTestInThreads() { return true; } - - void Main(); - -protected: - virtual bool RecvTake( - Shmem&& mem, - Shmem&& unsafe, - const size_t& expectedSize) override; - - virtual void ActorDestroy(ActorDestroyReason why) override - { - if (NormalShutdown != why) - fail("unexpected destruction!"); - passed("ok"); - QuitParent(); - } -}; - - -class TestSysVShmemChild : - public PTestSysVShmemChild -{ -public: - TestSysVShmemChild() { } - virtual ~TestSysVShmemChild() { } - -protected: - virtual bool RecvGive( - Shmem&& mem, - Shmem&& unsafe, - const size_t& expectedSize) override; - - virtual void ActorDestroy(ActorDestroyReason why) override - { - if (NormalShutdown != why) - fail("unexpected destruction!"); - QuitChild(); - } -}; - - -} // namespace _ipdltest -} // namespace mozilla - -#endif // ifndef mozilla__ipdltest_TestSysVShmem_h diff --git a/ipc/ipdl/test/cxx/moz.build b/ipc/ipdl/test/cxx/moz.build index 42d51de41c6e..fc04858b4289 100644 --- a/ipc/ipdl/test/cxx/moz.build +++ b/ipc/ipdl/test/cxx/moz.build @@ -53,11 +53,6 @@ SOURCES += [ 'TestUrgentHangs.cpp', ] -if CONFIG['OS_ARCH'] == 'Linux': - SOURCES += [ - 'TestSysVShmem.cpp', - ] - SOURCES += [ '!IPDLUnitTests.cpp', 'IPDLUnitTestProcessChild.cpp', @@ -127,7 +122,6 @@ IPDL_SOURCES += [ 'PTestSyncError.ipdl', 'PTestSyncHang.ipdl', 'PTestSyncWakeup.ipdl', - 'PTestSysVShmem.ipdl', 'PTestUrgency.ipdl', 'PTestUrgentHangs.ipdl', ] From f5674ca6c223b955863bbd2adc535f3f4f55bb04 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 18 Feb 2016 10:56:15 -0500 Subject: [PATCH 045/115] Bug 1245241 - part 3 - remove unused AdoptShmem from IPDL. r=billm --- ipc/glue/ProtocolUtils.h | 1 - ipc/glue/Shmem.h | 8 +-- ipc/ipdl/ipdl/lower.py | 109 +++------------------------------------ 3 files changed, 7 insertions(+), 111 deletions(-) diff --git a/ipc/glue/ProtocolUtils.h b/ipc/glue/ProtocolUtils.h index ac87acc439c3..36bc3bf5b94f 100644 --- a/ipc/glue/ProtocolUtils.h +++ b/ipc/glue/ProtocolUtils.h @@ -173,7 +173,6 @@ public: virtual Shmem::SharedMemory* CreateSharedMemory( size_t, SharedMemory::SharedMemoryType, bool, int32_t*) = 0; - virtual bool AdoptSharedMemory(Shmem::SharedMemory*, int32_t*) = 0; virtual Shmem::SharedMemory* LookupSharedMemory(int32_t) = 0; virtual bool IsTrackingSharedMemory(Shmem::SharedMemory*) = 0; virtual bool DestroySharedMemory(Shmem&) = 0; diff --git a/ipc/glue/Shmem.h b/ipc/glue/Shmem.h index 818dd015c3f0..afae28aa04ea 100644 --- a/ipc/glue/Shmem.h +++ b/ipc/glue/Shmem.h @@ -125,13 +125,7 @@ public: bool operator==(const Shmem& aRhs) const { - // need to compare IDs because of AdoptShmem(); two Shmems might - // refer to the same segment but with different IDs for different - // protocol trees. (NB: it's possible for this method to - // spuriously return true if AdoptShmem() gives the same ID for - // two protocol trees, but I don't think that can cause any - // problems since the Shmems really would be indistinguishable.) - return mSegment == aRhs.mSegment && mId == aRhs.mId; + return mSegment == aRhs.mSegment; } // Returns whether this Shmem is writable by you, and thus whether you can diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index 934d3b1d6dc5..619663d5f377 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -1120,9 +1120,6 @@ class Protocol(ipdl.ast.Protocol): def createSharedMemory(self): return ExprVar('CreateSharedMemory') - def adoptSharedMemory(self): - return ExprVar('AdoptSharedMemory') - def lookupSharedMemory(self): return ExprVar('LookupSharedMemory') @@ -3674,12 +3671,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): Decl(Type.BOOL, unsafevar.name), Decl(_shmemIdType(ptr=1), idvar.name) ], virtual=1)) - adoptshmem = MethodDefn(MethodDecl( - p.adoptSharedMemory().name, - ret=Type.BOOL, - params=[ Decl(_rawShmemType(ptr=1), rawvar.name), - Decl(_shmemIdType(ptr=1), idvar.name) ], - virtual=1)) lookupshmem = MethodDefn(MethodDecl( p.lookupSharedMemory().name, ret=_rawShmemType(ptr=1), @@ -3796,48 +3787,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): StmtReturn(rawsegmentvar) ]) - # SharedMemory* AdoptSharedMemory(SharedMemory*, id_t*): - # Shmem s(seg, [nextshmemid]); - # Message descriptor; - # if (!s->ShareTo(subprocess, mId, descriptor) || - # !Send(descriptor)) - # return false; - # mShmemMap.Add(seg, id); - # seg->AddRef(); - # return true; - - # XXX this is close to the same code as above, could be - # refactored - descriptorvar = ExprVar('descriptor') - adoptshmem.addstmts([ - StmtDecl( - Decl(_shmemType(), shmemvar.name), - initargs=[ _shmemBackstagePass(), - rawvar, - p.nextShmemIdExpr(self.side) ]), - StmtDecl(Decl(Type('Message', ptr=1), descriptorvar.name), - init=_shmemShareTo(shmemvar, - p.callOtherPid(), - p.routingId())) - ]) - failif = StmtIf(ExprNot(descriptorvar)) - failif.addifstmt(StmtReturn.FALSE) - adoptshmem.addstmt(failif) - - failif = StmtIf(ExprNot(ExprCall( - ExprSelect(p.channelVar(), p.channelSel(), 'Send'), - args=[ descriptorvar ]))) - adoptshmem.addstmt(failif) - - adoptshmem.addstmts([ - StmtExpr(ExprAssn(ExprDeref(idvar), _shmemId(shmemvar))), - StmtExpr(ExprCall( - ExprSelect(p.shmemMapVar(), '.', 'AddWithID'), - args=[ rawvar, ExprDeref(idvar) ])), - StmtExpr(ExprCall(ExprSelect(rawvar, '->', 'AddRef'))), - StmtReturn.TRUE - ]) - # SharedMemory* Lookup(id) lookupshmem.addstmt(StmtReturn(ExprCall( ExprSelect(p.shmemMapVar(), '.', 'Lookup'), @@ -3936,9 +3885,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): createshmem.addstmt(StmtReturn(ExprCall( ExprSelect(p.managerVar(), '->', p.createSharedMemory().name), [ sizevar, typevar, unsafevar, idvar ]))) - adoptshmem.addstmt(StmtReturn(ExprCall( - ExprSelect(p.managerVar(), '->', p.adoptSharedMemory().name), - [ rawvar, idvar ]))) lookupshmem.addstmt(StmtReturn(ExprCall( ExprSelect(p.managerVar(), '->', p.lookupSharedMemory().name), [ idvar ]))) @@ -4091,7 +4037,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): unregister, removemanagee, createshmem, - adoptshmem, lookupshmem, istracking, destroyshmem, @@ -4154,52 +4099,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): # bool AllocUnsafeShmem(size_t size, Type type, Shmem* outmem): allocUnsafeShmem = allocShmemMethod('AllocUnsafeShmem', True) - # bool AdoptShmem(Shmem& aMem, Shmem* aOutmem): - # SharedMemory* rawmem = aMem.Segment(); - # if (!rawmem || IsTrackingSharedMemory(rawmem)) { - # NS_WARNING("bad Shmem"); // or NS_RUNTIMEABORT on child side - # return false; - # } - # id_t id - # if (!AdoptSharedMemory(rawmem, &id)) - # return false - # *aOutmem = Shmem(rawmem, id); - # return true; - adoptShmem = MethodDefn(MethodDecl( - 'AdoptShmem', - params=[ Decl(_shmemType(const=1, ref=1), memvar.name), - Decl(_shmemType(ptr=1), outmemvar.name) ], - ret=Type.BOOL)) - - adoptShmem.addstmt(StmtDecl(Decl(_rawShmemType(ptr=1), rawvar.name), - init=_shmemSegment(memvar))) - ifbad = StmtIf(ExprBinary( - ExprNot(rawvar), '||', - ExprCall(ExprVar('IsTrackingSharedMemory'), args=[ rawvar ]))) - badShmemActions = [] - if (self.side == 'child'): - badShmemActions.append(_runtimeAbort('bad Shmem')); - else: - badShmemActions.append(_printWarningMessage('bad Shmem')); - badShmemActions.append(StmtReturn.FALSE); - ifbad.addifstmts(badShmemActions) - - adoptShmem.addstmt(ifbad) - - ifadoptfails = StmtIf(ExprNot(ExprCall( - p.adoptSharedMemory(), args=[ rawvar, ExprAddrOf(idvar) ]))) - ifadoptfails.addifstmt(StmtReturn.FALSE) - - adoptShmem.addstmts([ - Whitespace.NL, - StmtDecl(Decl(_shmemIdType(), idvar.name)), - ifadoptfails, - Whitespace.NL, - StmtExpr(ExprAssn(ExprDeref(outmemvar), - _shmemCtor(rawvar, idvar))), - StmtReturn.TRUE - ]) - # bool DeallocShmem(Shmem& mem): # bool ok = DestroySharedMemory(mem); ##ifdef DEBUG @@ -4217,6 +4116,12 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): okvar = ExprVar('ok') ifbad = StmtIf(ExprNot(okvar)) + badShmemActions = [] + if (self.side == 'child'): + badShmemActions.append(_runtimeAbort('bad Shmem')); + else: + badShmemActions.append(_printWarningMessage('bad Shmem')); + badShmemActions.append(StmtReturn.FALSE); ifbad.addifstmts(badShmemActions) deallocShmem.addstmts([ @@ -4235,8 +4140,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): Whitespace.NL, allocUnsafeShmem, Whitespace.NL, - adoptShmem, - Whitespace.NL, deallocShmem, Whitespace.NL ] From 05c95317a9ef72959e48d39980fd70aabd9fb6b4 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 18 Feb 2016 10:56:15 -0500 Subject: [PATCH 046/115] Bug 1245241 - part 4 - move SharedMemorySysV details into nsShmImage. r=nical --- ipc/glue/SharedMemory.h | 1 - ipc/glue/SharedMemorySysV.h | 162 -------------------------- ipc/glue/moz.build | 1 - widget/gtk/nsWindow.h | 8 +- widget/nsShmImage.cpp | 224 +++++++++++++++++++++++------------- widget/nsShmImage.h | 34 ++---- 6 files changed, 155 insertions(+), 275 deletions(-) delete mode 100644 ipc/glue/SharedMemorySysV.h diff --git a/ipc/glue/SharedMemory.h b/ipc/glue/SharedMemory.h index 73fc421e354d..74f9fc881f7a 100644 --- a/ipc/glue/SharedMemory.h +++ b/ipc/glue/SharedMemory.h @@ -47,7 +47,6 @@ protected: public: enum SharedMemoryType { TYPE_BASIC, - TYPE_SYSV, TYPE_UNKNOWN }; diff --git a/ipc/glue/SharedMemorySysV.h b/ipc/glue/SharedMemorySysV.h deleted file mode 100644 index d853d85c5061..000000000000 --- a/ipc/glue/SharedMemorySysV.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=8 et : - */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_ipc_SharedMemorySysV_h -#define mozilla_ipc_SharedMemorySysV_h - -#if (defined(OS_LINUX) && !defined(ANDROID)) || defined(OS_BSD) - -// SysV shared memory isn't available on Windows, but we define the -// following macro so that #ifdefs are clearer (compared to #ifdef -// OS_LINUX). -#define MOZ_HAVE_SHAREDMEMORYSYSV - -#include "SharedMemory.h" - -#include "nsDebug.h" - -#include -#include -#include -#include -#include -#include - -// -// This is a low-level wrapper around platform shared memory. Don't -// use it directly; use Shmem allocated through IPDL interfaces. -// - -namespace mozilla { -namespace ipc { - - -class SharedMemorySysV : public SharedMemoryCommon -{ -public: - SharedMemorySysV() : - mHandle(-1), - mData(nullptr) - { - } - - virtual ~SharedMemorySysV() - { - shmdt(mData); - mHandle = -1; - mData = nullptr; - } - - virtual bool SetHandle(const Handle& aHandle) override - { - MOZ_ASSERT(mHandle == -1, "already initialized"); - - mHandle = aHandle; - return true; - } - - virtual bool Create(size_t aNbytes) override - { - int id = shmget(IPC_PRIVATE, aNbytes, IPC_CREAT | 0600); - if (id == -1) - return false; - - mHandle = id; - mAllocSize = aNbytes; - Created(aNbytes); - - return Map(aNbytes); - } - - virtual bool Map(size_t nBytes) override - { - // already mapped - if (mData) - return true; - - if (!IsHandleValid(mHandle)) - return false; - - void* mem = shmat(mHandle, nullptr, 0); - if (mem == (void*) -1) { - char warning[256]; - ::snprintf(warning, sizeof(warning)-1, - "shmat(): %s (%d)\n", strerror(errno), errno); - - NS_WARNING(warning); - - return false; - } - - // Mark the handle as deleted so that, should this process go away, the - // segment is cleaned up. - shmctl(mHandle, IPC_RMID, 0); - - mData = mem; - -#ifdef DEBUG - struct shmid_ds info; - if (shmctl(mHandle, IPC_STAT, &info) < 0) - return false; - - MOZ_ASSERT(nBytes <= info.shm_segsz, - "Segment doesn't have enough space!"); -#endif - - Mapped(nBytes); - return true; - } - - virtual void* memory() const override - { - return mData; - } - - virtual SharedMemoryType Type() const override - { - return TYPE_SYSV; - } - - Handle GetHandle() const - { - MOZ_ASSERT(IsHandleValid(mHandle), "invalid handle"); - return mHandle; - } - - static Handle NULLHandle() - { - return -1; - } - - virtual bool IsHandleValid(const Handle& aHandle) const override - { - return aHandle != -1; - } - - virtual void CloseHandle() override - { - } - - virtual bool ShareToProcess(base::ProcessId aProcessId, Handle* aHandle) override { - if (mHandle == -1) { - return false; - } - *aHandle = mHandle; - return true; - } - -private: - Handle mHandle; - void* mData; -}; - -} // namespace ipc -} // namespace mozilla - -#endif // OS_LINUX - -#endif // ifndef mozilla_ipc_SharedMemorySysV_h diff --git a/ipc/glue/moz.build b/ipc/glue/moz.build index ff5503644658..e005ea81b125 100644 --- a/ipc/glue/moz.build +++ b/ipc/glue/moz.build @@ -31,7 +31,6 @@ EXPORTS.mozilla.ipc += [ 'ScopedXREEmbed.h', 'SharedMemory.h', 'SharedMemoryBasic.h', - 'SharedMemorySysV.h', 'Shmem.h', 'Transport.h', 'URIUtils.h', diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index aa3c0a69ef86..f42438217e8c 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -8,8 +8,6 @@ #ifndef __nsWindow_h__ #define __nsWindow_h__ -#include "mozilla/ipc/SharedMemorySysV.h" - #include "nsAutoPtr.h" #include "mozcontainer.h" @@ -27,6 +25,8 @@ #include #endif /* MOZ_X11 */ +#include "nsShmImage.h" + #ifdef ACCESSIBILITY #include "mozilla/a11y/Accessible.h" #endif @@ -64,10 +64,6 @@ extern PRLogModuleInfo *gWidgetDrawLog; class gfxASurface; class gfxPattern; class nsPluginNativeWindowGtk; -#if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV) -# define MOZ_HAVE_SHMIMAGE -class nsShmImage; -#endif namespace mozilla { class TimeStamp; diff --git a/widget/nsShmImage.cpp b/widget/nsShmImage.cpp index 4f097d4812e6..964e7a7d0be2 100644 --- a/widget/nsShmImage.cpp +++ b/widget/nsShmImage.cpp @@ -17,6 +17,14 @@ #endif #ifdef MOZ_HAVE_SHMIMAGE +#include "mozilla/X11Util.h" + +#include "mozilla/ipc/SharedMemory.h" + +#include +#include +#include +#include using namespace mozilla::ipc; using namespace mozilla::gfx; @@ -45,92 +53,143 @@ TrapShmError(Display* aDisplay, XErrorEvent* aEvent) } #endif -already_AddRefed -nsShmImage::Create(const LayoutDeviceIntSize& aSize, - Display* aDisplay, Visual* aVisual, unsigned int aDepth) +bool +nsShmImage::CreateShmSegment() { - RefPtr shm = new nsShmImage(); - shm->mDisplay = aDisplay; - shm->mImage = XShmCreateImage(aDisplay, aVisual, aDepth, - ZPixmap, nullptr, - &(shm->mInfo), - aSize.width, aSize.height); - if (!shm->mImage) { - return nullptr; - } + if (!mImage) { + return false; + } - size_t size = SharedMemory::PageAlignedSize( - shm->mImage->bytes_per_line * shm->mImage->height); - shm->mSegment = new SharedMemorySysV(); - if (!shm->mSegment->Create(size) || !shm->mSegment->Map(size)) { - return nullptr; - } + size_t size = SharedMemory::PageAlignedSize(mImage->bytes_per_line * mImage->height); - shm->mInfo.shmid = shm->mSegment->GetHandle(); - shm->mInfo.shmaddr = - shm->mImage->data = static_cast(shm->mSegment->memory()); - shm->mInfo.readOnly = False; + mInfo.shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0600); + if (mInfo.shmid == -1) { + return false; + } -#if defined(MOZ_WIDGET_GTK) - gShmError = 0; - XErrorHandler previousHandler = XSetErrorHandler(TrapShmError); - Status attachOk = XShmAttach(aDisplay, &shm->mInfo); - XSync(aDisplay, False); - XSetErrorHandler(previousHandler); - if (gShmError) { - attachOk = 0; - } -#elif defined(MOZ_WIDGET_QT) - Status attachOk = XShmAttach(aDisplay, &shm->mInfo); + mInfo.shmaddr = (char *)shmat(mInfo.shmid, nullptr, 0); + if (mInfo.shmaddr == (void *)-1) { + nsPrintfCString warning("shmat(): %s (%d)\n", strerror(errno), errno); + NS_WARNING(warning.get()); + return false; + } + + // Mark the handle as deleted so that, should this process go away, the + // segment is cleaned up. + shmctl(mInfo.shmid, IPC_RMID, 0); + +#ifdef DEBUG + struct shmid_ds info; + if (shmctl(mInfo.shmid, IPC_STAT, &info) < 0) { + return false; + } + + MOZ_ASSERT(size <= info.shm_segsz, + "Segment doesn't have enough space!"); #endif - if (!attachOk) { - // Assume XShm isn't available, and don't attempt to use it - // again. - gShmAvailable = false; - return nullptr; - } + mInfo.readOnly = False; - shm->mXAttached = true; - shm->mSize = aSize; - switch (shm->mImage->depth) { - case 32: - if ((shm->mImage->red_mask == 0xff0000) && - (shm->mImage->green_mask == 0xff00) && - (shm->mImage->blue_mask == 0xff)) { - shm->mFormat = SurfaceFormat::B8G8R8A8; - memset(shm->mSegment->memory(), 0, size); - break; - } - goto unsupported; - case 24: - // Only xRGB is supported. - if ((shm->mImage->red_mask == 0xff0000) && - (shm->mImage->green_mask == 0xff00) && - (shm->mImage->blue_mask == 0xff)) { - shm->mFormat = SurfaceFormat::B8G8R8X8; - memset(shm->mSegment->memory(), 0xFF, size); - break; - } - goto unsupported; - case 16: - shm->mFormat = SurfaceFormat::R5G6B5_UINT16; - memset(shm->mSegment->memory(), 0, size); - break; - unsupported: - default: - NS_WARNING("Unsupported XShm Image format!"); - gShmAvailable = false; - return nullptr; + mImage->data = mInfo.shmaddr; + + return true; +} + +void +nsShmImage::DestroyShmSegment() +{ + if (mInfo.shmid != -1) { + shmdt(mInfo.shmaddr); + mInfo.shmid = -1; + } +} + +bool +nsShmImage::CreateImage(const LayoutDeviceIntSize& aSize, + Display* aDisplay, Visual* aVisual, unsigned int aDepth) +{ + mDisplay = aDisplay; + mImage = XShmCreateImage(aDisplay, aVisual, aDepth, + ZPixmap, nullptr, + &mInfo, + aSize.width, aSize.height); + if (!mImage || !CreateShmSegment()) { + return false; + } + +#if defined(MOZ_WIDGET_GTK) + gShmError = 0; + XErrorHandler previousHandler = XSetErrorHandler(TrapShmError); + Status attachOk = XShmAttach(aDisplay, &mInfo); + XSync(aDisplay, False); + XSetErrorHandler(previousHandler); + if (gShmError) { + attachOk = 0; + } +#elif defined(MOZ_WIDGET_QT) + Status attachOk = XShmAttach(aDisplay, &mInfo); +#endif + + if (!attachOk) { + // Assume XShm isn't available, and don't attempt to use it + // again. + gShmAvailable = false; + return false; + } + + mXAttached = true; + mSize = aSize; + mFormat = SurfaceFormat::UNKNOWN; + switch (mImage->depth) { + case 32: + if ((mImage->red_mask == 0xff0000) && + (mImage->green_mask == 0xff00) && + (mImage->blue_mask == 0xff)) { + mFormat = SurfaceFormat::B8G8R8A8; + memset(mImage->data, 0, mImage->bytes_per_line * mImage->height); } - return shm.forget(); + break; + case 24: + // Only xRGB is supported. + if ((mImage->red_mask == 0xff0000) && + (mImage->green_mask == 0xff00) && + (mImage->blue_mask == 0xff)) { + mFormat = SurfaceFormat::B8G8R8X8; + memset(mImage->data, 0xFF, mImage->bytes_per_line * mImage->height); + } + break; + case 16: + mFormat = SurfaceFormat::R5G6B5_UINT16; + memset(mImage->data, 0, mImage->bytes_per_line * mImage->height); + break; + } + + if (mFormat == SurfaceFormat::UNKNOWN) { + NS_WARNING("Unsupported XShm Image format!"); + gShmAvailable = false; + return false; + } + + return true; +} + +nsShmImage::~nsShmImage() +{ + if (mImage) { + mozilla::FinishX(mDisplay); + if (mXAttached) { + XShmDetach(mDisplay, &mInfo); + } + XDestroyImage(mImage); + } + DestroyShmSegment(); } already_AddRefed nsShmImage::CreateDrawTarget() { return gfxPlatform::GetPlatform()->CreateDrawTargetForData( - static_cast(mSegment->memory()), + reinterpret_cast(mImage->data), mSize.ToUnknownSize(), mImage->bytes_per_line, mFormat); @@ -189,15 +248,18 @@ nsShmImage::EnsureShmImage(const LayoutDeviceIntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth, RefPtr& aImage) { - if (!aImage || aImage->Size() != aSize) { - // Because we XSync() after XShmAttach() to trap errors, we - // know that the X server has the old image's memory mapped - // into its address space, so it's OK to destroy the old image - // here even if there are outstanding Puts. The Detach is - // ordered after the Puts. - aImage = nsShmImage::Create(aSize, aDisplay, aVisual, aDepth); + if (!aImage || aImage->Size() != aSize) { + // Because we XSync() after XShmAttach() to trap errors, we + // know that the X server has the old image's memory mapped + // into its address space, so it's OK to destroy the old image + // here even if there are outstanding Puts. The Detach is + // ordered after the Puts. + aImage = new nsShmImage; + if (!aImage->CreateImage(aSize, aDisplay, aVisual, aDepth)) { + aImage = nullptr; } - return !aImage ? nullptr : aImage->CreateDrawTarget(); + } + return !aImage ? nullptr : aImage->CreateDrawTarget(); } -#endif // defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV) +#endif // MOZ_HAVE_SHMIMAGE diff --git a/widget/nsShmImage.h b/widget/nsShmImage.h index a0cd94a22ed1..27c9d23f5554 100644 --- a/widget/nsShmImage.h +++ b/widget/nsShmImage.h @@ -7,9 +7,7 @@ #ifndef __mozilla_widget_nsShmImage_h__ #define __mozilla_widget_nsShmImage_h__ -#include "mozilla/ipc/SharedMemorySysV.h" - -#if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV) +#if defined(MOZ_X11) # define MOZ_HAVE_SHMIMAGE #endif @@ -19,9 +17,7 @@ #include "nsIWidget.h" #include "nsAutoPtr.h" -#include "mozilla/X11Util.h" #include -#include #include #ifdef MOZ_WIDGET_QT @@ -33,30 +29,13 @@ class nsShmImage { // bug 1168843, compositor thread may create shared memory instances that are destroyed by main thread on shutdown, so this must use thread-safe RC to avoid hitting assertion NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsShmImage) - typedef mozilla::ipc::SharedMemorySysV SharedMemorySysV; - public: static bool UseShm(); - static already_AddRefed - Create(const mozilla::LayoutDeviceIntSize& aSize, - Display* aDisplay, Visual* aVisual, unsigned int aDepth); static already_AddRefed EnsureShmImage(const mozilla::LayoutDeviceIntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth, RefPtr& aImage); -private: - ~nsShmImage() { - if (mImage) { - mozilla::FinishX(mDisplay); - if (mXAttached) { - XShmDetach(mDisplay, &mInfo); - } - XDestroyImage(mImage); - } - } - -public: already_AddRefed CreateDrawTarget(); #ifdef MOZ_WIDGET_GTK @@ -74,9 +53,16 @@ private: , mDisplay(nullptr) , mFormat(mozilla::gfx::SurfaceFormat::UNKNOWN) , mXAttached(false) - { mInfo.shmid = SharedMemorySysV::NULLHandle(); } + { mInfo.shmid = -1; } + + ~nsShmImage(); + + bool CreateShmSegment(); + void DestroyShmSegment(); + + bool CreateImage(const mozilla::LayoutDeviceIntSize& aSize, + Display* aDisplay, Visual* aVisual, unsigned int aDepth); - RefPtr mSegment; XImage* mImage; Display* mDisplay; XShmSegmentInfo mInfo; From 0acb222f9a35d4973e71cec98dd3bcbde107fe2f Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Sat, 13 Feb 2016 12:10:02 -0500 Subject: [PATCH 047/115] Bug 1248203 - streamline h2 stream flow control buffer r=hurley --- netwerk/base/SimpleBuffer.cpp | 95 +++++++++++++++++++++++++++ netwerk/base/SimpleBuffer.h | 57 ++++++++++++++++ netwerk/base/moz.build | 1 + netwerk/protocol/http/ASpdySession.h | 2 +- netwerk/protocol/http/Http2Stream.cpp | 55 +++++----------- netwerk/protocol/http/Http2Stream.h | 6 +- 6 files changed, 172 insertions(+), 44 deletions(-) create mode 100644 netwerk/base/SimpleBuffer.cpp create mode 100644 netwerk/base/SimpleBuffer.h diff --git a/netwerk/base/SimpleBuffer.cpp b/netwerk/base/SimpleBuffer.cpp new file mode 100644 index 000000000000..d0e311f77cdf --- /dev/null +++ b/netwerk/base/SimpleBuffer.cpp @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "SimpleBuffer.h" +#include + +namespace mozilla { +namespace net { + +SimpleBuffer::SimpleBuffer() + : mStatus(NS_OK) + , mAvailable(0) +{ + mOwningThread = PR_GetCurrentThread(); +} + +nsresult SimpleBuffer::Write(char *src, size_t len) +{ + MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread); + if (NS_FAILED(mStatus)) { + return mStatus; + } + + while (len > 0) { + SimpleBufferPage *p = mBufferList.getLast(); + if (p && (p->mWriteOffset == SimpleBufferPage::kSimpleBufferPageSize)) { + // no room.. make a new page + p = nullptr; + } + if (!p) { + p = new (fallible) SimpleBufferPage(); + if (!p) { + mStatus = NS_ERROR_OUT_OF_MEMORY; + return mStatus; + } + mBufferList.insertBack(p); + } + size_t roomOnPage = SimpleBufferPage::kSimpleBufferPageSize - p->mWriteOffset; + size_t toWrite = std::min(roomOnPage, len); + memcpy(p->mBuffer + p->mWriteOffset, src, toWrite); + src += toWrite; + len -= toWrite; + p->mWriteOffset += toWrite; + mAvailable += toWrite; + } + return NS_OK; +} + +size_t SimpleBuffer::Read(char *dest, size_t maxLen) +{ + MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread); + if (NS_FAILED(mStatus)) { + return 0; + } + + size_t rv = 0; + for (SimpleBufferPage *p = mBufferList.getFirst(); + p && (rv < maxLen); p = mBufferList.getFirst()) { + size_t avail = p->mWriteOffset - p->mReadOffset; + size_t toRead = std::min(avail, (maxLen - rv)); + memcpy(dest + rv, p->mBuffer + p->mReadOffset, toRead); + rv += toRead; + p->mReadOffset += toRead; + if (p->mReadOffset == p->mWriteOffset) { + p->remove(); + delete p; + } + } + + MOZ_ASSERT(mAvailable >= rv); + mAvailable -= rv; + return rv; +} + +size_t SimpleBuffer::Available() +{ + MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread); + return NS_SUCCEEDED(mStatus) ? mAvailable : 0; +} + +void SimpleBuffer::Clear() +{ + MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread); + SimpleBufferPage *p; + while ((p = mBufferList.popFirst())) { + delete p; + } + mAvailable = 0; +} + +} // namespace net +} // namespace mozilla diff --git a/netwerk/base/SimpleBuffer.h b/netwerk/base/SimpleBuffer.h new file mode 100644 index 000000000000..765239001319 --- /dev/null +++ b/netwerk/base/SimpleBuffer.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef SimpleBuffer_h__ +#define SimpleBuffer_h__ + +/* + This class is similar to a nsPipe except it does not have any locking, stores + an unbounded amount of data, can only be used on one thread, and has much + simpler result code semantics to deal with. +*/ + +#include "prtypes.h" +#include "mozilla/LinkedList.h" +#include "nsIThreadInternal.h" + +namespace mozilla { +namespace net { + +class SimpleBufferPage : public LinkedListElement +{ +public: + SimpleBufferPage() : mReadOffset(0), mWriteOffset(0) {} + static const size_t kSimpleBufferPageSize = 32000; + +private: + friend class SimpleBuffer; + char mBuffer[kSimpleBufferPageSize]; + size_t mReadOffset; + size_t mWriteOffset; +}; + +class SimpleBuffer +{ +public: + SimpleBuffer(); + ~SimpleBuffer() {} + + nsresult Write(char *stc, size_t len); // return OK or OUT_OF_MEMORY + size_t Read(char *dest, size_t maxLen); // return bytes read + size_t Available(); + void Clear(); + +private: + PRThread *mOwningThread; + nsresult mStatus; + AutoCleanLinkedList mBufferList; + size_t mAvailable; +}; + +} // namespace net +} // namespace mozilla + +#endif diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index da47fe601825..21bec45a3a74 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -254,6 +254,7 @@ UNIFIED_SOURCES += [ 'ProxyAutoConfig.cpp', 'RedirectChannelRegistrar.cpp', 'SchedulingContextService.cpp', + 'SimpleBuffer.cpp', 'StreamingProtocolService.cpp', 'Tickler.cpp', 'TLSServerSocket.cpp', diff --git a/netwerk/protocol/http/ASpdySession.h b/netwerk/protocol/http/ASpdySession.h index b8d9899a6eb8..ec5d2c885d16 100644 --- a/netwerk/protocol/http/ASpdySession.h +++ b/netwerk/protocol/http/ASpdySession.h @@ -68,7 +68,7 @@ public: // this could go either way, but because there are network instances of // it being a hard error we should consider it hard. - if (code == NS_ERROR_FAILURE) { + if (code == NS_ERROR_FAILURE || code == NS_ERROR_OUT_OF_MEMORY) { return false; } diff --git a/netwerk/protocol/http/Http2Stream.cpp b/netwerk/protocol/http/Http2Stream.cpp index 40df0f262e41..73d41a1550b8 100644 --- a/netwerk/protocol/http/Http2Stream.cpp +++ b/netwerk/protocol/http/Http2Stream.cpp @@ -235,28 +235,12 @@ Http2Stream::ReadSegments(nsAHttpSegmentReader *reader, return rv; } -static bool -IsDataAvailable(nsIInputStream *stream) -{ - if (!stream) { - return false; - } - uint64_t avail; - if (NS_FAILED(stream->Available(&avail))) { - return false; - } - return (avail > 0); -} - uint64_t Http2Stream::LocalUnAcked() { // reduce unacked by the amount of undelivered data // to help assert flow control - uint64_t undelivered = 0; - if (mInputBufferIn) { - mInputBufferIn->Available(&undelivered); - } + uint64_t undelivered = mSimpleBuffer.Available(); if (undelivered > mLocalUnacked) { return 0; @@ -267,25 +251,20 @@ Http2Stream::LocalUnAcked() nsresult Http2Stream::BufferInput(uint32_t count, uint32_t *countWritten) { - static const uint32_t segmentSize = 32768; - char buf[segmentSize]; - - count = std::min(segmentSize, count); - if (!mInputBufferOut) { - NS_NewPipe(getter_AddRefs(mInputBufferIn), getter_AddRefs(mInputBufferOut), - segmentSize, UINT32_MAX); - if (!mInputBufferOut) { - return NS_ERROR_OUT_OF_MEMORY; - } + char buf[SimpleBufferPage::kSimpleBufferPageSize]; + if (SimpleBufferPage::kSimpleBufferPageSize < count) { + count = SimpleBufferPage::kSimpleBufferPageSize; } + mBypassInputBuffer = 1; nsresult rv = mSegmentWriter->OnWriteSegment(buf, count, countWritten); mBypassInputBuffer = 0; + if (NS_SUCCEEDED(rv)) { - uint32_t buffered; - rv = mInputBufferOut->Write(buf, *countWritten, &buffered); - if (NS_SUCCEEDED(rv) && (buffered != *countWritten)) { - rv = NS_ERROR_OUT_OF_MEMORY; + rv = mSimpleBuffer.Write(buf, *countWritten); + if (NS_FAILED(rv)) { + MOZ_ASSERT(rv == NS_ERROR_OUT_OF_MEMORY); + return NS_ERROR_OUT_OF_MEMORY; } } return rv; @@ -295,7 +274,7 @@ bool Http2Stream::DeferCleanup(nsresult status) { // do not cleanup a stream that has data buffered for the transaction - return (NS_SUCCEEDED(status) && IsDataAvailable(mInputBufferIn)); + return (NS_SUCCEEDED(status) && mSimpleBuffer.Available()); } // WriteSegments() is used to read data off the socket. Generally this is @@ -1432,16 +1411,12 @@ Http2Stream::OnWriteSegment(char *buf, // so that other streams can proceed when the gecko caller is not processing // data events fast enough and flow control hasn't caught up yet. This // gets the stored data out of that pipe - if (!mBypassInputBuffer && IsDataAvailable(mInputBufferIn)) { - nsresult rv = mInputBufferIn->Read(buf, count, countWritten); + if (!mBypassInputBuffer && mSimpleBuffer.Available()) { + *countWritten = mSimpleBuffer.Read(buf, count); + MOZ_ASSERT(*countWritten); LOG3(("Http2Stream::OnWriteSegment read from flow control buffer %p %x %d\n", this, mStreamID, *countWritten)); - if (!IsDataAvailable(mInputBufferIn)) { - // drop the pipe if we don't need it anymore - mInputBufferIn = nullptr; - mInputBufferOut = nullptr; - } - return rv; + return NS_OK; } // read from the network diff --git a/netwerk/protocol/http/Http2Stream.h b/netwerk/protocol/http/Http2Stream.h index ca542672bb84..5cb1d15ad7c3 100644 --- a/netwerk/protocol/http/Http2Stream.h +++ b/netwerk/protocol/http/Http2Stream.h @@ -13,6 +13,7 @@ #include "mozilla/UniquePtr.h" #include "nsAHttpTransaction.h" #include "nsISupportsPriority.h" +#include "SimpleBuffer.h" class nsStandardURL; class nsIInputStream; @@ -325,10 +326,9 @@ private: // For Http2Push Http2PushedStream *mPushSource; - // A pipe used to store stream data when the transaction cannot keep up + // Used to store stream data when the transaction channel cannot keep up // and flow control has not yet kicked in. - nsCOMPtr mInputBufferIn; - nsCOMPtr mInputBufferOut; + SimpleBuffer mSimpleBuffer; /// connect tunnels public: From fd14c1771251cd4e0b92028decb678caf3e04855 Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Fri, 12 Feb 2016 09:36:00 -0500 Subject: [PATCH 048/115] Bug 1247432 - Don't do any unnecessary I/O in cache2 after shutdown. r=michal --- netwerk/cache2/CacheObserver.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/netwerk/cache2/CacheObserver.cpp b/netwerk/cache2/CacheObserver.cpp index 282ae13f0e98..2b772bb3546b 100644 --- a/netwerk/cache2/CacheObserver.cpp +++ b/netwerk/cache2/CacheObserver.cpp @@ -503,18 +503,13 @@ CacheObserver::Observe(nsISupports* aSubject, return NS_OK; } - if (!strcmp(aTopic, "profile-before-change")) { + if (!strcmp(aTopic, "profile-change-net-teardown") || + !strcmp(aTopic, "profile-before-change") || + !strcmp(aTopic, "xpcom-shutdown")) { RefPtr service = CacheStorageService::Self(); - if (service) - service->Shutdown(); - - return NS_OK; - } - - if (!strcmp(aTopic, "xpcom-shutdown")) { - RefPtr service = CacheStorageService::Self(); - if (service) + if (service) { service->Shutdown(); + } CacheFileIOManager::Shutdown(); return NS_OK; @@ -522,8 +517,9 @@ CacheObserver::Observe(nsISupports* aSubject, if (!strcmp(aTopic, "last-pb-context-exited")) { RefPtr service = CacheStorageService::Self(); - if (service) + if (service) { service->DropPrivateBrowsingEntries(); + } return NS_OK; } From 06ad5a472fb0cdba7aee22a44e972749f35143de Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Thu, 18 Feb 2016 07:56:00 -0500 Subject: [PATCH 049/115] Bug 961430 - Allow pid be added to the log file name automatically. r=froydnj --- xpcom/base/Logging.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/xpcom/base/Logging.cpp b/xpcom/base/Logging.cpp index 2223f1b4bfbb..2d44d152ee02 100644 --- a/xpcom/base/Logging.cpp +++ b/xpcom/base/Logging.cpp @@ -12,12 +12,19 @@ #include "mozilla/FileUtils.h" #include "mozilla/Mutex.h" #include "mozilla/StaticPtr.h" +#include "mozilla/Snprintf.h" #include "nsClassHashtable.h" #include "nsDebug.h" #include "NSPRLogModulesParser.h" #include "prenv.h" #include "prprf.h" +#ifdef XP_WIN +#include +#else +#include +#include +#endif // NB: Initial amount determined by auditing the codebase for the total amount // of unique module names and padding up to the next power of 2. @@ -49,6 +56,15 @@ void log_print(const LogModule* aModule, va_end(ap); } +int log_pid() +{ +#ifdef XP_WIN + return _getpid(); +#else + return getpid(); +#endif +} + } LogLevel @@ -126,6 +142,18 @@ public: const char* logFile = PR_GetEnv("NSPR_LOG_FILE"); if (logFile && logFile[0]) { + static const char kPIDToken[] = "%PID"; + const char* pidTokenPtr = strstr(logFile, kPIDToken); + char buf[2048]; + if (pidTokenPtr && + snprintf_literal(buf, "%.*s%d%s", + static_cast(pidTokenPtr - logFile), logFile, + detail::log_pid(), + pidTokenPtr + strlen(kPIDToken)) > 0) + { + logFile = buf; + } + mOutFile = fopen(logFile, shouldAppend ? "a" : "w"); } } From 369929445b3b719683a9db76c596190058e04d2d Mon Sep 17 00:00:00 2001 From: Gian-Carlo Pascutto Date: Thu, 18 Feb 2016 17:25:22 +0100 Subject: [PATCH 050/115] Bug 1247236. r=jesup --- dom/media/systemservices/CamerasChild.cpp | 33 +++++++++++++++++++---- dom/media/systemservices/CamerasChild.h | 11 ++++---- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/dom/media/systemservices/CamerasChild.cpp b/dom/media/systemservices/CamerasChild.cpp index eb73b6ee98c6..4d6a54f9d8f4 100644 --- a/dom/media/systemservices/CamerasChild.cpp +++ b/dom/media/systemservices/CamerasChild.cpp @@ -474,13 +474,14 @@ void Shutdown(void) { OffTheBooksMutexAutoLock lock(CamerasSingleton::Mutex()); - if (!CamerasSingleton::Child()) { + CamerasChild* child = CamerasSingleton::Child(); + if (!child) { // We don't want to cause everything to get fired up if we're // really already shut down. LOG(("Shutdown when already shut down")); return; } - GetCamerasChild()->Shutdown(); + child->ShutdownAll(); } class ShutdownRunnable : public nsRunnable { @@ -505,14 +506,22 @@ private: }; void -CamerasChild::Shutdown() +CamerasChild::ShutdownAll() { + // Called with CamerasSingleton::Mutex() held + ShutdownParent(); + ShutdownChild(); +} + +void +CamerasChild::ShutdownParent() +{ + // Called with CamerasSingleton::Mutex() held { MonitorAutoLock monitor(mReplyMonitor); mIPCIsAlive = false; monitor.NotifyAll(); } - if (CamerasSingleton::Thread()) { LOG(("Dispatching actor deletion")); // Delete the parent actor. @@ -524,6 +533,16 @@ CamerasChild::Shutdown() return NS_OK; }); CamerasSingleton::Thread()->Dispatch(deleteRunnable, NS_DISPATCH_NORMAL); + } else { + LOG(("ShutdownParent called without PBackground thread")); + } +} + +void +CamerasChild::ShutdownChild() +{ + // Called with CamerasSingleton::Mutex() held + if (CamerasSingleton::Thread()) { LOG(("PBackground thread exists, dispatching close")); // Dispatch closing the IPC thread back to us when the // BackgroundChild is closed. @@ -607,7 +626,11 @@ CamerasChild::~CamerasChild() { OffTheBooksMutexAutoLock lock(CamerasSingleton::Mutex()); - Shutdown(); + // In normal circumstances we've already shut down and the + // following does nothing. But on fatal IPC errors we will + // get destructed immediately, and should not try to reach + // the parent. + ShutdownChild(); } MOZ_COUNT_DTOR(CamerasChild); diff --git a/dom/media/systemservices/CamerasChild.h b/dom/media/systemservices/CamerasChild.h index b2809f9e98c0..ca51a6014744 100644 --- a/dom/media/systemservices/CamerasChild.h +++ b/dom/media/systemservices/CamerasChild.h @@ -192,13 +192,9 @@ public: const unsigned int device_nameUTF8Length, char* unique_idUTF8, const unsigned int unique_idUTF8Length); - void Shutdown(); + void ShutdownAll(); webrtc::ExternalRenderer* Callback(CaptureEngine aCapEngine, int capture_id); - void AddCallback(const CaptureEngine aCapEngine, const int capture_id, - webrtc::ExternalRenderer* render); - void RemoveCallback(const CaptureEngine aCapEngine, const int capture_id); - private: CamerasChild(); @@ -207,6 +203,11 @@ private: // decidecated Cameras IPC/PBackground thread. bool DispatchToParent(nsIRunnable* aRunnable, MonitorAutoLock& aMonitor); + void AddCallback(const CaptureEngine aCapEngine, const int capture_id, + webrtc::ExternalRenderer* render); + void RemoveCallback(const CaptureEngine aCapEngine, const int capture_id); + void ShutdownParent(); + void ShutdownChild(); nsTArray mCallbacks; // Protects the callback arrays From cacec09ab2e96ce81802e99cea7b81373e65ca5a Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 18 Feb 2016 10:33:57 -0600 Subject: [PATCH 051/115] Bug 1241233 - Odin: don't report symbolicLinks memory usage twice (r=bbouvier) MozReview-Commit-ID: EH7pybiedfB --HG-- extra : rebase_source : ddb3660c47a2b502219d18b418b473a2aebedce3 --- js/src/asmjs/WasmModule.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/js/src/asmjs/WasmModule.cpp b/js/src/asmjs/WasmModule.cpp index 917f9f678ad9..3c1c83b49d9c 100644 --- a/js/src/asmjs/WasmModule.cpp +++ b/js/src/asmjs/WasmModule.cpp @@ -231,14 +231,9 @@ StaticLinkData::clone(JSContext* cx, StaticLinkData* out) const size_t StaticLinkData::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const { - size_t size = internalLinks.sizeOfExcludingThis(mallocSizeOf) + - symbolicLinks.sizeOfExcludingThis(mallocSizeOf) + - SizeOfVectorExcludingThis(funcPtrTables, mallocSizeOf); - - for (const Uint32Vector& offsets : symbolicLinks) - size += offsets.sizeOfExcludingThis(mallocSizeOf); - - return size; + return internalLinks.sizeOfExcludingThis(mallocSizeOf) + + symbolicLinks.sizeOfExcludingThis(mallocSizeOf) + + SizeOfVectorExcludingThis(funcPtrTables, mallocSizeOf); } static size_t From 579a548e8fb1782ed247a7f4bba29175b736951f Mon Sep 17 00:00:00 2001 From: Mason Chang Date: Thu, 18 Feb 2016 08:37:43 -0800 Subject: [PATCH 052/115] Bug 1249033 - Enable Subpixel AA Text on Skia for Dwrite and GDI Fonts. r=jrmuizel --- gfx/2d/DrawTargetSkia.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp index 2b94f7449b8f..b5ae360d8e40 100644 --- a/gfx/2d/DrawTargetSkia.cpp +++ b/gfx/2d/DrawTargetSkia.cpp @@ -554,6 +554,8 @@ DrawTargetSkia::ShouldLCDRenderText(FontType aFontType, AntialiasMode aAntialias if (aAntialiasMode == AntialiasMode::DEFAULT) { switch (aFontType) { case FontType::MAC: + case FontType::GDI: + case FontType::DWRITE: return true; default: // TODO: Figure out what to do for the other platforms. From 267abe39454ab722a3d15a660ce7f89263a0a5bb Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Thu, 18 Feb 2016 11:44:55 -0500 Subject: [PATCH 053/115] Bug 1242724: add an export of runnable_utils.h unless/until it gets moved to xpcom/mfbt r=glandium MozReview-Commit-ID: C577TmkWaWE --- dom/media/moz.build | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dom/media/moz.build b/dom/media/moz.build index cc661e746a6f..33d21433389d 100644 --- a/dom/media/moz.build +++ b/dom/media/moz.build @@ -155,6 +155,11 @@ EXPORTS.mozilla.media.webrtc += [ 'webrtc/WebrtcGlobal.h', ] +if not CONFIG['MOZ_WEBRTC']: + EXPORTS.mtransport += [ + '../../media/mtransport/runnable_utils.h', + ] + IPDL_SOURCES += [ 'webrtc/PWebrtcGlobal.ipdl' ] From b7841a51a85b0788bbea3ffe27e5cb5d071bf1bc Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Thu, 18 Feb 2016 09:09:28 -0800 Subject: [PATCH 054/115] Bug 1248097, part 1 - Fix indentation in SpecialPowersObserver.jsm. r=jmaher --- .../specialpowers/content/SpecialPowersObserver.jsm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/testing/specialpowers/content/SpecialPowersObserver.jsm b/testing/specialpowers/content/SpecialPowersObserver.jsm index 4717142a8cbd..140da657c271 100644 --- a/testing/specialpowers/content/SpecialPowersObserver.jsm +++ b/testing/specialpowers/content/SpecialPowersObserver.jsm @@ -257,12 +257,12 @@ SpecialPowersObserver.prototype.receiveMessage = function(aMessage) { let createdFiles = this._createdFiles; try { aMessage.data.forEach(function(request) { - let testFile = Services.dirsvc.get("ProfD", Ci.nsIFile); - testFile.append(request.name); - let outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); - outStream.init(testFile, 0x02 | 0x08 | 0x20, // PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE - 0666, 0); - if (request.data) { + let testFile = Services.dirsvc.get("ProfD", Ci.nsIFile); + testFile.append(request.name); + let outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); + outStream.init(testFile, 0x02 | 0x08 | 0x20, // PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE + 0666, 0); + if (request.data) { outStream.write(request.data, request.data.length); outStream.close(); } From 0d35a4fff9e4d9937897358a9c49726e06fe98b6 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Thu, 18 Feb 2016 09:09:28 -0800 Subject: [PATCH 055/115] Bug 1248097, part 2 - If no name is specified for createFiles, use createUnique to create one. r=jmaher --- .../Harness_sanity/test_createFiles.html | 23 +++++++++++++++++-- .../content/SpecialPowersObserver.jsm | 9 ++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/testing/mochitest/tests/Harness_sanity/test_createFiles.html b/testing/mochitest/tests/Harness_sanity/test_createFiles.html index f3a7a53175ef..795f6bf08631 100644 --- a/testing/mochitest/tests/Harness_sanity/test_createFiles.html +++ b/testing/mochitest/tests/Harness_sanity/test_createFiles.html @@ -52,15 +52,34 @@ is("emptyfile.txt", f2.name, "second test3 test file should have the right name"); is(f1.size, f1data.length, "size of first file should be length of its data"); is(f2.size, 0, "size of second file should be 0"); - SimpleTest.finish(); + test4(); }, function (msg) { ok(false, "Failed to create files: " + msg); - SimpleTest.finish(); + test4(); } ); }; + // Creating a file without specifying a name should work. + function test4() { + let fdata = "this is same data for a file"; + SpecialPowers.createFiles([{data:fdata}], + function (files) { + is(files.length, 1, "Created 1 file"); + let f = files[0]; + is("[object File]", f.toString(), "first thing in array is a file"); + is(f.size, fdata.length, "test4 size of first file should be length of its data"); + ok(f.name, "test4 test file should have a name"); + SimpleTest.finish(); + }, + function (msg) { + ok(false, "Should be able to create a file without a name without an error"); + SimpleTest.finish(); + } + ); + } + SimpleTest.waitForExplicitFinish(); test1(); diff --git a/testing/specialpowers/content/SpecialPowersObserver.jsm b/testing/specialpowers/content/SpecialPowersObserver.jsm index 140da657c271..191416d59b48 100644 --- a/testing/specialpowers/content/SpecialPowersObserver.jsm +++ b/testing/specialpowers/content/SpecialPowersObserver.jsm @@ -257,11 +257,16 @@ SpecialPowersObserver.prototype.receiveMessage = function(aMessage) { let createdFiles = this._createdFiles; try { aMessage.data.forEach(function(request) { + const filePerms = 0666; let testFile = Services.dirsvc.get("ProfD", Ci.nsIFile); - testFile.append(request.name); + if (request.name) { + testFile.append(request.name); + } else { + testFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, filePerms); + } let outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); outStream.init(testFile, 0x02 | 0x08 | 0x20, // PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE - 0666, 0); + filePerms, 0); if (request.data) { outStream.write(request.data, request.data.length); outStream.close(); From 4a6ef9bb88627d2c79e6a81669f25d2b043267bd Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Thu, 18 Feb 2016 09:09:28 -0800 Subject: [PATCH 056/115] Bug 1248097, part 3 - Add file creation support for options. r=jmaher --- testing/mochitest/tests/Harness_sanity/test_createFiles.html | 4 +++- testing/specialpowers/content/SpecialPowersObserver.jsm | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/testing/mochitest/tests/Harness_sanity/test_createFiles.html b/testing/mochitest/tests/Harness_sanity/test_createFiles.html index 795f6bf08631..502592acc9e0 100644 --- a/testing/mochitest/tests/Harness_sanity/test_createFiles.html +++ b/testing/mochitest/tests/Harness_sanity/test_createFiles.html @@ -11,14 +11,16 @@ From 54a06996e5abb57f8d87c07cf4dc20a0cc918bf8 Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Fri, 19 Feb 2016 08:37:32 +0900 Subject: [PATCH 104/115] Bug 1249212 part 5 - Remove max() clamping from endTime calculation; r=boris Based on discussion at: https://github.com/w3c/web-animations/issues/86 --- dom/animation/KeyframeEffect.cpp | 2 +- .../test/css-animations/file_animation-computed-timing.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dom/animation/KeyframeEffect.cpp b/dom/animation/KeyframeEffect.cpp index 6c076aca81b6..7ef8b2f990ec 100644 --- a/dom/animation/KeyframeEffect.cpp +++ b/dom/animation/KeyframeEffect.cpp @@ -42,7 +42,7 @@ GetComputedTimingDictionary(const ComputedTiming& aComputedTiming, // ComputedTimingProperties aRetVal.mActiveDuration = aComputedTiming.mActiveDuration.ToMilliseconds(); aRetVal.mEndTime - = std::max(aRetVal.mDelay + aRetVal.mActiveDuration + aRetVal.mEndDelay, 0.0); + = aRetVal.mDelay + aRetVal.mActiveDuration + aRetVal.mEndDelay; aRetVal.mLocalTime = AnimationUtils::TimeDurationToDouble(aLocalTime); aRetVal.mProgress = aComputedTiming.mProgress; if (!aRetVal.mProgress.IsNull()) { diff --git a/dom/animation/test/css-animations/file_animation-computed-timing.html b/dom/animation/test/css-animations/file_animation-computed-timing.html index 6a94b23a4d6d..3fae01c34b7b 100644 --- a/dom/animation/test/css-animations/file_animation-computed-timing.html +++ b/dom/animation/test/css-animations/file_animation-computed-timing.html @@ -188,11 +188,11 @@ test(function(t) { }, 'endTime of an infinitely repeating zero-duration animation'); test(function(t) { - // Fill forwards so div.getAnimations()[0] wouldn't return + // Fill forwards so div.getAnimations()[0] won't return an // undefined value. var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s forwards'}); var effect = div.getAnimations()[0].effect; - assert_equals(effect.getComputedTiming().endTime, 0, + assert_equals(effect.getComputedTiming().endTime, -90000, 'Initial value of endTime'); }, 'endTime of an animation that finishes before its startTime'); From 0919a8708bf1cc3175d3093f26b81ee7cf6d6b94 Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Fri, 19 Feb 2016 08:37:32 +0900 Subject: [PATCH 105/115] Bug 1249212 part 6 - Add tests for endTime calculation; r=boris --- .../keyframe-effect/getComputedTiming.html | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/testing/web-platform/tests/web-animations/keyframe-effect/getComputedTiming.html b/testing/web-platform/tests/web-animations/keyframe-effect/getComputedTiming.html index 89a4bddd1d37..7412824e7eee 100644 --- a/testing/web-platform/tests/web-animations/keyframe-effect/getComputedTiming.html +++ b/testing/web-platform/tests/web-animations/keyframe-effect/getComputedTiming.html @@ -198,6 +198,58 @@ gActiveDurationTests.forEach(function(stest) { }, "getComputedTiming().activeDuration for " + stest.desc); }); +var gEndTimeTests = [ + { desc: "an empty KeyframeEffectOptions object", + input: { }, + expected: 0 }, + { desc: "a non-zero duration and default iteration count", + input: { duration: 1000 }, + expected: 1000 }, + { desc: "a non-zero duration and non-default iteration count", + input: { duration: 1000, iterations: 2.5 }, + expected: 2500 }, + { desc: "a non-zero duration and non-zero delay", + input: { duration: 1000, delay: 1500 }, + expected: 2500 }, + { desc: "a non-zero duration, non-zero delay and non-default iteration", + input: { duration: 1000, delay: 1500, iterations: 2 }, + expected: 3500 }, + { desc: "an infinite iteration count", + input: { duration: 1000, iterations: Infinity }, + expected: Infinity }, + { desc: "an infinite duration", + input: { duration: Infinity, iterations: 10 }, + expected: Infinity }, + { desc: "an infinite duration and delay", + input: { duration: Infinity, iterations: 10, delay: 1000 }, + expected: Infinity }, + { desc: "an infinite duration and negative delay", + input: { duration: Infinity, iterations: 10, delay: -1000 }, + expected: Infinity }, + { desc: "an non-zero duration and negative delay", + input: { duration: 1000, iterations: 2, delay: -1000 }, + expected: 1000 }, + { desc: "an non-zero duration and negative delay greater than active " + + "duration", + input: { duration: 1000, iterations: 2, delay: -3000 }, + expected: -1000 }, + { desc: "a zero duration and negative delay", + input: { duration: 0, iterations: 2, delay: -1000 }, + expected: -1000 } +]; + +gEndTimeTests.forEach(function(stest) { + test(function(t) { + var effect = new KeyframeEffectReadOnly(target, + { left: ["10px", "20px"] }, + stest.input); + + assert_equals(effect.getComputedTiming().endTime, + stest.expected); + + }, "getComputedTiming().endTime for " + stest.desc); +}); + done(); From 1a43924a8a653728e848cbc47d038860c74849ec Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Fri, 19 Feb 2016 08:37:32 +0900 Subject: [PATCH 106/115] Bug 1249212 part 7 - Calculate the endTime in GetComputedTimingAt; r=boris Currently endTime is calculated when getComputedTiming() is called. As a result, the value returned there doesn't necessarily reflect what we are using in the model. It would be more simple, consistent and useful if we simply calculate this as part of GetComputedTimingAt and use it both internally and in the result to getComputedTiming(). --- dom/animation/Animation.cpp | 3 +-- dom/animation/KeyframeEffect.cpp | 5 +++-- dom/animation/KeyframeEffect.h | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dom/animation/Animation.cpp b/dom/animation/Animation.cpp index e479be06ea38..b113aae92434 100644 --- a/dom/animation/Animation.cpp +++ b/dom/animation/Animation.cpp @@ -1204,8 +1204,7 @@ Animation::EffectEnd() const return StickyTimeDuration(0); } - return mEffect->SpecifiedTiming().mDelay - + mEffect->GetComputedTiming().mActiveDuration; + return mEffect->GetComputedTiming().mEndTime; } nsIDocument* diff --git a/dom/animation/KeyframeEffect.cpp b/dom/animation/KeyframeEffect.cpp index 7ef8b2f990ec..74844634be3c 100644 --- a/dom/animation/KeyframeEffect.cpp +++ b/dom/animation/KeyframeEffect.cpp @@ -41,8 +41,7 @@ GetComputedTimingDictionary(const ComputedTiming& aComputedTiming, // ComputedTimingProperties aRetVal.mActiveDuration = aComputedTiming.mActiveDuration.ToMilliseconds(); - aRetVal.mEndTime - = aRetVal.mDelay + aRetVal.mActiveDuration + aRetVal.mEndDelay; + aRetVal.mEndTime = aComputedTiming.mEndTime.ToMilliseconds(); aRetVal.mLocalTime = AnimationUtils::TimeDurationToDouble(aLocalTime); aRetVal.mProgress = aComputedTiming.mProgress; if (!aRetVal.mProgress.IsNull()) { @@ -245,6 +244,8 @@ KeyframeEffectReadOnly::GetComputedTimingAt( 1.0f : aTiming.mIterations; result.mActiveDuration = ActiveDuration(result.mDuration, result.mIterations); + // Bug 1244635: Add endDelay to the end time calculation + result.mEndTime = aTiming.mDelay + result.mActiveDuration; result.mFill = aTiming.mFill == dom::FillMode::Auto ? dom::FillMode::None : aTiming.mFill; diff --git a/dom/animation/KeyframeEffect.h b/dom/animation/KeyframeEffect.h index f3b746b2cd88..f4c9d8fc2f88 100644 --- a/dom/animation/KeyframeEffect.h +++ b/dom/animation/KeyframeEffect.h @@ -57,6 +57,10 @@ struct ComputedTiming // Will equal StickyTimeDuration::Forever() if the animation repeats // indefinitely. StickyTimeDuration mActiveDuration; + // The effect end time in local time (i.e. an offset from the effect's + // start time). Will equal StickyTimeDuration::Forever() if the animation + // plays indefinitely. + StickyTimeDuration mEndTime; // Progress towards the end of the current iteration. If the effect is // being sampled backwards, this will go from 1.0 to 0.0. // Will be null if the animation is neither animating nor From a39d4038d7dd1afa4bd787b090cef76ee1ed6b4a Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Thu, 18 Feb 2016 16:57:32 -0800 Subject: [PATCH 107/115] Backed out changeset 40f18aee119c (bug 1232685) for xpcshell crashes in test_framebindings-03.js --HG-- extra : commitid : 97lAjWAXGil --- js/src/doc/Debugger/Conventions.md | 4 +- js/src/jit-test/tests/debug/class-01.js | 15 ---- js/src/jit-test/tests/debug/class-02.js | 20 ----- js/src/jit-test/tests/debug/class-03.js | 23 ------ js/src/jit-test/tests/debug/class-04.js | 22 ------ js/src/jit-test/tests/debug/class-05.js | 31 -------- js/src/jit-test/tests/debug/class-06.js | 22 ------ js/src/jit-test/tests/debug/class-07.js | 21 ----- js/src/vm/Debugger.cpp | 100 +++++------------------- js/src/vm/Debugger.h | 25 +----- js/src/vm/ScopeObject.cpp | 6 +- js/src/vm/ScopeObject.h | 3 +- js/src/vm/Stack-inl.h | 6 -- js/src/vm/Stack.h | 2 - 14 files changed, 27 insertions(+), 273 deletions(-) delete mode 100644 js/src/jit-test/tests/debug/class-01.js delete mode 100644 js/src/jit-test/tests/debug/class-02.js delete mode 100644 js/src/jit-test/tests/debug/class-03.js delete mode 100644 js/src/jit-test/tests/debug/class-04.js delete mode 100644 js/src/jit-test/tests/debug/class-05.js delete mode 100644 js/src/jit-test/tests/debug/class-06.js delete mode 100644 js/src/jit-test/tests/debug/class-07.js diff --git a/js/src/doc/Debugger/Conventions.md b/js/src/doc/Debugger/Conventions.md index b0ae3f564c3a..df7749a73ce5 100644 --- a/js/src/doc/Debugger/Conventions.md +++ b/js/src/doc/Debugger/Conventions.md @@ -111,9 +111,7 @@ resumption value has one of the following forms: was called as a constructor (that is, via a `new` expression), then value serves as the value returned by the function's body, not that produced by the `new` expression: if the value is not an object, - the `new` expression returns the frame's `this` value. Similarly, if - the function is the constructor for a subclass, then a non-object - value may result in a TypeError. + the `new` expression returns the frame's `this` value. { yield: value } : (Not yet implemented.) Yield value immediately as the diff --git a/js/src/jit-test/tests/debug/class-01.js b/js/src/jit-test/tests/debug/class-01.js deleted file mode 100644 index b4e3504da2d8..000000000000 --- a/js/src/jit-test/tests/debug/class-01.js +++ /dev/null @@ -1,15 +0,0 @@ -// |jit-test| error: TypeError - -newGlobal().Debugger(this).onExceptionUnwind = function() { - return { - // Force the return of an illegal value. - return: 1 - } -} - -class forceException extends class {} { - // An explicit exception to trigger unwinding. - // This function will throw for having an uninitialized this. - constructor() {} -} -new forceException; diff --git a/js/src/jit-test/tests/debug/class-02.js b/js/src/jit-test/tests/debug/class-02.js deleted file mode 100644 index 3821eea26ea9..000000000000 --- a/js/src/jit-test/tests/debug/class-02.js +++ /dev/null @@ -1,20 +0,0 @@ -// |jit-test| error: TypeError - -let g = newGlobal(); -let dbg = Debugger(g); - -let forceException = g.eval(` - (class extends class {} { - // Calling this will return a primitive immediately. - constructor() { return {}; } - }) -`); - -dbg.onEnterFrame = function() { - return { - // Force the return of an illegal value. - return: 1 - } -} - -new forceException; diff --git a/js/src/jit-test/tests/debug/class-03.js b/js/src/jit-test/tests/debug/class-03.js deleted file mode 100644 index da1a4f434501..000000000000 --- a/js/src/jit-test/tests/debug/class-03.js +++ /dev/null @@ -1,23 +0,0 @@ -// |jit-test| error: TypeError - -let g = newGlobal(); -let dbg = Debugger(g); - -let forceException = g.eval(` - (class extends class {} { - // Calling this will return a primitive immediately. - constructor() { - debugger; - return {}; - } - }) -`); - -dbg.onDebuggerStatement = function() { - return { - // Force the return of an illegal value. - return: 1 - } -} - -new forceException; diff --git a/js/src/jit-test/tests/debug/class-04.js b/js/src/jit-test/tests/debug/class-04.js deleted file mode 100644 index 5f772e4d384a..000000000000 --- a/js/src/jit-test/tests/debug/class-04.js +++ /dev/null @@ -1,22 +0,0 @@ -// |jit-test| error: TypeError - -let g = newGlobal(); -let dbg = Debugger(g); - -let forceException = g.eval(` - (class extends class {} { - // Calling this will return a primitive on return. - constructor() { return {}; } - }) -`); - -dbg.onEnterFrame = function(f) { - f.onPop = function() { - return { - // Force the return of an illegal value. - return: 1 - } - } -} - -new forceException; diff --git a/js/src/jit-test/tests/debug/class-05.js b/js/src/jit-test/tests/debug/class-05.js deleted file mode 100644 index 4af7c23f832f..000000000000 --- a/js/src/jit-test/tests/debug/class-05.js +++ /dev/null @@ -1,31 +0,0 @@ -// |jit-test| error: TypeError - -let g = newGlobal(); -let dbg = Debugger(g); - -let forceException = g.eval(` - (class extends class {} { - // Calling this will return a primitive immediately. - constructor() { - debugger; - return {}; - } - }) -`); - -let handler = { - hit() { - return { - // Force the return of an illegal value. - return: 1 - } - } -}; - -dbg.onDebuggerStatement = function(frame) { - var line0 = frame.script.getOffsetLocation(frame.offset).lineNumber; - var offs = frame.script.getLineOffsets(line0 + 1); - frame.script.setBreakpoint(offs[0], handler); -} - -new forceException; diff --git a/js/src/jit-test/tests/debug/class-06.js b/js/src/jit-test/tests/debug/class-06.js deleted file mode 100644 index fc6ebdbaa95b..000000000000 --- a/js/src/jit-test/tests/debug/class-06.js +++ /dev/null @@ -1,22 +0,0 @@ -// |jit-test| error: TypeError - -let g = newGlobal(); -let dbg = Debugger(g); - -let forceException = g.eval(` - (class extends class {} { - // Calling this will return a primitive immediately. - constructor() { return {}; } - }) -`); - -dbg.onEnterFrame = function(f) { - f.onStep = function() { - return { - // Force the return of an illegal value. - return: 1 - } - } -} - -new forceException; diff --git a/js/src/jit-test/tests/debug/class-07.js b/js/src/jit-test/tests/debug/class-07.js deleted file mode 100644 index 8613e737bfe1..000000000000 --- a/js/src/jit-test/tests/debug/class-07.js +++ /dev/null @@ -1,21 +0,0 @@ -// |jit-test| error: ReferenceError - -let g = newGlobal(); -let dbg = Debugger(g); - -let forceException = g.eval(` - (class extends class {} { - // Calling this will return a primitive immediately. - constructor() { return {}; } - }) -`); - -dbg.onEnterFrame = function() { - return { - // Force the return undefined, which will throw for returning - // while |this| is still undefined. - return: undefined - } -} -print("break here"); -new forceException; diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 685b7ae14048..0fecd9bed337 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -658,8 +658,7 @@ Debugger::slowPathOnLeaveFrame(JSContext* cx, AbstractFramePtr frame, bool frame Debugger* dbg = Debugger::fromChildJSObject(frameobj); if (dbg->enabled && - !frameobj->getReservedSlot(JSSLOT_DEBUGFRAME_ONPOP_HANDLER).isUndefined()) - { + !frameobj->getReservedSlot(JSSLOT_DEBUGFRAME_ONPOP_HANDLER).isUndefined()) { RootedValue handler(cx, frameobj->getReservedSlot(JSSLOT_DEBUGFRAME_ONPOP_HANDLER)); Maybe ac; @@ -675,10 +674,8 @@ Debugger::slowPathOnLeaveFrame(JSContext* cx, AbstractFramePtr frame, bool frame RootedValue rval(cx); bool hookOk = Invoke(cx, ObjectValue(*frameobj), handler, 1, completion.address(), &rval); - RootedValue nextValue(cx); - JSTrapStatus nextStatus = dbg->parseResumptionValue(ac, hookOk, rval, - frame, &nextValue); + JSTrapStatus nextStatus = dbg->parseResumptionValue(ac, hookOk, rval, &nextValue); /* * At this point, we are back in the debuggee compartment, and any error has @@ -1023,9 +1020,7 @@ private: JSTrapStatus Debugger::handleUncaughtExceptionHelper(Maybe& ac, - MutableHandleValue* vp, bool callHook, - const Maybe& thisVForCheck, - AbstractFramePtr frame) + MutableHandleValue* vp, bool callHook) { JSContext* cx = ac->context()->asJSContext(); if (cx->isExceptionPending()) { @@ -1036,10 +1031,8 @@ Debugger::handleUncaughtExceptionHelper(Maybe& ac, cx->clearPendingException(); RootedValue fval(cx, ObjectValue(*uncaughtExceptionHook)); RootedValue rv(cx); - if (Invoke(cx, ObjectValue(*object), fval, 1, exc.address(), &rv)) { - return vp ? parseResumptionValueHelper(ac, true, rv, thisVForCheck, frame, *vp, false) - : JSTRAP_CONTINUE; - } + if (Invoke(cx, ObjectValue(*object), fval, 1, exc.address(), &rv)) + return vp ? parseResumptionValue(ac, true, rv, *vp, false) : JSTRAP_CONTINUE; } if (cx->isExceptionPending()) { @@ -1076,16 +1069,15 @@ Debugger::handleUncaughtExceptionHelper(Maybe& ac, } JSTrapStatus -Debugger::handleUncaughtException(Maybe& ac, MutableHandleValue vp, bool callHook, - const Maybe& thisVForCheck, AbstractFramePtr frame) +Debugger::handleUncaughtException(Maybe& ac, MutableHandleValue vp, bool callHook) { - return handleUncaughtExceptionHelper(ac, &vp, callHook, thisVForCheck, frame); + return handleUncaughtExceptionHelper(ac, &vp, callHook); } JSTrapStatus Debugger::handleUncaughtException(Maybe& ac, bool callHook) { - return handleUncaughtExceptionHelper(ac, nullptr, callHook, mozilla::Nothing(), NullFramePtr()); + return handleUncaughtExceptionHelper(ac, nullptr, callHook); } /* static */ void @@ -1202,13 +1194,12 @@ ParseResumptionValueAsObject(JSContext* cx, HandleValue rv, JSTrapStatus* status } JSTrapStatus -Debugger::parseResumptionValueHelper(Maybe& ac, bool ok, const Value& rv, - const Maybe& thisVForCheck, AbstractFramePtr frame, - MutableHandleValue vp, bool callHook) +Debugger::parseResumptionValue(Maybe& ac, bool ok, const Value& rv, MutableHandleValue vp, + bool callHook) { vp.setUndefined(); if (!ok) - return handleUncaughtException(ac, vp, callHook, thisVForCheck, frame); + return handleUncaughtException(ac, vp, callHook); if (rv.isUndefined()) { ac.reset(); return JSTRAP_CONTINUE; @@ -1222,25 +1213,10 @@ Debugger::parseResumptionValueHelper(Maybe& ac, bool ok, const JSTrapStatus status = JSTRAP_CONTINUE; RootedValue v(cx); RootedValue rvRoot(cx, rv); - if (!ParseResumptionValueAsObject(cx, rvRoot, &status, &v) || !unwrapDebuggeeValue(cx, &v)) { - return handleUncaughtException(ac, vp, callHook, thisVForCheck, frame); - } - - if (status == JSTRAP_RETURN && thisVForCheck.isSome() && v.isPrimitive()) { - if (v.isUndefined()) { - if (thisVForCheck.ref().isMagic(JS_UNINITIALIZED_LEXICAL)) { - MOZ_ALWAYS_FALSE(ThrowUninitializedThis(cx, frame)); - return handleUncaughtException(ac, vp, callHook, thisVForCheck, frame); - } - - v = thisVForCheck.ref(); - } else { - ReportValueError(cx, JSMSG_BAD_DERIVED_RETURN, JSDVG_IGNORE_STACK, v, nullptr); - return handleUncaughtException(ac, vp, callHook, thisVForCheck, frame); - } + return handleUncaughtException(ac, vp, callHook); } ac.reset(); @@ -1253,43 +1229,6 @@ Debugger::parseResumptionValueHelper(Maybe& ac, bool ok, const return status; } -JSTrapStatus -Debugger::parseResumptionValue(Maybe& ac, bool ok, const Value& rv, - AbstractFramePtr frame, MutableHandleValue vp, bool callHook) -{ - JSContext* cx = ac->context()->asJSContext(); - RootedValue rootThis(cx); - Maybe thisArg; - if (frame.debuggerNeedsCheckPrimitiveReturn()) { - bool success; - { - AutoCompartment ac2(cx, frame.scopeChain()); - success = GetThisValueForDebuggerMaybeOptimizedOut(cx, frame, &rootThis); - } - if (!success || !cx->compartment()->wrap(cx, &rootThis)) { - ac.reset(); - return JSTRAP_ERROR; - } - MOZ_ASSERT_IF(rootThis.isMagic(), rootThis.isMagic(JS_UNINITIALIZED_LEXICAL)); - thisArg.emplace(HandleValue(rootThis)); - } - return parseResumptionValueHelper(ac, ok, rv, thisArg, frame, vp, callHook); -} - -JSTrapStatus -Debugger::parseResumptionValue(Maybe& ac, bool ok, const Value& rv, - const Value& thisV, AbstractFramePtr frame, MutableHandleValue vp, - bool callHook) -{ - JSContext* cx = ac->context()->asJSContext(); - RootedValue rootThis(cx, thisV); - Maybe thisArg; - if (frame.debuggerNeedsCheckPrimitiveReturn()) - thisArg.emplace(rootThis); - - return parseResumptionValueHelper(ac, ok, rv, thisArg, frame, vp, callHook); -} - static bool CallMethodIfPresent(JSContext* cx, HandleObject obj, const char* name, int argc, Value* argv, MutableHandleValue rval) @@ -1322,7 +1261,7 @@ Debugger::fireDebuggerStatement(JSContext* cx, MutableHandleValue vp) RootedValue rv(cx); bool ok = Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, scriptFrame.address(), &rv); - return parseResumptionValue(ac, ok, rv, iter.abstractFramePtr(), vp); + return parseResumptionValue(ac, ok, rv, vp); } JSTrapStatus @@ -1350,7 +1289,7 @@ Debugger::fireExceptionUnwind(JSContext* cx, MutableHandleValue vp) RootedValue rv(cx); bool ok = Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 2, argv.begin(), &rv); - JSTrapStatus st = parseResumptionValue(ac, ok, rv, iter.abstractFramePtr(), vp); + JSTrapStatus st = parseResumptionValue(ac, ok, rv, vp); if (st == JSTRAP_CONTINUE) cx->setPendingException(exc); return st; @@ -1372,8 +1311,7 @@ Debugger::fireEnterFrame(JSContext* cx, AbstractFramePtr frame, MutableHandleVal RootedValue rv(cx); bool ok = Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, scriptFrame.address(), &rv); - - return parseResumptionValue(ac, ok, rv, MagicValue(JS_UNINITIALIZED_LEXICAL), frame, vp); + return parseResumptionValue(ac, ok, rv, vp); } void @@ -1602,8 +1540,7 @@ Debugger::onTrap(JSContext* cx, MutableHandleValue vp) RootedValue rv(cx); Rooted handler(cx, bp->handler); bool ok = CallMethodIfPresent(cx, handler, "hit", 1, scriptFrame.address(), &rv); - JSTrapStatus st = dbg->parseResumptionValue(ac, ok, rv, iter.abstractFramePtr(), - vp, true); + JSTrapStatus st = dbg->parseResumptionValue(ac, ok, rv, vp, true); if (st != JSTRAP_CONTINUE) return st; @@ -1692,9 +1629,8 @@ Debugger::onSingleStep(JSContext* cx, MutableHandleValue vp) const Value& handler = frame->getReservedSlot(JSSLOT_DEBUGFRAME_ONSTEP_HANDLER); RootedValue rval(cx); - bool ok = Invoke(cx, ObjectValue(*frame), handler, 0, nullptr, &rval); - JSTrapStatus st = dbg->parseResumptionValue(ac, ok, rval, iter.abstractFramePtr(), vp); + JSTrapStatus st = dbg->parseResumptionValue(ac, ok, rval, vp); if (st != JSTRAP_CONTINUE) return st; } @@ -6516,7 +6452,7 @@ DebuggerFrame_getThis(JSContext* cx, unsigned argc, Value* vp) UpdateFrameIterPc(iter); - if (!GetThisValueForDebuggerMaybeOptimizedOut(cx, frame, &thisv)) + if (!GetThisValueForDebuggerMaybeOptimizedOut(cx, frame, iter.pc(), &thisv)) return false; } diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index efe5f27cd23d..bee5e81741fb 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -477,13 +477,10 @@ class Debugger : private mozilla::LinkedListElement * debuggee compartment. */ JSTrapStatus handleUncaughtException(mozilla::Maybe& ac, bool callHook); - JSTrapStatus handleUncaughtException(mozilla::Maybe& ac, MutableHandleValue vp, bool callHook, - const mozilla::Maybe& thisVForCheck = mozilla::Nothing(), - AbstractFramePtr frame = NullFramePtr()); + JSTrapStatus handleUncaughtException(mozilla::Maybe& ac, MutableHandleValue vp, bool callHook); JSTrapStatus handleUncaughtExceptionHelper(mozilla::Maybe& ac, - MutableHandleValue* vp, bool callHook, - const mozilla::Maybe& thisVForCheck, AbstractFramePtr frame); + MutableHandleValue* vp, bool callHook); /* * Handle the result of a hook that is expected to return a resumption @@ -510,25 +507,9 @@ class Debugger : private mozilla::LinkedListElement * anything else - Make a new TypeError the pending exception and * return handleUncaughtException(ac, vp, callHook). */ - JSTrapStatus parseResumptionValue(mozilla::Maybe& ac, bool OK, const Value& rv, - AbstractFramePtr frame, MutableHandleValue vp, - bool callHook = true); - - /* - * When we run the onEnterFrame hook, the |this| slot hasn't been fully - * initialized, because the initialzation happens in the function's - * prologue. To combat this, we pass the this for the primitive return - * check directly. When bug 1249193 is fixed, this overload should be - * removed. - */ - JSTrapStatus parseResumptionValue(mozilla::Maybe& ac, bool OK, const Value& rv, - const Value& thisVForCheck, AbstractFramePtr frame, + JSTrapStatus parseResumptionValue(mozilla::Maybe& ac, bool ok, const Value& rv, MutableHandleValue vp, bool callHook = true); - JSTrapStatus parseResumptionValueHelper(mozilla::Maybe& ac, bool ok, const Value& rv, - const mozilla::Maybe& thisVForCheck, AbstractFramePtr frame, - MutableHandleValue vp, bool callHook); - GlobalObject* unwrapDebuggeeArgument(JSContext* cx, const Value& v); static void traceObject(JSTracer* trc, JSObject* obj); diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 68273fdd70ab..4e9bcd912c5c 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -3157,10 +3157,10 @@ js::GetModuleEnvironmentForScript(JSScript* script) } bool -js::GetThisValueForDebuggerMaybeOptimizedOut(JSContext* cx, AbstractFramePtr frame, MutableHandleValue res) +js::GetThisValueForDebuggerMaybeOptimizedOut(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc, + MutableHandleValue res) { - RootedScript firstScript(cx, frame.script()); - for (ScopeIter si(cx, frame, firstScript->main()); !si.done(); ++si) { + for (ScopeIter si(cx, frame, pc); !si.done(); ++si) { if (si.type() == ScopeIter::Module) { res.setUndefined(); return true; diff --git a/js/src/vm/ScopeObject.h b/js/src/vm/ScopeObject.h index 907a0da0a72d..a8109db504a1 100644 --- a/js/src/vm/ScopeObject.h +++ b/js/src/vm/ScopeObject.h @@ -1543,7 +1543,8 @@ uint32_t StaticScopeChainLength(JSObject* staticScope); ModuleEnvironmentObject* GetModuleEnvironmentForScript(JSScript* script); -bool GetThisValueForDebuggerMaybeOptimizedOut(JSContext* cx, AbstractFramePtr frame, MutableHandleValue res); +bool GetThisValueForDebuggerMaybeOptimizedOut(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc, + MutableHandleValue res); bool CheckVarNameConflict(JSContext* cx, Handle lexicalScope, HandlePropertyName name); diff --git a/js/src/vm/Stack-inl.h b/js/src/vm/Stack-inl.h index c688bc4f7a96..e58bdfb28ca1 100644 --- a/js/src/vm/Stack-inl.h +++ b/js/src/vm/Stack-inl.h @@ -850,12 +850,6 @@ AbstractFramePtr::popWith(JSContext* cx) const asBaselineFrame()->popWith(cx); } -inline bool -AbstractFramePtr::debuggerNeedsCheckPrimitiveReturn() const -{ - return script()->isDerivedClassConstructor(); -} - ActivationEntryMonitor::~ActivationEntryMonitor() { if (entryMonitor_) diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index 8e12fbf0687d..7738375a8b5d 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -216,8 +216,6 @@ class AbstractFramePtr inline Value newTarget() const; - inline bool debuggerNeedsCheckPrimitiveReturn() const; - inline bool isFunctionFrame() const; inline bool isNonStrictDirectEvalFrame() const; inline bool isStrictEvalFrame() const; From 4c328ff55151e58848dc081cb7d9f4100f27e2b6 Mon Sep 17 00:00:00 2001 From: "Thinker K.F. Li" Date: Thu, 18 Feb 2016 17:12:40 -0800 Subject: [PATCH 108/115] Bug 1244943 - Make PostProcessLayers aware of preserve-3d. r=mattwoodrow --HG-- extra : commitid : S1u1kZ0sGV --- .../composite/LayerManagerComposite.cpp | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index b3eb72d38084..10a8b738c0b4 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -217,14 +217,54 @@ IntersectMaybeRects(const Maybe& aRect1, const Maybe& aRect2 return aRect2; } +/** + * Get accumulated transform of from the context creating layer to the + * given layer. + */ +static Matrix4x4 +GetAccTransformIn3DContext(Layer* aLayer) { + Matrix4x4 transform = aLayer->GetLocalTransform(); + for (Layer* layer = aLayer->GetParent(); + layer && layer->Extend3DContext(); + layer = layer->GetParent()) { + transform = transform * layer->GetLocalTransform(); + } + return transform; +} + void LayerManagerComposite::PostProcessLayers(Layer* aLayer, nsIntRegion& aOpaqueRegion, LayerIntRegion& aVisibleRegion, const Maybe& aClipFromAncestors) { + if (aLayer->Extend3DContext()) { + // For layers participating 3D rendering context, their visible + // region should be empty (invisible), so we pass through them + // without doing anything. + + // Direct children of the establisher may have a clip, becaue the + // item containing it; ex. of nsHTMLScrollFrame, may give it one. + Maybe layerClip = + aLayer->AsLayerComposite()->GetShadowClipRect(); + Maybe ancestorClipForChildren = + IntersectMaybeRects(layerClip, aClipFromAncestors); + MOZ_ASSERT(!layerClip || !aLayer->Combines3DTransformWithAncestors(), + "Only direct children of the establisher could have a clip"); + + for (Layer* child = aLayer->GetLastChild(); + child; + child = child->GetPrevSibling()) { + PostProcessLayers(child, aOpaqueRegion, aVisibleRegion, + ancestorClipForChildren); + } + return; + } + nsIntRegion localOpaque; - Matrix4x4 transform = aLayer->GetLocalTransform(); + // Treat layers on the path to the root of the 3D rendering context as + // a giant layer if it is a leaf. + Matrix4x4 transform = GetAccTransformIn3DContext(aLayer); Matrix transform2d; Maybe integerTranslation; // If aLayer has a simple transform (only an integer translation) then we @@ -242,6 +282,9 @@ LayerManagerComposite::PostProcessLayers(Layer* aLayer, // from our ancestors. LayerComposite* composite = aLayer->AsLayerComposite(); Maybe layerClip = composite->GetShadowClipRect(); + MOZ_ASSERT(!layerClip || !aLayer->Combines3DTransformWithAncestors(), + "The layer with a clip should not participate " + "a 3D rendering context"); Maybe outsideClip = IntersectMaybeRects(layerClip, aClipFromAncestors); From 320651835078b80e68917e5787229e39d6f26a5c Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Thu, 18 Feb 2016 15:27:48 +1100 Subject: [PATCH 109/115] Bug 1248909: [MSE] P2. Simplify diagnostic. r=gerald Also, an assert could have been incorrectly triggered, if eviction occurred on a source buffer while data was also being appended to it. MozReview-Commit-ID: 6gVHZdbL07B --- dom/media/mediasource/TrackBuffersManager.cpp | 7 ------- dom/media/mediasource/TrackBuffersManager.h | 5 +---- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp index 3c9c6c9cc0d2..e2e9e0815381 100644 --- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -104,7 +104,6 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBufferAttributes* aAttribute , mEvictionOccurred(false) , mMonitor("TrackBuffersManager") , mAppendRunning(false) - , mSegmentParserLoopRunning(false) { MOZ_ASSERT(NS_IsMainThread(), "Must be instanciated on the main thread"); } @@ -301,7 +300,6 @@ void TrackBuffersManager::CompleteResetParserState() { MOZ_ASSERT(OnTaskQueue()); - MOZ_DIAGNOSTIC_ASSERT(!mSegmentParserLoopRunning); MSE_DEBUG(""); for (auto& track : GetTracksList()) { @@ -437,7 +435,6 @@ bool TrackBuffersManager::CodedFrameRemoval(TimeInterval aInterval) { MOZ_ASSERT(OnTaskQueue()); - MOZ_ASSERT(!mSegmentParserLoopRunning, "Logic error: Append in progress"); MSE_DEBUG("From %.2fs to %.2f", aInterval.mStart.ToSeconds(), aInterval.mEnd.ToSeconds()); @@ -576,8 +573,6 @@ TrackBuffersManager::SegmentParserLoop() { MOZ_ASSERT(OnTaskQueue()); - mSegmentParserLoopRunning = true; - while (true) { // 1. If the input buffer is empty, then jump to the need more data step below. if (!mInputBuffer || mInputBuffer->IsEmpty()) { @@ -702,7 +697,6 @@ TrackBuffersManager::NeedMoreData() MSE_DEBUG(""); RestoreCachedVariables(); mAppendRunning = false; - mSegmentParserLoopRunning = false; { // Wake-up any pending Abort() MonitorAutoLock mon(mMonitor); @@ -716,7 +710,6 @@ TrackBuffersManager::RejectAppend(nsresult aRejectValue, const char* aName) { MSE_DEBUG("rv=%d", aRejectValue); mAppendRunning = false; - mSegmentParserLoopRunning = false; { // Wake-up any pending Abort() MonitorAutoLock mon(mMonitor); diff --git a/dom/media/mediasource/TrackBuffersManager.h b/dom/media/mediasource/TrackBuffersManager.h index f150e0d49819..6188df4d5474 100644 --- a/dom/media/mediasource/TrackBuffersManager.h +++ b/dom/media/mediasource/TrackBuffersManager.h @@ -350,11 +350,8 @@ private: // Monitor to protect following objects accessed across multipple threads. // mMonitor is also notified if the value of mAppendRunning becomes false. mutable Monitor mMonitor; - // Set to true while SegmentParserLoop is running. + // Set to true while a BufferAppend is running or is pending. Atomic mAppendRunning; - // Set to true while SegmentParserLoop is running. - // This is for diagnostic only. Only accessed on the task queue. - bool mSegmentParserLoopRunning; // Stable audio and video track time ranges. media::TimeIntervals mVideoBufferedRanges; media::TimeIntervals mAudioBufferedRanges; From 79b309644997caa28d446d6a4fcbe8bedc9af783 Mon Sep 17 00:00:00 2001 From: Sambuddha Basu Date: Thu, 18 Feb 2016 17:26:09 -0800 Subject: [PATCH 110/115] Bug 952564 - Disallow empty lists in moz.build variables r=gps --HG-- extra : rebase_source : 9a70b6a3150fe898a724a43815dc923bb0d70b89 extra : amend_source : 7aa800ef61427117e5dc461443f82ebd403d8164 --- dom/media/webspeech/synth/moz.build | 2 -- python/mozbuild/mozbuild/frontend/sandbox.py | 4 ++++ .../data/reader-error-empty-list/moz.build | 5 +++++ .../mozbuild/test/frontend/test_reader.py | 15 +++++++++++++-- 4 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 python/mozbuild/mozbuild/test/frontend/data/reader-error-empty-list/moz.build diff --git a/dom/media/webspeech/synth/moz.build b/dom/media/webspeech/synth/moz.build index de03c2fc4a4a..4a2eae08e783 100644 --- a/dom/media/webspeech/synth/moz.build +++ b/dom/media/webspeech/synth/moz.build @@ -41,8 +41,6 @@ if CONFIG['MOZ_WEBSPEECH']: 'test/nsFakeSynthServices.cpp' ] - DIRS = [] - if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': DIRS += ['windows'] diff --git a/python/mozbuild/mozbuild/frontend/sandbox.py b/python/mozbuild/mozbuild/frontend/sandbox.py index 0ae8e30daefb..9f2666f8c51b 100644 --- a/python/mozbuild/mozbuild/frontend/sandbox.py +++ b/python/mozbuild/mozbuild/frontend/sandbox.py @@ -286,6 +286,10 @@ class Sandbox(dict): if key in self._context and self._context[key] is not value: raise KeyError('global_ns', 'reassign', key) + if (key not in self._context and isinstance(value, (list, dict)) + and not value): + raise KeyError('Variable %s assigned an empty value.' % key) + self._context[key] = value else: dict.__setitem__(self, key, value) diff --git a/python/mozbuild/mozbuild/test/frontend/data/reader-error-empty-list/moz.build b/python/mozbuild/mozbuild/test/frontend/data/reader-error-empty-list/moz.build new file mode 100644 index 000000000000..fc4ce0217978 --- /dev/null +++ b/python/mozbuild/mozbuild/test/frontend/data/reader-error-empty-list/moz.build @@ -0,0 +1,5 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# Any copyright is dedicated to the Public Domain. +# http://creativecommons.org/publicdomain/zero/1.0/ + +DIRS = [] diff --git a/python/mozbuild/mozbuild/test/frontend/test_reader.py b/python/mozbuild/mozbuild/test/frontend/test_reader.py index 730588b71823..d50a0658354a 100644 --- a/python/mozbuild/mozbuild/test/frontend/test_reader.py +++ b/python/mozbuild/mozbuild/test/frontend/test_reader.py @@ -11,8 +11,10 @@ import unittest from mozunit import main from mozbuild.frontend.context import BugzillaComponent -from mozbuild.frontend.reader import BuildReaderError -from mozbuild.frontend.reader import BuildReader +from mozbuild.frontend.reader import ( + BuildReaderError, + BuildReader, +) from mozbuild.test.common import MockConfig @@ -246,6 +248,15 @@ class TestBuildReader(unittest.TestCase): contexts = list(reader.read_topsrcdir()) + def test_error_empty_list(self): + reader = self.reader('reader-error-empty-list') + + with self.assertRaises(BuildReaderError) as bre: + list(reader.read_topsrcdir()) + + e = bre.exception + self.assertIn('Variable DIRS assigned an empty value.', str(e)) + def test_inheriting_variables(self): reader = self.reader('inheriting-variables') From 4be3856258b7c77f083cabe07867a958e4fd4d0a Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Thu, 18 Feb 2016 17:32:34 -0800 Subject: [PATCH 111/115] Bug 1241634: Use is instead of ok in tests. r=me --HG-- extra : rebase_source : 42e2a1dde47957d813f11379bba173f62e8f8d70 --- .../test/mixedcontentblocker/test_frameNavigation.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dom/security/test/mixedcontentblocker/test_frameNavigation.html b/dom/security/test/mixedcontentblocker/test_frameNavigation.html index 3ee7b3876515..5b3ae50b0761 100644 --- a/dom/security/test/mixedcontentblocker/test_frameNavigation.html +++ b/dom/security/test/mixedcontentblocker/test_frameNavigation.html @@ -90,12 +90,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840388 switch(event.data.test) { case "insecurePage_navigate_child": - ok((event.data.msg == "navigated to insecure iframe on insecure page"), "navigating to insecure iframe blocked on insecure page"); + is(event.data.msg, "navigated to insecure iframe on insecure page", "navigating to insecure iframe blocked on insecure page"); testsToRunInsecure["insecurePage_navigate_child"] = true; break; case "insecurePage_navigate_grandchild": - ok((event.data.msg == "navigated to insecure grandchild iframe on insecure page"), "navigating to insecure grandchild iframe blocked on insecure page"); + is(event.data.msg, "navigated to insecure grandchild iframe on insecure page", "navigating to insecure grandchild iframe blocked on insecure page"); testsToRunInsecure["insecurePage_navigate_grandchild"] = true; break; @@ -105,7 +105,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840388 break; case "blankTarget": - ok((event.data.msg == "opened an http link with target=_blank from a secure page"), "couldn't open an http link in a new window from a secure page"); + is(event.data.msg, "opened an http link with target=_blank from a secure page", "couldn't open an http link in a new window from a secure page"); testsToRunSecure["blankTarget"] = true; break; From 2d3967c30f8574ad857737bd183da916b3482487 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 18 Feb 2016 20:57:29 -0500 Subject: [PATCH 112/115] Bug 1019856 - avoid double-buffering in BasicCompositor when window allows it. r=mattwoodrow --- gfx/layers/basic/BasicCompositor.cpp | 63 ++++++++++++++++++++-------- gfx/layers/basic/BasicCompositor.h | 5 +++ widget/cocoa/nsChildView.h | 4 +- widget/cocoa/nsChildView.mm | 3 +- widget/gtk/nsWindow.cpp | 22 ++++------ widget/gtk/nsWindow.h | 7 +++- widget/nsIWidget.h | 6 ++- 7 files changed, 73 insertions(+), 37 deletions(-) diff --git a/gfx/layers/basic/BasicCompositor.cpp b/gfx/layers/basic/BasicCompositor.cpp index 3259fda31018..241dfb4e143a 100644 --- a/gfx/layers/basic/BasicCompositor.cpp +++ b/gfx/layers/basic/BasicCompositor.cpp @@ -153,6 +153,32 @@ BasicCompositor::CreateRenderTargetFromSource(const IntRect &aRect, return nullptr; } +already_AddRefed +BasicCompositor::CreateRenderTargetForWindow(const IntRect& aRect, SurfaceInitMode aInit, BufferMode aBufferMode) +{ + if (aBufferMode != BufferMode::BUFFER_NONE) { + return CreateRenderTarget(aRect, aInit); + } + + MOZ_ASSERT(aRect.width != 0 && aRect.height != 0, "Trying to create a render target of invalid size"); + + if (aRect.width * aRect.height == 0) { + return nullptr; + } + + MOZ_ASSERT(mDrawTarget); + + // Adjust bounds rect to account for new origin at (0, 0). + IntRect rect(0, 0, aRect.XMost(), aRect.YMost()); + RefPtr rt = new BasicCompositingRenderTarget(mDrawTarget, rect); + + if (aInit == INIT_MODE_CLEAR) { + mDrawTarget->ClearRect(gfx::Rect(aRect)); + } + + return rt.forget(); +} + already_AddRefed BasicCompositor::CreateDataTextureSource(TextureFlags aFlags) { @@ -557,13 +583,14 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion, *aRenderBoundsOut = Rect(); } + BufferMode bufferMode = BufferMode::BUFFERED; if (mTarget) { // If we have a copy target, then we don't have a widget-provided mDrawTarget (currently). Use a dummy // placeholder so that CreateRenderTarget() works. mDrawTarget = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget(); } else { // StartRemoteDrawingInRegion can mutate mInvalidRegion. - mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion); + mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion, &bufferMode); if (!mDrawTarget) { return; } @@ -581,7 +608,7 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion, // Setup an intermediate render target to buffer all compositing. We will // copy this into mDrawTarget (the widget), and/or mTarget in EndFrame() RefPtr target = - CreateRenderTarget(mInvalidRect.ToUnknownRect(), INIT_MODE_CLEAR); + CreateRenderTargetForWindow(mInvalidRect.ToUnknownRect(), INIT_MODE_CLEAR, bufferMode); if (!target) { if (!mTarget) { mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion); @@ -592,8 +619,7 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion, // We only allocate a surface sized to the invalidated region, so we need to // translate future coordinates. - mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-mInvalidRect.x, - -mInvalidRect.y)); + mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-mRenderTarget->GetOrigin())); gfxUtils::ClipToRegion(mRenderTarget->mDrawTarget, mInvalidRegion.ToUnknownRegion()); @@ -631,22 +657,25 @@ BasicCompositor::EndFrame() // Pop aInvalidregion mRenderTarget->mDrawTarget->PopClip(); - // Note: Most platforms require us to buffer drawing to the widget surface. - // That's why we don't draw to mDrawTarget directly. - RefPtr source = mRenderTarget->mDrawTarget->Snapshot(); - RefPtr dest(mTarget ? mTarget : mDrawTarget); + if (mTarget || mRenderTarget->mDrawTarget != mDrawTarget) { + // Note: Most platforms require us to buffer drawing to the widget surface. + // That's why we don't draw to mDrawTarget directly. + RefPtr source = mRenderTarget->mDrawTarget->Snapshot(); + RefPtr dest(mTarget ? mTarget : mDrawTarget); - nsIntPoint offset = mTarget ? mTargetBounds.TopLeft() : nsIntPoint(); + nsIntPoint offset = mTarget ? mTargetBounds.TopLeft() : nsIntPoint(); - // The source DrawTarget is clipped to the invalidation region, so we have - // to copy the individual rectangles in the region or else we'll draw blank - // pixels. - for (auto iter = mInvalidRegion.RectIter(); !iter.Done(); iter.Next()) { - const LayoutDeviceIntRect& r = iter.Get(); - dest->CopySurface(source, - IntRect(r.x - mInvalidRect.x, r.y - mInvalidRect.y, r.width, r.height), - IntPoint(r.x - offset.x, r.y - offset.y)); + // The source DrawTarget is clipped to the invalidation region, so we have + // to copy the individual rectangles in the region or else we'll draw blank + // pixels. + for (auto iter = mInvalidRegion.RectIter(); !iter.Done(); iter.Next()) { + const LayoutDeviceIntRect& r = iter.Get(); + dest->CopySurface(source, + IntRect(r.x, r.y, r.width, r.height) - mRenderTarget->GetOrigin(), + IntPoint(r.x, r.y) - offset); + } } + if (!mTarget) { mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion); } diff --git a/gfx/layers/basic/BasicCompositor.h b/gfx/layers/basic/BasicCompositor.h index dfc7d8491fca..fcb7e680403b 100644 --- a/gfx/layers/basic/BasicCompositor.h +++ b/gfx/layers/basic/BasicCompositor.h @@ -62,6 +62,11 @@ public: const CompositingRenderTarget *aSource, const gfx::IntPoint &aSourcePoint) override; + virtual already_AddRefed + CreateRenderTargetForWindow(const gfx::IntRect& aRect, + SurfaceInitMode aInit, + BufferMode aBufferMode); + virtual already_AddRefed CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override; diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index ffe3aef394db..e41f2ef5c7bd 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -539,7 +539,9 @@ public: return nsCocoaUtils::DevPixelsToCocoaPoints(aRect, BackingScaleFactor()); } - already_AddRefed StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) override; + already_AddRefed + StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion, + mozilla::layers::BufferMode* aBufferMode) override; void EndRemoteDrawing() override; void CleanupRemoteDrawing() override; bool InitCompositor(mozilla::layers::Compositor* aCompositor) override; diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 56b45cbd27d1..76af2e1ae4c9 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -2635,7 +2635,8 @@ nsChildView::SwipeFinished() } already_AddRefed -nsChildView::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) +nsChildView::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion, + BufferMode* aBufferMode) { // should have created the GLPresenter in InitCompositor. MOZ_ASSERT(mGLPresenter); diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 56d963df3aa8..4869b1710088 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -2225,7 +2225,8 @@ nsWindow::OnExposeEvent(cairo_t *cr) return TRUE; } - RefPtr dt = GetDrawTarget(region); + BufferMode layerBuffering = BufferMode::BUFFERED; + RefPtr dt = GetDrawTarget(region, &layerBuffering); if (!dt) { return FALSE; } @@ -2245,7 +2246,6 @@ nsWindow::OnExposeEvent(cairo_t *cr) gfxUtils::ClipToRegion(dt, region.ToUnknownRegion()); } - BufferMode layerBuffering; if (shaped) { // The double buffering is done here to extract the shape mask. // (The shape mask won't be necessary when a visual with an alpha @@ -2254,16 +2254,6 @@ nsWindow::OnExposeEvent(cairo_t *cr) RefPtr destDT = dt->CreateSimilarDrawTarget(boundsRect.Size(), SurfaceFormat::B8G8R8A8); ctx = new gfxContext(destDT, boundsRect.TopLeft()); } else { -#ifdef MOZ_HAVE_SHMIMAGE - if (nsShmImage::UseShm()) { - // We're using an xshm mapping as a back buffer. - layerBuffering = BufferMode::BUFFER_NONE; - } else -#endif // MOZ_HAVE_SHMIMAGE - { - // Get the layer manager to do double buffering (if necessary). - layerBuffering = BufferMode::BUFFERED; - } ctx = new gfxContext(dt); } @@ -6455,7 +6445,7 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable, #endif already_AddRefed -nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion) +nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion, BufferMode* aBufferMode) { if (!mGdkWindow) { return nullptr; @@ -6474,12 +6464,14 @@ nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion) if (nsShmImage::UseShm()) { dt = nsShmImage::EnsureShmImage(size, mXDisplay, mXVisual, mXDepth, mShmImage); + *aBufferMode = BufferMode::BUFFER_NONE; } # endif // MOZ_HAVE_SHMIMAGE if (!dt) { RefPtr surf = new gfxXlibSurface(mXDisplay, mXWindow, mXVisual, size.ToUnknownSize()); if (!surf->CairoStatus()) { dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surf.get(), surf->GetSize()); + *aBufferMode = BufferMode::BUFFERED; } } #endif // MOZ_X11 @@ -6488,9 +6480,9 @@ nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion) } already_AddRefed -nsWindow::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) +nsWindow::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion, BufferMode* aBufferMode) { - return GetDrawTarget(aInvalidRegion); + return GetDrawTarget(aInvalidRegion, aBufferMode); } void diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index f42438217e8c..aa3b7b3d9c3c 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -216,7 +216,8 @@ public: #endif virtual already_AddRefed - StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) override; + StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion, + mozilla::layers::BufferMode* aBufferMode) override; virtual void EndRemoteDrawingInRegion(mozilla::gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aInvalidRegion) override; @@ -309,7 +310,9 @@ public: virtual nsresult ConfigureChildren(const nsTArray& aConfigurations) override; nsresult UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect, uint8_t* aAlphas, int32_t aStride); - virtual already_AddRefed GetDrawTarget(const LayoutDeviceIntRegion& aRegion); + + already_AddRefed GetDrawTarget(const LayoutDeviceIntRegion& aRegion, + mozilla::layers::BufferMode* aBufferMode); #if (MOZ_WIDGET_GTK == 2) static already_AddRefed GetSurfaceForGdkDrawable(GdkDrawable* aDrawable, diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 7c99fc42bc2a..0d8caff3f646 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -1287,9 +1287,13 @@ class nsIWidget : public nsISupports { * * Called by BasicCompositor on the compositor thread for OMTC drawing * before each composition. + * + * The window may specify its buffer mode. If unspecified, it is assumed + * to require double-buffering. */ virtual already_AddRefed StartRemoteDrawing() = 0; - virtual already_AddRefed StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) { + virtual already_AddRefed StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion, + mozilla::layers::BufferMode* aBufferMode) { return StartRemoteDrawing(); } From c363c26c533042f9fbbdf518544af475cb54b26e Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Thu, 18 Feb 2016 17:59:24 -0800 Subject: [PATCH 113/115] Bug 1247764 - Disable STENCIL_TEST on mac+intel when not needed. - r=jrmuizel --- dom/canvas/WebGLContext.cpp | 22 +++ dom/canvas/WebGLContext.h | 30 +++- dom/canvas/moz.build | 2 +- dom/canvas/test/webgl-mochitest.ini | 2 + .../test_hidden_depth_stencil.html | 159 ++++++++++++++++++ 5 files changed, 210 insertions(+), 5 deletions(-) create mode 100644 dom/canvas/test/webgl-mochitest/test_hidden_depth_stencil.html diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index f39e0f478c82..4a82e2522113 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -70,6 +70,10 @@ #include "WebGLVertexArray.h" #include "WebGLVertexAttribData.h" +#ifdef MOZ_WIDGET_COCOA +#include "nsCocoaFeatures.h" +#endif + // Generated #include "mozilla/dom/WebGLRenderingContextBinding.h" @@ -109,6 +113,7 @@ WebGLContext::WebGLContext() , mNeedsFakeNoAlpha(false) , mNeedsFakeNoDepth(false) , mNeedsFakeNoStencil(false) + , mNeedsEmulatedLoneDepthStencil(false) { mGeneration = 0; mInvalidated = false; @@ -891,6 +896,14 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) if (!mOptions.stencil && gl->Caps().stencil) mNeedsFakeNoStencil = true; + +#ifdef MOZ_WIDGET_COCOA + if (!nsCocoaFeatures::IsAtLeastVersion(10, 12) && + gl->Vendor() == GLVendor::Intel) + { + mNeedsEmulatedLoneDepthStencil = true; + } +#endif } // Update mOptions. @@ -1847,10 +1860,19 @@ WebGLContext::ScopedMaskWorkaround::~ScopedMaskWorkaround() mWebGL.gl->fEnable(LOCAL_GL_DEPTH_TEST); } if (mFakeNoStencil) { + MOZ_ASSERT(mWebGL.mStencilTestEnabled); mWebGL.gl->fEnable(LOCAL_GL_STENCIL_TEST); } } +/*static*/ bool +WebGLContext::ScopedMaskWorkaround::HasDepthButNoStencil(const WebGLFramebuffer* fb) +{ + const auto& depth = fb->DepthAttachment(); + const auto& stencil = fb->StencilAttachment(); + return depth.IsDefined() && !stencil.IsDefined(); +} + //////////////////////////////////////// ScopedUnpackReset::ScopedUnpackReset(WebGLContext* webgl) diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index 8bc4787e9469..0add07206cb4 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -1505,6 +1505,7 @@ protected: bool mNeedsFakeNoAlpha; bool mNeedsFakeNoDepth; bool mNeedsFakeNoStencil; + bool mNeedsEmulatedLoneDepthStencil; struct ScopedMaskWorkaround { WebGLContext& mWebGL; @@ -1527,11 +1528,32 @@ protected: webgl.mDepthTestEnabled; } + static bool HasDepthButNoStencil(const WebGLFramebuffer* fb); + static bool ShouldFakeNoStencil(WebGLContext& webgl) { - // We should only be doing this if we're about to draw to the backbuffer. - return !webgl.mBoundDrawFramebuffer && - webgl.mNeedsFakeNoStencil && - webgl.mStencilTestEnabled; + if (!webgl.mStencilTestEnabled) + return false; + + if (!webgl.mBoundDrawFramebuffer) { + if (webgl.mNeedsFakeNoStencil) + return true; + + if (webgl.mNeedsEmulatedLoneDepthStencil && + webgl.mOptions.depth && !webgl.mOptions.stencil) + { + return true; + } + + return false; + } + + if (webgl.mNeedsEmulatedLoneDepthStencil && + HasDepthButNoStencil(webgl.mBoundDrawFramebuffer)) + { + return true; + } + + return false; } explicit ScopedMaskWorkaround(WebGLContext& webgl); diff --git a/dom/canvas/moz.build b/dom/canvas/moz.build index 37baf58f4b1d..8597e63df6a2 100644 --- a/dom/canvas/moz.build +++ b/dom/canvas/moz.build @@ -7,7 +7,7 @@ TEST_DIRS += ['compiledtest'] # Number changes to this file to avoid bug 1081323 (clobber after changing a manifest): -# 9 +# 11 MOCHITEST_MANIFESTS += [ 'test/crossorigin/mochitest.ini', diff --git a/dom/canvas/test/webgl-mochitest.ini b/dom/canvas/test/webgl-mochitest.ini index f94abcbc31b4..9251401ac647 100644 --- a/dom/canvas/test/webgl-mochitest.ini +++ b/dom/canvas/test/webgl-mochitest.ini @@ -60,6 +60,8 @@ support-files = captureStream_common.js [webgl-mochitest/test_fb_param_crash.html] [webgl-mochitest/test_hidden_alpha.html] skip-if = (os == 'b2g') || buildapp == 'mulet' # Mulet - bug 1093639 (crashes in libLLVM-3.0.so) +[webgl-mochitest/test_hidden_depth_stencil.html] +fail-if = (os == 'win' && (os_version == '5.1' || os_version == '6.1')) [webgl-mochitest/test_implicit_color_buffer_float.html] [webgl-mochitest/test_highp_fs.html] [webgl-mochitest/test_no_arr_points.html] diff --git a/dom/canvas/test/webgl-mochitest/test_hidden_depth_stencil.html b/dom/canvas/test/webgl-mochitest/test_hidden_depth_stencil.html new file mode 100644 index 000000000000..987af9e371e2 --- /dev/null +++ b/dom/canvas/test/webgl-mochitest/test_hidden_depth_stencil.html @@ -0,0 +1,159 @@ + +WebGL test: Hidden depth/stencil passes without a depth/stencil buffer respectively + + + + + + + + + From 04f5066ce62e0e5d12c4d63aaa0b596debf3f300 Mon Sep 17 00:00:00 2001 From: bsilverberg Date: Thu, 18 Feb 2016 07:50:17 -0500 Subject: [PATCH 114/115] Bug 1246748 - Complete the implementation of chrome.i18n.getUILanguage, r=kmag Implement chrome.i18n.getUILanguage including tests Add API to content scripts MozReview-Commit-ID: IcDlLj8Et73 --HG-- extra : rebase_source : 9996c7da79d3a132bce73b167dfea7031083ad3a --- toolkit/components/extensions/Extension.jsm | 1 - .../extensions/ExtensionContent.jsm | 4 + .../components/extensions/ExtensionUtils.jsm | 11 ++- toolkit/components/extensions/ext-i18n.js | 4 + .../components/extensions/schemas/i18n.json | 1 - .../test/mochitest/test_ext_i18n.html | 81 +++++++++++++++++++ 6 files changed, 97 insertions(+), 5 deletions(-) diff --git a/toolkit/components/extensions/Extension.jsm b/toolkit/components/extensions/Extension.jsm index 55c92253aaab..724bdad6ce3e 100644 --- a/toolkit/components/extensions/Extension.jsm +++ b/toolkit/components/extensions/Extension.jsm @@ -1214,4 +1214,3 @@ Extension.prototype = extend(Object.create(ExtensionData.prototype), { return this.localize(this.manifest.name); }, }); - diff --git a/toolkit/components/extensions/ExtensionContent.jsm b/toolkit/components/extensions/ExtensionContent.jsm index e66ca20ae0f0..fd83aa29c612 100644 --- a/toolkit/components/extensions/ExtensionContent.jsm +++ b/toolkit/components/extensions/ExtensionContent.jsm @@ -118,6 +118,10 @@ var api = context => { getMessage: function(messageName, substitutions) { return context.extension.localizeMessage(messageName, substitutions); }, + + getUILanguage: function() { + return context.extension.localeData.uiLocale; + }, }, }; }; diff --git a/toolkit/components/extensions/ExtensionUtils.jsm b/toolkit/components/extensions/ExtensionUtils.jsm index d2bb97d11369..6cb101d93804 100644 --- a/toolkit/components/extensions/ExtensionUtils.jsm +++ b/toolkit/components/extensions/ExtensionUtils.jsm @@ -333,9 +333,7 @@ LocaleData.prototype = { // Check for certain pre-defined messages. if (message == "@@ui_locale") { - // Return the browser locale, but convert it to a Chrome-style - // locale code. - return Locale.getLocale().replace(/-/g, "_"); + return this.uiLocale; } else if (message.startsWith("@@bidi_")) { let registry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry); let rtl = registry.isLocaleRTL("global"); @@ -426,6 +424,13 @@ LocaleData.prototype = { this.messages.set(locale, result); return result; }, + + get uiLocale() { + // Return the browser locale, but convert it to a Chrome-style + // locale code. + return Locale.getLocale().replace(/-/g, "_"); + }, + }; // This is a generic class for managing event listeners. Example usage: diff --git a/toolkit/components/extensions/ext-i18n.js b/toolkit/components/extensions/ext-i18n.js index 141ea1692d2d..61ce563acb2f 100644 --- a/toolkit/components/extensions/ext-i18n.js +++ b/toolkit/components/extensions/ext-i18n.js @@ -6,6 +6,10 @@ extensions.registerSchemaAPI("i18n", null, (extension, context) => { getMessage: function(messageName, substitutions) { return extension.localizeMessage(messageName, substitutions); }, + + getUILanguage: function() { + return extension.localeData.uiLocale; + }, }, }; }); diff --git a/toolkit/components/extensions/schemas/i18n.json b/toolkit/components/extensions/schemas/i18n.json index fb87db8ed39d..d43d3cdbda87 100644 --- a/toolkit/components/extensions/schemas/i18n.json +++ b/toolkit/components/extensions/schemas/i18n.json @@ -68,7 +68,6 @@ }, { "name": "getUILanguage", - "unsupported": true, "type": "function", "description": "Gets the browser UI language of the browser. This is different from $(ref:i18n.getAcceptLanguages) which returns the preferred user languages.", "parameters": [], diff --git a/toolkit/components/extensions/test/mochitest/test_ext_i18n.html b/toolkit/components/extensions/test/mochitest/test_ext_i18n.html index 50e9ed97ab5c..844bdd0b361d 100644 --- a/toolkit/components/extensions/test/mochitest/test_ext_i18n.html +++ b/toolkit/components/extensions/test/mochitest/test_ext_i18n.html @@ -14,6 +14,8 @@ From d4303cccdf8c911457698256c3f53e6b218cbf9f Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Fri, 19 Feb 2016 01:08:07 -0500 Subject: [PATCH 115/115] Bug 1240760: Update DataChannel::Close() r=mcmanus MozReview-Commit-ID: 7nN9h3M3O8w --- netwerk/sctp/datachannel/DataChannel.cpp | 8 +++++--- netwerk/sctp/datachannel/DataChannel.h | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/netwerk/sctp/datachannel/DataChannel.cpp b/netwerk/sctp/datachannel/DataChannel.cpp index 5385c9e83219..48d1fc4db1a6 100644 --- a/netwerk/sctp/datachannel/DataChannel.cpp +++ b/netwerk/sctp/datachannel/DataChannel.cpp @@ -1778,7 +1778,7 @@ DataChannelConnection::HandleStreamResetEvent(const struct sctp_stream_reset_eve LOG(("Disconnected DataChannel %p from connection %p", (void *) channel.get(), (void *) channel->mConnection.get())); - channel->Destroy(); + channel->DestroyLocked(); // At this point when we leave here, the object is a zombie held alive only by the DOM object } else { LOG(("Can't find incoming channel %d",i)); @@ -2502,7 +2502,7 @@ DataChannelConnection::CloseInt(DataChannel *aChannel) aChannel->mState = CLOSING; if (mState == CLOSED) { // we're not going to hang around waiting - channel->Destroy(); + channel->DestroyLocked(); } // At this point when we leave here, the object is a zombie held alive only by the DOM object } @@ -2556,13 +2556,15 @@ void DataChannel::Close() { ENSURE_DATACONNECTION; + RefPtr connection(mConnection); mConnection->Close(this); } // Used when disconnecting from the DataChannelConnection void -DataChannel::Destroy() +DataChannel::DestroyLocked() { + mConnection->mLock.AssertCurrentThreadOwns(); ENSURE_DATACONNECTION; LOG(("Destroying Data channel %u", mStream)); diff --git a/netwerk/sctp/datachannel/DataChannel.h b/netwerk/sctp/datachannel/DataChannel.h index 2ccdc48a835d..6386dbb498df 100644 --- a/netwerk/sctp/datachannel/DataChannel.h +++ b/netwerk/sctp/datachannel/DataChannel.h @@ -337,10 +337,11 @@ private: ~DataChannel(); public: - void Destroy(); // when we disconnect from the connection after stream RESET - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataChannel) + // when we disconnect from the connection after stream RESET + void DestroyLocked(); + // Close this DataChannel. Can be called multiple times. MUST be called // before destroying the DataChannel (state must be CLOSED or CLOSING). void Close();