diff --git a/browser/base/content/aboutcerterror/aboutCertError.xhtml b/browser/base/content/aboutcerterror/aboutCertError.xhtml index a46073878341..9371fbc7e818 100644 --- a/browser/base/content/aboutcerterror/aboutCertError.xhtml +++ b/browser/base/content/aboutcerterror/aboutCertError.xhtml @@ -80,7 +80,8 @@ }; replaceWithHost(intro); - if (getCSSClass() == "expertBadCert") { + var cssClass = getCSSClass(); + if (cssClass == "expertBadCert") { toggle('technicalContent'); toggle('expertContent'); } @@ -88,8 +89,12 @@ // Disallow overrides if this is a Strict-Transport-Security // host and the cert is bad (STS Spec section 7.3) or if the // certerror is in a frame (bug 633691). - if (getCSSClass() == "badStsCert" || window != top) + if (cssClass == "badStsCert" || window != top) { document.getElementById("expertContent").setAttribute("hidden", "true"); + } + if (cssClass != "badStsCert") { + document.getElementById("badStsCertExplanation").setAttribute("hidden", "true"); + } var tech = document.getElementById("technicalContentText"); if (tech) @@ -214,6 +219,7 @@

&certerror.whatShouldIDo.heading;

&certerror.whatShouldIDo.content;

+

&certerror.whatShouldIDo.badStsCertExplanation;

diff --git a/browser/base/content/content.js b/browser/base/content/content.js index 0be96d20ceb5..9b484a9f0a7d 100644 --- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -80,7 +80,23 @@ addEventListener("blur", function(event) { if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) { addEventListener("contextmenu", function (event) { - sendSyncMessage("contextmenu", {}, { event: event }); + let defaultPrevented = event.defaultPrevented; + if (!Services.prefs.getBoolPref("dom.event.contextmenu.enabled")) { + let plugin = null; + try { + plugin = event.target.QueryInterface(Ci.nsIObjectLoadingContent); + } catch (e) {} + if (plugin && plugin.displayedType == Ci.nsIObjectLoadingContent.TYPE_PLUGIN) { + // Don't open a context menu for plugins. + return; + } + + defaultPrevented = false; + } + + if (!defaultPrevented) { + sendSyncMessage("contextmenu", {}, { event: event }); + } }, false); } else { addEventListener("mozUITour", function(event) { @@ -616,4 +632,4 @@ let DOMFullscreenHandler = { } } }; -DOMFullscreenHandler.init(); \ No newline at end of file +DOMFullscreenHandler.init(); diff --git a/browser/locales/en-US/chrome/browser/aboutCertError.dtd b/browser/locales/en-US/chrome/browser/aboutCertError.dtd index 21c722c72dfc..1d44d3600130 100644 --- a/browser/locales/en-US/chrome/browser/aboutCertError.dtd +++ b/browser/locales/en-US/chrome/browser/aboutCertError.dtd @@ -26,6 +26,10 @@ going to the right place. However, this site's identity can't be verified."> + diff --git a/build/stlport/moz.build b/build/stlport/moz.build index 6ad0efac265b..af9be36a0fa9 100644 --- a/build/stlport/moz.build +++ b/build/stlport/moz.build @@ -60,4 +60,5 @@ if CONFIG['GNU_CXX']: CXXFLAGS += [ '-Wno-empty-body', '-Wno-type-limits', + '-Wno-unused-local-typedefs', ] diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index dc4e612e4f38..b53ec83a9c69 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -592,6 +592,7 @@ ContentChild::Init(MessageLoop* aIOLoop, void ContentChild::InitProcessAttributes() { +#ifdef MOZ_WIDGET_GONK #ifdef MOZ_NUWA_PROCESS if (IsNuwaProcess()) { SetProcessName(NS_LITERAL_STRING("(Nuwa)"), false); @@ -603,7 +604,9 @@ ContentChild::InitProcessAttributes() } else { SetProcessName(NS_LITERAL_STRING("Browser"), false); } - +#else + SetProcessName(NS_LITERAL_STRING("Web Content"), true); +#endif } void diff --git a/dom/mobilemessage/src/android/MobileMessageDatabaseService.h b/dom/mobilemessage/src/android/MobileMessageDatabaseService.h index cf7191d4931d..269a599bca83 100644 --- a/dom/mobilemessage/src/android/MobileMessageDatabaseService.h +++ b/dom/mobilemessage/src/android/MobileMessageDatabaseService.h @@ -15,6 +15,9 @@ namespace mobilemessage { class MobileMessageDatabaseService MOZ_FINAL : public nsIMobileMessageDatabaseService { +private: + ~MobileMessageDatabaseService() {} + public: NS_DECL_ISUPPORTS NS_DECL_NSIMOBILEMESSAGEDATABASESERVICE diff --git a/dom/mobilemessage/src/android/SmsService.h b/dom/mobilemessage/src/android/SmsService.h index 7a1a4d438b85..daddf377536a 100644 --- a/dom/mobilemessage/src/android/SmsService.h +++ b/dom/mobilemessage/src/android/SmsService.h @@ -14,6 +14,9 @@ namespace mobilemessage { class SmsService MOZ_FINAL : public nsISmsService { +private: + ~SmsService() {} + public: NS_DECL_ISUPPORTS NS_DECL_NSISMSSERVICE diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index dec0bdf9a4af..da5c9064fff5 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -184,7 +184,10 @@ PluginModuleChild::Init(const std::string& aPluginFilename, AddQuirk(QUIRK_FLASH_EXPOSE_COORD_TRANSLATION); } #else // defined(OS_MACOSX) - mozilla::plugins::PluginUtilsOSX::SetProcessName(info.fName); + const char* namePrefix = "Plugin Content"; + char nameBuffer[80]; + snprintf(nameBuffer, sizeof(nameBuffer), "%s (%s)", namePrefix, info.fName); + mozilla::plugins::PluginUtilsOSX::SetProcessName(nameBuffer); #endif pluginFile.FreePluginInfo(info); diff --git a/dom/plugins/ipc/PluginUtilsOSX.mm b/dom/plugins/ipc/PluginUtilsOSX.mm index f76bc5ff369c..4973f7376da6 100644 --- a/dom/plugins/ipc/PluginUtilsOSX.mm +++ b/dom/plugins/ipc/PluginUtilsOSX.mm @@ -277,7 +277,7 @@ bool mozilla::plugins::PluginUtilsOSX::SetProcessName(const char* aProcessName) char formattedName[1024]; snprintf(formattedName, sizeof(formattedName), - "%s (%s)", [currentName UTF8String], aProcessName); + "%s %s", [currentName UTF8String], aProcessName); aProcessName = formattedName; diff --git a/dom/src/storage/DOMStorageCache.cpp b/dom/src/storage/DOMStorageCache.cpp index fbaa0f9cda0b..66df87eb0128 100644 --- a/dom/src/storage/DOMStorageCache.cpp +++ b/dom/src/storage/DOMStorageCache.cpp @@ -351,8 +351,6 @@ DOMStorageCache::WaitForPreload(Telemetry::ID aTelemetryID) nsresult DOMStorageCache::GetLength(const DOMStorage* aStorage, uint32_t* aRetval) { - Telemetry::AutoTimer autoTimer; - if (Persist(aStorage)) { WaitForPreload(Telemetry::LOCALDOMSTORAGE_GETLENGTH_BLOCKING_MS); if (NS_FAILED(mLoadResult)) { @@ -401,8 +399,6 @@ DOMStorageCache::GetKey(const DOMStorage* aStorage, uint32_t aIndex, nsAString& // suck if there's a large numer of indexes. Do we care? If so, // maybe we need to have a lazily populated key array here or // something? - Telemetry::AutoTimer autoTimer; - if (Persist(aStorage)) { WaitForPreload(Telemetry::LOCALDOMSTORAGE_GETKEY_BLOCKING_MS); if (NS_FAILED(mLoadResult)) { @@ -431,8 +427,6 @@ KeysArrayBuilder(const nsAString& aKey, const nsString aValue, void* aArg) void DOMStorageCache::GetKeys(const DOMStorage* aStorage, nsTArray& aKeys) { - Telemetry::AutoTimer autoTimer; - if (Persist(aStorage)) { WaitForPreload(Telemetry::LOCALDOMSTORAGE_GETALLKEYS_BLOCKING_MS); } @@ -448,8 +442,6 @@ nsresult DOMStorageCache::GetItem(const DOMStorage* aStorage, const nsAString& aKey, nsAString& aRetval) { - Telemetry::AutoTimer autoTimer; - if (Persist(aStorage)) { WaitForPreload(Telemetry::LOCALDOMSTORAGE_GETVALUE_BLOCKING_MS); if (NS_FAILED(mLoadResult)) { @@ -472,8 +464,6 @@ nsresult DOMStorageCache::SetItem(const DOMStorage* aStorage, const nsAString& aKey, const nsString& aValue, nsString& aOld) { - Telemetry::AutoTimer autoTimer; - if (Persist(aStorage)) { WaitForPreload(Telemetry::LOCALDOMSTORAGE_SETVALUE_BLOCKING_MS); if (NS_FAILED(mLoadResult)) { @@ -520,8 +510,6 @@ nsresult DOMStorageCache::RemoveItem(const DOMStorage* aStorage, const nsAString& aKey, nsString& aOld) { - Telemetry::AutoTimer autoTimer; - if (Persist(aStorage)) { WaitForPreload(Telemetry::LOCALDOMSTORAGE_REMOVEKEY_BLOCKING_MS); if (NS_FAILED(mLoadResult)) { @@ -556,8 +544,6 @@ DOMStorageCache::RemoveItem(const DOMStorage* aStorage, const nsAString& aKey, nsresult DOMStorageCache::Clear(const DOMStorage* aStorage) { - Telemetry::AutoTimer autoTimer; - bool refresh = false; if (Persist(aStorage)) { // We need to preload all data (know the size) before we can proceeed diff --git a/dom/system/android/nsHapticFeedback.h b/dom/system/android/nsHapticFeedback.h index 426bf17ff717..a8a9903f1aa7 100644 --- a/dom/system/android/nsHapticFeedback.h +++ b/dom/system/android/nsHapticFeedback.h @@ -7,6 +7,9 @@ class nsHapticFeedback MOZ_FINAL : public nsIHapticFeedback { +private: + ~nsHapticFeedback() {} + public: NS_DECL_ISUPPORTS NS_DECL_NSIHAPTICFEEDBACK diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index e2edab629190..3f21f68f3c25 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -451,7 +451,7 @@ CompositorD3D11::CreateRenderTargetFromSource(const gfx::IntRect &aRect, srcBox.front = 0; srcBox.right = aSourcePoint.x + aRect.width; srcBox.bottom = aSourcePoint.y + aRect.height; - srcBox.back = 0; + srcBox.back = 1; const IntSize& srcSize = sourceD3D11->GetSize(); MOZ_ASSERT(srcSize.width >= 0 && srcSize.height >= 0, diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index f12e4c9b60e7..8b2f2c00296f 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -44,6 +44,9 @@ static FT_Library gPlatformFTLibrary = nullptr; class FreetypeReporter MOZ_FINAL : public nsIMemoryReporter, public CountingAllocatorBase { +private: + ~FreetypeReporter() {} + public: NS_DECL_ISUPPORTS diff --git a/image/decoders/icon/android/nsIconChannel.h b/image/decoders/icon/android/nsIconChannel.h index f3540fd52097..2ae2a385a594 100644 --- a/image/decoders/icon/android/nsIconChannel.h +++ b/image/decoders/icon/android/nsIconChannel.h @@ -25,7 +25,6 @@ class nsIconChannel MOZ_FINAL : public nsIChannel { NS_FORWARD_NSICHANNEL(mRealChannel->) nsIconChannel() {} - ~nsIconChannel() {} /** * Called by nsIconProtocolHandler after it creates this channel. @@ -33,7 +32,10 @@ class nsIconChannel MOZ_FINAL : public nsIChannel { * If this method fails, no other function must be called on this object. */ nsresult Init(nsIURI* aURI); + private: + ~nsIconChannel() {} + /** * The channel to the temp icon file (e.g. to /tmp/2qy9wjqw.html). * Will always be non-null after a successful Init. diff --git a/ipc/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in b/ipc/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in index 823814d2640b..c07ad220d1bd 100644 --- a/ipc/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in +++ b/ipc/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in @@ -4,4 +4,4 @@ /* Localized versions of Info.plist keys */ -CFBundleName = "%APP_NAME% Plugin Process"; +CFBundleName = "%APP_NAME%"; diff --git a/ipc/glue/ProcessUtils_mac.mm b/ipc/glue/ProcessUtils_mac.mm new file mode 100644 index 000000000000..6c5738871e54 --- /dev/null +++ b/ipc/glue/ProcessUtils_mac.mm @@ -0,0 +1,20 @@ +/* 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 "ProcessUtils.h" + +#include "nsString.h" + +#include "mozilla/plugins/PluginUtilsOSX.h" + +namespace mozilla { +namespace ipc { + +void SetThisProcessName(const char *aName) +{ + mozilla::plugins::PluginUtilsOSX::SetProcessName(aName); +} + +} // namespace ipc +} // namespace mozilla diff --git a/ipc/glue/moz.build b/ipc/glue/moz.build index af3e146b6292..c5f465fd09c4 100644 --- a/ipc/glue/moz.build +++ b/ipc/glue/moz.build @@ -85,6 +85,10 @@ elif CONFIG['OS_ARCH'] in ('DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD'): UNIFIED_SOURCES += [ 'ProcessUtils_bsd.cpp' ] +elif CONFIG['OS_ARCH'] in ('Darwin'): + UNIFIED_SOURCES += [ + 'ProcessUtils_mac.mm' + ] else: UNIFIED_SOURCES += [ 'ProcessUtils_none.cpp', diff --git a/js/public/ProfilingFrameIterator.h b/js/public/ProfilingFrameIterator.h index 2da4ba0dbfb7..0cb573402cfc 100644 --- a/js/public/ProfilingFrameIterator.h +++ b/js/public/ProfilingFrameIterator.h @@ -15,7 +15,11 @@ class JSAtom; struct JSRuntime; -namespace js { class AsmJSActivation; class AsmJSProfilingFrameIterator; } + +namespace js { + class Activation; + class AsmJSProfilingFrameIterator; +} namespace JS { @@ -25,15 +29,15 @@ namespace JS { // unwound. class JS_PUBLIC_API(ProfilingFrameIterator) { - js::AsmJSActivation *activation_; + js::Activation *activation_; static const unsigned StorageSpace = 6 * sizeof(void*); mozilla::AlignedStorage storage_; - js::AsmJSProfilingFrameIterator &iter() { + js::AsmJSProfilingFrameIterator &asmJSIter() { JS_ASSERT(!done()); return *reinterpret_cast(storage_.addr()); } - const js::AsmJSProfilingFrameIterator &iter() const { + const js::AsmJSProfilingFrameIterator &asmJSIter() const { JS_ASSERT(!done()); return *reinterpret_cast(storage_.addr()); } @@ -64,6 +68,12 @@ class JS_PUBLIC_API(ProfilingFrameIterator) // Return a label suitable for regexp-matching as performed by // browser/devtools/profiler/cleopatra/js/parserWorker.js const char *label() const; + + private: + void iteratorConstruct(const RegisterState &state); + void iteratorConstruct(); + void iteratorDestroy(); + bool iteratorDone(); }; } // namespace JS diff --git a/js/src/ds/LifoAlloc.h b/js/src/ds/LifoAlloc.h index 0bad952b9037..7601a50a6462 100644 --- a/js/src/ds/LifoAlloc.h +++ b/js/src/ds/LifoAlloc.h @@ -7,6 +7,7 @@ #ifndef ds_LifoAlloc_h #define ds_LifoAlloc_h +#include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" #include "mozilla/MathAlgorithms.h" #include "mozilla/MemoryChecking.h" @@ -147,7 +148,7 @@ class BumpChunk } // namespace detail -void +MOZ_NORETURN void CrashAtUnhandlableOOM(const char *reason); // LIFO bump allocator: used for phase-oriented and fast LIFO allocations. diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 0ce36be10247..c88bfa648242 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -379,13 +379,13 @@ class MinorCollectionTracer : public JSTracer } /* namespace js */ static AllocKind -GetObjectAllocKindForCopy(JSRuntime *rt, JSObject *obj) +GetObjectAllocKindForCopy(const Nursery &nursery, JSObject *obj) { if (obj->is()) { JS_ASSERT(obj->numFixedSlots() == 0); /* Use minimal size object if we are just going to copy the pointer. */ - if (!rt->gc.nursery.isInside(obj->getElementsHeader())) + if (!nursery.isInside(obj->getElementsHeader())) return FINALIZE_OBJECT0_BACKGROUND; size_t nelements = obj->getDenseCapacity(); @@ -410,7 +410,7 @@ GetObjectAllocKindForCopy(JSRuntime *rt, JSObject *obj) return GetBackgroundAllocKind(kind); } -void * +MOZ_ALWAYS_INLINE void * js::Nursery::allocateFromTenured(Zone *zone, AllocKind thingKind) { void *t = zone->allocator.arenas.allocateFromFreeList(thingKind, Arena::thingSize(thingKind)); @@ -520,7 +520,8 @@ js::Nursery::traceObject(MinorCollectionTracer *trc, JSObject *obj) if (clasp->trace) clasp->trace(trc, obj); - if (!obj->isNative()) + MOZ_ASSERT(obj->isNative() == clasp->isNative()); + if (!clasp->isNative()) return; // Note: the contents of copy on write elements pointers are filled in @@ -569,8 +570,8 @@ js::Nursery::markSlot(MinorCollectionTracer *trc, HeapSlot *slotp) void * js::Nursery::moveToTenured(MinorCollectionTracer *trc, JSObject *src) { + AllocKind dstKind = GetObjectAllocKindForCopy(*this, src); Zone *zone = src->zone(); - AllocKind dstKind = GetObjectAllocKindForCopy(trc->runtime(), src); JSObject *dst = static_cast(allocateFromTenured(zone, dstKind)); if (!dst) CrashAtUnhandlableOOM("Failed to allocate object while tenuring."); @@ -585,7 +586,7 @@ js::Nursery::moveToTenured(MinorCollectionTracer *trc, JSObject *src) return static_cast(dst); } -size_t +MOZ_ALWAYS_INLINE size_t js::Nursery::moveObjectToTenured(JSObject *dst, JSObject *src, AllocKind dstKind) { size_t srcSize = Arena::thingSize(dstKind); @@ -646,7 +647,7 @@ js::Nursery::forwardTypedArrayPointers(JSObject *dst, JSObject *src) nslots); } -size_t +MOZ_ALWAYS_INLINE size_t js::Nursery::moveSlotsToTenured(JSObject *dst, JSObject *src, AllocKind dstKind) { /* Fixed slots have already been copied over. */ @@ -668,7 +669,7 @@ js::Nursery::moveSlotsToTenured(JSObject *dst, JSObject *src, AllocKind dstKind) return count * sizeof(HeapSlot); } -size_t +MOZ_ALWAYS_INLINE size_t js::Nursery::moveElementsToTenured(JSObject *dst, JSObject *src, AllocKind dstKind) { if (src->hasEmptyElements() || src->denseElementsAreCopyOnWrite()) diff --git a/js/src/gc/StoreBuffer.h b/js/src/gc/StoreBuffer.h index 3ba62980df0f..c0aa552e716e 100644 --- a/js/src/gc/StoreBuffer.h +++ b/js/src/gc/StoreBuffer.h @@ -13,6 +13,7 @@ # error "Generational GC requires exact rooting." #endif +#include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" #include "mozilla/ReentrancyGuard.h" @@ -25,7 +26,7 @@ namespace js { -void +MOZ_NORETURN void CrashAtUnhandlableOOM(const char *reason); namespace gc { diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index fab61384c1bd..0f9a4faf495c 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -7542,7 +7542,7 @@ IonBuilder::addTypedArrayLengthAndData(MDefinition *obj, #else bool isTenured = true; #endif - if (isTenured) { + if (isTenured && tarr->hasSingletonType()) { // The 'data' pointer can change in rare circumstances // (ArrayBufferObject::changeContents). types::TypeObjectKey *tarrType = types::TypeObjectKey::get(tarr); @@ -8677,6 +8677,10 @@ IonBuilder::jsop_getprop(PropertyName *name) MDefinition *obj = current->pop(); + // Try to optimize to a specific constant. + if (!getPropTryInferredConstant(&emitted, obj, name) || emitted) + return emitted; + // Try to optimize arguments.length. if (!getPropTryArgumentsLength(&emitted, obj) || emitted) return emitted; @@ -8766,6 +8770,28 @@ IonBuilder::checkIsDefinitelyOptimizedArguments(MDefinition *obj, bool *isOptimi return true; } +bool +IonBuilder::getPropTryInferredConstant(bool *emitted, MDefinition *obj, PropertyName *name) +{ + JS_ASSERT(*emitted == false); + + // Need a result typeset to optimize. + types::TemporaryTypeSet *objTypes = obj->resultTypeSet(); + if (!objTypes) + return true; + + Value constVal = UndefinedValue(); + if (objTypes->propertyIsConstant(constraints(), NameToId(name), &constVal)) { + spew("Optimized constant property"); + obj->setImplicitlyUsedUnchecked(); + if (!pushConstant(constVal)) + return false; + *emitted = true; + } + + return true; +} + bool IonBuilder::getPropTryArgumentsLength(bool *emitted, MDefinition *obj) { @@ -9380,13 +9406,16 @@ IonBuilder::jsop_setprop(PropertyName *name) if (!setPropTryTypedObject(&emitted, obj, name, value) || emitted) return emitted; - // Try to emit store from definite slots. - if (!setPropTryDefiniteSlot(&emitted, obj, name, value, barrier, objTypes) || emitted) - return emitted; + // Do not emit optimized stores to slots that may be constant. + if (objTypes && !objTypes->propertyMightBeConstant(constraints(), NameToId(name))) { + // Try to emit store from definite slots. + if (!setPropTryDefiniteSlot(&emitted, obj, name, value, barrier, objTypes) || emitted) + return emitted; - // Try to emit a monomorphic/polymorphic store based on baseline caches. - if (!setPropTryInlineAccess(&emitted, obj, name, value, barrier, objTypes) || emitted) - return emitted; + // Try to emit a monomorphic/polymorphic store based on baseline caches. + if (!setPropTryInlineAccess(&emitted, obj, name, value, barrier, objTypes) || emitted) + return emitted; + } // Emit a polymorphic cache. return setPropTryCache(&emitted, obj, name, value, barrier, objTypes); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 894fdcf3388d..153f07837f26 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -399,6 +399,7 @@ class IonBuilder : public MIRGenerator // jsop_getprop() helpers. bool checkIsDefinitelyOptimizedArguments(MDefinition *obj, bool *isOptimizedArgs); + bool getPropTryInferredConstant(bool *emitted, MDefinition *obj, PropertyName *name); bool getPropTryArgumentsLength(bool *emitted, MDefinition *obj); bool getPropTryArgumentsCallee(bool *emitted, MDefinition *obj, PropertyName *name); bool getPropTryConstant(bool *emitted, MDefinition *obj, PropertyName *name, diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index b98daab455ef..656d78d8ae0b 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -1754,6 +1754,69 @@ HeapTypeSetKey::nonWritable(CompilerConstraintList *constraints) return false; } +namespace { + +class ConstraintDataConstantProperty +{ + public: + explicit ConstraintDataConstantProperty() {} + + const char *kind() { return "constantProperty"; } + + bool invalidateOnNewType(Type type) { return false; } + bool invalidateOnNewPropertyState(TypeSet *property) { + return property->nonConstantProperty(); + } + bool invalidateOnNewObjectState(TypeObject *object) { return false; } + + bool constraintHolds(JSContext *cx, + const HeapTypeSetKey &property, TemporaryTypeSet *expected) + { + return !invalidateOnNewPropertyState(property.maybeTypes()); + } + + bool shouldSweep() { return false; } +}; + +} /* anonymous namespace */ + +bool +HeapTypeSetKey::constant(CompilerConstraintList *constraints, Value *valOut) +{ + if (nonData(constraints)) + return false; + + if (!maybeTypes()) + return false; + + if (maybeTypes()->nonConstantProperty()) + return false; + + // Only singleton object properties can be marked as constants. + JS_ASSERT(object()->singleton()); + + // Get the current value of the property. + Shape *shape = object()->singleton()->nativeLookupPure(id()); + if (!shape) + return false; + Value val = object()->singleton()->nativeGetSlot(shape->slot()); + + // If the value is a pointer to an object in the nursery, don't optimize. + if (val.isGCThing() && IsInsideNursery(val.toGCThing())) + return false; + + // If the value is a string that's not atomic, don't optimize. + if (val.isString() && !val.toString()->isAtom()) + return false; + + *valOut = val; + + LifoAlloc *alloc = constraints->alloc(); + typedef CompilerConstraintInstance T; + constraints->add(alloc->new_(alloc, *this, ConstraintDataConstantProperty())); + return true; +} + bool TemporaryTypeSet::filtersType(const TemporaryTypeSet *other, Type filteredType) const { @@ -1781,6 +1844,95 @@ TemporaryTypeSet::filtersType(const TemporaryTypeSet *other, Type filteredType) return true; } +namespace { + +// A constraint that never triggers recompilation. +class ConstraintDataInert +{ + public: + explicit ConstraintDataInert() {} + + const char *kind() { return "inert"; } + + bool invalidateOnNewType(Type type) { return false; } + bool invalidateOnNewPropertyState(TypeSet *property) { return false; } + bool invalidateOnNewObjectState(TypeObject *object) { return false; } + + bool constraintHolds(JSContext *cx, + const HeapTypeSetKey &property, TemporaryTypeSet *expected) + { + return true; + } + + bool shouldSweep() { return false; } +}; + +} /* anonymous namespace */ + +bool +TemporaryTypeSet::propertyMightBeConstant(CompilerConstraintList *constraints, jsid id) +{ + if (unknownObject()) + return true; + + for (size_t i = 0; i < getObjectCount(); i++) { + TypeObjectKey *type = getObject(i); + + // Type sets are only marked as constants when they are lazily + // constructed from the properties of singleton typed objects. So watch + // for the cases when a property either already is or might be marked + // as constant in the future. + + if (!type || !type->isSingleObject()) + continue; + + if (type->unknownProperties()) + return true; + + HeapTypeSetKey property = type->property(id); + if (!property.maybeTypes() || !property.maybeTypes()->nonConstantProperty()) + return true; + } + + // It is possible for a property that was not marked as constant to + // 'become' one, if we throw away the type property during a GC and + // regenerate it with the constant flag set. TypeObject::sweep only removes + // type properties if they have no constraints attached to them, so add + // inert constraints to pin these properties in place. + + LifoAlloc *alloc = constraints->alloc(); + for (size_t i = 0; i < getObjectCount(); i++) { + TypeObjectKey *type = getObject(i); + + if (!type || !type->isSingleObject()) + continue; + + HeapTypeSetKey property = type->property(id); + + typedef CompilerConstraintInstance T; + constraints->add(alloc->new_(alloc, property, ConstraintDataInert())); + } + + return false; +} + +bool +TemporaryTypeSet::propertyIsConstant(CompilerConstraintList *constraints, jsid id, Value *valOut) +{ + JS_ASSERT(valOut); + + JSObject *singleton = getSingleton(); + if (!singleton) + return false; + + TypeObjectKey *type = TypeObjectKey::get(singleton); + if (type->unknownProperties()) + return false; + + HeapTypeSetKey property = type->property(id); + return property.constant(constraints, valOut); +} + TemporaryTypeSet::DoubleConversion TemporaryTypeSet::convertDoubleElements(CompilerConstraintList *constraints) { @@ -2761,6 +2913,8 @@ static inline void UpdatePropertyType(ExclusiveContext *cx, HeapTypeSet *types, JSObject *obj, Shape *shape, bool indexed) { + JS_ASSERT(obj->hasSingletonType() && !obj->hasLazyType()); + if (!shape->writable()) types->setNonWritableProperty(cx); @@ -2782,6 +2936,14 @@ UpdatePropertyType(ExclusiveContext *cx, HeapTypeSet *types, JSObject *obj, Shap Type type = GetValueType(value); types->TypeSet::addType(type, &cx->typeLifoAlloc()); } + + if (indexed || shape->hadOverwrite()) { + types->setNonConstantProperty(cx); + } else { + InferSpew(ISpewOps, "typeSet: %sT%p%s property %s %s - setConstant", + InferSpewColor(types), types, InferSpewColorReset(), + TypeObjectString(obj->type()), TypeIdString(shape->propid())); + } } } @@ -2792,8 +2954,10 @@ TypeObject::updateNewPropertyTypes(ExclusiveContext *cx, jsid id, HeapTypeSet *t InferSpewColor(types), types, InferSpewColorReset(), TypeObjectString(this), TypeIdString(id)); - if (!singleton() || !singleton()->isNative()) + if (!singleton() || !singleton()->isNative()) { + types->setNonConstantProperty(cx); return; + } /* * Fill the property in with any type the object already has in an own @@ -2895,7 +3059,17 @@ InlineAddTypeProperty(ExclusiveContext *cx, TypeObject *obj, jsid id, Type type) AutoEnterAnalysis enter(cx); HeapTypeSet *types = obj->getProperty(cx, id); - if (!types || types->hasType(type)) + if (!types) + return; + + // Clear any constant flag if it exists. + if (!types->nonConstantProperty()) { + InferSpew(ISpewOps, "constantMutated: %sT%p%s %s", + InferSpewColor(types), types, InferSpewColorReset(), TypeString(type)); + types->setNonConstantProperty(cx); + } + + if (types->hasType(type)) return; InferSpew(ISpewOps, "externalType: property %s %s: %s", diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index cbc219b3da4c..a9492c390729 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -358,7 +358,7 @@ public: /* * For constraints attached to an object property's type set, mark the - * property as having its configuration changed. + * property as having changed somehow. */ virtual void newPropertyState(JSContext *cx, TypeSet *source) {} @@ -417,6 +417,9 @@ enum MOZ_ENUM_TYPE(uint32_t) { /* Whether the property has ever been made non-writable. */ TYPE_FLAG_NON_WRITABLE_PROPERTY = 0x00010000, + /* Whether the property might not be constant. */ + TYPE_FLAG_NON_CONSTANT_PROPERTY = 0x00020000, + /* * Whether the property is definitely in a particular slot on all objects * from which it has not been deleted or reconfigured. For singletons @@ -426,8 +429,8 @@ enum MOZ_ENUM_TYPE(uint32_t) { * If the property is definite, mask and shift storing the slot + 1. * Otherwise these bits are clear. */ - TYPE_FLAG_DEFINITE_MASK = 0xfffe0000, - TYPE_FLAG_DEFINITE_SHIFT = 17 + TYPE_FLAG_DEFINITE_MASK = 0xfffc0000, + TYPE_FLAG_DEFINITE_SHIFT = 18 }; typedef uint32_t TypeFlags; @@ -558,6 +561,9 @@ class TypeSet bool nonWritableProperty() const { return flags & TYPE_FLAG_NON_WRITABLE_PROPERTY; } + bool nonConstantProperty() const { + return flags & TYPE_FLAG_NON_CONSTANT_PROPERTY; + } bool definiteProperty() const { return flags & TYPE_FLAG_DEFINITE_MASK; } unsigned definiteSlot() const { JS_ASSERT(definiteProperty()); @@ -676,6 +682,9 @@ class HeapTypeSet : public ConstraintTypeSet /* Mark this type set as representing a non-writable property. */ inline void setNonWritableProperty(ExclusiveContext *cx); + + // Mark this type set as being non-constant. + inline void setNonConstantProperty(ExclusiveContext *cx); }; class CompilerConstraintList; @@ -766,6 +775,10 @@ class TemporaryTypeSet : public TypeSet /* Whether any objects in the type set needs a barrier on id. */ bool propertyNeedsBarrier(CompilerConstraintList *constraints, jsid id); + /* Whether any objects in the type set might treat id as a constant property. */ + bool propertyMightBeConstant(CompilerConstraintList *constraints, jsid id); + bool propertyIsConstant(CompilerConstraintList *constraints, jsid id, Value *valOut); + /* * Whether this set contains all types in other, except (possibly) the * specified type. @@ -1404,6 +1417,7 @@ class HeapTypeSetKey bool knownSubset(CompilerConstraintList *constraints, const HeapTypeSetKey &other); JSObject *singleton(CompilerConstraintList *constraints); bool needsBarrier(CompilerConstraintList *constraints); + bool constant(CompilerConstraintList *constraints, Value *valOut); }; /* diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 78db400ed6cd..f4582e156019 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -1108,6 +1108,16 @@ HeapTypeSet::setNonWritableProperty(ExclusiveContext *cx) newPropertyState(cx); } +inline void +HeapTypeSet::setNonConstantProperty(ExclusiveContext *cx) +{ + if (flags & TYPE_FLAG_NON_CONSTANT_PROPERTY) + return; + + flags |= TYPE_FLAG_NON_CONSTANT_PROPERTY; + newPropertyState(cx); +} + inline unsigned TypeSet::getObjectCount() const { diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 2e79c64e5ba6..8db8e475e2a6 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -4056,10 +4056,10 @@ UpdateShapeTypeAndValue(typename ExecutionModeTraits::ExclusiveContextType jsid id = shape->propid(); if (shape->hasSlot()) { if (mode == ParallelExecution) { - if (!obj->nativeSetSlotIfHasType(shape, value)) + if (!obj->nativeSetSlotIfHasType(shape, value, /* overwriting = */ false)) return false; } else { - obj->nativeSetSlotWithType(cx->asExclusiveContext(), shape, value); + obj->nativeSetSlotWithType(cx->asExclusiveContext(), shape, value, /* overwriting = */ false); } } if (!shape->hasSlot() || !shape->hasDefaultGetter() || !shape->hasDefaultSetter()) { diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 3ccd293c5c74..9d122c7f31a5 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -418,9 +418,10 @@ class JSObject : public js::ObjectImpl return setSlot(slot, value); } - inline bool nativeSetSlotIfHasType(js::Shape *shape, const js::Value &value); + inline bool nativeSetSlotIfHasType(js::Shape *shape, const js::Value &value, + bool overwriting = true); inline void nativeSetSlotWithType(js::ExclusiveContext *cx, js::Shape *shape, - const js::Value &value); + const js::Value &value, bool overwriting = true); inline const js::Value &getReservedSlot(uint32_t index) const { JS_ASSERT(index < JSSLOT_FREE(getClass())); diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 0dd13a9516c6..3bf981263a18 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -665,19 +665,27 @@ JSObject::hasProperty(JSContext *cx, js::HandleObject obj, } inline bool -JSObject::nativeSetSlotIfHasType(js::Shape *shape, const js::Value &value) +JSObject::nativeSetSlotIfHasType(js::Shape *shape, const js::Value &value, bool overwriting) { if (!js::types::HasTypePropertyId(this, shape->propid(), value)) return false; nativeSetSlot(shape->slot(), value); + + if (overwriting) + shape->setOverwritten(); + return true; } inline void JSObject::nativeSetSlotWithType(js::ExclusiveContext *cx, js::Shape *shape, - const js::Value &value) + const js::Value &value, bool overwriting) { nativeSetSlot(shape->slot(), value); + + if (overwriting) + shape->setOverwritten(); + js::types::AddTypePropertyId(cx, this, shape->propid(), value); } diff --git a/js/src/vm/ForkJoin.h b/js/src/vm/ForkJoin.h index d2eab5725b4b..b2bdb1bec710 100644 --- a/js/src/vm/ForkJoin.h +++ b/js/src/vm/ForkJoin.h @@ -267,6 +267,10 @@ class ForkJoinActivation : public Activation public: explicit ForkJoinActivation(JSContext *cx); ~ForkJoinActivation(); + + bool isProfiling() const { + return false; + } }; class ForkJoinContext; diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index 071b32ceb0be..9371afaa7a1e 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -78,6 +78,7 @@ PerThreadData::PerThreadData(JSRuntime *runtime) traceLogger(nullptr), #endif activation_(nullptr), + profilingActivation_(nullptr), asmJSActivationStack_(nullptr), autoFlushICache_(nullptr), #if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index b99be4e50e5c..060ea33690f8 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -567,6 +567,12 @@ class PerThreadData : public PerThreadDataFriendFields */ js::Activation *activation_; + /* + * Points to the most recent profiling activation running on the + * thread. Protected by rt->interruptLock. + */ + js::Activation * volatile profilingActivation_; + /* See AsmJSActivation comment. Protected by rt->interruptLock. */ js::AsmJSActivation * volatile asmJSActivationStack_; @@ -589,6 +595,10 @@ class PerThreadData : public PerThreadDataFriendFields return offsetof(PerThreadData, activation_); } + js::Activation *profilingActivation() const { + return profilingActivation_; + } + js::AsmJSActivation *asmJSActivationStack() const { return asmJSActivationStack_; } diff --git a/js/src/vm/Shape.h b/js/src/vm/Shape.h index e87723fa47a7..14f9a87ff3e7 100644 --- a/js/src/vm/Shape.h +++ b/js/src/vm/Shape.h @@ -823,7 +823,13 @@ class Shape : public gc::BarrieredCell /* Property stored in per-object dictionary, not shared property tree. */ IN_DICTIONARY = 0x02, - UNUSED_BITS = 0x3C + /* + * Slotful property was stored to more than once. This is used as a + * hint for type inference. + */ + OVERWRITTEN = 0x04, + + UNUSED_BITS = 0x38 }; /* Get a shape identical to this one, without parent/kids information. */ @@ -882,6 +888,13 @@ class Shape : public gc::BarrieredCell : UndefinedValue(); } + void setOverwritten() { + flags |= OVERWRITTEN; + } + bool hadOverwrite() const { + return flags & OVERWRITTEN; + } + void update(PropertyOp getter, StrictPropertyOp setter, uint8_t attrs); bool matches(const Shape *other) const { diff --git a/js/src/vm/Stack-inl.h b/js/src/vm/Stack-inl.h index 4af82bb93a0d..2ea3aa6c3cee 100644 --- a/js/src/vm/Stack-inl.h +++ b/js/src/vm/Stack-inl.h @@ -738,11 +738,16 @@ Activation::Activation(ThreadSafeContext *cx, Kind kind) : cx_(cx), compartment_(cx->compartment_), prev_(cx->perThreadData->activation_), + prevProfiling_(prev_ ? prev_->mostRecentProfiling() : nullptr), savedFrameChain_(0), hideScriptedCallerCount_(0), kind_(kind) { cx->perThreadData->activation_ = this; + + // Link the activation into the list of profiling activations if needed. + if (isProfiling()) + registerProfiling(); } Activation::~Activation() @@ -750,6 +755,33 @@ Activation::~Activation() JS_ASSERT(cx_->perThreadData->activation_ == this); JS_ASSERT(hideScriptedCallerCount_ == 0); cx_->perThreadData->activation_ = prev_; + + if (isProfiling()) + unregisterProfiling(); +} + +bool +Activation::isProfiling() const +{ + if (isInterpreter()) + return asInterpreter()->isProfiling(); + + if (isJit()) + return asJit()->isProfiling(); + + if (isForkJoin()) + return asForkJoin()->isProfiling(); + + JS_ASSERT(isAsmJS()); + return asAsmJS()->isProfiling(); +} + +Activation * +Activation::mostRecentProfiling() +{ + if (isProfiling()) + return this; + return prevProfiling_; } InterpreterActivation::InterpreterActivation(RunState &state, JSContext *cx, diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 70e2354088af..eb2cd5cfca44 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -1618,6 +1618,23 @@ InterpreterFrameIterator::operator++() return *this; } +void +Activation::registerProfiling() +{ + JS_ASSERT(isProfiling()); + JSRuntime::AutoLockForInterrupt lock(cx_->asJSContext()->runtime()); + cx_->perThreadData->profilingActivation_ = this; +} + +void +Activation::unregisterProfiling() +{ + JS_ASSERT(isProfiling()); + JSRuntime::AutoLockForInterrupt lock(cx_->asJSContext()->runtime()); + JS_ASSERT(cx_->perThreadData->profilingActivation_ == this); + cx_->perThreadData->profilingActivation_ = prevProfiling_; +} + ActivationIterator::ActivationIterator(JSRuntime *rt) : jitTop_(rt->mainThread.jitTop), activation_(rt->mainThread.activation_) @@ -1653,50 +1670,99 @@ ActivationIterator::settle() } JS::ProfilingFrameIterator::ProfilingFrameIterator(JSRuntime *rt, const RegisterState &state) - : activation_(rt->mainThread.asmJSActivationStack()) + : activation_(rt->mainThread.profilingActivation()) { if (!activation_) return; + JS_ASSERT(activation_->isProfiling()); + static_assert(sizeof(AsmJSProfilingFrameIterator) <= StorageSpace, "Need to increase storage"); - new (storage_.addr()) AsmJSProfilingFrameIterator(*activation_, state); + + iteratorConstruct(state); settle(); } JS::ProfilingFrameIterator::~ProfilingFrameIterator() { - if (!done()) - iter().~AsmJSProfilingFrameIterator(); + if (!done()) { + JS_ASSERT(activation_->isProfiling()); + iteratorDestroy(); + } } void JS::ProfilingFrameIterator::operator++() { JS_ASSERT(!done()); - ++iter(); + + JS_ASSERT(activation_->isAsmJS()); + ++asmJSIter(); settle(); } void JS::ProfilingFrameIterator::settle() { - while (iter().done()) { - iter().~AsmJSProfilingFrameIterator(); - activation_ = activation_->prevAsmJS(); + while (iteratorDone()) { + iteratorDestroy(); + activation_ = activation_->prevProfiling(); if (!activation_) return; - new (storage_.addr()) AsmJSProfilingFrameIterator(*activation_); + iteratorConstruct(); } } +void +JS::ProfilingFrameIterator::iteratorConstruct(const RegisterState &state) +{ + JS_ASSERT(!done()); + + JS_ASSERT(activation_->isAsmJS()); + new (storage_.addr()) AsmJSProfilingFrameIterator(*activation_->asAsmJS(), state); +} + +void +JS::ProfilingFrameIterator::iteratorConstruct() +{ + JS_ASSERT(!done()); + + JS_ASSERT(activation_->isAsmJS()); + new (storage_.addr()) AsmJSProfilingFrameIterator(*activation_->asAsmJS()); +} + +void +JS::ProfilingFrameIterator::iteratorDestroy() +{ + JS_ASSERT(!done()); + + JS_ASSERT(activation_->isAsmJS()); + asmJSIter().~AsmJSProfilingFrameIterator(); +} + +bool +JS::ProfilingFrameIterator::iteratorDone() +{ + JS_ASSERT(!done()); + + JS_ASSERT(activation_->isAsmJS()); + return asmJSIter().done(); +} + void * JS::ProfilingFrameIterator::stackAddress() const { - return iter().stackAddress(); + JS_ASSERT(!done()); + + JS_ASSERT(activation_->isAsmJS()); + return asmJSIter().stackAddress(); } const char * JS::ProfilingFrameIterator::label() const { - return iter().label(); + JS_ASSERT(!done()); + + JS_ASSERT(activation_->isAsmJS()); + return asmJSIter().label(); } diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index 04a8e6d6f55a..d1bfab36d587 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -1103,6 +1103,7 @@ class Activation ThreadSafeContext *cx_; JSCompartment *compartment_; Activation *prev_; + Activation *prevProfiling_; // Counter incremented by JS_SaveFrameChain on the top-most activation and // decremented by JS_RestoreFrameChain. If > 0, ScriptFrameIter should stop @@ -1133,6 +1134,8 @@ class Activation Activation *prev() const { return prev_; } + Activation *prevProfiling() const { return prevProfiling_; } + inline Activation *mostRecentProfiling(); bool isInterpreter() const { return kind_ == Interpreter; @@ -1147,6 +1150,10 @@ class Activation return kind_ == AsmJS; } + inline bool isProfiling() const; + void registerProfiling(); + void unregisterProfiling(); + InterpreterActivation *asInterpreter() const { JS_ASSERT(isInterpreter()); return (InterpreterActivation *)this; @@ -1238,6 +1245,10 @@ class InterpreterActivation : public Activation return opMask_; } + bool isProfiling() const { + return false; + } + // If this js::Interpret frame is running |script|, enable interrupts. void enableInterruptsIfRunning(JSScript *script) { if (regs_.fp()->script() == script) @@ -1323,6 +1334,10 @@ class JitActivation : public Activation } void setActive(JSContext *cx, bool active = true); + bool isProfiling() const { + return false; + } + uint8_t *prevJitTop() const { return prevJitTop_; } @@ -1481,6 +1496,10 @@ class AsmJSActivation : public Activation AsmJSModule &module() const { return module_; } AsmJSActivation *prevAsmJS() const { return prevAsmJS_; } + bool isProfiling() const { + return true; + } + // Returns a pointer to the base of the innermost stack frame of asm.js code // in this activation. uint8_t *fp() const { return fp_; } diff --git a/layout/reftests/svg/filters/css-filters/blur-calc-negative-ref.html b/layout/reftests/svg/filters/css-filters/blur-calc-negative-ref.html new file mode 100644 index 000000000000..fc260c2e2232 --- /dev/null +++ b/layout/reftests/svg/filters/css-filters/blur-calc-negative-ref.html @@ -0,0 +1,27 @@ + + + + + CSS Filters: Blur an HTML Element Using a Negative Calc Function Value + + + + + + + +

You should see a green square.

+
+ + diff --git a/layout/reftests/svg/filters/css-filters/blur-calc-negative.html b/layout/reftests/svg/filters/css-filters/blur-calc-negative.html new file mode 100644 index 000000000000..694c6cfc97c3 --- /dev/null +++ b/layout/reftests/svg/filters/css-filters/blur-calc-negative.html @@ -0,0 +1,28 @@ + + + + + CSS Filters: Blur an HTML Element Using a Negative Calc Function Value + + + + + + + +

You should see a green square.

+
+ + diff --git a/layout/reftests/svg/filters/css-filters/blur-calc-ref.html b/layout/reftests/svg/filters/css-filters/blur-calc-ref.html new file mode 100644 index 000000000000..8f3567274931 --- /dev/null +++ b/layout/reftests/svg/filters/css-filters/blur-calc-ref.html @@ -0,0 +1,23 @@ + + + + + CSS Filters: Blur an HTML Element Using a Calc Function Value + + + + +

You should see a blurred green square.

+
+ + diff --git a/layout/reftests/svg/filters/css-filters/blur-calc.html b/layout/reftests/svg/filters/css-filters/blur-calc.html new file mode 100644 index 000000000000..e4dc87e7d75d --- /dev/null +++ b/layout/reftests/svg/filters/css-filters/blur-calc.html @@ -0,0 +1,28 @@ + + + + + CSS Filters: Blur an HTML Element Using a Calc Function Value + + + + + + + +

You should see a blurred green square.

+
+ + diff --git a/layout/reftests/svg/filters/css-filters/reftest.list b/layout/reftests/svg/filters/css-filters/reftest.list index b5bc0ec94af6..b18ba158fcca 100644 --- a/layout/reftests/svg/filters/css-filters/reftest.list +++ b/layout/reftests/svg/filters/css-filters/reftest.list @@ -5,6 +5,8 @@ default-preferences pref(layout.css.filters.enabled,true) == blur.html blur-ref.html == blur.svg blur-ref.svg +== blur-calc.html blur-calc-ref.html +== blur-calc-negative.html blur-calc-negative-ref.html == blur-zero-radius.html blur-zero-radius-ref.html == blur-zoomed-page.html blur-zoomed-page-ref.html == brightness.html brightness-ref.html diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 547b067db9de..c8e76dda427e 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -8708,7 +8708,9 @@ nsRuleNode::SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter, int32_t mask = SETCOORD_PERCENT | SETCOORD_FACTOR; if (type == NS_STYLE_FILTER_BLUR) { - mask = SETCOORD_LENGTH | SETCOORD_STORE_CALC; + mask = SETCOORD_LENGTH | + SETCOORD_CALC_LENGTH_ONLY | + SETCOORD_CALC_CLAMP_NONNEGATIVE; } else if (type == NS_STYLE_FILTER_HUE_ROTATE) { mask = SETCOORD_ANGLE; } diff --git a/mobile/android/base/mozglue/GeckoLoader.java.in b/mobile/android/base/mozglue/GeckoLoader.java.in index a5ae4278c375..872821b9ae2e 100644 --- a/mobile/android/base/mozglue/GeckoLoader.java.in +++ b/mobile/android/base/mozglue/GeckoLoader.java.in @@ -249,7 +249,7 @@ public final class GeckoLoader { loadMozGlue(context); loadLibsSetup(context); - loadSQLiteLibsNative(apkName, false); + loadSQLiteLibsNative(apkName); } public static void loadNSSLibs(final Context context, final String apkName) { @@ -262,7 +262,7 @@ public final class GeckoLoader { loadMozGlue(context); loadLibsSetup(context); - loadNSSLibsNative(apkName, false); + loadNSSLibsNative(apkName); } /** @@ -537,6 +537,6 @@ public final class GeckoLoader { // These methods are implemented in mozglue/android/APKOpen.cpp public static native void nativeRun(String args); private static native void loadGeckoLibsNative(String apkName); - private static native void loadSQLiteLibsNative(String apkName, boolean shouldExtract); - private static native void loadNSSLibsNative(String apkName, boolean shouldExtract); + private static native void loadSQLiteLibsNative(String apkName); + private static native void loadNSSLibsNative(String apkName); } diff --git a/mobile/android/components/build/nsShellService.h b/mobile/android/components/build/nsShellService.h index f80569d48931..5663b773ab99 100644 --- a/mobile/android/components/build/nsShellService.h +++ b/mobile/android/components/build/nsShellService.h @@ -15,11 +15,10 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSISHELLSERVICE - nsShellService() {}; + nsShellService() {} private: - ~nsShellService() {}; - + ~nsShellService() {} }; #define nsShellService_CID \ diff --git a/mozglue/android/APKOpen.cpp b/mozglue/android/APKOpen.cpp index a91cc8df1011..c7a9f4e8df07 100644 --- a/mozglue/android/APKOpen.cpp +++ b/mozglue/android/APKOpen.cpp @@ -317,11 +317,7 @@ Java_org_mozilla_gecko_mozglue_GeckoLoader_loadGeckoLibsNative(JNIEnv *jenv, jcl } extern "C" NS_EXPORT void JNICALL -Java_org_mozilla_gecko_mozglue_GeckoLoader_loadSQLiteLibsNative(JNIEnv *jenv, jclass jGeckoAppShellClass, jstring jApkName, jboolean jShouldExtract) { - if (jShouldExtract) { - putenv("MOZ_LINKER_EXTRACT=1"); - } - +Java_org_mozilla_gecko_mozglue_GeckoLoader_loadSQLiteLibsNative(JNIEnv *jenv, jclass jGeckoAppShellClass, jstring jApkName) { const char* str; // XXX: java doesn't give us true UTF8, we should figure out something // better to do here @@ -339,11 +335,7 @@ Java_org_mozilla_gecko_mozglue_GeckoLoader_loadSQLiteLibsNative(JNIEnv *jenv, jc } extern "C" NS_EXPORT void JNICALL -Java_org_mozilla_gecko_mozglue_GeckoLoader_loadNSSLibsNative(JNIEnv *jenv, jclass jGeckoAppShellClass, jstring jApkName, jboolean jShouldExtract) { - if (jShouldExtract) { - putenv("MOZ_LINKER_EXTRACT=1"); - } - +Java_org_mozilla_gecko_mozglue_GeckoLoader_loadNSSLibsNative(JNIEnv *jenv, jclass jGeckoAppShellClass, jstring jApkName) { const char* str; // XXX: java doesn't give us true UTF8, we should figure out something // better to do here diff --git a/netwerk/base/src/Tickler.cpp b/netwerk/base/src/Tickler.cpp index bc56effbfcac..dc9c29f6fe46 100644 --- a/netwerk/base/src/Tickler.cpp +++ b/netwerk/base/src/Tickler.cpp @@ -225,9 +225,9 @@ class TicklerTimer MOZ_FINAL : public nsITimerCallback mTickler = do_GetWeakReference(aTickler); } - ~TicklerTimer() {}; - private: + ~TicklerTimer() {} + nsWeakPtr mTickler; }; diff --git a/netwerk/protocol/device/AndroidCaptureProvider.h b/netwerk/protocol/device/AndroidCaptureProvider.h index 92f7cb141c6c..03f02870979f 100644 --- a/netwerk/protocol/device/AndroidCaptureProvider.h +++ b/netwerk/protocol/device/AndroidCaptureProvider.h @@ -17,9 +17,11 @@ #include "mozilla/ReentrantMonitor.h" class AndroidCaptureProvider MOZ_FINAL : public nsDeviceCaptureProvider { + private: + ~AndroidCaptureProvider(); + public: AndroidCaptureProvider(); - ~AndroidCaptureProvider(); NS_DECL_THREADSAFE_ISUPPORTS @@ -28,9 +30,11 @@ class AndroidCaptureProvider MOZ_FINAL : public nsDeviceCaptureProvider { }; class AndroidCameraInputStream MOZ_FINAL : public nsIAsyncInputStream, mozilla::net::CameraStreamImpl::FrameCallback { + private: + ~AndroidCameraInputStream(); + public: AndroidCameraInputStream(); - ~AndroidCameraInputStream(); NS_IMETHODIMP Init(nsACString& aContentType, nsCaptureParams* aParams); diff --git a/netwerk/system/android/nsAndroidNetworkLinkService.h b/netwerk/system/android/nsAndroidNetworkLinkService.h index 2fbfdf806aba..9fdda7cae052 100644 --- a/netwerk/system/android/nsAndroidNetworkLinkService.h +++ b/netwerk/system/android/nsAndroidNetworkLinkService.h @@ -16,6 +16,8 @@ public: NS_DECL_NSINETWORKLINKSERVICE nsAndroidNetworkLinkService(); + +private: virtual ~nsAndroidNetworkLinkService(); }; diff --git a/profile/dirserviceprovider/ProfileUnlockerWin.cpp b/profile/dirserviceprovider/ProfileUnlockerWin.cpp index a06b115982fd..705ee8524b2b 100644 --- a/profile/dirserviceprovider/ProfileUnlockerWin.cpp +++ b/profile/dirserviceprovider/ProfileUnlockerWin.cpp @@ -171,8 +171,12 @@ ProfileUnlockerWin::Unlock(uint32_t aSeverity) if (error != ERROR_SUCCESS) { return NS_ERROR_FAILURE; } + if (numEntries == 0) { + // Nobody else is locking the file; the other process must have terminated + return NS_OK; + } - nsresult rv; + nsresult rv = NS_ERROR_FAILURE; for (UINT i = 0; i < numEntries; ++i) { rv = TryToTerminate(info[i].Process); if (NS_SUCCEEDED(rv)) { @@ -188,6 +192,12 @@ ProfileUnlockerWin::Unlock(uint32_t aSeverity) nsresult ProfileUnlockerWin::TryToTerminate(RM_UNIQUE_PROCESS& aProcess) { + // Subtle: If the target process terminated before this call to OpenProcess, + // this call will still succeed. This is because the restart manager session + // internally retains a handle to the target process. The rules for Windows + // PIDs state that the PID of a terminated process remains valid as long as + // at least one handle to that process remains open, so when we reach this + // point the PID is still valid and the process will open successfully. DWORD accessRights = PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE; nsAutoHandle otherProcess(::OpenProcess(accessRights, FALSE, aProcess.dwProcessId)); @@ -207,7 +217,19 @@ ProfileUnlockerWin::TryToTerminate(RM_UNIQUE_PROCESS& aProcess) WCHAR imageName[MAX_PATH]; DWORD imageNameLen = MAX_PATH; if (!mQueryFullProcessImageName(otherProcess, 0, imageName, &imageNameLen)) { - return NS_ERROR_FAILURE; + // The error codes for this function are not very descriptive. There are + // actually two failure cases here: Either the call failed because the + // process is no longer running, or it failed for some other reason. We + // need to know which case that is. + DWORD otherProcessExitCode; + if (!::GetExitCodeProcess(otherProcess, &otherProcessExitCode) || + otherProcessExitCode == STILL_ACTIVE) { + // The other process is still running. + return NS_ERROR_FAILURE; + } + // The other process must have terminated. We should return NS_OK so that + // this process may proceed with startup. + return NS_OK; } nsCOMPtr otherProcessImageName; if (NS_FAILED(NS_NewLocalFile(nsDependentString(imageName, imageNameLen), @@ -241,7 +263,11 @@ ProfileUnlockerWin::TryToTerminate(RM_UNIQUE_PROCESS& aProcess) // We know that another process holds the lock and that it shares the same // image name as our process. Let's kill it. - if (!::TerminateProcess(otherProcess, 1)) { + // Subtle: TerminateProcess returning ERROR_ACCESS_DENIED is actually an + // indicator that the target process managed to shut down on its own. In that + // case we should return NS_OK since we may proceed with startup. + if (!::TerminateProcess(otherProcess, 1) && + ::GetLastError() != ERROR_ACCESS_DENIED) { return NS_ERROR_FAILURE; } diff --git a/testing/mochitest/runtests.py b/testing/mochitest/runtests.py index d4fb793150fc..a705244c93d4 100644 --- a/testing/mochitest/runtests.py +++ b/testing/mochitest/runtests.py @@ -1912,9 +1912,12 @@ class Mochitest(MochitestUtilsMixin): stackFixerCommand = [self.perl, os.path.join(self.utilityPath, "fix-linux-stack.pl")] stackFixerProcess = subprocess.Popen(stackFixerCommand, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - def fixFunc(line): - stackFixerProcess.stdin.write(line + '\n') - return stackFixerProcess.stdout.readline().rstrip() + def fixFunc(lines): + out = [] + for line in lines.split('\n'): + stackFixerProcess.stdin.write(line + '\n') + out.append(stackFixerProcess.stdout.readline().rstrip()) + return '\n'.join(out) stackFixerFunction = fixFunc diff --git a/toolkit/components/aboutmemory/tests/test_aboutmemory5.xul b/toolkit/components/aboutmemory/tests/test_aboutmemory5.xul index 8210030777af..871e75b13c92 100644 --- a/toolkit/components/aboutmemory/tests/test_aboutmemory5.xul +++ b/toolkit/components/aboutmemory/tests/test_aboutmemory5.xul @@ -126,7 +126,10 @@ // Note: Match "vsize" but not "vsize-max-contiguous". let vsizes = actual.match(/vsize[^-]/g); - let endOfBrowsers = actual.match(/End of Browser/g); + let endOfBrowsers = actual.match(/End of Browser/g); + if (endOfBrowsers == null) { + endOfBrowsers = actual.match(/End of Web Content/g); + } let m2 = (vsizes.length == 4 && endOfBrowsers.length == 3); ok(m2, "three child processes present in loaded data"); good = good && !!m2; diff --git a/toolkit/components/aboutmemory/tests/test_memoryReporters2.xul b/toolkit/components/aboutmemory/tests/test_memoryReporters2.xul index 5ec729a366fc..eff11a4cee30 100644 --- a/toolkit/components/aboutmemory/tests/test_memoryReporters2.xul +++ b/toolkit/components/aboutmemory/tests/test_memoryReporters2.xul @@ -85,8 +85,8 @@ if (processes[i] == "") { numEmptyProcesses++; } else { - ok(processes[i].startsWith("Browser ("), - "correct non-empty process name prefix"); + ok(processes[i].startsWith("Browser (") || processes[i].startsWith("Web Content ("), + "correct non-empty process name prefix: " + processes[i]); numNonEmptyProcesses++; } } diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index abe52ee6a77a..f731a978769f 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -4056,14 +4056,6 @@ "kind": "boolean", "description": "True when we had to wait for a pending preload on first access to localStorage data, false otherwise" }, - "LOCALDOMSTORAGE_GETALLKEYS_MS": { - "expires_in_version": "never", - "kind": "exponential", - "high": "3000", - "n_buckets": 10, - "extended_statistics_ok": true, - "description": "Time to return a list of all keys in domain's LocalStorage (ms)" - }, "LOCALDOMSTORAGE_GETALLKEYS_BLOCKING_MS": { "expires_in_version": "never", "kind": "exponential", @@ -4072,14 +4064,6 @@ "extended_statistics_ok": true, "description": "Time to block before we return a list of all keys in domain's LocalStorage (ms)" }, - "LOCALDOMSTORAGE_GETKEY_MS": { - "expires_in_version": "never", - "kind": "exponential", - "high": "3000", - "n_buckets": 10, - "extended_statistics_ok": true, - "description": "Time to return a key name in domain's LocalStorage (ms)" - }, "LOCALDOMSTORAGE_GETKEY_BLOCKING_MS": { "expires_in_version": "never", "kind": "exponential", @@ -4088,14 +4072,6 @@ "extended_statistics_ok": true, "description": "Time to block before we return a key name in domain's LocalStorage (ms)" }, - "LOCALDOMSTORAGE_GETLENGTH_MS": { - "expires_in_version": "never", - "kind": "exponential", - "high": "3000", - "n_buckets": 10, - "extended_statistics_ok": true, - "description": "Time to return number of keys in domain's LocalStorage (ms)" - }, "LOCALDOMSTORAGE_GETLENGTH_BLOCKING_MS": { "expires_in_version": "never", "kind": "exponential", @@ -4104,14 +4080,6 @@ "extended_statistics_ok": true, "description": "Time to block before we return number of keys in domain's LocalStorage (ms)" }, - "LOCALDOMSTORAGE_GETVALUE_MS": { - "expires_in_version": "never", - "kind": "exponential", - "high": "3000", - "n_buckets": 10, - "extended_statistics_ok": true, - "description": "Time to return a value for a key in LocalStorage (ms)" - }, "LOCALDOMSTORAGE_GETVALUE_BLOCKING_MS": { "expires_in_version": "never", "kind": "exponential", @@ -4120,14 +4088,6 @@ "extended_statistics_ok": true, "description": "Time to block before we return a value for a key in LocalStorage (ms)" }, - "LOCALDOMSTORAGE_SETVALUE_MS": { - "expires_in_version": "never", - "kind": "exponential", - "high": "3000", - "n_buckets": 10, - "extended_statistics_ok": true, - "description": "Time to set a single key's value in LocalStorage (ms)" - }, "LOCALDOMSTORAGE_SETVALUE_BLOCKING_MS": { "expires_in_version": "never", "kind": "exponential", @@ -4136,14 +4096,6 @@ "extended_statistics_ok": true, "description": "Time to block before we set a single key's value in LocalStorage (ms)" }, - "LOCALDOMSTORAGE_REMOVEKEY_MS": { - "expires_in_version": "never", - "kind": "exponential", - "high": "3000", - "n_buckets": 10, - "extended_statistics_ok": true, - "description": "Time to remove a single key from LocalStorage (ms)" - }, "LOCALDOMSTORAGE_REMOVEKEY_BLOCKING_MS": { "expires_in_version": "never", "kind": "exponential", @@ -4152,14 +4104,6 @@ "extended_statistics_ok": true, "description": "Time to block before we remove a single key from LocalStorage (ms)" }, - "LOCALDOMSTORAGE_CLEAR_MS": { - "expires_in_version": "never", - "kind": "exponential", - "high": "3000", - "n_buckets": 10, - "extended_statistics_ok": true, - "description": "Time to clear LocalStorage for all domains (ms)" - }, "LOCALDOMSTORAGE_CLEAR_BLOCKING_MS": { "expires_in_version": "never", "kind": "exponential", diff --git a/toolkit/system/androidproxy/nsAndroidSystemProxySettings.cpp b/toolkit/system/androidproxy/nsAndroidSystemProxySettings.cpp index 5a98be32ce47..4b6bbcb30ce9 100644 --- a/toolkit/system/androidproxy/nsAndroidSystemProxySettings.cpp +++ b/toolkit/system/androidproxy/nsAndroidSystemProxySettings.cpp @@ -26,7 +26,7 @@ public: nsresult Init(); private: - ~nsAndroidSystemProxySettings() {}; + virtual ~nsAndroidSystemProxySettings() {} }; NS_IMPL_ISUPPORTS(nsAndroidSystemProxySettings, nsISystemProxySettings) diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 2574eeb3b440..6a78edd36960 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1687,7 +1687,41 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative, static const char kProfileProperties[] = "chrome://mozapps/locale/profile/profileSelection.properties"; -static nsresult +namespace { + +/** + * This class, instead of a raw nsresult, should be the return type of any + * function called by SelectProfile that initializes XPCOM. + */ +class ReturnAbortOnError +{ +public: + MOZ_IMPLICIT ReturnAbortOnError(nsresult aRv) + { + mRv = ConvertRv(aRv); + } + + operator nsresult() + { + return mRv; + } + +private: + inline nsresult + ConvertRv(nsresult aRv) + { + if (NS_SUCCEEDED(aRv) || aRv == NS_ERROR_LAUNCHED_CHILD_PROCESS) { + return aRv; + } + return NS_ERROR_ABORT; + } + + nsresult mRv; +}; + +} // anonymous namespace + +static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir, nsIProfileUnlocker* aUnlocker, nsINativeAppSupport* aNative, nsIProfileLock* *aResult) @@ -1857,7 +1891,7 @@ ProfileLockedDialog(nsIToolkitProfile* aProfile, nsIProfileUnlocker* aUnlocker, static const char kProfileManagerURL[] = "chrome://mozapps/content/profile/profileSelection.xul"; -static nsresult +static ReturnAbortOnError ShowProfileManager(nsIToolkitProfileService* aProfileSvc, nsINativeAppSupport* aNative) { diff --git a/uriloader/exthandler/android/nsAndroidHandlerApp.h b/uriloader/exthandler/android/nsAndroidHandlerApp.h index ad828b1137c2..bb38724638ab 100644 --- a/uriloader/exthandler/android/nsAndroidHandlerApp.h +++ b/uriloader/exthandler/android/nsAndroidHandlerApp.h @@ -15,14 +15,14 @@ public: NS_DECL_NSIHANDLERAPP NS_DECL_NSISHARINGHANDLERAPP - public: nsAndroidHandlerApp(const nsAString& aName, const nsAString& aDescription, const nsAString& aPackageName, const nsAString& aClassName, const nsACString& aMimeType, const nsAString& aAction); - virtual ~nsAndroidHandlerApp(); private: + virtual ~nsAndroidHandlerApp(); + nsString mName; nsString mDescription; nsString mPackageName; diff --git a/uriloader/exthandler/android/nsMIMEInfoAndroid.h b/uriloader/exthandler/android/nsMIMEInfoAndroid.h index 33339603131f..af732dbb52a3 100644 --- a/uriloader/exthandler/android/nsMIMEInfoAndroid.h +++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.h @@ -30,7 +30,9 @@ public: nsMIMEInfoAndroid(const nsACString& aMIMEType); -protected: +private: + ~nsMIMEInfoAndroid() {} + virtual nsresult LaunchDefaultWithFile(nsIFile* aFile); virtual nsresult LoadUriInternal(nsIURI *aURI); nsCOMPtr mHandlerApps; @@ -40,16 +42,18 @@ protected: nsHandlerInfoAction mPrefAction; nsString mDescription; nsCOMPtr mPrefApp; - + +public: class SystemChooser MOZ_FINAL : public nsIHandlerApp { public: NS_DECL_ISUPPORTS NS_DECL_NSIHANDLERAPP - SystemChooser(nsMIMEInfoAndroid* aOuter): mOuter(aOuter) {}; - + SystemChooser(nsMIMEInfoAndroid* aOuter): mOuter(aOuter) {} + private: + ~SystemChooser() {} + nsMIMEInfoAndroid* mOuter; - }; }; diff --git a/widget/android/APZCCallbackHandler.cpp b/widget/android/APZCCallbackHandler.cpp index f00fcd4c95ba..28a53a1fe5e6 100644 --- a/widget/android/APZCCallbackHandler.cpp +++ b/widget/android/APZCCallbackHandler.cpp @@ -122,7 +122,8 @@ APZCCallbackHandler::HandleDoubleTap(const CSSPoint& aPoint, int32_t aModifiers, const mozilla::layers::ScrollableLayerGuid& aGuid) { - nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", aPoint.x, aPoint.y); + CSSIntPoint point = RoundedToInt(aPoint); + nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", point.x, point.y); nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeBroadcastEvent( NS_LITERAL_CSTRING("Gesture:DoubleTap"), data)); } @@ -133,7 +134,8 @@ APZCCallbackHandler::HandleSingleTap(const CSSPoint& aPoint, const mozilla::layers::ScrollableLayerGuid& aGuid) { // FIXME Send the modifier data to Gecko for use in mouse events. - nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", aPoint.x, aPoint.y); + CSSIntPoint point = RoundedToInt(aPoint); + nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", point.x, point.y); nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeBroadcastEvent( NS_LITERAL_CSTRING("Gesture:SingleTap"), data)); } @@ -144,7 +146,8 @@ APZCCallbackHandler::HandleLongTap(const CSSPoint& aPoint, const mozilla::layers::ScrollableLayerGuid& aGuid) { // TODO send content response back to APZC - nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", aPoint.x, aPoint.y); + CSSIntPoint point = RoundedToInt(aPoint); + nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", point.x, point.y); nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeBroadcastEvent( NS_LITERAL_CSTRING("Gesture:LongPress"), data)); } diff --git a/widget/android/GfxInfo.cpp b/widget/android/GfxInfo.cpp index d94e0a2d43a6..4ab9da311ede 100644 --- a/widget/android/GfxInfo.cpp +++ b/widget/android/GfxInfo.cpp @@ -115,6 +115,10 @@ GfxInfo::GfxInfo() { } +GfxInfo::~GfxInfo() +{ +} + /* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after gfxPlatform initialization * has occurred because they depend on it for information. (See bug 591561) */ nsresult diff --git a/widget/android/GfxInfo.h b/widget/android/GfxInfo.h index 47bd64346374..0112ef4b96fd 100644 --- a/widget/android/GfxInfo.h +++ b/widget/android/GfxInfo.h @@ -24,6 +24,9 @@ namespace widget { class GfxInfo : public GfxInfoBase { +private: + ~GfxInfo(); + public: GfxInfo(); diff --git a/widget/android/nsAndroidProtocolHandler.cpp b/widget/android/nsAndroidProtocolHandler.cpp index 7c1d9357d1cc..189470ed2c31 100644 --- a/widget/android/nsAndroidProtocolHandler.cpp +++ b/widget/android/nsAndroidProtocolHandler.cpp @@ -25,11 +25,15 @@ public: mBridgeInputStream = env->NewGlobalRef(GeckoAppShell::CreateInputStream(connection)); mBridgeChannel = env->NewGlobalRef(AndroidBridge::ChannelCreate(mBridgeInputStream)); } + +private: virtual ~AndroidInputStream() { JNIEnv *env = GetJNIForThread(); env->DeleteGlobalRef(mBridgeInputStream); env->DeleteGlobalRef(mBridgeChannel); } + +public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIINPUTSTREAM diff --git a/widget/android/nsAndroidProtocolHandler.h b/widget/android/nsAndroidProtocolHandler.h index 6c9552de45a0..68af2a97df5e 100644 --- a/widget/android/nsAndroidProtocolHandler.h +++ b/widget/android/nsAndroidProtocolHandler.h @@ -29,6 +29,8 @@ public: // nsAndroidProtocolHandler methods: nsAndroidProtocolHandler() {} + +private: ~nsAndroidProtocolHandler() {} }; diff --git a/widget/android/nsAppShell.cpp b/widget/android/nsAppShell.cpp index 23bb8c9887fa..222bf3ff0a2b 100644 --- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -111,7 +111,10 @@ private: }; class WakeLockListener MOZ_FINAL : public nsIDOMMozWakeLockListener { - public: +private: + ~WakeLockListener() {} + +public: NS_DECL_ISUPPORTS; nsresult Callback(const nsAString& topic, const nsAString& state) { diff --git a/widget/android/nsClipboard.h b/widget/android/nsClipboard.h index fae02f6f63e2..17faca0c3bb7 100644 --- a/widget/android/nsClipboard.h +++ b/widget/android/nsClipboard.h @@ -10,6 +10,9 @@ class nsClipboard MOZ_FINAL : public nsIClipboard { +private: + ~nsClipboard() {} + public: NS_DECL_ISUPPORTS NS_DECL_NSICLIPBOARD diff --git a/widget/android/nsDeviceContextAndroid.h b/widget/android/nsDeviceContextAndroid.h index cac5f5eb8d95..1addb1cb84fb 100644 --- a/widget/android/nsDeviceContextAndroid.h +++ b/widget/android/nsDeviceContextAndroid.h @@ -7,6 +7,9 @@ class nsDeviceContextSpecAndroid MOZ_FINAL : public nsIDeviceContextSpec { +private: + ~nsDeviceContextSpecAndroid() {} + public: NS_DECL_ISUPPORTS diff --git a/widget/android/nsScreenManagerAndroid.h b/widget/android/nsScreenManagerAndroid.h index a07976ef7777..d7e2e1be4981 100644 --- a/widget/android/nsScreenManagerAndroid.h +++ b/widget/android/nsScreenManagerAndroid.h @@ -30,9 +30,11 @@ protected: class nsScreenManagerAndroid MOZ_FINAL : public nsIScreenManager { +private: + ~nsScreenManagerAndroid(); + public: nsScreenManagerAndroid(); - ~nsScreenManagerAndroid(); NS_DECL_ISUPPORTS NS_DECL_NSISCREENMANAGER diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 622ba0fea406..9ef305188d47 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -87,6 +87,10 @@ static StaticRefPtr gContentCreationNotifier; // are created. Currently an update for the screen size is sent. class ContentCreationNotifier MOZ_FINAL : public nsIObserver { +private: + ~ContentCreationNotifier() {} + +public: NS_DECL_ISUPPORTS NS_IMETHOD Observe(nsISupports* aSubject, diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index 3c105be2dbd2..7c80ddd29344 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -32,11 +32,13 @@ namespace mozilla { class nsWindow : public nsBaseWidget { +private: + virtual ~nsWindow(); + public: using nsBaseWidget::GetLayerManager; nsWindow(); - virtual ~nsWindow(); NS_DECL_ISUPPORTS_INHERITED diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index 4ab0aadcbfea..5434fecdeb63 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -987,17 +987,36 @@ nsNativeThemeCocoa::DrawMenuIcon(CGContextRef cgContext, const CGRect& aRect, aRect.origin.y + ceil(paddingY / 2), aIconSize.width, aIconSize.height); - NSString* state = IsDisabled(aFrame, inState) ? @"disabled" : - (CheckBooleanAttr(aFrame, nsGkAtoms::menuactive) ? @"pressed" : @"normal"); + BOOL isDisabled = IsDisabled(aFrame, inState); + BOOL isActive = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive); + + // On 10.6 and at least on 10.7.0, Apple doesn’t seem to have implemented all + // keys and values used on 10.7.5 and later. We can however draw menu icons + // on earlier OS versions by using different keys/values. + BOOL otherKeysAndValues = !nsCocoaFeatures::OnLionOrLater() || + (nsCocoaFeatures::OSXVersionMajor() == 10 && + nsCocoaFeatures::OSXVersionMinor() == 7 && + nsCocoaFeatures::OSXVersionBugFix() < 5); + + // 2 states combined with 2 different backgroundTypeKeys on earlier versions. + NSString* state = isDisabled ? @"disabled" : + (isActive && !otherKeysAndValues) ? @"pressed" : @"normal"; + NSString* backgroundTypeKey = !otherKeysAndValues ? @"kCUIBackgroundTypeMenu" : + !isDisabled && isActive ? @"backgroundTypeDark" : @"backgroundTypeLight"; + + NSMutableArray* keys = [NSMutableArray arrayWithObjects:@"backgroundTypeKey", + @"imageNameKey", @"state", @"widget", @"is.flipped", nil]; + NSMutableArray* values = [NSMutableArray arrayWithObjects: backgroundTypeKey, + aImageName, state, @"image", [NSNumber numberWithBool:YES], nil]; + + if (otherKeysAndValues) { // Earlier versions used one more key-value pair. + [keys insertObject:@"imageIsGrayscaleKey" atIndex:1]; + [values insertObject:[NSNumber numberWithBool:YES] atIndex:1]; + } CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext, - (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys: - @"kCUIBackgroundTypeMenu", @"backgroundTypeKey", - aImageName, @"imageNameKey", - state, @"state", - @"image", @"widget", - [NSNumber numberWithBool:YES], @"is.flipped", - nil], nil); + (CFDictionaryRef)[NSDictionary dictionaryWithObjects:values + forKeys:keys], nil); #if DRAW_IN_FRAME_DEBUG CGContextSetRGBFillColor(cgContext, 0.0, 0.0, 0.5, 0.25);