зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound a=merge
This commit is contained in:
Коммит
dac5eaa4c4
|
@ -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 @@
|
|||
<h2>&certerror.whatShouldIDo.heading;</h2>
|
||||
<div id="whatShouldIDoContentText">
|
||||
<p>&certerror.whatShouldIDo.content;</p>
|
||||
<p id="badStsCertExplanation">&certerror.whatShouldIDo.badStsCertExplanation;</p>
|
||||
<button id='getMeOutOfHereButton'>&certerror.getMeOutOfHere.label;</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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();
|
||||
DOMFullscreenHandler.init();
|
||||
|
|
|
@ -26,6 +26,10 @@ going to the right place. However, this site's identity can't be verified.">
|
|||
<!ENTITY certerror.whatShouldIDo.content "If you usually connect to
|
||||
this site without problems, this error could mean that someone is
|
||||
trying to impersonate the site, and you shouldn't continue.">
|
||||
<!ENTITY certerror.whatShouldIDo.badStsCertExplanation "This site uses HTTP
|
||||
Strict Transport Security (HSTS) to specify that &brandShortName; only connect
|
||||
to it securely. As a result, it is not possible to add an exception for this
|
||||
certificate.">
|
||||
<!ENTITY certerror.getMeOutOfHere.label "Get me out of here!">
|
||||
|
||||
<!ENTITY certerror.expert.heading "I Understand the Risks">
|
||||
|
|
|
@ -60,4 +60,5 @@ if CONFIG['GNU_CXX']:
|
|||
CXXFLAGS += [
|
||||
'-Wno-empty-body',
|
||||
'-Wno-type-limits',
|
||||
'-Wno-unused-local-typedefs',
|
||||
]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -15,6 +15,9 @@ namespace mobilemessage {
|
|||
|
||||
class MobileMessageDatabaseService MOZ_FINAL : public nsIMobileMessageDatabaseService
|
||||
{
|
||||
private:
|
||||
~MobileMessageDatabaseService() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMOBILEMESSAGEDATABASESERVICE
|
||||
|
|
|
@ -14,6 +14,9 @@ namespace mobilemessage {
|
|||
|
||||
class SmsService MOZ_FINAL : public nsISmsService
|
||||
{
|
||||
private:
|
||||
~SmsService() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISMSSERVICE
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -351,8 +351,6 @@ DOMStorageCache::WaitForPreload(Telemetry::ID aTelemetryID)
|
|||
nsresult
|
||||
DOMStorageCache::GetLength(const DOMStorage* aStorage, uint32_t* aRetval)
|
||||
{
|
||||
Telemetry::AutoTimer<Telemetry::LOCALDOMSTORAGE_GETLENGTH_MS> 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<Telemetry::LOCALDOMSTORAGE_GETKEY_MS> 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<nsString>& aKeys)
|
||||
{
|
||||
Telemetry::AutoTimer<Telemetry::LOCALDOMSTORAGE_GETALLKEYS_MS> 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<Telemetry::LOCALDOMSTORAGE_GETVALUE_MS> 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<Telemetry::LOCALDOMSTORAGE_SETVALUE_MS> 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<Telemetry::LOCALDOMSTORAGE_REMOVEKEY_MS> 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<Telemetry::LOCALDOMSTORAGE_CLEAR_MS> autoTimer;
|
||||
|
||||
bool refresh = false;
|
||||
if (Persist(aStorage)) {
|
||||
// We need to preload all data (know the size) before we can proceeed
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
class nsHapticFeedback MOZ_FINAL : public nsIHapticFeedback
|
||||
{
|
||||
private:
|
||||
~nsHapticFeedback() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIHAPTICFEEDBACK
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -44,6 +44,9 @@ static FT_Library gPlatformFTLibrary = nullptr;
|
|||
class FreetypeReporter MOZ_FINAL : public nsIMemoryReporter,
|
||||
public CountingAllocatorBase<FreetypeReporter>
|
||||
{
|
||||
private:
|
||||
~FreetypeReporter() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
CFBundleName = "%APP_NAME% Plugin Process";
|
||||
CFBundleName = "%APP_NAME%";
|
||||
|
|
|
@ -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
|
|
@ -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',
|
||||
|
|
|
@ -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<StorageSpace> storage_;
|
||||
js::AsmJSProfilingFrameIterator &iter() {
|
||||
js::AsmJSProfilingFrameIterator &asmJSIter() {
|
||||
JS_ASSERT(!done());
|
||||
return *reinterpret_cast<js::AsmJSProfilingFrameIterator*>(storage_.addr());
|
||||
}
|
||||
const js::AsmJSProfilingFrameIterator &iter() const {
|
||||
const js::AsmJSProfilingFrameIterator &asmJSIter() const {
|
||||
JS_ASSERT(!done());
|
||||
return *reinterpret_cast<const js::AsmJSProfilingFrameIterator*>(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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<ArrayObject>()) {
|
||||
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<JSObject *>(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<void *>(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())
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<ConstraintDataConstantProperty> T;
|
||||
constraints->add(alloc->new_<T>(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<ConstraintDataInert> T;
|
||||
constraints->add(alloc->new_<T>(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",
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -4056,10 +4056,10 @@ UpdateShapeTypeAndValue(typename ExecutionModeTraits<mode>::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()) {
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -267,6 +267,10 @@ class ForkJoinActivation : public Activation
|
|||
public:
|
||||
explicit ForkJoinActivation(JSContext *cx);
|
||||
~ForkJoinActivation();
|
||||
|
||||
bool isProfiling() const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class ForkJoinContext;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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_;
|
||||
}
|
||||
|
|
|
@ -823,7 +823,13 @@ class Shape : public gc::BarrieredCell<Shape>
|
|||
/* 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<Shape>
|
|||
: 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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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_; }
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Filters: Blur an HTML Element Using a Negative Calc Function Value</title>
|
||||
<link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
|
||||
<link rel="help" href="http://www.w3.org/TR/filter-effects-1/#funcdef-blur">
|
||||
<link rel="match" href="blur-calc-negative-ref.html">
|
||||
<meta name="assert"
|
||||
content="Given a calc() value that evaluates to a negative result, the
|
||||
CSS blur filter function should not blur an HTML element.">
|
||||
<style type="text/css">
|
||||
#target {
|
||||
background-color: #0f0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>You should see a green square.</p>
|
||||
<div id="target"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,28 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Filters: Blur an HTML Element Using a Negative Calc Function Value</title>
|
||||
<link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
|
||||
<link rel="help" href="http://www.w3.org/TR/filter-effects-1/#funcdef-blur">
|
||||
<link rel="match" href="blur-calc-negative-ref.html">
|
||||
<meta name="assert"
|
||||
content="Given a calc() value that evaluates to a negative result, the
|
||||
CSS blur filter function should not blur an HTML element.">
|
||||
<style type="text/css">
|
||||
#target {
|
||||
filter: blur(calc(-10px));
|
||||
background-color: #0f0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>You should see a green square.</p>
|
||||
<div id="target"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,23 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Filters: Blur an HTML Element Using a Calc Function Value</title>
|
||||
<link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
|
||||
<style type="text/css">
|
||||
#target {
|
||||
filter: blur(10px);
|
||||
background-color: #0f0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>You should see a blurred green square.</p>
|
||||
<div id="target"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,28 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Filters: Blur an HTML Element Using a Calc Function Value</title>
|
||||
<link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
|
||||
<link rel="help" href="http://www.w3.org/TR/filter-effects-1/#funcdef-blur">
|
||||
<link rel="match" href="blur-calc-ref.html">
|
||||
<meta name="assert"
|
||||
content="Given a calc() value that evaluates to a positive result, the
|
||||
CSS blur filter function should blur an HTML element.">
|
||||
<style type="text/css">
|
||||
#target {
|
||||
filter: blur(calc(2 * 5px));
|
||||
background-color: #0f0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>You should see a blurred green square.</p>
|
||||
<div id="target"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -15,11 +15,10 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISHELLSERVICE
|
||||
|
||||
nsShellService() {};
|
||||
nsShellService() {}
|
||||
|
||||
private:
|
||||
~nsShellService() {};
|
||||
|
||||
~nsShellService() {}
|
||||
};
|
||||
|
||||
#define nsShellService_CID \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -225,9 +225,9 @@ class TicklerTimer MOZ_FINAL : public nsITimerCallback
|
|||
mTickler = do_GetWeakReference(aTickler);
|
||||
}
|
||||
|
||||
~TicklerTimer() {};
|
||||
|
||||
private:
|
||||
~TicklerTimer() {}
|
||||
|
||||
nsWeakPtr mTickler;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ public:
|
|||
NS_DECL_NSINETWORKLINKSERVICE
|
||||
|
||||
nsAndroidNetworkLinkService();
|
||||
|
||||
private:
|
||||
virtual ~nsAndroidNetworkLinkService();
|
||||
};
|
||||
|
||||
|
|
|
@ -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<nsIFile> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
nsresult Init();
|
||||
|
||||
private:
|
||||
~nsAndroidSystemProxySettings() {};
|
||||
virtual ~nsAndroidSystemProxySettings() {}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAndroidSystemProxySettings, nsISystemProxySettings)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -30,7 +30,9 @@ public:
|
|||
|
||||
nsMIMEInfoAndroid(const nsACString& aMIMEType);
|
||||
|
||||
protected:
|
||||
private:
|
||||
~nsMIMEInfoAndroid() {}
|
||||
|
||||
virtual nsresult LaunchDefaultWithFile(nsIFile* aFile);
|
||||
virtual nsresult LoadUriInternal(nsIURI *aURI);
|
||||
nsCOMPtr<nsIMutableArray> mHandlerApps;
|
||||
|
@ -40,16 +42,18 @@ protected:
|
|||
nsHandlerInfoAction mPrefAction;
|
||||
nsString mDescription;
|
||||
nsCOMPtr<nsIHandlerApp> 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;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -24,6 +24,9 @@ namespace widget {
|
|||
|
||||
class GfxInfo : public GfxInfoBase
|
||||
{
|
||||
private:
|
||||
~GfxInfo();
|
||||
|
||||
public:
|
||||
GfxInfo();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@ public:
|
|||
|
||||
// nsAndroidProtocolHandler methods:
|
||||
nsAndroidProtocolHandler() {}
|
||||
|
||||
private:
|
||||
~nsAndroidProtocolHandler() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
|
||||
class nsClipboard MOZ_FINAL : public nsIClipboard
|
||||
{
|
||||
private:
|
||||
~nsClipboard() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICLIPBOARD
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
class nsDeviceContextSpecAndroid MOZ_FINAL : public nsIDeviceContextSpec
|
||||
{
|
||||
private:
|
||||
~nsDeviceContextSpecAndroid() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
|
|
@ -30,9 +30,11 @@ protected:
|
|||
|
||||
class nsScreenManagerAndroid MOZ_FINAL : public nsIScreenManager
|
||||
{
|
||||
private:
|
||||
~nsScreenManagerAndroid();
|
||||
|
||||
public:
|
||||
nsScreenManagerAndroid();
|
||||
~nsScreenManagerAndroid();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISCREENMANAGER
|
||||
|
|
|
@ -87,6 +87,10 @@ static StaticRefPtr<ContentCreationNotifier> 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,
|
||||
|
|
|
@ -32,11 +32,13 @@ namespace mozilla {
|
|||
class nsWindow :
|
||||
public nsBaseWidget
|
||||
{
|
||||
private:
|
||||
virtual ~nsWindow();
|
||||
|
||||
public:
|
||||
using nsBaseWidget::GetLayerManager;
|
||||
|
||||
nsWindow();
|
||||
virtual ~nsWindow();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче