diff --git a/browser/components/preferences/in-content-old/advanced.js b/browser/components/preferences/in-content-old/advanced.js index d8ebb341e504..b7413a093f15 100644 --- a/browser/components/preferences/in-content-old/advanced.js +++ b/browser/components/preferences/in-content-old/advanced.js @@ -217,8 +217,17 @@ var gAdvancedPane = { }, /** - * security.OCSP.enabled is an integer value for legacy reasons. - * A value of 1 means OCSP is enabled. Any other value means it is disabled. + * readEnableOCSP is used by the preferences UI to determine whether or not + * the checkbox for OCSP fetching should be checked (it returns true if it + * should be checked and false otherwise). The about:config preference + * "security.OCSP.enabled" is an integer rather than a boolean, so it can't be + * directly mapped from {true,false} to {checked,unchecked}. The possible + * values for "security.OCSP.enabled" are: + * 0: fetching is disabled + * 1: fetch for all certificates + * 2: fetch only for EV certificates + * Hence, if "security.OCSP.enabled" is non-zero, the checkbox should be + * checked. Otherwise, it should be unchecked. */ readEnableOCSP() { var preference = document.getElementById("security.OCSP.enabled"); @@ -226,15 +235,27 @@ var gAdvancedPane = { if (preference.value === undefined) { return true; } - return preference.value == 1; + return preference.value != 0; }, /** - * See documentation for readEnableOCSP. + * writeEnableOCSP is used by the preferences UI to map the checked/unchecked + * state of the OCSP fetching checkbox to the value that the preference + * "security.OCSP.enabled" should be set to (it returns that value). See the + * readEnableOCSP documentation for more background. We unfortunately don't + * have enough information to map from {true,false} to all possible values for + * "security.OCSP.enabled", but a reasonable alternative is to map from + * {true,false} to {,0}. That is, if the box is checked, + * "security.OCSP.enabled" will be set to whatever default it should be, given + * the platform and channel. If the box is unchecked, the preference will be + * set to 0. Obviously this won't work if the default is 0, so we will have to + * revisit this if we ever set it to 0. */ writeEnableOCSP() { var checkbox = document.getElementById("enableOCSP"); - return checkbox.checked ? 1 : 0; + var defaults = Services.prefs.getDefaultBranch(null); + var defaultValue = defaults.getIntPref("security.OCSP.enabled"); + return checkbox.checked ? defaultValue : 0; }, /** diff --git a/browser/components/preferences/in-content/privacy.js b/browser/components/preferences/in-content/privacy.js index 28e4e85db696..67f658dc5aa4 100644 --- a/browser/components/preferences/in-content/privacy.js +++ b/browser/components/preferences/in-content/privacy.js @@ -1131,10 +1131,18 @@ var gPrivacyPane = { permissionType: "install" }, - /** - * security.OCSP.enabled is an integer value for legacy reasons. - * A value of 1 means OCSP is enabled. Any other value means it is disabled. + * readEnableOCSP is used by the preferences UI to determine whether or not + * the checkbox for OCSP fetching should be checked (it returns true if it + * should be checked and false otherwise). The about:config preference + * "security.OCSP.enabled" is an integer rather than a boolean, so it can't be + * directly mapped from {true,false} to {checked,unchecked}. The possible + * values for "security.OCSP.enabled" are: + * 0: fetching is disabled + * 1: fetch for all certificates + * 2: fetch only for EV certificates + * Hence, if "security.OCSP.enabled" is non-zero, the checkbox should be + * checked. Otherwise, it should be unchecked. */ readEnableOCSP() { var preference = document.getElementById("security.OCSP.enabled"); @@ -1142,15 +1150,27 @@ var gPrivacyPane = { if (preference.value === undefined) { return true; } - return preference.value == 1; + return preference.value != 0; }, /** - * See documentation for readEnableOCSP. + * writeEnableOCSP is used by the preferences UI to map the checked/unchecked + * state of the OCSP fetching checkbox to the value that the preference + * "security.OCSP.enabled" should be set to (it returns that value). See the + * readEnableOCSP documentation for more background. We unfortunately don't + * have enough information to map from {true,false} to all possible values for + * "security.OCSP.enabled", but a reasonable alternative is to map from + * {true,false} to {,0}. That is, if the box is checked, + * "security.OCSP.enabled" will be set to whatever default it should be, given + * the platform and channel. If the box is unchecked, the preference will be + * set to 0. Obviously this won't work if the default is 0, so we will have to + * revisit this if we ever set it to 0. */ writeEnableOCSP() { var checkbox = document.getElementById("enableOCSP"); - return checkbox.checked ? 1 : 0; + var defaults = Services.prefs.getDefaultBranch(null); + var defaultValue = defaults.getIntPref("security.OCSP.enabled"); + return checkbox.checked ? defaultValue : 0; }, /** diff --git a/browser/extensions/e10srollout/bootstrap.js b/browser/extensions/e10srollout/bootstrap.js index fd9a0df8a463..b398c0302d6d 100644 --- a/browser/extensions/e10srollout/bootstrap.js +++ b/browser/extensions/e10srollout/bootstrap.js @@ -19,9 +19,12 @@ const TEST_THRESHOLD = { }; // If a user qualifies for the e10s-multi experiement, this is how many -// content processes to use. -const MULTI_BUCKETS = { - "beta": { 1: .5, 4: 1, }, +// content processes to use and whether to allow addons for the experiment. +const MULTI_EXPERIMENT = { + "beta": { buckets: { 1: .5, 4: 1, }, // 1 process: 50%, 4 processes: 50% + addons: true }, + "release": { buckets: { 1: .2, 4: 1 }, // 1 process: 20%, 4 processes: 80% + addons: false }, }; const ADDON_ROLLOUT_POLICY = { @@ -160,14 +163,17 @@ function defineCohort() { } // Now determine if this user should be in the e10s-multi experiment. - // - We only run the experiment on channels defined in MULTI_BUCKETS. + // - We only run the experiment on channels defined in MULTI_EXPERIMENT. + // - If this experiment doesn't allow addons and we have a cohort prefix + // (i.e. there's at least one addon installed) we stop here. // - We decided above whether this user qualifies for the experiment. // - If the user already opted into multi, then their prefs are already set // correctly, we're done. // - If the user has addons that disqualify them for multi, leave them with // the default number of content processes (1 on beta) but still in the // test cohort. - if (!(updateChannel in MULTI_BUCKETS) || + if (!(updateChannel in MULTI_EXPERIMENT) || + (!MULTI_EXPERIMENT[updateChannel].addons && cohortPrefix) || !eligibleForMulti || userOptedIn.multi || disqualified) { @@ -185,7 +191,7 @@ function defineCohort() { // The user is in the multi experiment! // Decide how many content processes to use for this user. - let buckets = MULTI_BUCKETS[updateChannel]; + let buckets = MULTI_EXPERIMENT[updateChannel].buckets; let multiUserSample = getUserSample(true); for (let sampleName of Object.getOwnPropertyNames(buckets)) { diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index 1c29103ee3d7..f2c78284f9b3 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -591,8 +591,8 @@ service.install.ok.label=Enable Services service.install.ok.accesskey=E # These are visible when opening the popup inside the bookmarks sidebar -sidebar.moveToLeft=Move sidebar to left -sidebar.moveToRight=Move sidebar to right +sidebar.moveToLeft=Move Sidebar to Left +sidebar.moveToRight=Move Sidebar to Right # LOCALIZATION NOTE (social.markpageMenu.label): %S is the name of the social provider social.markpageMenu.label=Save Page to %S diff --git a/devtools/client/responsivedesign/test/browser_responsiveui_touch.js b/devtools/client/responsivedesign/test/browser_responsiveui_touch.js index c23d2dd12722..4fd46fd600e1 100644 --- a/devtools/client/responsivedesign/test/browser_responsiveui_touch.js +++ b/devtools/client/responsivedesign/test/browser_responsiveui_touch.js @@ -142,7 +142,7 @@ function synthesizeClick(element) { } function pushPrefs(...aPrefs) { - let deferred = promise.defer(); - SpecialPowers.pushPrefEnv({"set": aPrefs}, deferred.resolve); - return deferred.promise; + return new Promise(resolve => { + SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve); + }); } diff --git a/devtools/client/responsivedesign/test/head.js b/devtools/client/responsivedesign/test/head.js index 18658faf789c..dd4ea58ed0e8 100644 --- a/devtools/client/responsivedesign/test/head.js +++ b/devtools/client/responsivedesign/test/head.js @@ -130,9 +130,9 @@ var closeToolbox = Task.async(function* () { */ function waitForToolboxFrameFocus(toolbox) { info("Making sure that the toolbox's frame is focused"); - let def = promise.defer(); - waitForFocus(def.resolve, toolbox.win); - return def.promise; + return new Promise(resolve => { + waitForFocus(resolve, toolbox.win); + }); } /** @@ -210,27 +210,27 @@ var addTab = Task.async(function* (url) { * @return promise */ function waitForDocLoadComplete(aBrowser = gBrowser) { - let deferred = promise.defer(); - let progressListener = { - onStateChange: function (webProgress, req, flags, status) { - let docStop = Ci.nsIWebProgressListener.STATE_IS_NETWORK | - Ci.nsIWebProgressListener.STATE_STOP; - info(`Saw state ${flags.toString(16)} and status ${status.toString(16)}`); + return new Promise(resolve => { + let progressListener = { + onStateChange: function (webProgress, req, flags, status) { + let docStop = Ci.nsIWebProgressListener.STATE_IS_NETWORK | + Ci.nsIWebProgressListener.STATE_STOP; + info(`Saw state ${flags.toString(16)} and status ${status.toString(16)}`); - // When a load needs to be retargetted to a new process it is cancelled - // with NS_BINDING_ABORTED so ignore that case - if ((flags & docStop) == docStop && status != Cr.NS_BINDING_ABORTED) { - aBrowser.removeProgressListener(progressListener); - info("Browser loaded"); - deferred.resolve(); - } - }, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, + // When a load needs to be retargetted to a new process it is cancelled + // with NS_BINDING_ABORTED so ignore that case + if ((flags & docStop) == docStop && status != Cr.NS_BINDING_ABORTED) { + aBrowser.removeProgressListener(progressListener); + info("Browser loaded"); + resolve(); + } + }, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]) - }; - aBrowser.addProgressListener(progressListener); - info("Waiting for browser load"); - return deferred.promise; + }; + aBrowser.addProgressListener(progressListener); + info("Waiting for browser load"); + }); } /** diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index b151f79fd347..1f3249b8f0c2 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -9651,8 +9651,7 @@ public: : js::NukeWindowReferences); } else { // We only want to nuke wrappers for the chrome->content case - js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), - js::SingleCompartment(cpt), + js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), cpt, win->IsInnerWindow() ? js::DontNukeWindowReferences : js::NukeWindowReferences, js::NukeIncomingReferences); diff --git a/gfx/vr/openvr/src/envvartools_public.cpp b/gfx/vr/openvr/src/envvartools_public.cpp index bb050d68a594..f95849536202 100644 --- a/gfx/vr/openvr/src/envvartools_public.cpp +++ b/gfx/vr/openvr/src/envvartools_public.cpp @@ -3,7 +3,7 @@ #include #if defined(_WIN32) -#include +#include #undef GetEnvironmentVariable #undef SetEnvironmentVariable diff --git a/gfx/vr/openvr/src/pathtools_public.cpp b/gfx/vr/openvr/src/pathtools_public.cpp index 6413c34352ac..7f7c7e8f463a 100644 --- a/gfx/vr/openvr/src/pathtools_public.cpp +++ b/gfx/vr/openvr/src/pathtools_public.cpp @@ -3,11 +3,12 @@ #include "pathtools_public.h" #if defined( _WIN32) -#include +#include #include -#include -#include -#include +#include +#include +#include +#include #undef GetEnvironmentVariable #else diff --git a/gfx/vr/openvr/src/sharedlibtools_public.cpp b/gfx/vr/openvr/src/sharedlibtools_public.cpp index 9c0661ef1a57..e7948cf640e6 100644 --- a/gfx/vr/openvr/src/sharedlibtools_public.cpp +++ b/gfx/vr/openvr/src/sharedlibtools_public.cpp @@ -3,7 +3,7 @@ #include #if defined(_WIN32) -#include +#include #endif #if defined(POSIX) @@ -22,7 +22,7 @@ SharedLibHandle SharedLib_Load( const char *pchPath ) void *SharedLib_GetFunction( SharedLibHandle lib, const char *pchFunctionName) { #if defined( _WIN32) - return GetProcAddress( (HMODULE)lib, pchFunctionName ); + return (void*)GetProcAddress( (HMODULE)lib, pchFunctionName ); #elif defined(POSIX) return dlsym( lib, pchFunctionName ); #endif diff --git a/gfx/vr/openvr/src/vrpathregistry_public.cpp b/gfx/vr/openvr/src/vrpathregistry_public.cpp index cf61c866a026..061f5fbcbb7d 100644 --- a/gfx/vr/openvr/src/vrpathregistry_public.cpp +++ b/gfx/vr/openvr/src/vrpathregistry_public.cpp @@ -9,7 +9,7 @@ #if defined( WIN32 ) #include -#include +#include #undef GetEnvironmentVariable #elif defined OSX @@ -23,7 +23,9 @@ #include #ifndef VRLog - #if defined( WIN32 ) + #if defined( __MINGW32__ ) + #define VRLog(args...) fprintf(stderr, args) + #elif defined( WIN32 ) #define VRLog(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) #else #define VRLog(args...) fprintf(stderr, args) diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index 89e1060ee126..e70aaaed04c9 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -2618,16 +2618,20 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): self.cls.addstmt(typedef) for typedef in self.includedActorTypedefs: self.cls.addstmt(typedef) - for md in p.messageDecls: - if self.receivesMessage(md) and md.hasAsyncReturns(): - self.cls.addstmt( - Typedef(_makePromise(md.returns, self.side, resolver=True), - md.promiseName())) self.cls.addstmt(Whitespace.NL) self.cls.addstmts([ Typedef(p.fqStateType(), 'State'), Whitespace.NL ]) + self.cls.addstmt(Label.PUBLIC) + for md in p.messageDecls: + if self.receivesMessage(md) and md.hasAsyncReturns(): + self.cls.addstmt( + Typedef(_makePromise(md.returns, self.side, resolver=True), + md.promiseName())) + self.cls.addstmt(Whitespace.NL) + + self.cls.addstmt(Label.PROTECTED) # interface methods that the concrete subclass has to impl for md in p.messageDecls: isctor, isdtor = md.decl.type.isCtor(), md.decl.type.isDtor() diff --git a/js/src/devtools/rootAnalysis/annotations.js b/js/src/devtools/rootAnalysis/annotations.js index de6b2a3a91d3..0aa75f3c2ff7 100644 --- a/js/src/devtools/rootAnalysis/annotations.js +++ b/js/src/devtools/rootAnalysis/annotations.js @@ -231,6 +231,8 @@ var ignoreFunctions = { // The big hammers. "PR_GetCurrentThread" : true, "calloc" : true, + + "uint8 nsContentUtils::IsExpandedPrincipal(nsIPrincipal*)" : true, }; function extraGCFunctions() { diff --git a/js/src/gc/NurseryAwareHashMap.h b/js/src/gc/NurseryAwareHashMap.h index 30516b49198a..6e187e5998cc 100644 --- a/js/src/gc/NurseryAwareHashMap.h +++ b/js/src/gc/NurseryAwareHashMap.h @@ -87,6 +87,7 @@ class NurseryAwareHashMap using Lookup = typename MapType::Lookup; using Ptr = typename MapType::Ptr; using Range = typename MapType::Range; + using Entry = typename MapType::Entry; explicit NurseryAwareHashMap(AllocPolicy a = AllocPolicy()) : map(a) {} diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp index 3f5cf19a0956..b842c34e4841 100644 --- a/js/src/gc/Statistics.cpp +++ b/js/src/gc/Statistics.cpp @@ -879,6 +879,7 @@ Statistics::endGC() runtime->addTelemetry(JS_TELEMETRY_GC_MS, t(total)); runtime->addTelemetry(JS_TELEMETRY_GC_MAX_PAUSE_MS, t(longest)); + runtime->addTelemetry(JS_TELEMETRY_GC_MAX_PAUSE_MS_2, t(longest)); const double mmu50 = computeMMU(TimeDuration::FromMilliseconds(50)); runtime->addTelemetry(JS_TELEMETRY_GC_MMU_50, mmu50 * 100); diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 7b8be1a7f0c6..163434a71536 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -681,9 +681,9 @@ JSCompartment::traceOutgoingCrossCompartmentWrappers(JSTracer* trc) MOZ_ASSERT(JS::CurrentThreadIsHeapMajorCollecting()); MOZ_ASSERT(!zone()->isCollectingFromAnyThread() || trc->runtime()->gc.isHeapCompacting()); - for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) { - Value v = e.front().value().unbarrieredGet(); + for (NonStringWrapperEnum e(this); !e.empty(); e.popFront()) { if (e.front().key().is()) { + Value v = e.front().value().unbarrieredGet(); ProxyObject* wrapper = &v.toObject().as(); /* diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index c22a8b92bc10..279f81660fac 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -184,15 +184,11 @@ class CrossCompartmentKey return wrapped.match(matcher); } - // Valid for JSObject* and Debugger keys. Crashes immediately if used on a - // JSString* key. JSCompartment* compartment() { struct GetCompartmentFunctor { JSCompartment* operator()(JSObject** tp) const { return (*tp)->compartment(); } JSCompartment* operator()(JSScript** tp) const { return (*tp)->compartment(); } - JSCompartment* operator()(JSString** tp) const { - MOZ_CRASH("invalid ccw key"); return nullptr; - } + JSCompartment* operator()(JSString** tp) const { return nullptr; } }; return applyToWrapped(GetCompartmentFunctor()); } @@ -239,9 +235,191 @@ class CrossCompartmentKey WrappedType wrapped; }; +// The data structure for storing CCWs, which has a map per target compartment +// so we can access them easily. Note string CCWs are stored separately from the +// others because they have target compartment nullptr. +class WrapperMap +{ + static const size_t InitialInnerMapSize = 4; -using WrapperMap = NurseryAwareHashMap; + using InnerMap = NurseryAwareHashMap; + using OuterMap = GCHashMap, + SystemAllocPolicy>; + + OuterMap map; + + public: + class Enum + { + public: + enum SkipStrings : bool { + WithStrings = false, + WithoutStrings = true + }; + + private: + Enum(const Enum&) = delete; + void operator=(const Enum&) = delete; + + void goToNext() { + if (outer.isNothing()) + return; + for (; !outer->empty(); outer->popFront()) { + JSCompartment* c = outer->front().key(); + // Need to skip string at first, because the filter may not be + // happy with a nullptr. + if (!c && skipStrings) + continue; + if (filter && !filter->match(c)) + continue; + InnerMap& m = outer->front().value(); + if (!m.empty()) { + if (inner.isSome()) + inner.reset(); + inner.emplace(m); + outer->popFront(); + return; + } + } + } + + mozilla::Maybe outer; + mozilla::Maybe inner; + const CompartmentFilter* filter; + SkipStrings skipStrings; + + public: + explicit Enum(WrapperMap& m, SkipStrings s = WithStrings) : + filter(nullptr), skipStrings(s) { + outer.emplace(m.map); + goToNext(); + } + + Enum(WrapperMap& m, const CompartmentFilter& f, SkipStrings s = WithStrings) : + filter(&f), skipStrings(s) { + outer.emplace(m.map); + goToNext(); + } + + Enum(WrapperMap& m, JSCompartment* target) { + // Leave the outer map as nothing and only iterate the inner map we + // find here. + auto p = m.map.lookup(target); + if (p) + inner.emplace(p->value()); + } + + bool empty() const { + return (outer.isNothing() || outer->empty()) && + (inner.isNothing() || inner->empty()); + } + + InnerMap::Entry& front() const { + MOZ_ASSERT(inner.isSome() && !inner->empty()); + return inner->front(); + } + + void popFront() { + MOZ_ASSERT(!empty()); + if (!inner->empty()) { + inner->popFront(); + if (!inner->empty()) + return; + } + goToNext(); + } + + void removeFront() { + MOZ_ASSERT(inner.isSome()); + inner->removeFront(); + } + }; + + class Ptr : public InnerMap::Ptr + { + friend class WrapperMap; + + InnerMap* map; + + Ptr() : InnerMap::Ptr(), map(nullptr) {} + Ptr(const InnerMap::Ptr& p, InnerMap& m) : InnerMap::Ptr(p), map(&m) {} + }; + + MOZ_MUST_USE bool init(uint32_t len) { return map.init(len); } + + bool empty() { + if (map.empty()) + return true; + for (OuterMap::Enum e(map); !e.empty(); e.popFront()) { + if (!e.front().value().empty()) + return false; + } + return true; + } + + Ptr lookup(const CrossCompartmentKey& k) const { + auto op = map.lookup(const_cast(k).compartment()); + if (op) { + auto ip = op->value().lookup(k); + if (ip) + return Ptr(ip, op->value()); + } + return Ptr(); + } + + void remove(Ptr p) { + if (p) + p.map->remove(p); + } + + MOZ_MUST_USE bool put(const CrossCompartmentKey& k, const JS::Value& v) { + JSCompartment* c = const_cast(k).compartment(); + MOZ_ASSERT(k.is() == !c); + auto p = map.lookupForAdd(c); + if (!p) { + InnerMap m; + if (!m.init(InitialInnerMapSize) || !map.add(p, c, mozilla::Move(m))) + return false; + } + return p->value().put(k, v); + } + + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { + size_t size = map.sizeOfExcludingThis(mallocSizeOf); + for (OuterMap::Enum e(map); !e.empty(); e.popFront()) + size += e.front().value().sizeOfExcludingThis(mallocSizeOf); + return size; + } + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { + size_t size = map.sizeOfIncludingThis(mallocSizeOf); + for (OuterMap::Enum e(map); !e.empty(); e.popFront()) + size += e.front().value().sizeOfIncludingThis(mallocSizeOf); + return size; + } + + void sweepAfterMinorGC(JSTracer* trc) { + for (OuterMap::Enum e(map); !e.empty(); e.popFront()) { + InnerMap& m = e.front().value(); + m.sweepAfterMinorGC(trc); + if (m.empty()) + e.removeFront(); + } + } + + void sweep() { + for (OuterMap::Enum e(map); !e.empty(); e.popFront()) { + InnerMap& m = e.front().value(); + m.sweep(); + if (m.empty()) + e.removeFront(); + } + } +}; // We must ensure that all newly allocated JSObjects get their metadata // set. However, metadata builders may require the new object be in a sane @@ -678,6 +856,16 @@ struct JSCompartment explicit WrapperEnum(JSCompartment* c) : js::WrapperMap::Enum(c->crossCompartmentWrappers) {} }; + struct NonStringWrapperEnum : public js::WrapperMap::Enum { + explicit NonStringWrapperEnum(JSCompartment* c) : js::WrapperMap::Enum(c->crossCompartmentWrappers, WithoutStrings) {} + explicit NonStringWrapperEnum(JSCompartment* c, const js::CompartmentFilter& f) : js::WrapperMap::Enum(c->crossCompartmentWrappers, f, WithoutStrings) {} + explicit NonStringWrapperEnum(JSCompartment* c, JSCompartment* target) : js::WrapperMap::Enum(c->crossCompartmentWrappers, target) { MOZ_ASSERT(target); } + }; + + struct StringWrapperEnum : public js::WrapperMap::Enum { + explicit StringWrapperEnum(JSCompartment* c) : js::WrapperMap::Enum(c->crossCompartmentWrappers, nullptr) {} + }; + js::LexicalEnvironmentObject* getOrCreateNonSyntacticLexicalEnvironment(JSContext* cx, js::HandleObject enclosing); js::LexicalEnvironmentObject* getNonSyntacticLexicalEnvironment(JSObject* enclosing) const; diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 6886e6f4092e..a81d2dc696bb 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -122,6 +122,7 @@ enum { JS_TELEMETRY_GC_BUDGET_MS, JS_TELEMETRY_GC_ANIMATION_MS, JS_TELEMETRY_GC_MAX_PAUSE_MS, + JS_TELEMETRY_GC_MAX_PAUSE_MS_2, JS_TELEMETRY_GC_MARK_MS, JS_TELEMETRY_GC_SWEEP_MS, JS_TELEMETRY_GC_COMPACT_MS, @@ -1230,7 +1231,7 @@ struct CompartmentsWithPrincipals : public CompartmentFilter { extern JS_FRIEND_API(bool) NukeCrossCompartmentWrappers(JSContext* cx, const CompartmentFilter& sourceFilter, - const CompartmentFilter& targetFilter, + JSCompartment* target, NukeReferencesToWindow nukeReferencesToWindow, NukeReferencesFromTarget nukeReferencesFromTarget); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 7c8457948e5a..779c145cda9f 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -4022,9 +4022,7 @@ GCRuntime::markCompartments() while (!workList.empty()) { JSCompartment* comp = workList.popCopy(); - for (JSCompartment::WrapperEnum e(comp); !e.empty(); e.popFront()) { - if (e.front().key().is()) - continue; + for (JSCompartment::NonStringWrapperEnum e(comp); !e.empty(); e.popFront()) { JSCompartment* dest = e.front().mutableKey().compartment(); if (dest && !dest->maybeAlive) { dest->maybeAlive = true; @@ -4419,9 +4417,9 @@ DropStringWrappers(JSRuntime* rt) * compartment group. */ for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) { - for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) { - if (e.front().key().is()) - e.removeFront(); + for (JSCompartment::StringWrapperEnum e(c); !e.empty(); e.popFront()) { + MOZ_ASSERT(e.front().key().is()); + e.removeFront(); } } } @@ -4665,10 +4663,8 @@ AssertNoWrappersInGrayList(JSRuntime* rt) #ifdef DEBUG for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) { MOZ_ASSERT(!c->gcIncomingGrayPointers); - for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) { - if (!e.front().key().is()) - AssertNotOnGrayList(&e.front().value().unbarrieredGet().toObject()); - } + for (JSCompartment::NonStringWrapperEnum e(c); !e.empty(); e.popFront()) + AssertNotOnGrayList(&e.front().value().unbarrieredGet().toObject()); } #endif } diff --git a/js/src/proxy/CrossCompartmentWrapper.cpp b/js/src/proxy/CrossCompartmentWrapper.cpp index 9c43efe96f0a..f71792858135 100644 --- a/js/src/proxy/CrossCompartmentWrapper.cpp +++ b/js/src/proxy/CrossCompartmentWrapper.cpp @@ -525,7 +525,7 @@ js::NukeCrossCompartmentWrapper(JSContext* cx, JSObject* wrapper) JS_FRIEND_API(bool) js::NukeCrossCompartmentWrappers(JSContext* cx, const CompartmentFilter& sourceFilter, - const CompartmentFilter& targetFilter, + JSCompartment* target, js::NukeReferencesToWindow nukeReferencesToWindow, js::NukeReferencesFromTarget nukeReferencesFromTarget) { @@ -541,18 +541,31 @@ js::NukeCrossCompartmentWrappers(JSContext* cx, // If the compartment matches both the source and target filter, we may // want to cut both incoming and outgoing wrappers. bool nukeAll = (nukeReferencesFromTarget == NukeAllReferences && - targetFilter.match(c)); + target == c.get()); - // Iterate the wrappers looking for anything interesting. - for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) { - // Some cross-compartment wrappers are for strings. We're not - // interested in those. - const CrossCompartmentKey& k = e.front().key(); + // Iterate only the wrappers that have target compartment matched unless + // |nukeAll| is true. The string wrappers that we're not interested in + // won't be iterated, we can exclude them easily because they have + // compartment nullptr. Use Maybe to avoid copying from conditionally + // initializing NonStringWrapperEnum. + mozilla::Maybe e; + if (MOZ_LIKELY(!nukeAll)) + e.emplace(c, target); + else + e.emplace(c); + for (; !e->empty(); e->popFront()) { + // Skip debugger references because NukeCrossCompartmentWrapper() + // doesn't know how to nuke them yet, see bug 1084626 for more + // information. + const CrossCompartmentKey& k = e->front().key(); if (!k.is()) continue; - AutoWrapperRooter wobj(cx, WrapperValue(e)); - JSObject* wrapped = UncheckedUnwrap(wobj); + AutoWrapperRooter wobj(cx, WrapperValue(*e)); + + // Unwrap from the wrapped object in CrossCompartmentKey instead of + // the wrapper, this could save us a bit of time. + JSObject* wrapped = UncheckedUnwrap(k.as()); // We never nuke script source objects, since only ever used internally by the JS // engine, and are expected to remain valid throughout a scripts lifetime. @@ -568,11 +581,9 @@ js::NukeCrossCompartmentWrappers(JSContext* cx, continue; } - if (MOZ_UNLIKELY(nukeAll) || targetFilter.match(wrapped->compartment())) { - // We found a wrapper to nuke. - e.removeFront(); - NukeRemovedCrossCompartmentWrapper(cx, wobj); - } + // Now this is the wrapper we want to nuke. + e->removeFront(); + NukeRemovedCrossCompartmentWrapper(cx, wobj); } } @@ -691,16 +702,12 @@ js::RecomputeWrappers(JSContext* cx, const CompartmentFilter& sourceFilter, continue; // Iterate over the wrappers, filtering appropriately. - for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) { + for (JSCompartment::NonStringWrapperEnum e(c, targetFilter); !e.empty(); e.popFront()) { // Filter out non-objects. CrossCompartmentKey& k = e.front().mutableKey(); if (!k.is()) continue; - // Filter by target compartment. - if (!targetFilter.match(k.compartment())) - continue; - // Add it to the list. if (!toRecompute.append(WrapperValue(e))) return false; diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 72a8354ec190..5d6897322620 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -591,8 +591,7 @@ NukeAllWrappersForCompartment(JSContext* cx, JSCompartment* compartment, // we need to be sure that we don't have any existing cross-compartment // wrappers which may be replaced with dead wrappers during unrelated // wrapper recomputation *before* we set that bit. - js::NukeCrossCompartmentWrappers(cx, js::AllCompartments(), - js::SingleCompartment(compartment), + js::NukeCrossCompartmentWrappers(cx, js::AllCompartments(), compartment, nukeReferencesToWindow, js::NukeAllReferences); @@ -2696,6 +2695,9 @@ AccumulateTelemetryCallback(int id, uint32_t sample, const char* key) case JS_TELEMETRY_GC_MAX_PAUSE_MS: Telemetry::Accumulate(Telemetry::GC_MAX_PAUSE_MS, sample); break; + case JS_TELEMETRY_GC_MAX_PAUSE_MS_2: + Telemetry::Accumulate(Telemetry::GC_MAX_PAUSE_MS_2, sample); + break; case JS_TELEMETRY_GC_MARK_MS: Telemetry::Accumulate(Telemetry::GC_MARK_MS, sample); break; diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/FxAccountPushHandler.java b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/FxAccountPushHandler.java index d7cb83f648c0..2d63bdf028bc 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/FxAccountPushHandler.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/FxAccountPushHandler.java @@ -97,8 +97,6 @@ public class FxAccountPushHandler { } final AndroidFxAccount fxAccount = new AndroidFxAccount(context, account); if (!fxAccount.getDeviceId().equals(data.getString("id"))) { - Log.e(LOG_TAG, "The device ID to disconnect doesn't match with the local device ID.\n" - + "Local: " + fxAccount.getDeviceId() + ", ID to disconnect: " + data.getString("id")); return; } AccountManager.get(context).removeAccount(account, null, null); diff --git a/python/mozbuild/mozbuild/mach_commands.py b/python/mozbuild/mozbuild/mach_commands.py index b33679c1e204..5317f94a09a2 100644 --- a/python/mozbuild/mozbuild/mach_commands.py +++ b/python/mozbuild/mozbuild/mach_commands.py @@ -5,6 +5,7 @@ from __future__ import absolute_import, print_function, unicode_literals import argparse +import collections import errno import itertools import json @@ -475,6 +476,26 @@ class Build(MachCommandBase): # there are more important things in the log to look for than # whatever code we warned about. if not status: + # Suppress warnings for 3rd party projects in local builds + # until we suppress them for real. + # TODO remove entries/feature once we stop generating warnings + # in these directories. + LOCAL_SUPPRESS_DIRS = ( + 'gfx/angle', + 'gfx/cairo', + 'intl/icu/source', + 'js/src/ctypes/libffi', + 'media/libtheora', + 'media/mtransport/third_party/nICEr', + 'media/mtransport/third_party/nrappkit', + 'media/webrtc/trunk/webrtc', + 'netwerk/sctp/src/netinet', + 'nsprpub', + 'security/nss', + ) + + suppressed_by_dir = collections.Counter() + for warning in sorted(monitor.instance_warnings): path = mozpath.normsep(warning['filename']) if path.startswith(self.topsrcdir): @@ -482,6 +503,15 @@ class Build(MachCommandBase): warning['normpath'] = path + if (path.startswith(LOCAL_SUPPRESS_DIRS) and + 'MOZ_AUTOMATION' not in os.environ): + for d in LOCAL_SUPPRESS_DIRS: + if path.startswith(d): + suppressed_by_dir[d] += 1 + break + + continue + if warning['column'] is not None: self.log(logging.WARNING, 'compiler_warning', warning, 'warning: {normpath}:{line}:{column} [{flag}] ' @@ -490,6 +520,11 @@ class Build(MachCommandBase): self.log(logging.WARNING, 'compiler_warning', warning, 'warning: {normpath}:{line} [{flag}] {message}') + for d, count in sorted(suppressed_by_dir.items()): + self.log(logging.WARNING, 'suppressed_warning', + {'dir': d, 'count': count}, + '(suppressed {count} warnings in {dir})') + monitor.finish(record_usage=status==0) high_finder, finder_percent = monitor.have_high_finder_usage() diff --git a/security/certverifier/ExtendedValidation.cpp b/security/certverifier/ExtendedValidation.cpp index 3cc57a23de6d..8962fc37b55b 100644 --- a/security/certverifier/ExtendedValidation.cpp +++ b/security/certverifier/ExtendedValidation.cpp @@ -647,18 +647,6 @@ static const struct EVInfo kEVInfos[] = { "IUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOQ==", "CYP0", }, - { - // CN=Swisscom Root EV CA 2,OU=Digital Certificate Services,O=Swisscom,C=ch - "2.16.756.1.83.21.0", - "Swisscom EV OID", - { 0xD9, 0x5F, 0xEA, 0x3C, 0xA4, 0xEE, 0xDC, 0xE7, 0x4C, 0xD7, 0x6E, - 0x75, 0xFC, 0x6D, 0x1F, 0xF6, 0x2C, 0x44, 0x1F, 0x0F, 0xA8, 0xBC, - 0x77, 0xF0, 0x34, 0xB1, 0x9E, 0x5D, 0xB2, 0x58, 0x01, 0x5D }, - "MGcxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln" - "aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEeMBwGA1UEAxMVU3dpc3Njb20gUm9v" - "dCBFViBDQSAy", - "APL6ZOJ0Y9ON/RAdBB92ylg=", - }, { // CN=VeriSign Universal Root Certification Authority,OU="(c) 2008 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US "2.16.840.1.113733.1.7.23.6", diff --git a/security/manager/ssl/security-prefs.js b/security/manager/ssl/security-prefs.js index 8e896d9268e9..a8a428167b9b 100644 --- a/security/manager/ssl/security-prefs.js +++ b/security/manager/ssl/security-prefs.js @@ -47,7 +47,15 @@ pref("security.family_safety.mode", 2); pref("security.enterprise_roots.enabled", false); +// The supported values of this pref are: +// 0: do not fetch OCSP +// 1: fetch OCSP for DV and EV certificates +// 2: fetch OCSP only for EV certificates +#ifdef RELEASE_OR_BETA pref("security.OCSP.enabled", 1); +#else +pref("security.OCSP.enabled", 2); +#endif pref("security.OCSP.require", false); pref("security.OCSP.GET.enabled", false); #ifdef RELEASE_OR_BETA diff --git a/services/fxaccounts/FxAccounts.jsm b/services/fxaccounts/FxAccounts.jsm index 51ae8afb2e4a..b92a8a6f8e58 100644 --- a/services/fxaccounts/FxAccounts.jsm +++ b/services/fxaccounts/FxAccounts.jsm @@ -1572,9 +1572,6 @@ FxAccountsInternal.prototype = { this.notifyObservers(ON_DEVICE_DISCONNECTED_NOTIFICATION); return this.signOut(true); } - log.error( - `The device ID to disconnect doesn't match with the local device ID. ` + - `Local: ${localDeviceId}, ID to disconnect: ${deviceId}`); return null; }); }, diff --git a/services/sync/modules/policies.js b/services/sync/modules/policies.js index de1205e040bd..d1d06305357b 100644 --- a/services/sync/modules/policies.js +++ b/services/sync/modules/policies.js @@ -184,9 +184,11 @@ SyncScheduler.prototype = { } else { this._log.warn(`Resync attempt ${this._resyncs} exceeded ` + `maximum ${this.maxResyncs}`); + Svc.Obs.notify("weave:service:resyncs-finished"); } } else { this._resyncs = 0; + Svc.Obs.notify("weave:service:resyncs-finished"); } this._syncErrors = 0; diff --git a/services/sync/tps/extensions/tps/resource/modules/tabs.jsm b/services/sync/tps/extensions/tps/resource/modules/tabs.jsm index 797a939c09c6..01794b0cc3af 100644 --- a/services/sync/tps/extensions/tps/resource/modules/tabs.jsm +++ b/services/sync/tps/extensions/tps/resource/modules/tabs.jsm @@ -29,10 +29,10 @@ var BrowserTabs = { let wm = Cc["@mozilla.org/appshell/window-mediator;1"] .getService(Ci.nsIWindowMediator); let mainWindow = wm.getMostRecentWindow("navigator:browser"); - let newtab = mainWindow.getBrowser().addTab(uri); - mainWindow.getBrowser().selectedTab = newtab; - let win = mainWindow.getBrowser().getBrowserForTab(newtab); - win.addEventListener("load", function() { fn.call(); }, true); + let browser = mainWindow.getBrowser(); + browser.addEventListener("load", fn, { once: true }); + let newtab = browser.addTab(uri); + browser.selectedTab = newtab; }, /** diff --git a/services/sync/tps/extensions/tps/resource/tps.jsm b/services/sync/tps/extensions/tps/resource/tps.jsm index c5486a6cfeec..f24a833e4f90 100644 --- a/services/sync/tps/extensions/tps/resource/tps.jsm +++ b/services/sync/tps/extensions/tps/resource/tps.jsm @@ -100,7 +100,8 @@ const OBSERVER_TOPICS = ["fxaccounts:onlogin", "weave:service:sync:finish", "weave:service:sync:delayed", "weave:service:sync:error", - "weave:service:sync:start" + "weave:service:sync:start", + "weave:service:resyncs-finished", ]; var TPS = { @@ -213,7 +214,7 @@ var TPS = { break; - case "weave:service:sync:finish": + case "weave:service:resyncs-finished": this._syncActive = false; this._syncErrors = 0; this._triggeredSync = false; @@ -1117,7 +1118,7 @@ var TPS = { */ waitForSyncFinished: function TPS__waitForSyncFinished() { if (this._syncActive) { - this.waitForEvent("weave:service:sync:finished"); + this.waitForEvent("weave:service:resyncs-finished"); } }, diff --git a/servo/support/android/openssl.makefile b/servo/support/android/openssl.makefile index 6ababf0fd25f..a052fdbb6a1f 100644 --- a/servo/support/android/openssl.makefile +++ b/servo/support/android/openssl.makefile @@ -10,5 +10,5 @@ openssl-1.0.1t/libssl.so: openssl-1.0.1t/Configure ./openssl.sh ${ANDROID_NDK} openssl-1.0.1t/Configure: - wget https://www.openssl.org/source/openssl-1.0.1t.tar.gz + wget https://www.openssl.org/source/old/1.0.1/openssl-1.0.1t.tar.gz tar -zxf openssl-1.0.1t.tar.gz diff --git a/taskcluster/docs/parameters.rst b/taskcluster/docs/parameters.rst index b71abb024195..98a3ea2c67be 100644 --- a/taskcluster/docs/parameters.rst +++ b/taskcluster/docs/parameters.rst @@ -22,10 +22,6 @@ topic. Push Information ---------------- -``triggered_by`` - The event that precipitated this decision task; one of ``"nightly"`` or - ``"push"``. - ``base_repository`` The repository from which to do an initial clone, utilizing any available caching. diff --git a/taskcluster/mach_commands.py b/taskcluster/mach_commands.py index e07065612a72..eb64b71a724a 100644 --- a/taskcluster/mach_commands.py +++ b/taskcluster/mach_commands.py @@ -149,10 +149,6 @@ class MachCommands(MachCommandBase): @CommandArgument('--level', required=True, help='SCM level of this repository') - @CommandArgument('--triggered-by', - choices=['nightly', 'push'], - default='push', - help='Source of execution of the decision graph') @CommandArgument('--target-tasks-method', help='method for selecting the target tasks to generate') def taskgraph_decision(self, **options): diff --git a/taskcluster/taskgraph/cron/decision.py b/taskcluster/taskgraph/cron/decision.py index 4cb41acc8835..8dba8f7886e3 100644 --- a/taskcluster/taskgraph/cron/decision.py +++ b/taskcluster/taskgraph/cron/decision.py @@ -16,8 +16,6 @@ import slugid def run_decision_task(job, params): arguments = [] - if 'triggered-by' in job: - arguments.append('--triggered-by={}'.format(job['triggered-by'])) if 'target-tasks-method' in job: arguments.append('--target-tasks-method={}'.format(job['target-tasks-method'])) return [ diff --git a/taskcluster/taskgraph/cron/schema.py b/taskcluster/taskgraph/cron/schema.py index 4c27be93e221..999d7f47b80f 100644 --- a/taskcluster/taskgraph/cron/schema.py +++ b/taskcluster/taskgraph/cron/schema.py @@ -33,9 +33,6 @@ cron_yml_schema = Schema({ # Treeherder symbol for the cron task Required('treeherder-symbol'): basestring, - # --triggered-by './mach taskgraph decision' argument - 'triggered-by': basestring, - # --target-tasks-method './mach taskgraph decision' argument 'target-tasks-method': basestring, }), diff --git a/taskcluster/taskgraph/decision.py b/taskcluster/taskgraph/decision.py index 67c34a3d7f77..33ca75874943 100644 --- a/taskcluster/taskgraph/decision.py +++ b/taskcluster/taskgraph/decision.py @@ -157,7 +157,6 @@ def get_decision_parameters(options): 'pushdate', 'owner', 'level', - 'triggered_by', 'target_tasks_method', ] if n in options} diff --git a/taskcluster/taskgraph/parameters.py b/taskcluster/taskgraph/parameters.py index d84f81104dd2..e5e104a5069a 100644 --- a/taskcluster/taskgraph/parameters.py +++ b/taskcluster/taskgraph/parameters.py @@ -28,7 +28,6 @@ PARAMETER_NAMES = set([ 'pushdate', 'pushlog_id', 'target_tasks_method', - 'triggered_by', ]) diff --git a/testing/mozharness/configs/builds/releng_base_android_64_builds.py b/testing/mozharness/configs/builds/releng_base_android_64_builds.py index 57403e235441..7f539c2c6c40 100644 --- a/testing/mozharness/configs/builds/releng_base_android_64_builds.py +++ b/testing/mozharness/configs/builds/releng_base_android_64_builds.py @@ -48,6 +48,15 @@ config = { {'filename': '/builds/adjust-sdk-beta.token', 'secret_name': 'project/releng/gecko/build/level-%(scm-level)s/adjust-sdk-beta.token', 'min_scm_level': 2, 'default': 'try-build-has-no-secrets'}, + {'filename': '/builds/leanplum-sdk-release.token', + 'secret_name': 'project/releng/gecko/build/level-%(scm-level)s/leanplum-sdk-release.token', + 'min_scm_level': 2, 'default': 'try-build-has-no-secrets'}, + {'filename': '/builds/leanplum-sdk-beta.token', + 'secret_name': 'project/releng/gecko/build/level-%(scm-level)s/leanplum-sdk-beta.token', + 'min_scm_level': 2, 'default': 'try-build-has-no-secrets'}, + {'filename': '/builds/leanplum-sdk-nightly.token', + 'secret_name': 'project/releng/gecko/build/level-%(scm-level)s/leanplum-sdk-nightly.token', + 'min_scm_level': 2, 'default': 'try-build-has-no-secrets'}, ], 'vcs_share_base': '/builds/hg-shared', 'objdir': 'obj-firefox', diff --git a/testing/tps/tps/testrunner.py b/testing/tps/tps/testrunner.py index fb59403aefbc..6b490b603aec 100644 --- a/testing/tps/tps/testrunner.py +++ b/testing/tps/tps/testrunner.py @@ -78,6 +78,7 @@ class TPSTestRunner(object): 'xpinstall.signatures.required': False, 'services.sync.testing.tps': True, 'engine.bookmarks.repair.enabled': False, + 'extensions.allow-non-mpc-extensions': True, } debug_preferences = { diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index dd0e3ed2930d..2e597a19f2f4 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -753,10 +753,12 @@ "CYCLE_COLLECTOR_MAX_PAUSE": { "record_in_processes": ["main", "content"], "alert_emails": ["dev-telemetry-gc-alerts@mozilla.org"], + "bug_numbers": [1364503], "expires_in_version": "never", "kind": "exponential", "high": 10000, "n_buckets": 50, + "releaseChannelCollection": "opt-out", "description": "Longest pause for an individual slice of one cycle collection, including preparation (ms)" }, "CYCLE_COLLECTOR_FINISH_IGC": { @@ -996,12 +998,24 @@ "GC_MAX_PAUSE_MS": { "record_in_processes": ["main", "content"], "alert_emails": ["dev-telemetry-gc-alerts@mozilla.org"], - "expires_in_version": "never", + "bug_numbers": [1364503], + "expires_in_version": "61", "kind": "linear", "high": 1000, "n_buckets": 50, "description": "Longest GC slice in a GC (ms)" }, + "GC_MAX_PAUSE_MS_2": { + "record_in_processes": ["main", "content"], + "alert_emails": ["dev-telemetry-gc-alerts@mozilla.org"], + "bug_numbers": [1364503], + "expires_in_version": "never", + "kind": "exponential", + "high": 10000, + "n_buckets": 50, + "releaseChannelCollection": "opt-out", + "description": "Longest GC slice in a GC (ms)" + }, "GC_MARK_MS": { "record_in_processes": ["main", "content"], "alert_emails": ["dev-telemetry-gc-alerts@mozilla.org"], diff --git a/toolkit/components/telemetry/histogram-whitelists.json b/toolkit/components/telemetry/histogram-whitelists.json index 3672d63e86e3..1c99e528feba 100644 --- a/toolkit/components/telemetry/histogram-whitelists.json +++ b/toolkit/components/telemetry/histogram-whitelists.json @@ -771,7 +771,6 @@ "CYCLE_COLLECTOR_COLLECTED", "CYCLE_COLLECTOR_FINISH_IGC", "CYCLE_COLLECTOR_FULL", - "CYCLE_COLLECTOR_MAX_PAUSE", "CYCLE_COLLECTOR_NEED_GC", "CYCLE_COLLECTOR_OOM", "CYCLE_COLLECTOR_SYNC_SKIPPABLE", @@ -976,7 +975,6 @@ "GC_MARK_GRAY_MS", "GC_MARK_MS", "GC_MARK_ROOTS_MS", - "GC_MAX_PAUSE_MS", "GC_MINOR_REASON", "GC_MINOR_REASON_LONG", "GC_MINOR_US", diff --git a/toolkit/components/telemetry/histogram_tools.py b/toolkit/components/telemetry/histogram_tools.py index 0ad5ccca1f8a..65ba35c2e3b1 100644 --- a/toolkit/components/telemetry/histogram_tools.py +++ b/toolkit/components/telemetry/histogram_tools.py @@ -74,20 +74,22 @@ always_allowed_keys = ['kind', 'description', 'cpp_guard', 'expires_in_version', 'bug_numbers', 'record_in_processes'] whitelists = None -try: - whitelist_path = os.path.join(os.path.abspath(os.path.realpath(os.path.dirname(__file__))), - 'histogram-whitelists.json') - with open(whitelist_path, 'r') as f: - try: - whitelists = json.load(f) - for name, whitelist in whitelists.iteritems(): - whitelists[name] = set(whitelist) - except ValueError, e: - raise ParserError('Error parsing whitelist: %s' % whitelist_path) -except IOError: - whitelists = None - print('Unable to parse whitelist: %s.\nAssuming all histograms are acceptable.' % - whitelist_path) + + +def load_whitelist(): + try: + whitelist_path = os.path.join(os.path.abspath(os.path.realpath(os.path.dirname(__file__))), + 'histogram-whitelists.json') + with open(whitelist_path, 'r') as f: + try: + whitelists = json.load(f) + for name, whitelist in whitelists.iteritems(): + whitelists[name] = set(whitelist) + except ValueError: + raise ParserError('Error parsing whitelist: %s' % whitelist_path) + except IOError: + whitelists = None + raise ParserError('Unable to parse whitelist: %s.' % whitelist_path) class Histogram: @@ -594,6 +596,9 @@ def from_files(filenames, strict_type_checks=True): """Return an iterator that provides a sequence of Histograms for the histograms defined in filenames. """ + if strict_type_checks: + load_whitelist() + all_histograms = OrderedDict() for filename in filenames: parser = FILENAME_PARSERS[os.path.basename(filename)] diff --git a/toolkit/content/tests/widgets/test_videocontrols.html b/toolkit/content/tests/widgets/test_videocontrols.html index 04875c43fee1..d5ee4aa26c3e 100644 --- a/toolkit/content/tests/widgets/test_videocontrols.html +++ b/toolkit/content/tests/widgets/test_videocontrols.html @@ -420,9 +420,14 @@ function runTest(event) { case 33: is(event.type, "play", "checking event type"); ok(true, "video resume after mouseup"); - SimpleTest.finish(); + synthesizeMouse(video, playButtonCenterX, playButtonCenterY, { }); break; + // Bug 1367194: Always ensure video is paused before calling SimpleTest.finish(). + case 34: + is(event.type, "pause", "checking event type"); + SimpleTest.finish(); + break; default: throw "unexpected test #" + testnum + " w/ event " + event.type; diff --git a/toolkit/mozapps/extensions/AddonManagerWebAPI.cpp b/toolkit/mozapps/extensions/AddonManagerWebAPI.cpp index ca33f3afe7cb..3f2a7a5299f2 100644 --- a/toolkit/mozapps/extensions/AddonManagerWebAPI.cpp +++ b/toolkit/mozapps/extensions/AddonManagerWebAPI.cpp @@ -20,6 +20,22 @@ using namespace mozilla::dom; static bool IsValidHost(const nsACString& host) { + // This is ugly, but Preferences.h doesn't have support + // for default prefs or locked prefs + nsCOMPtr prefService (do_GetService(NS_PREFSERVICE_CONTRACTID)); + nsCOMPtr prefs; + if (prefService) { + prefService->GetDefaultBranch(nullptr, getter_AddRefs(prefs)); + bool isEnabled; + if (NS_SUCCEEDED(prefs->GetBoolPref("xpinstall.enabled", &isEnabled)) && !isEnabled) { + bool isLocked; + prefs->PrefIsLocked("xpinstall.enabled", &isLocked); + if (isLocked) { + return false; + } + } + } + if (host.Equals("addons.mozilla.org") || host.Equals("discovery.addons.mozilla.org") || host.Equals("testpilot.firefox.com")) { diff --git a/xpcom/threads/MozPromise.h b/xpcom/threads/MozPromise.h index f6cb8ee5e430..3cf11efa44b8 100644 --- a/xpcom/threads/MozPromise.h +++ b/xpcom/threads/MozPromise.h @@ -1051,8 +1051,11 @@ public: { PROMISE_ASSERT(mMagic1 == sMagic && mMagic2 == sMagic && mMagic3 == sMagic && mMagic4 == &mMutex); MutexAutoLock lock(mMutex); - MOZ_ASSERT(IsPending()); PROMISE_LOG("%s resolving MozPromise (%p created at %s)", aResolveSite, this, mCreationSite); + if (!IsPending()) { + PROMISE_LOG("%s ignored already resolved or rejected MozPromise (%p created at %s)", aResolveSite, this, mCreationSite); + return; + } mValue.SetResolve(Forward(aResolveValue)); DispatchAll(); } @@ -1062,8 +1065,11 @@ public: { PROMISE_ASSERT(mMagic1 == sMagic && mMagic2 == sMagic && mMagic3 == sMagic && mMagic4 == &mMutex); MutexAutoLock lock(mMutex); - MOZ_ASSERT(IsPending()); PROMISE_LOG("%s rejecting MozPromise (%p created at %s)", aRejectSite, this, mCreationSite); + if (!IsPending()) { + PROMISE_LOG("%s ignored already resolved or rejected MozPromise (%p created at %s)", aRejectSite, this, mCreationSite); + return; + } mValue.SetReject(Forward(aRejectValue)); DispatchAll(); } @@ -1073,8 +1079,11 @@ public: { PROMISE_ASSERT(mMagic1 == sMagic && mMagic2 == sMagic && mMagic3 == sMagic && mMagic4 == &mMutex); MutexAutoLock lock(mMutex); - MOZ_ASSERT(IsPending()); PROMISE_LOG("%s resolveOrRejecting MozPromise (%p created at %s)", aSite, this, mCreationSite); + if (!IsPending()) { + PROMISE_LOG("%s ignored already resolved or rejected MozPromise (%p created at %s)", aSite, this, mCreationSite); + return; + } mValue = Forward(aValue); DispatchAll(); }