author | Bogdan Tara <btara@mozilla.com> |
Mon, 04 Dec 2017 22:20:49 +0200 | |
changeset 446650 | 7d191882de19faa537753b2deaea9444277a6533 |
parent 446617 | 4a003542df78bc7f08b37c4759e3a64c71e74552 (current diff) |
parent 446649 | d1b45fb8d2049dd04d169582e099a34140abfdfe (diff) |
child 446651 | 5be384bcf00191f97d32b4ac3ecd1b85ec7b18e1 |
push id | 8527 |
push user | Callek@gmail.com |
push date | Thu, 11 Jan 2018 21:05:50 +0000 |
treeherder | mozilla-beta@95342d212a7a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge, merge |
milestone | 59.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/base/content/test/alerts/browser.ini +++ b/browser/base/content/test/alerts/browser.ini @@ -5,10 +5,11 @@ support-files = [browser_notification_close.js] skip-if = os == 'win' # Bug 1227785 [browser_notification_do_not_disturb.js] skip-if = os == 'win' # Bug 1352791 [browser_notification_open_settings.js] skip-if = os == 'win' # Bug 1411118 [browser_notification_remove_permission.js] +skip-if = os == 'win' # Bug 1411118 [browser_notification_replace.js] [browser_notification_tab_switching.js]
--- a/browser/base/content/test/performance/browser_startup_flicker.js +++ b/browser/base/content/test/performance/browser_startup_flicker.js @@ -36,17 +36,18 @@ add_task(async function() { } rects = rects.filter(rect => { let inRange = (val, min, max) => min <= val && val <= max; let width = frame.width; let exceptions = [ {name: "bug 1403648 - urlbar down arrow shouldn't flicker", - condition: r => r.h == 5 && inRange(r.w, 8, 9) && // 5x9px area + condition: r => // 5x9px area, sometimes less at the end of the opacity transition + inRange(r.h, 3, 5) && inRange(r.w, 7, 9) && inRange(r.y1, 40, 80) && // in the toolbar // at ~80% of the window width inRange(r.x1, width * .75, width * .9) }, {name: "bug 1394914 - sidebar toolbar icon should be visible at first paint", condition: r => r.h == 13 && inRange(r.w, 14, 16) && // icon size inRange(r.y1, 40, 80) && // in the toolbar
--- a/browser/base/content/test/performance/browser_windowopen_flicker.js +++ b/browser/base/content/test/performance/browser_windowopen_flicker.js @@ -66,49 +66,58 @@ add_task(async function() { Services.tm.idleDispatchToMainThread(() => { waitForIdle(count - 1); }); })(); }); win.removeEventListener("MozAfterPaint", afterPaintListener); let unexpectedRects = 0; - let foundTinyPaint = false; + let ignoreTinyPaint = true; for (let i = 1; i < frames.length; ++i) { let frame = frames[i], previousFrame = frames[i - 1]; - if (!foundTinyPaint && + if (ignoreTinyPaint && previousFrame.width == 1 && previousFrame.height == 1) { - foundTinyPaint = true; - todo(false, "shouldn't first paint a 1x1px window"); + todo(false, "shouldn't initially paint a 1x1px window"); continue; } + ignoreTinyPaint = false; let rects = compareFrames(frame, previousFrame).filter(rect => { let inRange = (val, min, max) => min <= val && val <= max; let width = frame.width; const spaceBeforeFirstTab = AppConstants.platform == "macosx" ? 100 : 0; let inFirstTab = r => inRange(r.x1, spaceBeforeFirstTab, spaceBeforeFirstTab + 50) && r.y1 < 30; let exceptions = [ {name: "bug 1403648 - urlbar down arrow shouldn't flicker", - condition: r => r.h == 5 && inRange(r.w, 8, 9) && // 5x9px area + condition: r => // 5x9px area, sometimes less at the end of the opacity transition + inRange(r.h, 3, 5) && inRange(r.w, 7, 9) && inRange(r.y1, 40, 80) && // in the toolbar // at ~80% of the window width inRange(r.x1, width * .75, width * .9) }, {name: "bug 1394914 - sidebar toolbar icon should be visible at first paint", condition: r => r.h == 13 && inRange(r.w, 14, 16) && // icon size inRange(r.y1, 40, 80) && // in the toolbar // near the right end of screen inRange(r.x1, width - 100, width - 50) }, + {name: "bug 1403648 - urlbar should be focused at first paint", + condition: r => inRange(r.y2, 60, 80) && // in the toolbar + // taking 50% to 75% of the window width + inRange(r.w, width * .5, width * .75) && + // starting at 15 to 25% of the window width + inRange(r.x1, width * .15, width * .25) + }, + {name: "bug 1421463 - reload toolbar icon shouldn't flicker", condition: r => r.h == 13 && inRange(r.w, 14, 16) && // icon size inRange(r.y1, 40, 80) && // in the toolbar // near the left side of the screen inRange(r.x1, 65, 100) }, {name: "bug 1401955 - about:home favicon should be visible at first paint",
--- a/browser/components/sessionstore/SessionStore.jsm +++ b/browser/components/sessionstore/SessionStore.jsm @@ -2705,17 +2705,18 @@ var SessionStoreInternal = { let activePageData = tabData.entries[tabData.index - 1] || null; // If the page has a title, set it. if (activePageData) { if (activePageData.title && activePageData.title != activePageData.url) { win.gBrowser.setInitialTabTitle(tab, activePageData.title, { isContentTitle: true }); - } else if (activePageData.url != "about:blank") { + } else if (activePageData.url != "about:blank" && + activePageData.url != "about:newtab") { win.gBrowser.setInitialTabTitle(tab, activePageData.url); } } // Restore the tab icon. if ("image" in tabData) { // Use the serialized contentPrincipal with the new icon load. let loadingPrincipal = Utils.deserializePrincipal(tabData.iconLoadingPrincipal);
--- a/build/moz.configure/toolchain.configure +++ b/build/moz.configure/toolchain.configure @@ -1251,16 +1251,29 @@ def pgo_flags(compiler): ) set_config('PROFILE_GEN_CFLAGS', pgo_flags.gen_cflags) set_config('PROFILE_GEN_LDFLAGS', pgo_flags.gen_ldflags) set_config('PROFILE_USE_CFLAGS', pgo_flags.use_cflags) set_config('PROFILE_USE_LDFLAGS', pgo_flags.use_ldflags) + +@depends(c_compiler) +def preprocess_option(compiler): + # The uses of PREPROCESS_OPTION depend on the spacing for -o/-Fi. + if compiler.type in ('gcc', 'clang'): + return '-E -o ' + else: + return '-P -Fi' + + +set_config('PREPROCESS_OPTION', preprocess_option) + + # We only want to include windows.configure when we are compiling on # Windows, for Windows. @depends(target, host) def is_windows(target, host): return host.kernel == 'WINNT' and target.kernel == 'WINNT'
--- a/dom/base/nsContentSink.cpp +++ b/dom/base/nsContentSink.cpp @@ -677,16 +677,17 @@ nsContentSink::ProcessLinkHeader(const n href.Truncate(); rel.Truncate(); title.Truncate(); type.Truncate(); media.Truncate(); anchor.Truncate(); referrerPolicy.Truncate(); crossOrigin.SetIsVoid(true); + as.Truncate(); seenParameters = false; } start = ++end; } href.Trim(" \t\n\r\f"); // trim HTML5 whitespace
--- a/dom/clients/manager/ClientManagerActors.cpp +++ b/dom/clients/manager/ClientManagerActors.cpp @@ -32,10 +32,17 @@ AllocClientManagerParent() bool DeallocClientManagerParent(PClientManagerParent* aActor) { delete aActor; return true; } +void +InitClientManagerParent(PClientManagerParent* aActor) +{ + auto actor = static_cast<ClientManagerParent*>(aActor); + actor->Init(); +} + } // namespace dom } // namespace mozilla
--- a/dom/clients/manager/ClientManagerActors.h +++ b/dom/clients/manager/ClientManagerActors.h @@ -19,13 +19,16 @@ bool DeallocClientManagerChild(PClientManagerChild* aActor); PClientManagerParent* AllocClientManagerParent(); bool DeallocClientManagerParent(PClientManagerParent* aActor); +void +InitClientManagerParent(PClientManagerParent* aActor); + } // namespace dom } // namespace mozilla #endif // _mozilla_dom_ClientManagerActors_h
--- a/dom/clients/manager/ClientManagerParent.cpp +++ b/dom/clients/manager/ClientManagerParent.cpp @@ -112,12 +112,19 @@ ClientManagerParent::RecvPClientSourceCo ClientManagerParent::ClientManagerParent() : mService(ClientManagerService::GetOrCreateInstance()) { } ClientManagerParent::~ClientManagerParent() { + mService->RemoveManager(this); +} + +void +ClientManagerParent::Init() +{ + mService->AddManager(this); } } // namespace dom } // namespace mozilla
--- a/dom/clients/manager/ClientManagerParent.h +++ b/dom/clients/manager/ClientManagerParent.h @@ -58,14 +58,17 @@ class ClientManagerParent final : public mozilla::ipc::IPCResult RecvPClientSourceConstructor(PClientSourceParent* aActor, const ClientSourceConstructorArgs& aArgs) override; public: ClientManagerParent(); ~ClientManagerParent(); + + void + Init(); }; } // namespace dom } // namespace mozilla #endif // _mozilla_dom_ClientManagerParent_h
--- a/dom/clients/manager/ClientManagerService.cpp +++ b/dom/clients/manager/ClientManagerService.cpp @@ -1,19 +1,23 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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 "ClientManagerService.h" +#include "ClientManagerParent.h" #include "ClientSourceParent.h" #include "mozilla/ipc/BackgroundParent.h" #include "mozilla/ipc/PBackgroundSharedTypes.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/SystemGroup.h" +#include "nsIAsyncShutdown.h" namespace mozilla { namespace dom { using mozilla::ipc::AssertIsOnBackgroundThread; using mozilla::ipc::ContentPrincipalInfo; using mozilla::ipc::PrincipalInfo; @@ -51,46 +55,175 @@ MatchPrincipalInfo(const PrincipalInfo& break; } } // Clients (windows/workers) should never have an expanded principal type. MOZ_CRASH("unexpected principal type!"); } +class ClientShutdownBlocker final : public nsIAsyncShutdownBlocker +{ + RefPtr<GenericPromise::Private> mPromise; + + ~ClientShutdownBlocker() = default; + +public: + explicit ClientShutdownBlocker(GenericPromise::Private* aPromise) + : mPromise(aPromise) + { + MOZ_DIAGNOSTIC_ASSERT(mPromise); + } + + NS_IMETHOD + GetName(nsAString& aNameOut) override + { + aNameOut = + NS_LITERAL_STRING("ClientManagerService: start destroying IPC actors early"); + return NS_OK; + } + + NS_IMETHOD + BlockShutdown(nsIAsyncShutdownClient* aClient) override + { + mPromise->Resolve(true, __func__); + aClient->RemoveBlocker(this); + return NS_OK; + } + + NS_IMETHOD + GetState(nsIPropertyBag**) override + { + return NS_OK; + } + + NS_DECL_ISUPPORTS +}; + +NS_IMPL_ISUPPORTS(ClientShutdownBlocker, nsIAsyncShutdownBlocker) + +// Helper function the resolves a MozPromise when we detect that the browser +// has begun to shutdown. +RefPtr<GenericPromise> +OnShutdown() +{ + RefPtr<GenericPromise::Private> ref = new GenericPromise::Private(__func__); + + nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("ClientManagerServer::OnShutdown", + [ref] () { + nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown(); + if (!svc) { + ref->Resolve(true, __func__); + return; + } + + nsCOMPtr<nsIAsyncShutdownClient> phase; + MOZ_ALWAYS_SUCCEEDS(svc->GetXpcomWillShutdown(getter_AddRefs(phase))); + if (!phase) { + ref->Resolve(true, __func__); + return; + } + + nsCOMPtr<nsIAsyncShutdownBlocker> blocker = new ClientShutdownBlocker(ref); + nsresult rv = + phase->AddBlocker(blocker, NS_LITERAL_STRING(__FILE__), __LINE__, + NS_LITERAL_STRING("ClientManagerService shutdown")); + + if (NS_FAILED(rv)) { + ref->Resolve(true, __func__); + return; + } + }); + + MOZ_ALWAYS_SUCCEEDS( + SystemGroup::Dispatch(TaskCategory::Other, r.forget())); + + return ref.forget(); +} + } // anonymous namespace ClientManagerService::ClientManagerService() + : mShutdown(false) { AssertIsOnBackgroundThread(); + + // While the ClientManagerService will be gracefully terminated as windows + // and workers are naturally killed, this can cause us to do extra work + // relatively late in the shutdown process. To avoid this we eagerly begin + // shutdown at the first sign it has begun. Since we handle normal shutdown + // gracefully we don't really need to block anything here. We just begin + // destroying our IPC actors immediately. + OnShutdown()->Then(GetCurrentThreadSerialEventTarget(), __func__, + [] () { + RefPtr<ClientManagerService> svc = ClientManagerService::GetInstance(); + if (svc) { + svc->Shutdown(); + } + }); } ClientManagerService::~ClientManagerService() { AssertIsOnBackgroundThread(); MOZ_DIAGNOSTIC_ASSERT(mSourceTable.Count() == 0); + MOZ_DIAGNOSTIC_ASSERT(mManagerList.IsEmpty()); MOZ_DIAGNOSTIC_ASSERT(sClientManagerServiceInstance == this); sClientManagerServiceInstance = nullptr; } +void +ClientManagerService::Shutdown() +{ + AssertIsOnBackgroundThread(); + + // If many ClientManagerService are created and destroyed quickly we can + // in theory get more than one shutdown listener calling us. + if (mShutdown) { + return; + } + mShutdown = true; + + // Begin destroying our various manager actors which will in turn destroy + // all source, handle, and operation actors. + AutoTArray<ClientManagerParent*, 16> list(mManagerList); + for (auto actor : list) { + Unused << PClientManagerParent::Send__delete__(actor); + } +} + // static already_AddRefed<ClientManagerService> ClientManagerService::GetOrCreateInstance() { AssertIsOnBackgroundThread(); if (!sClientManagerServiceInstance) { sClientManagerServiceInstance = new ClientManagerService(); } RefPtr<ClientManagerService> ref(sClientManagerServiceInstance); return ref.forget(); } +// static +already_AddRefed<ClientManagerService> +ClientManagerService::GetInstance() +{ + AssertIsOnBackgroundThread(); + + if (!sClientManagerServiceInstance) { + return nullptr; + } + + RefPtr<ClientManagerService> ref(sClientManagerServiceInstance); + return ref.forget(); +} + bool ClientManagerService::AddSource(ClientSourceParent* aSource) { AssertIsOnBackgroundThread(); MOZ_ASSERT(aSource); auto entry = mSourceTable.LookupForAdd(aSource->Info().Id()); // Do not permit overwriting an existing ClientSource with the same // UUID. This would allow a spoofed ClientParentSource actor to @@ -129,10 +262,33 @@ ClientManagerService::FindSource(const n if (source->IsFrozen() || !MatchPrincipalInfo(source->Info().PrincipalInfo(), aPrincipalInfo)) { return nullptr; } return source; } +void +ClientManagerService::AddManager(ClientManagerParent* aManager) +{ + AssertIsOnBackgroundThread(); + MOZ_DIAGNOSTIC_ASSERT(aManager); + MOZ_ASSERT(!mManagerList.Contains(aManager)); + mManagerList.AppendElement(aManager); + + // If shutdown has already begun then immediately destroy the actor. + if (mShutdown) { + Unused << PClientManagerParent::Send__delete__(aManager); + } +} + +void +ClientManagerService::RemoveManager(ClientManagerParent* aManager) +{ + AssertIsOnBackgroundThread(); + MOZ_DIAGNOSTIC_ASSERT(aManager); + DebugOnly<bool> removed = mManagerList.RemoveElement(aManager); + MOZ_ASSERT(removed); +} + } // namespace dom } // namespace mozilla
--- a/dom/clients/manager/ClientManagerService.h +++ b/dom/clients/manager/ClientManagerService.h @@ -2,49 +2,68 @@ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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_dom_ClientManagerService_h #define _mozilla_dom_ClientManagerService_h #include "mozilla/ipc/PBackgroundSharedTypes.h" +#include "mozilla/MozPromise.h" #include "nsDataHashtable.h" namespace mozilla { namespace dom { +class ClientManagerParent; class ClientSourceParent; // Define a singleton service to manage client activity throughout the // browser. This service runs on the PBackground thread. To interact // it with it please use the ClientManager and ClientHandle classes. class ClientManagerService final { // Store the ClientSourceParent objects in a hash table. We want to // optimize for insertion, removal, and lookup by UUID. nsDataHashtable<nsIDHashKey, ClientSourceParent*> mSourceTable; + nsTArray<ClientManagerParent*> mManagerList; + + bool mShutdown; + ClientManagerService(); ~ClientManagerService(); + void + Shutdown(); + public: static already_AddRefed<ClientManagerService> GetOrCreateInstance(); + // Returns nullptr if the service is not already created. + static already_AddRefed<ClientManagerService> + GetInstance(); + bool AddSource(ClientSourceParent* aSource); bool RemoveSource(ClientSourceParent* aSource); ClientSourceParent* FindSource(const nsID& aID, const mozilla::ipc::PrincipalInfo& aPrincipalInfo); + void + AddManager(ClientManagerParent* aManager); + + void + RemoveManager(ClientManagerParent* aManager); + NS_INLINE_DECL_REFCOUNTING(mozilla::dom::ClientManagerService) }; } // namespace dom } // namespace mozilla #endif // _mozilla_dom_ClientManagerService_h
--- a/dom/file/nsHostObjectProtocolHandler.cpp +++ b/dom/file/nsHostObjectProtocolHandler.cpp @@ -18,16 +18,17 @@ #include "mozilla/LoadInfo.h" #include "mozilla/ModuleUtils.h" #include "mozilla/Preferences.h" #include "mozilla/SystemGroup.h" #include "nsClassHashtable.h" #include "nsContentUtils.h" #include "nsError.h" #include "nsHostObjectURI.h" +#include "nsIAsyncShutdown.h" #include "nsIMemoryReporter.h" #include "nsIPrincipal.h" #include "nsIUUIDGenerator.h" #include "nsNetUtil.h" #define RELEASING_TIMER 5000 using namespace mozilla; @@ -432,87 +433,166 @@ class BlobURLsReporter final : public ns } } }; NS_IMPL_ISUPPORTS(BlobURLsReporter, nsIMemoryReporter) class ReleasingTimerHolder final : public nsITimerCallback , public nsINamed + , public nsIAsyncShutdownBlocker { public: NS_DECL_ISUPPORTS static void Create(const nsACString& aURI, bool aBroadcastToOtherProcesses) { + MOZ_ASSERT(NS_IsMainThread()); + RefPtr<ReleasingTimerHolder> holder = new ReleasingTimerHolder(aURI, aBroadcastToOtherProcesses); + + auto raii = mozilla::MakeScopeExit([&] { + holder->CancelTimerAndRevokeURI(); + }); + nsresult rv = NS_NewTimerWithCallback(getter_AddRefs(holder->mTimer), holder, RELEASING_TIMER, nsITimer::TYPE_ONE_SHOT, SystemGroup::EventTargetFor(TaskCategory::Other)); NS_ENSURE_SUCCESS_VOID(rv); + + nsCOMPtr<nsIAsyncShutdownClient> phase = GetShutdownPhase(); + NS_ENSURE_TRUE_VOID(!!phase); + + rv = phase->AddBlocker(holder, NS_LITERAL_STRING(__FILE__), __LINE__, + NS_LITERAL_STRING("ReleasingTimerHolder shutdown")); + NS_ENSURE_SUCCESS_VOID(rv); + + raii.release(); } + // nsITimerCallback interface + NS_IMETHOD Notify(nsITimer* aTimer) override { + RevokeURI(mBroadcastToOtherProcesses); + return NS_OK; + } + + // nsINamed interface + + NS_IMETHOD + GetName(nsACString& aName) override + { + aName.AssignLiteral("ReleasingTimerHolder"); + return NS_OK; + } + + // nsIAsyncShutdownBlocker interface + + NS_IMETHOD + GetName(nsAString& aName) override + { + aName.AssignLiteral("ReleasingTimerHolder"); + return NS_OK; + } + + NS_IMETHOD + BlockShutdown(nsIAsyncShutdownClient* aClient) override + { + CancelTimerAndRevokeURI(); + return NS_OK; + } + + NS_IMETHOD + GetState(nsIPropertyBag**) override + { + return NS_OK; + } + +private: + ReleasingTimerHolder(const nsACString& aURI, bool aBroadcastToOtherProcesses) + : mURI(aURI) + , mBroadcastToOtherProcesses(aBroadcastToOtherProcesses) + {} + + ~ReleasingTimerHolder() + {} + + void + RevokeURI(bool aBroadcastToOtherProcesses) + { + // Remove the shutting down blocker + nsCOMPtr<nsIAsyncShutdownClient> phase = GetShutdownPhase(); + if (phase) { + phase->RemoveBlocker(this); + } + // If we have to broadcast the unregistration, let's do it now. - if (mBroadcastToOtherProcesses) { + if (aBroadcastToOtherProcesses) { BroadcastBlobURLUnregistration(mURI); } DataInfo* info = GetDataInfo(mURI, true /* We care about revoked dataInfo */); if (!info) { // Already gone! - return NS_OK; + return; } MOZ_ASSERT(info->mRevoked); for (uint32_t i = 0; i < info->mURIs.Length(); ++i) { nsCOMPtr<nsIURI> uri = do_QueryReferent(info->mURIs[i]); if (uri) { static_cast<nsHostObjectURI*>(uri.get())->ForgetBlobImpl(); } } gDataTable->Remove(mURI); if (gDataTable->Count() == 0) { delete gDataTable; gDataTable = nullptr; } + } - return NS_OK; + void + CancelTimerAndRevokeURI() + { + if (mTimer) { + mTimer->Cancel(); + mTimer = nullptr; + } + + RevokeURI(false /* aBroadcastToOtherProcesses */); } - NS_IMETHOD - GetName(nsACString& aName) override + static nsCOMPtr<nsIAsyncShutdownClient> + GetShutdownPhase() { - aName.AssignLiteral("ReleasingTimerHolder"); - return NS_OK; - } + nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown(); + NS_ENSURE_TRUE(!!svc, nullptr); -private: - ReleasingTimerHolder(const nsACString& aURI, bool aBroadcastToOtherProcesses) - : mURI(aURI) - , mBroadcastToOtherProcesses(aBroadcastToOtherProcesses) - {} + nsCOMPtr<nsIAsyncShutdownClient> phase; + nsresult rv = svc->GetXpcomWillShutdown(getter_AddRefs(phase)); + NS_ENSURE_SUCCESS(rv, nullptr); - ~ReleasingTimerHolder() - {} + return Move(phase); + } nsCString mURI; bool mBroadcastToOtherProcesses; nsCOMPtr<nsITimer> mTimer; }; -NS_IMPL_ISUPPORTS(ReleasingTimerHolder, nsITimerCallback, nsINamed) +NS_IMPL_ISUPPORTS(ReleasingTimerHolder, nsITimerCallback, nsINamed, + nsIAsyncShutdownBlocker) } // namespace mozilla template<typename T> static nsresult AddDataEntryInternal(const nsACString& aURI, T aObject, nsIPrincipal* aPrincipal) {
--- a/dom/webidl/RTCPeerConnection.webidl +++ b/dom/webidl/RTCPeerConnection.webidl @@ -63,18 +63,18 @@ dictionary RTCDataChannelInit { dictionary RTCOfferAnswerOptions { // boolean voiceActivityDetection = true; // TODO: support this (Bug 1184712) }; dictionary RTCAnswerOptions : RTCOfferAnswerOptions { }; dictionary RTCOfferOptions : RTCOfferAnswerOptions { - long offerToReceiveVideo; - long offerToReceiveAudio; + boolean offerToReceiveVideo; + boolean offerToReceiveAudio; boolean iceRestart = false; }; interface RTCDataChannel; [Pref="media.peerconnection.enabled", JSImplementation="@mozilla.org/dom/peerconnection;1", Constructor (optional RTCConfiguration configuration,
--- a/ipc/glue/BackgroundParentImpl.cpp +++ b/ipc/glue/BackgroundParentImpl.cpp @@ -975,16 +975,23 @@ BackgroundParentImpl::AllocPClientManage } bool BackgroundParentImpl::DeallocPClientManagerParent(mozilla::dom::PClientManagerParent* aActor) { return mozilla::dom::DeallocClientManagerParent(aActor); } +mozilla::ipc::IPCResult +BackgroundParentImpl::RecvPClientManagerConstructor(mozilla::dom::PClientManagerParent* aActor) +{ + mozilla::dom::InitClientManagerParent(aActor); + return IPC_OK(); +} + } // namespace ipc } // namespace mozilla void TestParent::ActorDestroy(ActorDestroyReason aWhy) { mozilla::ipc::AssertIsInMainProcess(); AssertIsOnBackgroundThread();
--- a/ipc/glue/BackgroundParentImpl.h +++ b/ipc/glue/BackgroundParentImpl.h @@ -263,14 +263,17 @@ protected: virtual bool DeallocPHttpBackgroundChannelParent(PHttpBackgroundChannelParent *aActor) override; virtual PClientManagerParent* AllocPClientManagerParent() override; virtual bool DeallocPClientManagerParent(PClientManagerParent* aActor) override; + + virtual mozilla::ipc::IPCResult + RecvPClientManagerConstructor(PClientManagerParent* aActor) override; }; } // namespace ipc } // namespace mozilla #endif // mozilla_ipc_backgroundparentimpl_h__
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/typedarray/typed-array-inline-cache.js @@ -0,0 +1,53 @@ +// ECMA262 9.4.5.2 [[HasProperty]] +function check_in(x, a) { + return (x in a); +} + +function check_has_own(x, a) { + return a.hasOwnProperty(x); +} + +//make sure baseline gets compiled +function warmup(a) { + for (var i = 0; i < 1001; i++) { + check_in(i, a); + check_has_own(i, a); + } +} + +function check_assertions(a) { + assertEq(check_in(1, a), true); + assertEq(check_in("-0",a), false); // -0 access + assertEq(check_in(-10,a), false); // Negative access + assertEq(check_in(1012,a), false); // OOB access + + + assertEq(check_has_own(1, a), true); + assertEq(check_has_own("-0",a), false); // -0 access + assertEq(check_has_own(-10,a), false); // Negative access + assertEq(check_has_own(1012,a), false); // OOB access +} + +function test_with_no_protochain(a) { + var a = new Int32Array(1000).fill(1); + warmup(a); + check_assertions(a); +} + +// Attempting to validate against this comment: +// https://bugzilla.mozilla.org/show_bug.cgi?id=1419372#c3 +// +// "Out of bounds "in" or "hasOwnProperty" should always +// return false, and not consider the prototype chain at all" +function test_with_protochain(a) { + var a = new Int32Array(1000).fill(1); + // try to force the behaviour of 9.4.5.2 + a[1012] = "1012"; + a["-0"] = "-0"; + a[-10] = "-10"; + warmup(a); + check_assertions(a); +} + +test_with_no_protochain(); +test_with_protochain();
--- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -2560,16 +2560,39 @@ HasPropIRGenerator::tryAttachUnboxedExpa writer.loadBooleanResult(true); writer.returnFromIC(); trackAttached("UnboxedExpandoHasProp"); return true; } bool +HasPropIRGenerator::tryAttachTypedArray(HandleObject obj, ObjOperandId objId, + uint32_t index, Int32OperandId indexId) +{ + if (!obj->is<TypedArrayObject>() && !IsPrimitiveArrayTypedObject(obj)) + return false; + + // Don't attach typed object stubs if the underlying storage could be + // detached, as the stub will always bail out. + if (IsPrimitiveArrayTypedObject(obj) && cx_->compartment()->detachedTypedObjects) + return false; + + TypedThingLayout layout = GetTypedThingLayout(obj->getClass()); + writer.guardShape(objId, obj->as<ShapedObject>().shape()); + + writer.loadTypedElementExistsResult(objId, indexId, layout); + + writer.returnFromIC(); + + trackAttached("TypedArrayObject"); + return true; +} + +bool HasPropIRGenerator::tryAttachTypedObject(JSObject* obj, ObjOperandId objId, jsid key, ValOperandId keyId) { if (!obj->is<TypedObject>()) return false; if (!obj->as<TypedObject>().typeDescr().hasProperty(cx_->names(), key)) return false; @@ -2688,16 +2711,18 @@ HasPropIRGenerator::tryAttachStub() uint32_t index; Int32OperandId indexId; if (maybeGuardInt32Index(idVal_, keyId, &index, &indexId)) { if (tryAttachDense(obj, objId, index, indexId)) return true; if (tryAttachDenseHole(obj, objId, index, indexId)) return true; + if (tryAttachTypedArray(obj, objId, index, indexId)) + return true; trackNotAttached(); return false; } trackNotAttached(); return false; }
--- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -234,16 +234,17 @@ extern const char* CacheKindNames[]; /* The *Result ops load a value into the cache's result register. */ \ _(LoadFixedSlotResult) \ _(LoadDynamicSlotResult) \ _(LoadUnboxedPropertyResult) \ _(LoadTypedObjectResult) \ _(LoadDenseElementResult) \ _(LoadDenseElementHoleResult) \ _(LoadDenseElementExistsResult) \ + _(LoadTypedElementExistsResult) \ _(LoadDenseElementHoleExistsResult) \ _(LoadTypedElementResult) \ _(LoadInt32ArrayLengthResult) \ _(LoadArgumentsObjectArgResult) \ _(LoadArgumentsObjectLengthResult) \ _(LoadFunctionLengthResult) \ _(LoadStringCharResult) \ _(LoadStringLengthResult) \ @@ -925,16 +926,21 @@ class MOZ_RAII CacheIRWriter : public JS void loadDenseElementHoleResult(ObjOperandId obj, Int32OperandId index) { writeOpWithOperandId(CacheOp::LoadDenseElementHoleResult, obj); writeOperandId(index); } void loadDenseElementExistsResult(ObjOperandId obj, Int32OperandId index) { writeOpWithOperandId(CacheOp::LoadDenseElementExistsResult, obj); writeOperandId(index); } + void loadTypedElementExistsResult(ObjOperandId obj, Int32OperandId index, TypedThingLayout layout) { + writeOpWithOperandId(CacheOp::LoadTypedElementExistsResult, obj); + writeOperandId(index); + buffer_.writeByte(uint32_t(layout)); + } void loadDenseElementHoleExistsResult(ObjOperandId obj, Int32OperandId index) { writeOpWithOperandId(CacheOp::LoadDenseElementHoleExistsResult, obj); writeOperandId(index); } void loadTypedElementResult(ObjOperandId obj, Int32OperandId index, TypedThingLayout layout, Scalar::Type elementType) { writeOpWithOperandId(CacheOp::LoadTypedElementResult, obj); writeOperandId(index); @@ -1434,16 +1440,18 @@ class MOZ_RAII HasPropIRGenerator : publ { HandleValue val_; HandleValue idVal_; bool tryAttachDense(HandleObject obj, ObjOperandId objId, uint32_t index, Int32OperandId indexId); bool tryAttachDenseHole(HandleObject obj, ObjOperandId objId, uint32_t index, Int32OperandId indexId); + bool tryAttachTypedArray(HandleObject obj, ObjOperandId objId, + uint32_t index, Int32OperandId indexId); bool tryAttachNamedProp(HandleObject obj, ObjOperandId objId, HandleId key, ValOperandId keyId); bool tryAttachMegamorphic(ObjOperandId objId, ValOperandId keyId); bool tryAttachNative(JSObject* obj, ObjOperandId objId, jsid key, ValOperandId keyId, PropertyResult prop, JSObject* holder); bool tryAttachUnboxed(JSObject* obj, ObjOperandId objId, jsid key, ValOperandId keyId);
--- a/js/src/jit/CacheIRCompiler.cpp +++ b/js/src/jit/CacheIRCompiler.cpp @@ -1949,16 +1949,40 @@ CacheIRCompiler::emitLoadDenseElementHol masm.bind(&hole); masm.moveValue(UndefinedValue(), output.valueReg()); masm.bind(&done); return true; } bool +CacheIRCompiler::emitLoadTypedElementExistsResult() +{ + AutoOutputRegister output(*this); + Register obj = allocator.useRegister(masm, reader.objOperandId()); + Register index = allocator.useRegister(masm, reader.int32OperandId()); + TypedThingLayout layout = reader.typedThingLayout(); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + Label outOfBounds, done; + + // Bound check. + LoadTypedThingLength(masm, layout, obj, scratch); + masm.branch32(Assembler::BelowOrEqual, scratch, index, &outOfBounds); + EmitStoreBoolean(masm, true, output); + masm.jump(&done); + + masm.bind(&outOfBounds); + EmitStoreBoolean(masm, false, output); + + masm.bind(&done); + return true; +} + +bool CacheIRCompiler::emitLoadDenseElementExistsResult() { AutoOutputRegister output(*this); Register obj = allocator.useRegister(masm, reader.objOperandId()); Register index = allocator.useRegister(masm, reader.int32OperandId()); AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); FailurePath* failure;
--- a/js/src/jit/CacheIRCompiler.h +++ b/js/src/jit/CacheIRCompiler.h @@ -45,16 +45,17 @@ namespace jit { _(LoadFunctionLengthResult) \ _(LoadStringLengthResult) \ _(LoadStringCharResult) \ _(LoadArgumentsObjectArgResult) \ _(LoadDenseElementResult) \ _(LoadDenseElementHoleResult) \ _(LoadDenseElementExistsResult) \ _(LoadDenseElementHoleExistsResult) \ + _(LoadTypedElementExistsResult) \ _(LoadTypedElementResult) \ _(LoadObjectResult) \ _(LoadTypeOfObjectResult) \ _(CompareStringResult) \ _(CompareObjectResult) \ _(CompareSymbolResult) \ _(ArrayJoinResult) \ _(CallPrintString) \
--- a/js/src/old-configure.in +++ b/js/src/old-configure.in @@ -1919,28 +1919,16 @@ if test "$MOZ_DEBUG"; then fi AC_SUBST(MOZ_DEV_EDITION) if test -n "$MOZ_DEV_EDITION"; then AC_DEFINE(MOZ_DEV_EDITION) fi dnl ======================================================== -dnl Determine options to use for running the preprocessor. -dnl ======================================================== - -if test -z "$GNU_CC" -a "$OS_ARCH" = "WINNT"; then - PREPROCESS_OPTION="-P -Fi" -else - PREPROCESS_OPTION="-E -o " -fi - -AC_SUBST(PREPROCESS_OPTION) - -dnl ======================================================== dnl JavaScript shell dnl ======================================================== MOZ_CHECK_ALLOCATOR AC_CHECK_FUNCS(setlocale localeconv) AC_SUBST(MOZILLA_VERSION)
--- a/js/src/vm/Shape.cpp +++ b/js/src/vm/Shape.cpp @@ -613,25 +613,88 @@ NativeObject::addDataPropertyInternal(JS MOZ_ASSERT(shape == obj->lastProperty()); if (table) shape->updateDictionaryTable(table, entry, keep); return shape; } +static MOZ_ALWAYS_INLINE Shape* +PropertyTreeReadBarrier(Shape* parent, Shape* shape) +{ + JS::Zone* zone = shape->zone(); + if (zone->needsIncrementalBarrier()) { + // We need a read barrier for the shape tree, since these are weak + // pointers. + Shape* tmp = shape; + TraceManuallyBarrieredEdge(zone->barrierTracer(), &tmp, "read barrier"); + MOZ_ASSERT(tmp == shape); + return shape; + } + + if (MOZ_LIKELY(!zone->isGCSweepingOrCompacting() || + !IsAboutToBeFinalizedUnbarriered(&shape))) + { + if (shape->isMarkedGray()) + UnmarkGrayShapeRecursively(shape); + return shape; + } + + // The shape we've found is unreachable and due to be finalized, so + // remove our weak reference to it and don't use it. + MOZ_ASSERT(parent->isMarkedAny()); + parent->removeChild(shape); + + return nullptr; +} + /* static */ Shape* NativeObject::addEnumerableDataProperty(JSContext* cx, HandleNativeObject obj, HandleId id) { // Like addProperty(Internal), but optimized for the common case of adding a // new enumerable data property. - AutoKeepShapeTables keep(cx); AutoCheckShapeConsistency check(obj); + // Fast path for non-dictionary shapes with a single kid. + do { + AutoCheckCannotGC nogc; + + Shape* lastProperty = obj->lastProperty(); + if (lastProperty->inDictionary()) + break; + + KidsPointer* kidp = &lastProperty->kids; + if (!kidp->isShape()) + break; + + Shape* kid = kidp->toShape(); + MOZ_ASSERT(!kid->inDictionary()); + + if (kid->propidRaw() != id || + kid->isAccessorShape() || + kid->attributes() != JSPROP_ENUMERATE || + kid->base()->unowned() != lastProperty->base()->unowned()) + { + break; + } + + MOZ_ASSERT(kid->isDataProperty()); + + kid = PropertyTreeReadBarrier(lastProperty, kid); + if (!kid) + break; + + if (!obj->setLastProperty(cx, kid)) + return nullptr; + return kid; + } while (0); + + AutoKeepShapeTables keep(cx); ShapeTable* table = nullptr; ShapeTable::Entry* entry = nullptr; if (!obj->inDictionaryMode()) { if (MOZ_UNLIKELY(ShouldConvertToDictionary(obj))) { if (!toDictionaryMode(cx, obj)) return nullptr; table = obj->lastProperty()->maybeTable(keep); @@ -1671,40 +1734,19 @@ PropertyTree::inlinedGetChild(JSContext* } else if (kidp->isHash()) { if (KidsHash::Ptr p = kidp->toHash()->lookup(child)) existingShape = *p; } else { /* If kidp->isNull(), we always insert. */ } if (existingShape) { - JS::Zone* zone = existingShape->zone(); - if (zone->needsIncrementalBarrier()) { - /* - * We need a read barrier for the shape tree, since these are weak - * pointers. - */ - Shape* tmp = existingShape; - TraceManuallyBarrieredEdge(zone->barrierTracer(), &tmp, "read barrier"); - MOZ_ASSERT(tmp == existingShape); + existingShape = PropertyTreeReadBarrier(parent, existingShape); + if (existingShape) return existingShape; - } - if (!zone->isGCSweepingOrCompacting() || - !IsAboutToBeFinalizedUnbarriered(&existingShape)) - { - if (existingShape->isMarkedGray()) - UnmarkGrayShapeRecursively(existingShape); - return existingShape; - } - /* - * The shape we've found is unreachable and due to be finalized, so - * remove our weak reference to it and don't use it. - */ - MOZ_ASSERT(parent->isMarkedAny()); - parent->removeChild(existingShape); } RootedShape parentRoot(cx, parent); Shape* shape = Shape::new_(cx, child, parentRoot->numFixedSlots()); if (!shape) return nullptr; if (!insertChild(cx, parentRoot, shape))
--- a/netwerk/dns/DNS.cpp +++ b/netwerk/dns/DNS.cpp @@ -2,17 +2,16 @@ * 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 "mozilla/net/DNS.h" #include "mozilla/Assertions.h" #include "mozilla/mozalloc.h" #include "mozilla/ArrayUtils.h" -#include "nsString.h" #include <string.h> #ifdef XP_WIN #include "ws2tcpip.h" #endif namespace mozilla { namespace net { @@ -287,67 +286,89 @@ NetAddrElement::NetAddrElement(const PRN NetAddrElement::NetAddrElement(const NetAddrElement& netAddr) { mAddress = netAddr.mAddress; } NetAddrElement::~NetAddrElement() = default; -AddrInfo::AddrInfo(const nsACString& host, const PRAddrInfo *prAddrInfo, - bool disableIPv4, bool filterNameCollision, - const nsACString& cname) - : mHostName(host) - , mCanonicalName(cname) +AddrInfo::AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, + bool disableIPv4, bool filterNameCollision, const char *cname) + : mHostName(nullptr) + , mCanonicalName(nullptr) , ttl(NO_TTL_DATA) { MOZ_ASSERT(prAddrInfo, "Cannot construct AddrInfo with a null prAddrInfo pointer!"); const uint32_t nameCollisionAddr = htonl(0x7f003535); // 127.0.53.53 + Init(host, cname); PRNetAddr tmpAddr; void *iter = nullptr; do { iter = PR_EnumerateAddrInfo(iter, prAddrInfo, 0, &tmpAddr); bool addIt = iter && (!disableIPv4 || tmpAddr.raw.family != PR_AF_INET) && (!filterNameCollision || tmpAddr.raw.family != PR_AF_INET || (tmpAddr.inet.ip != nameCollisionAddr)); if (addIt) { auto *addrElement = new NetAddrElement(&tmpAddr); mAddresses.insertBack(addrElement); } } while (iter); } -AddrInfo::AddrInfo(const nsACString& host, const nsACString& cname) - : mHostName(host) - , mCanonicalName(cname) +AddrInfo::AddrInfo(const char *host, const char *cname) + : mHostName(nullptr) + , mCanonicalName(nullptr) , ttl(NO_TTL_DATA) { + Init(host, cname); } AddrInfo::~AddrInfo() { NetAddrElement *addrElement; while ((addrElement = mAddresses.popLast())) { delete addrElement; } + free(mHostName); + free(mCanonicalName); +} + +void +AddrInfo::Init(const char *host, const char *cname) +{ + MOZ_ASSERT(host, "Cannot initialize AddrInfo with a null host pointer!"); + + ttl = NO_TTL_DATA; + size_t hostlen = strlen(host); + mHostName = static_cast<char*>(moz_xmalloc(hostlen + 1)); + memcpy(mHostName, host, hostlen + 1); + if (cname) { + size_t cnameLen = strlen(cname); + mCanonicalName = static_cast<char*>(moz_xmalloc(cnameLen + 1)); + memcpy(mCanonicalName, cname, cnameLen + 1); + } + else { + mCanonicalName = nullptr; + } } void AddrInfo::AddAddress(NetAddrElement *address) { MOZ_ASSERT(address, "Cannot add the address to an uninitialized list"); mAddresses.insertBack(address); } size_t AddrInfo::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const { size_t n = mallocSizeOf(this); - n += mHostName.SizeOfExcludingThisIfUnshared(mallocSizeOf); - n += mCanonicalName.SizeOfExcludingThisIfUnshared(mallocSizeOf); + n += mallocSizeOf(mHostName); + n += mallocSizeOf(mCanonicalName); n += mAddresses.sizeOfExcludingThis(mallocSizeOf); return n; } } // namespace net } // namespace mozilla
--- a/netwerk/dns/DNS.h +++ b/netwerk/dns/DNS.h @@ -3,17 +3,16 @@ /* 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 DNS_h_ #define DNS_h_ #include "nscore.h" -#include "nsString.h" #include "prio.h" #include "prnetdb.h" #include "plstr.h" #include "mozilla/LinkedList.h" #include "mozilla/MemoryReporting.h" #if !defined(XP_WIN) #include <arpa/inet.h> @@ -129,37 +128,38 @@ public: NetAddrElement(const NetAddrElement& netAddr); ~NetAddrElement(); NetAddr mAddress; }; class AddrInfo { public: - // Creates an AddrInfo object. - AddrInfo(const nsACString& host, const PRAddrInfo *prAddrInfo, - bool disableIPv4, bool filterNameCollision, - const nsACString& cname); + // Creates an AddrInfo object. It calls the AddrInfo(const char*, const char*) + // to initialize the host and the cname. + AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, bool disableIPv4, + bool filterNameCollision, const char *cname); - // Creates a basic AddrInfo object (initialize only the host and the - // cname). - AddrInfo(const nsACString& host, const nsACString& cname); - + // Creates a basic AddrInfo object (initialize only the host and the cname). + AddrInfo(const char *host, const char *cname); ~AddrInfo(); void AddAddress(NetAddrElement *address); size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; - nsCString mHostName; - nsCString mCanonicalName; + char *mHostName; + char *mCanonicalName; uint32_t ttl; static const uint32_t NO_TTL_DATA = (uint32_t) -1; LinkedList<NetAddrElement> mAddresses; + +private: + void Init(const char *host, const char *cname); }; // Copies the contents of a PRNetAddr to a NetAddr. // Does not do a ptr safety check! void PRNetAddrToNetAddr(const PRNetAddr *prAddr, NetAddr *addr); // Copies the contents of a NetAddr to a PRNetAddr. // Does not do a ptr safety check!
--- a/netwerk/dns/GetAddrInfo.cpp +++ b/netwerk/dns/GetAddrInfo.cpp @@ -246,19 +246,20 @@ static MOZ_ALWAYS_INLINE nsresult //////////////////////////////////// // PORTABLE RUNTIME IMPLEMENTATION// //////////////////////////////////// static MOZ_ALWAYS_INLINE nsresult _GetAddrInfo_Portable(const char* aCanonHost, uint16_t aAddressFamily, uint16_t aFlags, const char* aNetworkInterface, - UniquePtr<AddrInfo>& aAddrInfo) + AddrInfo** aAddrInfo) { MOZ_ASSERT(aCanonHost); + MOZ_ASSERT(aAddrInfo); // We accept the same aFlags that nsHostResolver::ResolveHost accepts, but we // need to translate the aFlags into a form that PR_GetAddrInfoByName // accepts. int prFlags = PR_AI_ADDRCONFIG; if (!(aFlags & nsHostResolver::RES_CANON_NAME)) { prFlags |= PR_AI_NOCANONNAME; } @@ -277,24 +278,24 @@ static MOZ_ALWAYS_INLINE nsresult } const char* canonName = nullptr; if (aFlags & nsHostResolver::RES_CANON_NAME) { canonName = PR_GetCanonNameFromAddrInfo(prai); } bool filterNameCollision = !(aFlags & nsHostResolver::RES_ALLOW_NAME_COLLISION); - auto ai = MakeUnique<AddrInfo>(nsCString(aCanonHost), prai, disableIPv4, - filterNameCollision, nsCString(canonName)); + nsAutoPtr<AddrInfo> ai(new AddrInfo(aCanonHost, prai, disableIPv4, + filterNameCollision, canonName)); PR_FreeAddrInfo(prai); if (ai->mAddresses.isEmpty()) { return NS_ERROR_UNKNOWN_HOST; } - aAddrInfo = Move(ai); + *aAddrInfo = ai.forget(); return NS_OK; } ////////////////////////////////////// // COMMON/PLATFORM INDEPENDENT CODE // ////////////////////////////////////// nsresult @@ -316,50 +317,49 @@ GetAddrInfoShutdown() { return _GetAddrInfoShutdown_Windows(); #else return NS_OK; #endif } nsresult GetAddrInfo(const char* aHost, uint16_t aAddressFamily, uint16_t aFlags, - const char* aNetworkInterface, - UniquePtr<AddrInfo>& aAddrInfo, bool aGetTtl) + const char* aNetworkInterface, AddrInfo** aAddrInfo, bool aGetTtl) { - if (NS_WARN_IF(!aHost)) { + if (NS_WARN_IF(!aHost) || NS_WARN_IF(!aAddrInfo)) { return NS_ERROR_NULL_POINTER; } #if DNSQUERY_AVAILABLE // The GetTTLData needs the canonical name to function properly if (aGetTtl) { aFlags |= nsHostResolver::RES_CANON_NAME; } #endif - aAddrInfo = nullptr; + *aAddrInfo = nullptr; nsresult rv = _GetAddrInfo_Portable(aHost, aAddressFamily, aFlags, aNetworkInterface, aAddrInfo); #if DNSQUERY_AVAILABLE if (aGetTtl && NS_SUCCEEDED(rv)) { // Figure out the canonical name, or if that fails, just use the host name // we have. const char *name = nullptr; - if (aAddrInfo && !aAddrInfo->mCanonicalName.IsEmpty()) { - name = aAddrInfo->mCanonicalName.get(); + if (*aAddrInfo != nullptr && (*aAddrInfo)->mCanonicalName) { + name = (*aAddrInfo)->mCanonicalName; } else { name = aHost; } LOG("Getting TTL for %s (cname = %s).", aHost, name); uint32_t ttl = 0; nsresult ttlRv = _GetTTLData_Windows(name, &ttl, aAddressFamily); if (NS_SUCCEEDED(ttlRv)) { - aAddrInfo->ttl = ttl; + (*aAddrInfo)->ttl = ttl; LOG("Got TTL %u for %s (name = %s).", ttl, aHost, name); } else { LOG_WARNING("Could not get TTL for %s (cname = %s).", aHost, name); } } #endif return rv;
--- a/netwerk/dns/GetAddrInfo.h +++ b/netwerk/dns/GetAddrInfo.h @@ -35,18 +35,17 @@ class AddrInfo; * hostname (PR_AI_NOCANONNAME will be ignored if the TTL is retrieved). * @param aAddrInfo[out] Will point to the results of the host lookup, or be * null if the lookup failed. * @param aGetTtl[in] If true, and TTL_AVAILABLE is truthy, the TTL will be * retrieved if DNS provides the answers.. */ nsresult GetAddrInfo(const char* aHost, uint16_t aAddressFamily, uint16_t aFlags, - const char* aNetworkInterface, - UniquePtr<AddrInfo>& aAddrInfo, bool aGetTtl); + const char* aNetworkInterface, AddrInfo** aAddrInfo, bool aGetTtl); /** * Initialize the GetAddrInfo module. * * GetAddrInfoShutdown() should be called for every time this function is * called. */ nsresult
--- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -83,31 +83,28 @@ NS_IMPL_ISUPPORTS(nsDNSRecord, nsIDNSRec NS_IMETHODIMP nsDNSRecord::GetCanonicalName(nsACString &result) { // this method should only be called if we have a CNAME NS_ENSURE_TRUE(mHostRecord->flags & nsHostResolver::RES_CANON_NAME, NS_ERROR_NOT_AVAILABLE); + // if the record is for an IP address literal, then the canonical + // host name is the IP address literal. + const char *cname; { MutexAutoLock lock(mHostRecord->addr_info_lock); - - // if the record is for an IP address literal, then the canonical - // host name is the IP address literal. - if (!mHostRecord->addr_info) { - result = mHostRecord->host; - return NS_OK; - } - - if (mHostRecord->addr_info->mCanonicalName.IsEmpty()) { - result = mHostRecord->addr_info->mHostName; - } else { - result = mHostRecord->addr_info->mCanonicalName; - } + if (mHostRecord->addr_info) + cname = mHostRecord->addr_info->mCanonicalName ? + mHostRecord->addr_info->mCanonicalName : + mHostRecord->addr_info->mHostName; + else + cname = mHostRecord->host; + result.Assign(cname); } return NS_OK; } NS_IMETHODIMP nsDNSRecord::GetNextAddr(uint16_t port, NetAddr *addr) { if (mDone) {
--- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -226,16 +226,17 @@ nsHostRecord::CopyExpirationTimesAndFlag mValidEnd = aFromHostRecord->mValidEnd; mGraceStart = aFromHostRecord->mGraceStart; mDoomed = aFromHostRecord->mDoomed; } nsHostRecord::~nsHostRecord() { Telemetry::Accumulate(Telemetry::DNS_BLACKLIST_COUNT, mBlacklistedCount); + delete addr_info; } bool nsHostRecord::Blacklisted(NetAddr *aQuery) { // must call locked LOG(("Checking blacklist for host [%s%s%s], host record [%p].\n", LOG_HOST(host, netInterface), this)); @@ -593,18 +594,17 @@ void nsHostResolver::ClearPendingQueue(PRCList *aPendingQ) { // loop through pending queue, erroring out pending lookups. if (!PR_CLIST_IS_EMPTY(aPendingQ)) { PRCList *node = aPendingQ->next; while (node != aPendingQ) { nsHostRecord *rec = static_cast<nsHostRecord *>(node); node = node->next; - OnLookupComplete(rec, NS_ERROR_ABORT, - mozilla::UniquePtr<AddrInfo>(nullptr)); + OnLookupComplete(rec, NS_ERROR_ABORT, nullptr); } } } // // FlushCache() is what we call when the network has changed. We must not // trust names that were resolved before this change. They may resolve // differently now. @@ -865,31 +865,34 @@ nsHostResolver::ResolveHost(const char LOG((" Trying AF_UNSPEC entry for host [%s%s%s] af: %s.\n", LOG_HOST(host, netInterface), (af == PR_AF_INET) ? "AF_INET" : "AF_INET6")); // We need to lock in case any other thread is reading // addr_info. MutexAutoLock lock(he->rec->addr_info_lock); + // XXX: note that this actually leaks addr_info. + // For some reason, freeing the memory causes a crash in + // nsDNSRecord::GetNextAddr - see bug 1422173 he->rec->addr_info = nullptr; if (unspecHe->rec->negative) { he->rec->negative = unspecHe->rec->negative; he->rec->CopyExpirationTimesAndFlagsFrom(unspecHe->rec); } else if (unspecHe->rec->addr_info) { // Search for any valid address in the AF_UNSPEC entry // in the cache (not blacklisted and from the right // family). NetAddrElement *addrIter = unspecHe->rec->addr_info->mAddresses.getFirst(); while (addrIter) { if ((af == addrIter->mAddress.inet.family) && !unspecHe->rec->Blacklisted(&addrIter->mAddress)) { if (!he->rec->addr_info) { - he->rec->addr_info = mozilla::MakeUnique<AddrInfo>( + he->rec->addr_info = new AddrInfo( unspecHe->rec->addr_info->mHostName, unspecHe->rec->addr_info->mCanonicalName); he->rec->CopyExpirationTimesAndFlagsFrom(unspecHe->rec); } he->rec->addr_info->AddAddress( new NetAddrElement(*addrIter)); } addrIter = addrIter->getNext(); @@ -1235,17 +1238,17 @@ nsHostResolver::PrepareRecordExpiration( static bool different_rrset(AddrInfo *rrset1, AddrInfo *rrset2) { if (!rrset1 || !rrset2) { return true; } - LOG(("different_rrset %s\n", rrset1->mHostName.get())); + LOG(("different_rrset %s\n", rrset1->mHostName)); nsTArray<NetAddr> orderedSet1; nsTArray<NetAddr> orderedSet2; for (NetAddrElement *element = rrset1->mAddresses.getFirst(); element; element = element->getNext()) { if (LOG_ENABLED()) { char buf[128]; NetAddrToString(&element->mAddress, buf, 128); @@ -1281,49 +1284,53 @@ different_rrset(AddrInfo *rrset1, AddrIn return false; } // // OnLookupComplete() checks if the resolving should be redone and if so it // returns LOOKUP_RESOLVEAGAIN, but only if 'status' is not NS_ERROR_ABORT. // takes ownership of AddrInfo parameter nsHostResolver::LookupStatus -nsHostResolver::OnLookupComplete(nsHostRecord* rec, nsresult status, - mozilla::UniquePtr<AddrInfo>&& newRRSet) +nsHostResolver::OnLookupComplete(nsHostRecord* rec, nsresult status, AddrInfo* newRRSet) { // get the list of pending callbacks for this lookup, and notify // them that the lookup is complete. PRCList cbs; PR_INIT_CLIST(&cbs); { MutexAutoLock lock(mLock); if (rec->mResolveAgain && (status != NS_ERROR_ABORT)) { LOG(("nsHostResolver record %p resolve again due to flushcache\n", rec)); rec->mResolveAgain = false; + delete newRRSet; return LOOKUP_RESOLVEAGAIN; } // grab list of callbacks to notify MoveCList(rec->callbacks, cbs); // update record fields. We might have a rec->addr_info already if a // previous lookup result expired and we're reresolving it.. + AddrInfo *old_addr_info; { MutexAutoLock lock(rec->addr_info_lock); - if (different_rrset(rec->addr_info.get(), newRRSet.get())) { + if (different_rrset(rec->addr_info, newRRSet)) { LOG(("nsHostResolver record %p new gencnt\n", rec)); - rec->addr_info = Move(newRRSet); + old_addr_info = rec->addr_info; + rec->addr_info = newRRSet; rec->addr_info_gencnt++; } else { if (rec->addr_info && newRRSet) { rec->addr_info->ttl = newRRSet->ttl; } + old_addr_info = newRRSet; } } + delete old_addr_info; rec->negative = !rec->addr_info; PrepareRecordExpiration(rec); rec->resolving = false; if (rec->usingAnyThread) { mActiveAnyThreadCount--; rec->usingAnyThread = false; @@ -1463,34 +1470,34 @@ nsHostResolver::ThreadFunc(void *arg) AUTO_PROFILER_REGISTER_THREAD(name.BeginReading()); NS_SetCurrentThreadName(name.BeginReading()); #if defined(RES_RETRY_ON_FAILURE) nsResState rs; #endif nsHostResolver *resolver = (nsHostResolver *)arg; nsHostRecord *rec = nullptr; - mozilla::UniquePtr<AddrInfo> ai = nullptr; + AddrInfo *ai = nullptr; while (rec || resolver->GetHostToLookup(&rec)) { LOG(("DNS lookup thread - Calling getaddrinfo for host [%s%s%s].\n", LOG_HOST(rec->host, rec->netInterface))); TimeStamp startTime = TimeStamp::Now(); #if TTL_AVAILABLE bool getTtl = rec->mGetTtl; #else bool getTtl = false; #endif nsresult status = GetAddrInfo(rec->host, rec->af, rec->flags, rec->netInterface, - ai, getTtl); + &ai, getTtl); #if defined(RES_RETRY_ON_FAILURE) if (NS_FAILED(status) && rs.Reset()) { - status = GetAddrInfo(rec->host, rec->af, rec->flags, rec->netInterface, ai, + status = GetAddrInfo(rec->host, rec->af, rec->flags, rec->netInterface, &ai, getTtl); } #endif { // obtain lock to check shutdown and manage inter-module telemetry MutexAutoLock lock(resolver->mLock); if (!resolver->mShutdown) { @@ -1516,18 +1523,17 @@ nsHostResolver::ThreadFunc(void *arg) } } // OnLookupComplete may release "rec", long before we lose it. LOG(("DNS lookup thread - lookup completed for host [%s%s%s]: %s.\n", LOG_HOST(rec->host, rec->netInterface), ai ? "success" : "failure: unknown host")); - if (LOOKUP_RESOLVEAGAIN == resolver->OnLookupComplete(rec, status, - mozilla::Move(ai))) { + if (LOOKUP_RESOLVEAGAIN == resolver->OnLookupComplete(rec, status, ai)) { // leave 'rec' assigned and loop to make a renewed host resolve LOG(("DNS lookup thread - Re-resolving host [%s%s%s].\n", LOG_HOST(rec->host, rec->netInterface))); } else { rec = nullptr; } } resolver->mThreadCount--;
--- a/netwerk/dns/nsHostResolver.h +++ b/netwerk/dns/nsHostResolver.h @@ -70,17 +70,17 @@ public: * nsDNSService2 class. |addr| doesn't change after it has been * assigned a value. only the resolver worker thread modifies * nsHostRecord (and only in nsHostResolver::OnLookupComplete); * the other threads just read it. therefore the resolver worker * thread doesn't need to lock when reading |addr_info|. */ Mutex addr_info_lock; int addr_info_gencnt; /* generation count of |addr_info| */ - mozilla::UniquePtr<mozilla::net::AddrInfo> addr_info; + mozilla::net::AddrInfo *addr_info; mozilla::UniquePtr<mozilla::net::NetAddr> addr; bool negative; /* True if this record is a cache of a failed lookup. Negative cache entries are valid just like any other (though never for more than 60 seconds), but a use of that negative entry forces an asynchronous refresh. */ enum ExpirationStatus { EXP_VALID, @@ -313,18 +313,17 @@ private: nsresult IssueLookup(nsHostRecord *); bool GetHostToLookup(nsHostRecord **m); enum LookupStatus { LOOKUP_OK, LOOKUP_RESOLVEAGAIN, }; - LookupStatus OnLookupComplete(nsHostRecord *, nsresult, - mozilla::UniquePtr<mozilla::net::AddrInfo>&&); + LookupStatus OnLookupComplete(nsHostRecord *, nsresult, mozilla::net::AddrInfo *); void DeQueue(PRCList &aQ, nsHostRecord **aResult); void ClearPendingQueue(PRCList *aPendingQueue); nsresult ConditionallyCreateThread(nsHostRecord *rec); /** * Starts a new lookup in the background for entries that are in the grace * period with a failed connect or all cached entries are negative. */
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp +++ b/netwerk/protocol/websocket/WebSocketChannel.cpp @@ -2046,16 +2046,20 @@ WebSocketChannel::PrimeNewOutgoingMessag "Not ping message!"); else mCurrentOut = (OutboundMessage *)mOutgoingMessages.PopFront(); } if (!mCurrentOut) return; + auto cleanupAfterFailure = MakeScopeExit([&] { + DeleteCurrentOutGoingMessage(); + }); + WsMsgType msgType = mCurrentOut->GetMsgType(); LOG(("WebSocketChannel::PrimeNewOutgoingMessage " "%p found queued msg %p [type=%s len=%d]\n", this, mCurrentOut, msgNames[msgType], mCurrentOut->Length())); mCurrentOutSent = 0; mHdrOut = mOutHeader; @@ -2065,16 +2069,17 @@ WebSocketChannel::PrimeNewOutgoingMessag uint8_t *payload = nullptr; if (msgType == kMsgTypeFin) { // This is a demand to create a close message if (mClientClosed) { DeleteCurrentOutGoingMessage(); PrimeNewOutgoingMessage(); + cleanupAfterFailure.release(); return; } mClientClosed = 1; mOutHeader[0] = kFinalFragBit | nsIWebSocketFrame::OPCODE_CLOSE; mOutHeader[1] = maskBit; // payload is offset 2 plus size of the mask @@ -2253,16 +2258,18 @@ WebSocketChannel::PrimeNewOutgoingMessag mHdrOutToSend += len; mCurrentOutSent = len; } // Transmitting begins - mHdrOutToSend bytes from mOutHeader and // mCurrentOut->Length() bytes from mCurrentOut. The latter may be // coaleseced into the former for small messages or as the result of the // compression process. + + cleanupAfterFailure.release(); } void WebSocketChannel::DeleteCurrentOutGoingMessage() { delete mCurrentOut; mCurrentOut = nullptr; mCurrentOutSent = 0;
--- a/old-configure.in +++ b/old-configure.in @@ -4970,28 +4970,16 @@ HAVE_STATVFS HAVE_STATFS64 HAVE_STATFS HAVE_SYS_STATVFS_H HAVE_SYS_STATFS_H HAVE_SYS_VFS_H HAVE_SYS_MOUNT_H " -dnl ======================================================== -dnl Determine options to use for running the preprocessor. -dnl ======================================================== - -if test -z "$GNU_CC" -a "$OS_ARCH" = "WINNT"; then - PREPROCESS_OPTION="-P -Fi" -else - PREPROCESS_OPTION="-E -o " -fi - -AC_SUBST(PREPROCESS_OPTION) - # Avoid using obsolete NSPR features AC_DEFINE(NO_NSPR_10_SUPPORT) # Don't build NSS libpkix NSS_DISABLE_LIBPKIX=1 AC_SUBST(NSS_DISABLE_LIBPKIX) MOZ_CREATE_CONFIG_STATUS()
--- a/taskcluster/ci/build/windows.yml +++ b/taskcluster/ci/build/windows.yml @@ -476,17 +476,17 @@ win64-ccov/debug: product: firefox job-name: win64-ccov-debug treeherder: platform: windows2012-64/ccov symbol: tc(B) tier: 3 worker-type: aws-provisioner-v1/gecko-{level}-b-win2012 worker: - max-run-time: 14400 + max-run-time: 7200 env: TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest" run: using: mozharness options: [append-env-variables-from-configs] script: mozharness/scripts/fx_desktop_build.py config: - builds/releng_base_firefox.py
--- a/taskcluster/ci/release-bouncer-aliases/kind.yml +++ b/taskcluster/ci/release-bouncer-aliases/kind.yml @@ -28,17 +28,17 @@ jobs: buildername: release-{branch}-fennec_bouncer_aliases release-promotion: true worker: properties: tuxedo_server_url: by-project: mozilla-beta: https://bounceradmin.mozilla.com/api mozilla-release: https://bounceradmin.mozilla.com/api - maple: https://admin-bouncer.stage.mozaws.net/api/ + maple: https://admin-bouncer-releng.stage.mozaws.net/api/ default: http://localhost/api routes: - index.releases.v1.{branch}.latest.fennec.latest.bouncer_submitter - index.releases.v1.{branch}.{revision}.fennec.{underscore_version}.build{build_number}.bouncer_submitter index: type: release product: fennec job-name: android-api-16-opt
--- a/taskcluster/ci/release-uptake-monitoring/kind.yml +++ b/taskcluster/ci/release-uptake-monitoring/kind.yml @@ -30,17 +30,17 @@ jobs: worker: properties: # TODO: Calculate "platforms" dynamically platforms: "android-api-16, android-x86" tuxedo_server_url: by-project: mozilla-beta: https://bounceradmin.mozilla.com/api mozilla-release: https://bounceradmin.mozilla.com/api - maple: https://admin-bouncer.stage.mozaws.net/api/ + maple: https://admin-bouncer-releng.stage.mozaws.net/api/ default: http://localhost/api routes: - index.releases.v1.{branch}.latest.fennec.latest.uptake_monitoring - index.releases.v1.{branch}.{revision}.fennec.{underscore_version}.build{build_number}.uptake_monitoring index: type: release product: fennec job-name: android-api-16-opt
--- a/taskcluster/ci/test/talos.yml +++ b/taskcluster/ci/test/talos.yml @@ -416,31 +416,22 @@ talos-tp6-stylo-threads: mozharness: extra-options: - --suite=tp6-stylo-threads talos-xperf: description: "Talos xperf" try-name: xperf treeherder-symbol: tc-T(x) + virtualization: virtual run-on-projects: by-test-platform: windows7-32.*: ['mozilla-beta', 'mozilla-central', 'mozilla-inbound', 'autoland', 'try'] default: [] mozharness: extra-options: - --suite=xperf - --add-option - --webServer,localhost - -talos-xperf-stylo-disabled: - description: "Talos Stylo disabled xperf" - try-name: xperf-stylo-disabled - treeherder-symbol: tc-Tsd(x) - run-on-projects: - by-test-platform: - windows7-32.*: ['mozilla-beta', 'mozilla-central', 'try'] - default: [] - mozharness: - extra-options: - - --suite=xperf-stylo-disabled - - --add-option - - --webServer,localhost + config: + by-test-platform: + windows.*: + - talos/windows_vm_config.py
--- a/taskcluster/taskgraph/transforms/tests.py +++ b/taskcluster/taskgraph/transforms/tests.py @@ -890,16 +890,18 @@ def set_worker_type(config, tests): test['worker-type'] = MACOSX_WORKER_TYPES['macosx64'] elif test_platform.startswith('win'): win_worker_type_platform = WINDOWS_WORKER_TYPES[ test_platform.split('/')[0] ] if test.get('suite', '') == 'talos' and 'ccov' not in test['build-platform']: if try_options.get('taskcluster_worker'): test['worker-type'] = win_worker_type_platform['hardware'] + elif test['virtualization'] == 'virtual': + test['worker-type'] = win_worker_type_platform[test['virtualization']] else: test['worker-type'] = 'buildbot-bridge/buildbot-bridge' else: test['worker-type'] = win_worker_type_platform[test['virtualization']] elif test_platform.startswith('linux') or test_platform.startswith('android'): if test.get('suite', '') == 'talos' and test['build-platform'] != 'linux64-ccov/opt': if try_options.get('taskcluster_worker'): test['worker-type'] = 'releng-hardware/gecko-t-linux-talos'
--- a/testing/geckodriver/CONTRIBUTING.md +++ b/testing/geckodriver/CONTRIBUTING.md @@ -224,9 +224,9 @@ Communication The mailing list for geckodriver discussion is tools-marionette@lists.mozilla.org ([subscribe], [archive]). If you prefer real-time chat, there is often someone in the #ateam IRC channel on irc.mozilla.org. Don’t ask if you can ask a question, just ask, and please wait for an answer as we might not be in your timezone. [subscribe]: https://lists.mozilla.org/listinfo/tools-marionette -[archive]: http://groups.google.com/group/mozilla.tools.marionette +[archive]: https://groups.google.com/group/mozilla.tools.marionette
--- a/testing/geckodriver/README.md +++ b/testing/geckodriver/README.md @@ -597,9 +597,9 @@ Contact The mailing list for geckodriver discussion is tools-marionette@lists.mozilla.org ([subscribe], [archive]). There is also an IRC channel to talk about using and developing geckodriver in #ateam on irc.mozilla.org. [subscribe]: https://lists.mozilla.org/listinfo/tools-marionette -[archive]: http://groups.google.com/group/mozilla.tools.marionette +[archive]: https://groups.google.com/group/mozilla.tools.marionette
--- a/testing/marionette/CONTRIBUTING.md +++ b/testing/marionette/CONTRIBUTING.md @@ -199,9 +199,9 @@ Communication The mailing list for Marionette discussion is tools-marionette@lists.mozilla.org ([subscribe], [archive]). If you prefer real-time chat, there is often someone in the #ateam IRC channel on irc.mozilla.org. Don’t ask if you can ask a question, just ask, and please wait for an answer as we might not be in your timezone. [subscribe]: https://lists.mozilla.org/listinfo/tools-marionette -[archive]: http://groups.google.com/group/mozilla.tools.marionette +[archive]: https://groups.google.com/group/mozilla.tools.marionette
--- a/testing/marionette/README.md +++ b/testing/marionette/README.md @@ -60,9 +60,9 @@ for an answer as we might not be in your [clients]: #clients [protocol]: #protocol [command]: #command [response]: #response [error]: #error-object [WebDriver standard]: https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors [reference client]: client/ [subscribe]: https://lists.mozilla.org/listinfo/tools-marionette -[archive]: http://groups.google.com/group/mozilla.tools.marionette +[archive]: https://groups.google.com/group/mozilla.tools.marionette
--- a/testing/marionette/doc/index.rst +++ b/testing/marionette/doc/index.rst @@ -1,38 +1,71 @@ ========== Marionette ========== -Marionette is an automation driver for Mozilla's Gecko engine. +Marionette is the remote protocol that lets OOP programs communicate +with, instrument, and control Gecko. + + +Description +=========== + +Marionette is an automation driver for Mozilla’s Gecko engine. It can remotely control either the UI or the internal JavaScript of -a Gecko platform, such as Firefox. It can control both the chrome -(i.e. menus and functions) or the content (the webpage loaded inside -the browsing context), giving a high level of control and ability -to replicate user actions. In addition to performing actions on the -browser, Marionette can also read the properties and attributes of -the DOM. +Gecko-based browsers, such as Firefox and Fennec. It can control +both the chrome and the content document, giving a high level of +control and ability to replicate user interaction. In addition +to performing actions on the browser, Marionette can also ready +properties and attributes of the DOM. + For users ========= + .. toctree:: :maxdepth: 1 Intro.md Protocol.md See also: -* Documentation for `Marionette Python Client <http://marionette-client.readthedocs.io>`_, - which is used in-tree to write many kinds of Marionette-based tests. -* Documentation for `Firefox Puppeteer <http://firefox-puppeteer.readthedocs.io>`_, which is - used to in-tree to write Firefox UI tests. +* Documentation for `Marionette Python client`_., which is used + in-tree to write many kinds of Marionette-based tests. +* Documentation for `Firefox Puppeteer`_, which is used to in-tree + to write Firefox UI tests. -For marionette developers -========================== +.. _Marionette Python client: http://marionette-client.readthedocs.io +.. _Firefox Puppeteer: http://firefox-puppeteer.readthedocs.io + + +For developers +============== + .. toctree:: :maxdepth: 1 + ../CONTRIBUTING.md NewContributors.md Debugging.md PythonTests.md SeleniumAtoms.md + + +Bugs +==== + +Bugs are tracked in the `Testing :: Marionette` component. + + +Communication +============= + +The mailing list for discussion is tools-marionette@lists.mozilla.org +(subscribe_, archive_). If you prefer real-time chat, there +is often someone in the #ateam IRC channel on irc.mozilla.org. +Don’t ask if you can ask a question, just ask, and please wait +for an answer as we might not be in your timezone. + +.. _subscribe: https://lists.mozilla.org/listinfo/tools-marionette +.. _archive: https://groups.google.com/group/mozilla.tools.marionette
--- a/testing/talos/talos/xtalos/xperf_whitelist.json +++ b/testing/talos/talos/xtalos/xperf_whitelist.json @@ -6,16 +6,19 @@ "ignore": true }, "C:\\$Secure": { "ignore": true }, "C:\\$logfile": { "ignore": true }, + "Z:\\$logfile": { + "ignore": true + }, "C:\\Windows\\Prefetch\\{prefetch}.pf": { "ignore": true }, "c:\\program files\\desktop.ini": { "mincount": 2, "maxcount": 2, "minbytes": 352, "maxbytes": 352
--- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -96028,28 +96028,16 @@ [ "/css/compositing/mix-blend-mode/reference/mix-blend-mode-svg-ref.html", "==" ] ], {} ] ], - "css/compositing/mix-blend-mode/mix-blend-mode-transition.html": [ - [ - "/css/compositing/mix-blend-mode/mix-blend-mode-transition.html", - [ - [ - "/css/compositing/mix-blend-mode/reference/mix-blend-mode-transition-ref.html", - "==" - ] - ], - {} - ] - ], "css/compositing/mix-blend-mode/mix-blend-mode-video-sibling.html": [ [ "/css/compositing/mix-blend-mode/mix-blend-mode-video-sibling.html", [ [ "/css/compositing/mix-blend-mode/reference/mix-blend-mode-video-sibling-notref.html", "!=" ] @@ -228108,21 +228096,16 @@ {} ] ], "css/compositing/mix-blend-mode/reference/mix-blend-mode-svg-ref.html": [ [ {} ] ], - "css/compositing/mix-blend-mode/reference/mix-blend-mode-transition-ref.html": [ - [ - {} - ] - ], "css/compositing/mix-blend-mode/reference/mix-blend-mode-video-notref.html": [ [ {} ] ], "css/compositing/mix-blend-mode/reference/mix-blend-mode-video-sibling-notref.html": [ [ {} @@ -463553,20 +463536,16 @@ "css/compositing/mix-blend-mode/mix-blend-mode-stacking-context-creates-isolation.html": [ "3e4bf24c8e89f3e127419eafafcee58b29e5d207", "reftest" ], "css/compositing/mix-blend-mode/mix-blend-mode-svg.html": [ "b0cf703533a323305eb772c6def00afe21cdcdb8", "reftest" ], - "css/compositing/mix-blend-mode/mix-blend-mode-transition.html": [ - "2a9c826f5db1d9eb5a4748351a7d411b4c65a93b", - "reftest" - ], "css/compositing/mix-blend-mode/mix-blend-mode-video-sibling.html": [ "d9682264f4ce1859b0d7f22b8dfca5cc482028a8", "reftest" ], "css/compositing/mix-blend-mode/mix-blend-mode-video.html": [ "53c1adad26086551ab5c7212c477d14aaf7ae672", "reftest" ], @@ -463693,20 +463672,16 @@ "css/compositing/mix-blend-mode/reference/mix-blend-mode-stacking-context-creates-isolation-ref.html": [ "55faa83db514df5fad411f34ff98e9a487f0f46d", "support" ], "css/compositing/mix-blend-mode/reference/mix-blend-mode-svg-ref.html": [ "543892c3466ace307bd125801a2231dae3a95b92", "support" ], - "css/compositing/mix-blend-mode/reference/mix-blend-mode-transition-ref.html": [ - "2fdce2d337a053453bc339ffb7f9e0560c1f0095", - "support" - ], "css/compositing/mix-blend-mode/reference/mix-blend-mode-video-notref.html": [ "4407e55ee0412f2064caeee74acad93424a849c7", "support" ], "css/compositing/mix-blend-mode/reference/mix-blend-mode-video-sibling-notref.html": [ "de4eea01cbb8138c53aac94b5c3fea347a46c7d8", "support" ],
deleted file mode 100644 --- a/testing/web-platform/tests/css/compositing/mix-blend-mode/mix-blend-mode-transition.html +++ /dev/null @@ -1,37 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>CSS Test: Blended element with transition</title> - <link rel="author" title="Mihai Tica" href="mailto:mitica@adobe.com"> - <link rel="help" href="https://drafts.fxtf.org/compositing-1/#mix-blend-mode"> - <meta name="assert" content="Test checks that an element having a transition applied on opacity blends with the parent element."> - <meta name="flags" content="dom"/> - <link rel="reviewer" title="Rik Cabanier" href="mailto:cabanier@adobe.com"> - <link rel="reviewer" title="Mirela Budaes" href="mailto:mbudaes@adobe.com"> - <link rel="match" href="reference/mix-blend-mode-transition-ref.html"> - <style type="text/css"> - div { - width: 100px; - height: 100px; - background: #FF0; - } - - #blender { - background: #F00; - mix-blend-mode: difference; - transition: opacity 1s ease; - } - - .opaqueBox { - opacity: 0.4; - } - </style> - </head> - <body> - <p>Test passes if you can see a fading green rectangle.</p> - <div><div id="blender"></div></div> - <script type="text/javascript"> - setInterval(function(){ document.getElementById('blender').className = 'opaqueBox'; }, 100); - </script> - </body> -</html>
deleted file mode 100644 --- a/testing/web-platform/tests/css/compositing/mix-blend-mode/reference/mix-blend-mode-transition-ref.html +++ /dev/null @@ -1,30 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>CSS Test: Blended element with transition</title> - <link rel="author" title="Mihai Tica" href="mailto:mitica@adobe.com"> - <meta name="flags" content="dom"/> - <style type="text/css"> - div { - width: 100px; - height: 100px; - } - - #blender { - background: #0F0; - transition: opacity 1s ease; - } - - .opaqueBox { - opacity: 0.4; - } - </style> - </head> - <body> - <p>Test passes if you can see a fading green rectangle.</p> - <div style="background: #FF0;"><div id="blender"></div></div> - <script type="text/javascript"> - setInterval(function(){ document.getElementById('blender').className = 'opaqueBox'; }, 100); - </script> - </body> -</html>
--- a/toolkit/components/extensions/test/xpcshell/xpcshell-content.ini +++ b/toolkit/components/extensions/test/xpcshell/xpcshell-content.ini @@ -3,9 +3,10 @@ skip-if = os == "android" || (os == "win [test_ext_i18n_css.js] [test_ext_contentscript.js] [test_ext_contentscript_scriptCreated.js] skip-if = debug # Bug 1407501 [test_ext_contentscript_triggeringPrincipal.js] skip-if = os == "android" && debug [test_ext_contentscript_xrays.js] [test_ext_contentScripts_register.js] +skip-if = os == "android" [test_ext_adoption_with_xrays.js]
--- a/toolkit/components/windowcreator/test/mochitest.ini +++ b/toolkit/components/windowcreator/test/mochitest.ini @@ -4,10 +4,11 @@ support-files = [test_bug293834.html] skip-if = (toolkit == "cocoa" && e10s) # bug 1252223 [test_bug499115.html] [test_nsFind.html] [test_private_window_from_content.html] [test_window_open_position_constraint.html] skip-if = toolkit == 'android' +fail-if = (os == "win" && ccov) # bug 1421715 [test_window_open_units.html] skip-if = toolkit == 'android'
--- a/toolkit/crashreporter/test/unit/xpcshell.ini +++ b/toolkit/crashreporter/test/unit/xpcshell.ini @@ -44,58 +44,65 @@ skip-if = os != 'win' || bits != 64 [test_crash_win64cfi_push_nonvol.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 [test_crash_win64cfi_alloc_small.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 +fail-if = os == 'win' && ccov [test_crash_win64cfi_alloc_large.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 [test_crash_win64cfi_save_nonvol.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 [test_crash_win64cfi_save_nonvol_far.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 +fail-if = os == 'win' && ccov [test_crash_win64cfi_save_xmm128.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 [test_crash_win64cfi_save_xmm128_far.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 +fail-if = os == 'win' && ccov [test_crash_win64cfi_epilog.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 [test_crash_win64cfi_infinite_entry_chain.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 +fail-if = os == 'win' && ccov support-files = test_crash_win64cfi_infinite_entry_chain.exe [test_crash_win64cfi_infinite_code_chain.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 +fail-if = os == 'win' && ccov support-files = test_crash_win64cfi_infinite_code_chain.exe [test_crash_win64cfi_invalid_exception_rva.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 +fail-if = os == 'win' && ccov support-files = test_crash_win64cfi_invalid_exception_rva.exe [test_crash_win64cfi_not_a_pe.js] head = head_crashreporter.js head_win64cfi.js skip-if = os != 'win' || bits != 64 +fail-if = os == 'win' && ccov support-files = test_crash_win64cfi_not_a_pe.exe
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini +++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini @@ -25,16 +25,17 @@ skip-if = appname != "firefox" tags = blocklist [test_provider_markSafe.js] [test_provider_shutdown.js] [test_provider_unsafe_access_shutdown.js] [test_provider_unsafe_access_startup.js] [test_ProductAddonChecker.js] [test_shutdown.js] [test_system_update_blank.js] +fail-if = os == 'win' && ccov [test_system_update_checkSizeHash.js] [test_system_update_custom.js] [test_system_update_empty.js] skip-if = true # Failing intermittently due to a race condition in the test, see bug 1348981 [test_system_update_fail.js] [test_system_update_newset.js] [test_system_update_overlapping.js] [test_system_update_upgrades.js]
--- a/toolkit/mozapps/update/tests/unit_service_updater/xpcshell.ini +++ b/toolkit/mozapps/update/tests/unit_service_updater/xpcshell.ini @@ -2,16 +2,17 @@ # 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/. # Tests that require the updater binary and the maintenance service. [DEFAULT] tags = appupdate head = head_update.js +fail-if = os == 'win' && ccov [bootstrapSvc.js] run-sequentially = Uses the Mozilla Maintenance Service. [invalidArgInstallDirPathTooLongFailureSvc.js] run-sequentially = Uses the Mozilla Maintenance Service. [invalidArgInstallDirPathTraversalFailureSvc.js] run-sequentially = Uses the Mozilla Maintenance Service. [invalidArgInstallWorkingDirPathNotSameFailureSvc_win.js]