From e7767cdaa56ee060b14702ed64ae594958fcb1dd Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Thu, 25 May 2017 17:02:40 -0700 Subject: [PATCH] #375: M1363423 M1273828 M1364661 --- browser/base/content/tabbrowser.xml | 6 +-- js/src/jsapi.cpp | 58 ++++++++++++++++++++++++++--- layout/base/FrameLayerBuilder.cpp | 4 ++ 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index c9d0a83d0..d36f51e85 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -2281,7 +2281,7 @@ // update the UI early for responsiveness aTab.collapsed = true; - this.tabContainer._fillTrailingGap(); + //this.tabContainer._fillTrailingGap(); this._blurTab(aTab); this._removingTabs.splice(this._removingTabs.indexOf(aTab), 1); @@ -5077,7 +5077,7 @@ var width = this.mTabstrip.boxObject.width; if (width != this.mTabstripWidth) { this.adjustTabstrip(); - this._fillTrailingGap(); + //this._fillTrailingGap(); this._handleTabSelect(); this.mTabstripWidth = width; } @@ -5237,7 +5237,7 @@ this.adjustTabstrip(); if (tab.getAttribute("selected") == "true") { - this._fillTrailingGap(); + //this._fillTrailingGap(); this._handleTabSelect(); } else { this._notifyBackgroundTab(tab); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index adbee56ef..df0a2c7cd 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -6064,19 +6064,67 @@ DescribeScriptedCaller(JSContext* cx, AutoFilename* filename, unsigned* lineno, return true; } +// Fast path to get the activation to use for GetScriptedCallerGlobal. If this +// returns false, the fast path didn't work out and the caller has to use the +// (much slower) NonBuiltinFrameIter path. +// +// The optimization here is that we skip Ion-inlined frames and only look at +// 'outer' frames. That's fine: each activation is tied to a single compartment, +// so if an activation contains at least one non-self-hosted frame, we can use +// the activation's global for GetScriptedCallerGlobal. If, however, all 'outer' +// frames are self-hosted, it's possible Ion inlined a non-self-hosted script, +// so we must return false and use the slower path. +static bool +GetScriptedCallerActivationFast(JSContext* cx, Activation** activation) +{ + ActivationIterator activationIter(cx->runtime()); + + while (!activationIter.done() && activationIter->cx() != cx) + ++activationIter; + + if (activationIter.done()) { + *activation = nullptr; + return true; + } + + *activation = activationIter.activation(); + + if (activationIter->isJit()) { + for (jit::JitFrameIterator iter(activationIter); !iter.done(); ++iter) { + if (iter.isScripted() && !iter.script()->selfHosted()) + return true; + } + } else if (activationIter->isInterpreter()) { + for (InterpreterFrameIterator iter((*activation)->asInterpreter()); !iter.done(); ++iter) { + if (!iter.frame()->script()->selfHosted()) + return true; + } + } + + return false; +} + JS_PUBLIC_API(JSObject*) GetScriptedCallerGlobal(JSContext* cx) { - NonBuiltinFrameIter i(cx); - if (i.done()) - return nullptr; + Activation* activation; + + if (GetScriptedCallerActivationFast(cx, &activation)) { + if (!activation) + return nullptr; + } else { + NonBuiltinFrameIter i(cx); + if (i.done()) + return nullptr; + activation = i.activation(); + } // If the caller is hidden, the embedding wants us to return null here so // that it can check its own stack (see HideScriptedCaller). - if (i.activation()->scriptedCallerIsHidden()) + if (activation->scriptedCallerIsHidden()) return nullptr; - GlobalObject* global = i.activation()->compartment()->maybeGlobal(); + GlobalObject* global = activation->compartment()->maybeGlobal(); // Noone should be running code in the atoms compartment or running code in // a compartment without any live objects, so there should definitely be a diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 1404683ef..864f83682 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -3575,6 +3575,10 @@ PaintedLayerData::AccumulateEventRegions(ContainerState* aState, nsDisplayLayerE tmp.Or(mVerticalPanRegion, aEventRegions->VerticalPanRegion()); mVerticalPanRegion = tmp; #endif + // Avoid quadratic performance as a result of the region growing to include + // and arbitrarily large number of rects, which can happen on some pages. + mMaybeHitRegion.SimplifyOutward(8); + // Calculate scaled versions of the bounds of mHitRegion and mMaybeHitRegion // for quick access in FindPaintedLayerFor(). mScaledHitRegionBounds = aState->ScaleToOutsidePixels(mHitRegion.GetBounds());