From 83ed1d9024982a725276f18152c99a3b484015c1 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Thu, 17 Sep 2015 12:51:00 -0700 Subject: [PATCH 01/59] Bug 1204169 - Push SPS pseudo frame entries when GCing; r=terrence --- js/src/gc/GCInternals.h | 1 + js/src/jsgc.cpp | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/js/src/gc/GCInternals.h b/js/src/gc/GCInternals.h index 79cab1b3f35d..03124f86fdff 100644 --- a/js/src/gc/GCInternals.h +++ b/js/src/gc/GCInternals.h @@ -56,6 +56,7 @@ class MOZ_RAII AutoTraceSession void operator=(const AutoTraceSession&) = delete; JS::HeapState prevState; + AutoSPSEntry pseudoFrame; }; struct MOZ_RAII AutoPrepareForTracing diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 1f6e3d9fc3b3..722ead72d9d8 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -5580,11 +5580,28 @@ GCRuntime::finishCollection(JS::gcreason::Reason reason) } } +static const char* +HeapStateToLabel(JS::HeapState heapState) +{ + switch (heapState) { + case JS::HeapState::MinorCollecting: + return "js::Nursery::collect"; + case JS::HeapState::MajorCollecting: + return "js::GCRuntime::collect"; + case JS::HeapState::Tracing: + return "JS_IterateCompartments"; + case JS::HeapState::Idle: + MOZ_CRASH("Should never have an Idle heap state when pushing GC pseudo frames!"); + } + MOZ_ASSERT_UNREACHABLE("Should have exhausted every JS::HeapState variant!"); +} + /* Start a new heap session. */ AutoTraceSession::AutoTraceSession(JSRuntime* rt, JS::HeapState heapState) : lock(rt), runtime(rt), - prevState(rt->heapState_) + prevState(rt->heapState_), + pseudoFrame(rt, HeapStateToLabel(heapState), ProfileEntry::Category::GC) { MOZ_ASSERT(rt->heapState_ == JS::HeapState::Idle); MOZ_ASSERT(heapState != JS::HeapState::Idle); From 3e52d7cc21b7ba51b43654f6932063bc3206bcb3 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Thu, 17 Sep 2015 12:51:00 -0700 Subject: [PATCH 02/59] Bug 1074935 - Add SPS pseudo frames for JSRope flattening; r=jandem --- js/src/vm/String.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/js/src/vm/String.cpp b/js/src/vm/String.cpp index 064834ff27c5..52c7edcbb5b6 100644 --- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -14,6 +14,7 @@ #include "gc/Marking.h" #include "js/UbiNode.h" +#include "vm/SPSProfiler.h" #include "jscntxtinlines.h" #include "jscompartmentinlines.h" @@ -554,6 +555,10 @@ JSRope::flattenInternal(ExclusiveContext* maybecx) JSFlatString* JSRope::flatten(ExclusiveContext* maybecx) { + mozilla::Maybe sps; + if (maybecx && maybecx->isJSContext()) + sps.emplace(maybecx->asJSContext()->runtime(), "JSRope::flatten"); + if (zone()->needsIncrementalBarrier()) return flattenInternal(maybecx); return flattenInternal(maybecx); From 2606bb64e2ee0dee24ddb7d87b6fea1b20c57c5f Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 16 Sep 2015 16:12:43 -0400 Subject: [PATCH 03/59] Bug 1199434 - Fire an event when the print engine encounters an error. r=smaug The print engine used to directly cause a prompt to be displayed in the most recent window in the event of an error. This patch causes the print engine to fire an event instead so that the front-end can choose to display or ignore the error. --HG-- extra : commitid : J2icIUiO8Lv extra : rebase_source : 0288d18cf29b8c167da2be9b907f234cf4c3f2b7 --- layout/base/nsDocumentViewer.cpp | 6 +- layout/printing/nsPrintEngine.cpp | 106 ++++++++---------------------- layout/printing/nsPrintEngine.h | 3 +- 3 files changed, 34 insertions(+), 81 deletions(-) diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 51516bc5aba6..7b2dbfe703bd 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -3691,7 +3691,11 @@ nsDocumentViewer::Print(nsIPrintSettings* aPrintSettings, if (GetIsPrinting()) { // Let the user know we are not ready to print. rv = NS_ERROR_NOT_AVAILABLE; - nsPrintEngine::ShowPrintErrorDialog(rv); + + if (mPrintEngine) { + mPrintEngine->FirePrintingErrorEvent(rv); + } + return rv; } diff --git a/layout/printing/nsPrintEngine.cpp b/layout/printing/nsPrintEngine.cpp index d7aa1c4816d4..cb44510c22fb 100644 --- a/layout/printing/nsPrintEngine.cpp +++ b/layout/printing/nsPrintEngine.cpp @@ -11,6 +11,7 @@ #include "mozilla/AsyncEventDispatcher.h" #include "mozilla/dom/Selection.h" +#include "mozilla/dom/CustomEvent.h" #include "nsIScriptGlobalObject.h" #include "nsPIDOMWindow.h" #include "nsIDocShell.h" @@ -121,6 +122,7 @@ static const char kPrintingPromptService[] = "@mozilla.org/embedcomp/printingpro #include "nsContentList.h" #include "nsIChannel.h" #include "xpcpublic.h" +#include "nsVariant.h" using namespace mozilla; using namespace mozilla::dom; @@ -414,8 +416,9 @@ nsPrintEngine::CommonPrint(bool aIsPrintPreview, } if (mProgressDialogIsShown) CloseProgressDialog(aWebProgressListener); - if (rv != NS_ERROR_ABORT && rv != NS_ERROR_OUT_OF_MEMORY) - ShowPrintErrorDialog(rv, !aIsPrintPreview); + if (rv != NS_ERROR_ABORT && rv != NS_ERROR_OUT_OF_MEMORY) { + FirePrintingErrorEvent(rv); + } delete mPrt; mPrt = nullptr; } @@ -783,7 +786,7 @@ nsPrintEngine::PrintPreview(nsIPrintSettings* aPrintSettings, if (NS_FAILED(docShell->GetBusyFlags(&busyFlags)) || busyFlags != nsIDocShell::BUSY_FLAGS_NONE) { CloseProgressDialog(aWebProgressListener); - ShowPrintErrorDialog(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY, false); + FirePrintingErrorEvent(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY); return NS_ERROR_FAILURE; } @@ -1505,7 +1508,7 @@ nsresult nsPrintEngine::CleanupOnFailure(nsresult aResult, bool aIsPrinting) * print job without displaying any error messages */ if (aResult != NS_ERROR_ABORT) { - ShowPrintErrorDialog(aResult, aIsPrinting); + FirePrintingErrorEvent(aResult); } FirePrintCompletionEvent(); @@ -1516,81 +1519,28 @@ nsresult nsPrintEngine::CleanupOnFailure(nsresult aResult, bool aIsPrinting) //--------------------------------------------------------------------- void -nsPrintEngine::ShowPrintErrorDialog(nsresult aPrintError, bool aIsPrinting) +nsPrintEngine::FirePrintingErrorEvent(nsresult aPrintError) { - nsAutoCString stringName; - nsXPIDLString msg, title; - nsresult rv = NS_OK; + nsCOMPtr cv = do_QueryInterface(mDocViewerPrint); + nsCOMPtr doc = cv->GetDocument(); + nsCOMPtr event = + NS_NewDOMCustomEvent(doc, nullptr, nullptr); - switch(aPrintError) - { -#define ENTITY_FOR_ERROR(label) \ - case NS_ERROR_##label: stringName.AssignLiteral("PERR_" #label); break + MOZ_ASSERT(event); + nsCOMPtr resultVariant = new nsVariant(); + // nsresults are Uint32_t's, but XPConnect will interpret it as a double + // when any JS attempts to access it, and will therefore interpret it + // incorrectly. We preempt this by casting and setting as a double. + resultVariant->SetAsDouble(static_cast(aPrintError)); - ENTITY_FOR_ERROR(GFX_PRINTER_NO_PRINTER_AVAILABLE); - ENTITY_FOR_ERROR(GFX_PRINTER_NAME_NOT_FOUND); - ENTITY_FOR_ERROR(GFX_PRINTER_COULD_NOT_OPEN_FILE); - ENTITY_FOR_ERROR(GFX_PRINTER_STARTDOC); - ENTITY_FOR_ERROR(GFX_PRINTER_ENDDOC); - ENTITY_FOR_ERROR(GFX_PRINTER_STARTPAGE); - ENTITY_FOR_ERROR(GFX_PRINTER_DOC_IS_BUSY); + event->InitCustomEvent(NS_LITERAL_STRING("PrintingError"), false, false, + resultVariant); + event->SetTrusted(true); - ENTITY_FOR_ERROR(ABORT); - ENTITY_FOR_ERROR(NOT_AVAILABLE); - ENTITY_FOR_ERROR(NOT_IMPLEMENTED); - ENTITY_FOR_ERROR(OUT_OF_MEMORY); - ENTITY_FOR_ERROR(UNEXPECTED); - - default: - ENTITY_FOR_ERROR(FAILURE); - -#undef ENTITY_FOR_ERROR - } - - if (!aIsPrinting) { - // Try first with _PP suffix. - stringName.AppendLiteral("_PP"); - rv = nsContentUtils::GetLocalizedString( - nsContentUtils::ePRINTING_PROPERTIES, stringName.get(), msg); - if (NS_FAILED(rv)) { - stringName.Truncate(stringName.Length() - 3); - } - } - if (aIsPrinting || NS_FAILED(rv)) { - rv = nsContentUtils::GetLocalizedString( - nsContentUtils::ePRINTING_PROPERTIES, stringName.get(), msg); - } - if (NS_FAILED(rv)) { - return; - } - - rv = nsContentUtils::GetLocalizedString( - nsContentUtils::ePRINTING_PROPERTIES, - aIsPrinting ? "print_error_dialog_title" - : "printpreview_error_dialog_title", - title); - if (NS_FAILED(rv)) { - return; - } - - nsCOMPtr wwatch = - do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); - if (NS_FAILED(rv)) { - return; - } - - nsCOMPtr active; - wwatch->GetActiveWindow(getter_AddRefs(active)); - - nsCOMPtr dialog; - /* |GetNewPrompter| allows that |active| is |nullptr| - * (see bug 234982 ("nsPrintEngine::ShowPrintErrorDialog() fails in many cases")) */ - wwatch->GetNewPrompter(active, getter_AddRefs(dialog)); - if (!dialog) { - return; - } - - dialog->Alert(title.get(), msg.get()); + nsRefPtr asyncDispatcher = + new AsyncEventDispatcher(doc, event); + asyncDispatcher->mOnlyChromeDispatch = true; + asyncDispatcher->RunDOMEventWhenSafe(); } //----------------------------------------------------------------- @@ -2696,7 +2646,7 @@ nsPrintEngine::PrePrintPage() // Shouldn't |mPrt->mIsAborted| set to true all the time if something // wents wrong? if (rv != NS_ERROR_ABORT) { - ShowPrintErrorDialog(rv); + FirePrintingErrorEvent(rv); mPrt->mIsAborted = true; } done = true; @@ -2715,7 +2665,7 @@ nsPrintEngine::PrintPage(nsPrintObject* aPO, // Although these should NEVER be nullptr // This is added insurance, to make sure we don't crash in optimized builds if (!mPrt || !aPO || !mPageSeqFrame) { - ShowPrintErrorDialog(NS_ERROR_FAILURE); + FirePrintingErrorEvent(NS_ERROR_FAILURE); return true; // means we are done printing } @@ -2777,7 +2727,7 @@ nsPrintEngine::PrintPage(nsPrintObject* aPO, nsresult rv = mPageSeqFrame->PrintNextPage(); if (NS_FAILED(rv)) { if (rv != NS_ERROR_ABORT) { - ShowPrintErrorDialog(rv); + FirePrintingErrorEvent(rv); mPrt->mIsAborted = true; } return true; diff --git a/layout/printing/nsPrintEngine.h b/layout/printing/nsPrintEngine.h index e893a8c90af8..8184337c18b4 100644 --- a/layout/printing/nsPrintEngine.h +++ b/layout/printing/nsPrintEngine.h @@ -137,6 +137,7 @@ public: bool IsThereARangeSelection(nsIDOMWindow * aDOMWin); + void FirePrintingErrorEvent(nsresult aPrintError); //--------------------------------------------------------------------- @@ -165,8 +166,6 @@ public: nsAString& aTitle, nsAString& aURLStr, eDocTitleDefault aDefType); - static void ShowPrintErrorDialog(nsresult printerror, - bool aIsPrinting = true); static bool HasFramesetChild(nsIContent* aContent); From acf57ca511cd1a490a03df5772ae0ca79da03834 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 16 Sep 2015 16:12:54 -0400 Subject: [PATCH 04/59] Bug 1199434 - Send printer error messages to the parent process to report to the user. r=Mossop The printing back-end used to be in charge of opening up an error dialog when things go wrong with printing. Now we fire an event and let PrintUtils do the work of showing the error message. This has the added bonus of making the error messages work with e10s. --HG-- extra : commitid : LPWfOvQ1TaI extra : rebase_source : fa6f71e6c9cf9062feb2bd1d0f362680899385fc --- .../components/printing/content/printUtils.js | 83 +++++++++++++++++++ toolkit/content/browser-content.js | 18 ++++ 2 files changed, 101 insertions(+) diff --git a/toolkit/components/printing/content/printUtils.js b/toolkit/components/printing/content/printUtils.js index b9bd7a4dd792..c3476cf136c1 100644 --- a/toolkit/components/printing/content/printUtils.js +++ b/toolkit/components/printing/content/printUtils.js @@ -65,6 +65,17 @@ var gSavePrintSettings = false; var gFocusedElement = null; var PrintUtils = { + init() { + window.messageManager.addMessageListener("Printing:Error", this); + }, + + get bundle() { + let stringService = Components.classes["@mozilla.org/intl/stringbundle;1"] + .getService(Components.interfaces.nsIStringBundleService); + delete this.bundle; + return this.bundle = stringService.createBundle("chrome://global/locale/printing.properties"); + }, + /** * Shows the page setup dialog, and saves any settings changed in * that dialog if print.save_print_settings is set to true. @@ -300,7 +311,77 @@ var PrintUtils = { return this.usingRemoteTabs = usingRemoteTabs; }, + displayPrintingError(nsresult, isPrinting) { + // The nsresults from a printing error are mapped to strings that have + // similar names to the errors themselves. For example, for error + // NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE, the name of the string + // for the error message is: PERR_GFX_PRINTER_NO_PRINTER_AVAILABLE. What's + // more, if we're in the process of doing a print preview, it's possible + // that there are strings specific for print preview for these errors - + // if so, the names of those strings have _PP as a suffix. It's possible + // that no print preview specific strings exist, in which case it is fine + // to fall back to the original string name. + const MSG_CODES = [ + "GFX_PRINTER_NO_PRINTER_AVAILABLE", + "GFX_PRINTER_NAME_NOT_FOUND", + "GFX_PRINTER_COULD_NOT_OPEN_FILE", + "GFX_PRINTER_STARTDOC", + "GFX_PRINTER_ENDDOC", + "GFX_PRINTER_STARTPAGE", + "GFX_PRINTER_DOC_IS_BUSY", + "ABORT", + "NOT_AVAILABLE", + "NOT_IMPLEMENTED", + "OUT_OF_MEMORY", + "UNEXPECTED", + ]; + + // PERR_FAILURE is the catch-all error message if we've gotten one that + // we don't recognize. + msgName = "PERR_FAILURE"; + + for (let code of MSG_CODES) { + let nsErrorResult = "NS_ERROR_" + code; + if (Components.results[nsErrorResult] == nsresult) { + msgName = "PERR_" + code; + break; + } + } + + let msg, title; + + if (!isPrinting) { + // Try first with _PP suffix. + let ppMsgName = msgName + "_PP"; + try { + msg = this.bundle.GetStringFromName(ppMsgName); + } catch(e) { + // We allow localizers to not have the print preview error string, + // and just fall back to the printing error string. + } + } + + if (!msg) { + msg = this.bundle.GetStringFromName(msgName); + } + + title = this.bundle.GetStringFromName(isPrinting ? "print_error_dialog_title" + : "printpreview_error_dialog_title"); + + let promptSvc = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] + .getService(Components.interfaces.nsIPromptService); + promptSvc.alert(window, title, msg); + }, + receiveMessage(aMessage) { + if (aMessage.name == "Printing:Error") { + this.displayPrintingError(aMessage.data.nsresult, + aMessage.data.isPrinting); + return; + } + + // If we got here, then the message we've received must involve + // updating the print progress UI. if (!this._webProgressPP.value) { // We somehow didn't get a nsIWebProgressListener to be updated... // I guess there's nothing to do. @@ -537,3 +618,5 @@ var PrintUtils = { } } } + +PrintUtils.init(); diff --git a/toolkit/content/browser-content.js b/toolkit/content/browser-content.js index 6f3602571de2..f797933a31ad 100644 --- a/toolkit/content/browser-content.js +++ b/toolkit/content/browser-content.js @@ -377,6 +377,7 @@ var Printing = { init() { this.MESSAGES.forEach(msgName => addMessageListener(msgName, this)); + addEventListener("PrintingError", this, true); }, get shouldSavePrintSettings() { @@ -384,6 +385,19 @@ var Printing = { Services.prefs.getBoolPref("print.save_print_settings", false); }, + handleEvent(event) { + if (event.type == "PrintingError") { + let win = event.target.defaultView; + let wbp = win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebBrowserPrint); + let nsresult = event.detail; + sendAsyncMessage("Printing:Error", { + isPrinting: wbp.doingPrint, + nsresult: nsresult, + }); + } + }, + receiveMessage(message) { let objects = message.objects; let data = message.data; @@ -489,6 +503,10 @@ var Printing = { if (e.result != Cr.NS_ERROR_ABORT) { Cu.reportError(`In Printing:Print:Done handler, got unexpected rv ${e.result}.`); + sendAsyncMessage("Printing:Error", { + isPrinting: true, + nsresult: e.result, + }); } } From 0027642c1e9d0cc650fa7bd6e70e88a7a6faa92d Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Thu, 17 Sep 2015 15:26:59 -0400 Subject: [PATCH 05/59] Bug 1205810 - telemetry for local h2 goaway code r=hurley --- netwerk/protocol/http/Http2Session.cpp | 3 +++ netwerk/protocol/http/Http2Session.h | 5 +++-- toolkit/components/telemetry/Histograms.json | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp index acab064df41f..67bc1c43a460 100644 --- a/netwerk/protocol/http/Http2Session.cpp +++ b/netwerk/protocol/http/Http2Session.cpp @@ -95,6 +95,7 @@ Http2Session::Http2Session(nsISocketTransport *aSocketTransport, uint32_t versio , mCleanShutdown(false) , mTLSProfileConfirmed(false) , mGoAwayReason(NO_HTTP_ERROR) + , mClientGoAwayReason(UNASSIGNED) , mPeerGoAwayReason(UNASSIGNED) , mGoAwayID(0) , mOutgoingGoAwayID(0) @@ -195,6 +196,7 @@ Http2Session::~Http2Session() Telemetry::Accumulate(Telemetry::SPDY_REQUEST_PER_CONN, (mNextStreamID - 1) / 2); Telemetry::Accumulate(Telemetry::SPDY_SERVER_INITIATED_STREAMS, mServerPushedResources); + Telemetry::Accumulate(Telemetry::SPDY_GOAWAY_LOCAL, mClientGoAwayReason); Telemetry::Accumulate(Telemetry::SPDY_GOAWAY_PEER, mPeerGoAwayReason); } @@ -806,6 +808,7 @@ Http2Session::GenerateGoAway(uint32_t aStatusCode) MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); LOG3(("Http2Session::GenerateGoAway %p code=%X\n", this, aStatusCode)); + mClientGoAwayReason = aStatusCode; uint32_t frameSize = kFrameHeaderBytes + 8; char *packet = EnsureOutputBuffer(frameSize); mOutputQueueUsed += frameSize; diff --git a/netwerk/protocol/http/Http2Session.h b/netwerk/protocol/http/Http2Session.h index 0c94ad25ed6b..e463379e9701 100644 --- a/netwerk/protocol/http/Http2Session.h +++ b/netwerk/protocol/http/Http2Session.h @@ -424,8 +424,9 @@ private: // only NO_HTTP_ERROR, PROTOCOL_ERROR, or INTERNAL_ERROR will be sent. errorType mGoAwayReason; - // The error code received from the peer in a goaway frame. UNASSIGNED/31 - // if not received. + // The error code sent/received on the session goaway frame. UNASSIGNED/31 + // if not transmitted. + int32_t mClientGoAwayReason; int32_t mPeerGoAwayReason; // If a GoAway message was received this is the ID of the last valid diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 6aae6ee0e3ca..8fe78bd7967a 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -1524,6 +1524,12 @@ "extended_statistics_ok": true, "description": "H2: Settings Initial Window (rounded to KB)" }, + "SPDY_GOAWAY_LOCAL": { + "expires_in_version": "never", + "kind": "enumerated", + "n_values": 32, + "description": "H2: goaway reason client sent from rfc 7540. 31 is none sent." + }, "SPDY_GOAWAY_PEER": { "expires_in_version": "never", "kind": "enumerated", From 1b482dcc58f8e79422573eca375f22924fa6be05 Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Wed, 26 Aug 2015 17:54:53 -0400 Subject: [PATCH 06/59] bug 1199735 - remove event logging from the windows AccessibleWrap::HandleAccEvent r=davidb if this is useful it would make more sense to log it outside of the windows layer. Since its not clear it is useful, and it makes it harder to separate event dispatch logic from HandleAccEvent its easiest to just remove it for now. --- accessible/windows/msaa/AccessibleWrap.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/accessible/windows/msaa/AccessibleWrap.cpp b/accessible/windows/msaa/AccessibleWrap.cpp index c4e613fe2af3..0b06677ec3ad 100644 --- a/accessible/windows/msaa/AccessibleWrap.cpp +++ b/accessible/windows/msaa/AccessibleWrap.cpp @@ -1242,24 +1242,6 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent) HWND hWnd = GetHWNDFor(accessible); NS_ENSURE_TRUE(hWnd, NS_ERROR_FAILURE); - nsAutoString tag; - nsAutoCString id; - nsIContent* cnt = accessible->GetContent(); - if (cnt) { - cnt->NodeInfo()->NameAtom()->ToString(tag); - nsIAtom* aid = cnt->GetID(); - if (aid) - aid->ToUTF8String(id); - } - -#ifdef A11Y_LOG - if (logging::IsEnabled(logging::ePlatforms)) { - printf("\n\nMSAA event: event: %d, target: %s@id='%s', childid: %d, hwnd: %p\n\n", - eventType, NS_ConvertUTF16toUTF8(tag).get(), id.get(), - childID, hWnd); - } -#endif - // Fire MSAA event for client area window. ::NotifyWinEvent(winEvent, hWnd, OBJID_CLIENT, childID); From 24ad5cfa23f75ddfc3416ddc0d442165d866a419 Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Wed, 26 Aug 2015 18:40:24 -0400 Subject: [PATCH 07/59] bug 1199735 - factor win event dispatch logic into its own function r=davidb --- accessible/windows/msaa/AccessibleWrap.cpp | 62 +++++++++++++--------- accessible/windows/msaa/AccessibleWrap.h | 2 + 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/accessible/windows/msaa/AccessibleWrap.cpp b/accessible/windows/msaa/AccessibleWrap.cpp index 0b06677ec3ad..30d8994cfe5b 100644 --- a/accessible/windows/msaa/AccessibleWrap.cpp +++ b/accessible/windows/msaa/AccessibleWrap.cpp @@ -1199,6 +1199,41 @@ AccessibleWrap::GetNativeInterface(void** aOutAccessible) NS_ADDREF_THIS(); } +void +AccessibleWrap::FireWinEvent(Accessible* aTarget, uint32_t aEventType) +{ + static_assert(sizeof(gWinEventMap)/sizeof(gWinEventMap[0]) == nsIAccessibleEvent::EVENT_LAST_ENTRY, + "MSAA event map skewed"); + + NS_ASSERTION(aEventType > 0 && aEventType < ArrayLength(gWinEventMap), "invalid event type"); + + uint32_t winEvent = gWinEventMap[aEventType]; + if (!winEvent) + return; + + int32_t childID = GetChildIDFor(aTarget); + if (!childID) + return; // Can't fire an event without a child ID + + HWND hwnd = GetHWNDFor(aTarget); + if (!hwnd) { + return; + } + + // Fire MSAA event for client area window. + ::NotifyWinEvent(winEvent, hwnd, OBJID_CLIENT, childID); + + // JAWS announces collapsed combobox navigation based on focus events. + if (aEventType == nsIAccessibleEvent::EVENT_SELECTION && + Compatibility::IsJAWS()) { + roles::Role role = aTarget->IsProxy() ? aTarget->Proxy()->Role() : + aTarget->Role(); + if (role == roles::COMBOBOX_OPTION) { + ::NotifyWinEvent(EVENT_OBJECT_FOCUS, hwnd, OBJID_CLIENT, childID); + } + } +} + //////////////////////////////////////////////////////////////////////////////// // Accessible @@ -1214,15 +1249,6 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent) uint32_t eventType = aEvent->GetEventType(); - static_assert(sizeof(gWinEventMap)/sizeof(gWinEventMap[0]) == nsIAccessibleEvent::EVENT_LAST_ENTRY, - "MSAA event map skewed"); - - NS_ENSURE_TRUE(eventType > 0 && eventType < ArrayLength(gWinEventMap), NS_ERROR_FAILURE); - - uint32_t winEvent = gWinEventMap[eventType]; - if (!winEvent) - return NS_OK; - // Means we're not active. NS_ENSURE_TRUE(!IsDefunct(), NS_ERROR_FAILURE); @@ -1235,23 +1261,7 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent) UpdateSystemCaretFor(accessible); } - int32_t childID = GetChildIDFor(accessible); // get the id for the accessible - if (!childID) - return NS_OK; // Can't fire an event without a child ID - - HWND hWnd = GetHWNDFor(accessible); - NS_ENSURE_TRUE(hWnd, NS_ERROR_FAILURE); - - // Fire MSAA event for client area window. - ::NotifyWinEvent(winEvent, hWnd, OBJID_CLIENT, childID); - - // JAWS announces collapsed combobox navigation based on focus events. - if (Compatibility::IsJAWS()) { - if (eventType == nsIAccessibleEvent::EVENT_SELECTION && - accessible->Role() == roles::COMBOBOX_OPTION) { - ::NotifyWinEvent(EVENT_OBJECT_FOCUS, hWnd, OBJID_CLIENT, childID); - } - } + FireWinEvent(accessible, eventType); return NS_OK; } diff --git a/accessible/windows/msaa/AccessibleWrap.h b/accessible/windows/msaa/AccessibleWrap.h index 771dad5a02cd..fc0b8bedab32 100644 --- a/accessible/windows/msaa/AccessibleWrap.h +++ b/accessible/windows/msaa/AccessibleWrap.h @@ -159,6 +159,8 @@ public: // construction, destruction static int32_t GetChildIDFor(Accessible* aAccessible); static HWND GetHWNDFor(Accessible* aAccessible); + static void FireWinEvent(Accessible* aTarget, uint32_t aEventType); + /** * System caret support: update the Windows caret position. * The system caret works more universally than the MSAA caret From 75ffe89c69f5dc1292393c8e0868cc13fd76802f Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Thu, 27 Aug 2015 14:03:53 -0400 Subject: [PATCH 08/59] bug 1199735 - fire windows events on proxies r=davidb --- accessible/windows/msaa/Platform.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/accessible/windows/msaa/Platform.cpp b/accessible/windows/msaa/Platform.cpp index 791205ccd855..74cc6d131acc 100644 --- a/accessible/windows/msaa/Platform.cpp +++ b/accessible/windows/msaa/Platform.cpp @@ -76,18 +76,23 @@ a11y::ProxyDestroyed(ProxyAccessible* aProxy) } void -a11y::ProxyEvent(ProxyAccessible*, uint32_t) +a11y::ProxyEvent(ProxyAccessible* aTarget, uint32_t aEventType) { + AccessibleWrap::FireWinEvent(WrapperFor(aTarget), aEventType); } void -a11y::ProxyStateChangeEvent(ProxyAccessible*, uint64_t, bool) +a11y::ProxyStateChangeEvent(ProxyAccessible* aTarget, uint64_t, bool) { + AccessibleWrap::FireWinEvent(WrapperFor(aTarget), + nsIAccessibleEvent::EVENT_STATE_CHANGE); } void a11y::ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset) { + AccessibleWrap::FireWinEvent(WrapperFor(aTarget), + nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED); } void @@ -104,4 +109,8 @@ a11y::ProxyTextChangeEvent(ProxyAccessible* aText, const nsString& aStr, if (text) { ia2AccessibleText::UpdateTextChangeData(text, aInsert, aStr, aStart, aLen); } + + uint32_t eventType = aInsert ? nsIAccessibleEvent::EVENT_TEXT_INSERTED : + nsIAccessibleEvent::EVENT_TEXT_REMOVED; + AccessibleWrap::FireWinEvent(wrapper, eventType); } From 5f70fae987695f4dcd2c1ef79f6afeb066a36e70 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Thu, 17 Sep 2015 13:58:15 -0700 Subject: [PATCH 09/59] Backed out 2 changesets (bug 1204169, bug 1074935) for Werror bustage CLOSED TREE Backed out changeset b4621131ea01 (bug 1074935) Backed out changeset 14dbd30e63af (bug 1204169) --- js/src/gc/GCInternals.h | 1 - js/src/jsgc.cpp | 19 +------------------ js/src/vm/String.cpp | 5 ----- 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/js/src/gc/GCInternals.h b/js/src/gc/GCInternals.h index 03124f86fdff..79cab1b3f35d 100644 --- a/js/src/gc/GCInternals.h +++ b/js/src/gc/GCInternals.h @@ -56,7 +56,6 @@ class MOZ_RAII AutoTraceSession void operator=(const AutoTraceSession&) = delete; JS::HeapState prevState; - AutoSPSEntry pseudoFrame; }; struct MOZ_RAII AutoPrepareForTracing diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 722ead72d9d8..1f6e3d9fc3b3 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -5580,28 +5580,11 @@ GCRuntime::finishCollection(JS::gcreason::Reason reason) } } -static const char* -HeapStateToLabel(JS::HeapState heapState) -{ - switch (heapState) { - case JS::HeapState::MinorCollecting: - return "js::Nursery::collect"; - case JS::HeapState::MajorCollecting: - return "js::GCRuntime::collect"; - case JS::HeapState::Tracing: - return "JS_IterateCompartments"; - case JS::HeapState::Idle: - MOZ_CRASH("Should never have an Idle heap state when pushing GC pseudo frames!"); - } - MOZ_ASSERT_UNREACHABLE("Should have exhausted every JS::HeapState variant!"); -} - /* Start a new heap session. */ AutoTraceSession::AutoTraceSession(JSRuntime* rt, JS::HeapState heapState) : lock(rt), runtime(rt), - prevState(rt->heapState_), - pseudoFrame(rt, HeapStateToLabel(heapState), ProfileEntry::Category::GC) + prevState(rt->heapState_) { MOZ_ASSERT(rt->heapState_ == JS::HeapState::Idle); MOZ_ASSERT(heapState != JS::HeapState::Idle); diff --git a/js/src/vm/String.cpp b/js/src/vm/String.cpp index 52c7edcbb5b6..064834ff27c5 100644 --- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -14,7 +14,6 @@ #include "gc/Marking.h" #include "js/UbiNode.h" -#include "vm/SPSProfiler.h" #include "jscntxtinlines.h" #include "jscompartmentinlines.h" @@ -555,10 +554,6 @@ JSRope::flattenInternal(ExclusiveContext* maybecx) JSFlatString* JSRope::flatten(ExclusiveContext* maybecx) { - mozilla::Maybe sps; - if (maybecx && maybecx->isJSContext()) - sps.emplace(maybecx->asJSContext()->runtime(), "JSRope::flatten"); - if (zone()->needsIncrementalBarrier()) return flattenInternal(maybecx); return flattenInternal(maybecx); From cf7ee31873f50d801842aecd6f2e58b756b996b4 Mon Sep 17 00:00:00 2001 From: David Burns Date: Thu, 17 Sep 2015 22:22:38 +0100 Subject: [PATCH 10/59] Bug 1204496: When searching by link text start from the startNode and not the rootNode; r=ato --HG-- extra : commitid : B41EB2spDLA extra : rebase_source : 19077dc84eefe0b11d862c04dc1f8bbc595cca82 --- .../client/marionette/tests/unit/test_findelement.py | 8 ++++++++ .../marionette/client/marionette/www/nestedElements.html | 9 +++++++++ testing/marionette/elements.js | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 testing/marionette/client/marionette/www/nestedElements.html diff --git a/testing/marionette/client/marionette/tests/unit/test_findelement.py b/testing/marionette/client/marionette/tests/unit/test_findelement.py index 5d4ed9848ac5..3f2dff3eafa7 100644 --- a/testing/marionette/client/marionette/tests/unit/test_findelement.py +++ b/testing/marionette/client/marionette/tests/unit/test_findelement.py @@ -169,3 +169,11 @@ class TestElements(MarionetteTestCase): self.assertIsNotNone(re.search(uuid_regex, el.id), 'UUID for the WebElement is not valid. ID is {}'\ .format(el.id)) + def test_should_find_elements_by_link_text(self): + test_html = self.marionette.absolute_url("nestedElements.html") + self.marionette.navigate(test_html) + element = self.marionette.find_element(By.NAME, "div1") + children = element.find_elements(By.LINK_TEXT, "hello world") + self.assertEqual(len(children), 2) + self.assertEqual("link1", children[0].get_attribute("name")) + self.assertEqual("link2", children[1].get_attribute("name")) diff --git a/testing/marionette/client/marionette/www/nestedElements.html b/testing/marionette/client/marionette/www/nestedElements.html new file mode 100644 index 000000000000..618bf3231b6f --- /dev/null +++ b/testing/marionette/client/marionette/www/nestedElements.html @@ -0,0 +1,9 @@ + +hello world +hello worldhello world + + +hello worldhello worldhello world diff --git a/testing/marionette/elements.js b/testing/marionette/elements.js index dd67c99a3ea9..c140753af187 100644 --- a/testing/marionette/elements.js +++ b/testing/marionette/elements.js @@ -681,7 +681,7 @@ ElementManager.prototype = { break; case LINK_TEXT: case PARTIAL_LINK_TEXT: - let allLinks = rootNode.getElementsByTagName('A'); + let allLinks = startNode.getElementsByTagName('A'); for (let i = 0; i < allLinks.length; i++) { let text = allLinks[i].text; if (PARTIAL_LINK_TEXT == using) { From 0e20f9477dcaaddbb39d0bc7821c722975bedc0e Mon Sep 17 00:00:00 2001 From: William Chen Date: Thu, 17 Sep 2015 14:49:00 -0700 Subject: [PATCH 11/59] Bug 1176829 - Remove custom elements base element queue. r=smaug --HG-- extra : rebase_source : 27fb6a6d80575235dbd18f849cab5578a1dd6d14 --- dom/base/nsContentUtils.cpp | 1 - dom/base/nsDocument.cpp | 54 ++++--------------------------------- dom/base/nsDocument.h | 8 +----- 3 files changed, 6 insertions(+), 57 deletions(-) diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 47fd964dcdfa..fc0181982813 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -5230,7 +5230,6 @@ nsContentUtils::LeaveMicroTask() MOZ_ASSERT(NS_IsMainThread()); if (--sMicroTaskLevel == 0) { PerformMainThreadMicroTaskCheckpoint(); - nsDocument::ProcessBaseElementQueue(); } } diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index dc162816c049..b18ac8e64a18 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -5895,29 +5895,6 @@ nsDocument::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName) return NS_OK; } -namespace { - -class ProcessStackRunner final : public nsIRunnable -{ - ~ProcessStackRunner() {} -public: - explicit ProcessStackRunner(bool aIsBaseQueue = false) - : mIsBaseQueue(aIsBaseQueue) - { - } - NS_DECL_ISUPPORTS - NS_IMETHOD Run() override - { - nsDocument::ProcessTopElementQueue(mIsBaseQueue); - return NS_OK; - } - bool mIsBaseQueue; -}; - -NS_IMPL_ISUPPORTS(ProcessStackRunner, nsIRunnable); - -} // namespace - void nsDocument::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType, Element* aCustomElement, @@ -6019,10 +5996,7 @@ nsDocument::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType, // A new element queue needs to be pushed if the queue at the // top of the stack is associated with another microtask level. - // Don't push a queue for the level 0 microtask (base element queue) - // because we don't want to process the queue until the - // microtask checkpoint. - bool shouldPushElementQueue = nsContentUtils::MicroTaskLevel() > 0 && + bool shouldPushElementQueue = (!lastData || lastData->mAssociatedMicroTask < static_cast(nsContentUtils::MicroTaskLevel())); @@ -6045,39 +6019,22 @@ nsDocument::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType, // should be invoked prior to returning control back to script. // Create a script runner to process the top of the processing // stack as soon as it is safe to run script. - nsContentUtils::AddScriptRunner(new ProcessStackRunner()); + nsCOMPtr runnable = + NS_NewRunnableFunction(&nsDocument::ProcessTopElementQueue); + nsContentUtils::AddScriptRunner(runnable); } } } // static void -nsDocument::ProcessBaseElementQueue() -{ - // Prevent re-entrance. Also, if a microtask checkpoint is reached - // and there is no processing stack to process, then we are done. - if (sProcessingBaseElementQueue || !sProcessingStack) { - return; - } - - MOZ_ASSERT(nsContentUtils::MicroTaskLevel() == 0); - sProcessingBaseElementQueue = true; - nsContentUtils::AddScriptRunner(new ProcessStackRunner(true)); -} - -// static -void -nsDocument::ProcessTopElementQueue(bool aIsBaseQueue) +nsDocument::ProcessTopElementQueue() { MOZ_ASSERT(nsContentUtils::IsSafeToRunScript()); nsTArray>& stack = *sProcessingStack; uint32_t firstQueue = stack.LastIndexOf((CustomElementData*) nullptr); - if (aIsBaseQueue && firstQueue != 0) { - return; - } - for (uint32_t i = firstQueue + 1; i < stack.Length(); ++i) { // Callback queue may have already been processed in an earlier // element queue or in an element queue that was popped @@ -6095,7 +6052,6 @@ nsDocument::ProcessTopElementQueue(bool aIsBaseQueue) } else { // Don't pop sentinel for base element queue. stack.SetLength(1); - sProcessingBaseElementQueue = false; } } diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 081328434215..5606647ce365 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -1303,7 +1303,7 @@ public: mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr, mozilla::dom::CustomElementDefinition* aDefinition = nullptr) override; - static void ProcessTopElementQueue(bool aIsBaseQueue = false); + static void ProcessTopElementQueue(); void GetCustomPrototype(int32_t aNamespaceID, nsIAtom* aAtom, @@ -1600,15 +1600,9 @@ private: // queue in the stack is the base element queue. static mozilla::Maybe>> sProcessingStack; - // Flag to prevent re-entrance into base element queue as described in the - // custom elements speicification. - static bool sProcessingBaseElementQueue; - static bool CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp); public: - static void ProcessBaseElementQueue(); - // Enqueue created callback or register upgrade candidate for // newly created custom elements, possibly extending an existing type. // ex. ,