From 097e11fcece3b5b790e02c3d1ff913abcd415f83 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 29 May 2015 15:46:12 -0400 Subject: [PATCH 01/85] Bug 1168207. Be a bit more careful with overflow checking in XHR. r=baku --- dom/base/nsXMLHttpRequest.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/dom/base/nsXMLHttpRequest.cpp b/dom/base/nsXMLHttpRequest.cpp index 1548a6f07bc6..2912ff4fd626 100644 --- a/dom/base/nsXMLHttpRequest.cpp +++ b/dom/base/nsXMLHttpRequest.cpp @@ -10,6 +10,7 @@ #include #endif #include "mozilla/ArrayUtils.h" +#include "mozilla/CheckedInt.h" #include "mozilla/dom/BlobSet.h" #include "mozilla/dom/File.h" #include "mozilla/dom/XMLHttpRequestUploadBinding.h" @@ -3993,26 +3994,30 @@ ArrayBufferBuilder::append(const uint8_t *aNewData, uint32_t aDataLen, { MOZ_ASSERT(!mMapPtr); + CheckedUint32 neededCapacity = mLength; + neededCapacity += aDataLen; + if (!neededCapacity.isValid()) { + return false; + } if (mLength + aDataLen > mCapacity) { - uint32_t newcap; + CheckedUint32 newcap = mCapacity; // Double while under aMaxGrowth or if not specified. if (!aMaxGrowth || mCapacity < aMaxGrowth) { - newcap = mCapacity * 2; + newcap *= 2; } else { - newcap = mCapacity + aMaxGrowth; + newcap += aMaxGrowth; } - // But make sure there's always enough to satisfy our request. - if (newcap < mLength + aDataLen) { - newcap = mLength + aDataLen; - } - - // Did we overflow? - if (newcap < mCapacity) { + if (!newcap.isValid()) { return false; } - if (!setCapacity(newcap)) { + // But make sure there's always enough to satisfy our request. + if (newcap.value() < neededCapacity.value()) { + newcap = neededCapacity; + } + + if (!setCapacity(newcap.value())) { return false; } } From 51f05cc785ed4bfbc2e6f6c3f3244a89348ca3e0 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Fri, 29 May 2015 10:40:52 -0700 Subject: [PATCH 02/85] Bug 1120487 - Implement shim before moving security checks into AsyncOpen; adding wrapper (r=sicking,sworkman) --- netwerk/base/moz.build | 2 + netwerk/base/nsISecCheckWrapChannel.idl | 24 ++++++ netwerk/base/nsSecCheckWrapChannel.cpp | 108 ++++++++++++++++++++++++ netwerk/base/nsSecCheckWrapChannel.h | 85 +++++++++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 netwerk/base/nsISecCheckWrapChannel.idl create mode 100644 netwerk/base/nsSecCheckWrapChannel.cpp create mode 100644 netwerk/base/nsSecCheckWrapChannel.h diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index 7cecb35e1e73..49d716235edd 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -91,6 +91,7 @@ XPIDL_SOURCES += [ 'nsIRequestObserverProxy.idl', 'nsIResponseHeadProvider.idl', 'nsIResumableChannel.idl', + 'nsISecCheckWrapChannel.idl', 'nsISecretDecoderRing.idl', 'nsISecureBrowserUI.idl', 'nsISecurityEventSink.idl', @@ -213,6 +214,7 @@ UNIFIED_SOURCES += [ 'nsProtocolProxyService.cpp', 'nsProxyInfo.cpp', 'nsRequestObserverProxy.cpp', + 'nsSecCheckWrapChannel.cpp', 'nsSerializationHelper.cpp', 'nsServerSocket.cpp', 'nsSimpleNestedURI.cpp', diff --git a/netwerk/base/nsISecCheckWrapChannel.idl b/netwerk/base/nsISecCheckWrapChannel.idl new file mode 100644 index 000000000000..21f4d0c290c5 --- /dev/null +++ b/netwerk/base/nsISecCheckWrapChannel.idl @@ -0,0 +1,24 @@ +/* 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 "nsISupports.idl" + +interface nsIChannel; + +/** + * nsISecCheckWrapChannel + * Describes an XPCOM component used to wrap channels for performing + * security checks. Channels wrapped inside this class can use + * this interface to query the wrapped inner channel. + */ + +[scriptable, uuid(9446c5d5-c9fb-4a6e-acf9-ca4fc666efe0)] +interface nsISecCheckWrapChannel : nsISupports +{ + /** + * Returns the wrapped channel inside this class. + */ + readonly attribute nsIChannel innerChannel; + +}; diff --git a/netwerk/base/nsSecCheckWrapChannel.cpp b/netwerk/base/nsSecCheckWrapChannel.cpp new file mode 100644 index 000000000000..09a7f6fce750 --- /dev/null +++ b/netwerk/base/nsSecCheckWrapChannel.cpp @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 "nsSecCheckWrapChannel.h" +#include "nsHttpChannel.h" +#include "nsCOMPtr.h" + +#ifdef PR_LOGGING +static PRLogModuleInfo* +GetChannelWrapperLog() +{ + static PRLogModuleInfo* gChannelWrapperPRLog; + if (!gChannelWrapperPRLog) { + gChannelWrapperPRLog = PR_NewLogModule("ChannelWrapper"); + } + return gChannelWrapperPRLog; +} +#endif + +#define CHANNELWRAPPERLOG(args) PR_LOG(GetChannelWrapperLog(), 4, args) + +NS_IMPL_ADDREF(nsSecCheckWrapChannelBase) +NS_IMPL_RELEASE(nsSecCheckWrapChannelBase) + +NS_INTERFACE_MAP_BEGIN(nsSecCheckWrapChannelBase) + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel) + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHttpChannel) + NS_INTERFACE_MAP_ENTRY(nsIRequest) + NS_INTERFACE_MAP_ENTRY(nsIChannel) + NS_INTERFACE_MAP_ENTRY(nsISecCheckWrapChannel) +NS_INTERFACE_MAP_END + +//--------------------------------------------------------- +// nsSecCheckWrapChannelBase implementation +//--------------------------------------------------------- + +nsSecCheckWrapChannelBase::nsSecCheckWrapChannelBase(nsIChannel* aChannel) + : mChannel(aChannel) + , mHttpChannel(do_QueryInterface(aChannel)) + , mHttpChannelInternal(do_QueryInterface(aChannel)) + , mRequest(do_QueryInterface(aChannel)) +{ + MOZ_ASSERT(mChannel, "can not create a channel wrapper without a channel"); +} + +nsSecCheckWrapChannelBase::~nsSecCheckWrapChannelBase() +{ +} + +//--------------------------------------------------------- +// nsISecCheckWrapChannel implementation +//--------------------------------------------------------- + +NS_IMETHODIMP +nsSecCheckWrapChannelBase::GetInnerChannel(nsIChannel **aInnerChannel) +{ + NS_IF_ADDREF(*aInnerChannel = mChannel); + return NS_OK; +} + +//--------------------------------------------------------- +// nsSecCheckWrapChannel implementation +//--------------------------------------------------------- + +nsSecCheckWrapChannel::nsSecCheckWrapChannel(nsIChannel* aChannel, + nsILoadInfo* aLoadInfo) + : nsSecCheckWrapChannelBase(aChannel) + , mLoadInfo(aLoadInfo) +{ +#ifdef PR_LOGGING + { + nsCOMPtr uri; + mChannel->GetURI(getter_AddRefs(uri)); + nsAutoCString spec; + if (uri) { + uri->GetSpec(spec); + } + CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::nsSecCheckWrapChannel [%p] (%s)",this, spec.get())); + } +#endif +} + +nsSecCheckWrapChannel::~nsSecCheckWrapChannel() +{ +} + +//--------------------------------------------------------- +// nsIChannel implementation +//--------------------------------------------------------- + +NS_IMETHODIMP +nsSecCheckWrapChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) +{ + CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::GetLoadInfo() [%p]",this)); + NS_IF_ADDREF(*aLoadInfo = mLoadInfo); + return NS_OK; +} + +NS_IMETHODIMP +nsSecCheckWrapChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) +{ + CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::SetLoadInfo() [%p]", this)); + mLoadInfo = aLoadInfo; + return NS_OK; +} diff --git a/netwerk/base/nsSecCheckWrapChannel.h b/netwerk/base/nsSecCheckWrapChannel.h new file mode 100644 index 000000000000..9ba164ca61ce --- /dev/null +++ b/netwerk/base/nsSecCheckWrapChannel.h @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +#ifndef nsSecCheckWrapChannel_h__ +#define nsSecCheckWrapChannel_h__ + +#include "nsIHttpChannel.h" +#include "nsIHttpChannelInternal.h" +#include "nsISecCheckWrapChannel.h" +#include "nsIWyciwygChannel.h" +#include "mozilla/LoadInfo.h" + +/* + * The nsSecCheckWrapChannelBase wraps channels that do *not* + * * provide a newChannel2() implementation + * * provide get/setLoadInfo functions + * + * In order to perform security checks for channels + * a) before opening the channel, and + * b) after redirects + * we are attaching a loadinfo object to every channel which + * provides information about the content-type of the channel, + * who initiated the load, etc. + * + * Addon created channels might *not* provide that loadInfo object for + * some transition time before we mark the NewChannel-API as deprecated. + * We do not want to break those addons hence we wrap such channels + * using the provided wrapper in this class. + * + * Please note that the wrapper only forwards calls for + * * nsIRequest + * * nsIChannel + * * nsIHttpChannel + * * nsIHttpChannelInternal + * + * In case any addon needs to query the inner channel this class + * provides a readonly function to query the wrapped channel. + * + */ + +class nsSecCheckWrapChannelBase : public nsIHttpChannel + , public nsIHttpChannelInternal + , public nsISecCheckWrapChannel +{ +public: + NS_FORWARD_NSIHTTPCHANNEL(mHttpChannel->) + NS_FORWARD_NSIHTTPCHANNELINTERNAL(mHttpChannelInternal->) + NS_FORWARD_NSICHANNEL(mChannel->) + NS_FORWARD_NSIREQUEST(mRequest->) + NS_DECL_NSISECCHECKWRAPCHANNEL + NS_DECL_ISUPPORTS + + explicit nsSecCheckWrapChannelBase(nsIChannel* aChannel); + +protected: + virtual ~nsSecCheckWrapChannelBase(); + + nsCOMPtr mChannel; + // We do a QI in the constructor to set the following pointers. + nsCOMPtr mHttpChannel; + nsCOMPtr mHttpChannelInternal; + nsCOMPtr mRequest; +}; + +/* We define a separate class here to make it clear that we're + * overriding Get/SetLoadInfo, rather that using the forwarded + * implementations provided by NS_FORWARD_NSICHANNEL" + */ +class nsSecCheckWrapChannel : public nsSecCheckWrapChannelBase +{ +public: + NS_IMETHOD GetLoadInfo(nsILoadInfo **aLoadInfo); + NS_IMETHOD SetLoadInfo(nsILoadInfo *aLoadInfo); + + nsSecCheckWrapChannel(nsIChannel* aChannel, nsILoadInfo* aLoadInfo); + +protected: + virtual ~nsSecCheckWrapChannel(); + + nsCOMPtr mLoadInfo; +}; + +#endif // nsSecCheckWrapChannel_h__ From 2f7f6f2cce4e3b2eb29aa86f3ff3e96e2dd35ae6 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Fri, 29 May 2015 10:41:41 -0700 Subject: [PATCH 03/85] Bug 1120487 - Implement shim before moving security checks into AsyncOpen, ioservice changes (r=sicking,sworkman) --- netwerk/base/nsIOService.cpp | 46 +++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp index 0d443024de97..692b4c97a213 100644 --- a/netwerk/base/nsIOService.cpp +++ b/netwerk/base/nsIOService.cpp @@ -22,6 +22,7 @@ #include "nsEscape.h" #include "nsNetCID.h" #include "nsCRT.h" +#include "nsSecCheckWrapChannel.h" #include "nsSimpleNestedURI.h" #include "nsNetUtil.h" #include "nsTArray.h" @@ -661,43 +662,43 @@ nsIOService::NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI, // Keep in mind that Addons can implement their own Protocolhandlers, hence // NewChannel2() might *not* be implemented. // We do not want to break those addons, therefore we first try to create a channel - // calling NewChannel2(); if that fails we fall back to creating a channel by calling - // NewChannel(); - - bool newChannel2Succeeded = true; - + // calling NewChannel2(); if that fails: + // * we fall back to creating a channel by calling NewChannel() + // * wrap the addon channel + // * and attach the loadInfo to the channel wrapper + nsCOMPtr channel; nsCOMPtr pph = do_QueryInterface(handler); if (pph) { rv = pph->NewProxiedChannel2(aURI, nullptr, aProxyFlags, aProxyURI, - aLoadInfo, result); + aLoadInfo, getter_AddRefs(channel)); // if calling NewProxiedChannel2() fails we try to fall back to // creating a new proxied channel by calling NewProxiedChannel(). if (NS_FAILED(rv)) { - newChannel2Succeeded = false; rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI, - result); + getter_AddRefs(channel)); + NS_ENSURE_SUCCESS(rv, rv); + // we have to wrap that channel + channel = new nsSecCheckWrapChannel(channel, aLoadInfo); } } else { - rv = handler->NewChannel2(aURI, aLoadInfo, result); + rv = handler->NewChannel2(aURI, aLoadInfo, getter_AddRefs(channel)); // if calling newChannel2() fails we try to fall back to // creating a new channel by calling NewChannel(). if (NS_FAILED(rv)) { - newChannel2Succeeded = false; - rv = handler->NewChannel(aURI, result); + rv = handler->NewChannel(aURI, getter_AddRefs(channel)); + NS_ENSURE_SUCCESS(rv, rv); + // we have to wrap that channel + channel = new nsSecCheckWrapChannel(channel, aLoadInfo); } } - NS_ENSURE_SUCCESS(rv, rv); - if (aLoadInfo && newChannel2Succeeded) { - // Make sure that all the individual protocolhandlers attach - // a loadInfo within it's implementation of ::newChannel2(). - // Once Bug 1087720 lands, we should remove the surrounding - // if-clause here and always assert that we indeed have a - // loadinfo on the newly created channel. - nsCOMPtr loadInfo; - (*result)->GetLoadInfo(getter_AddRefs(loadInfo)); + // Make sure that all the individual protocolhandlers attach a loadInfo. + if (aLoadInfo) { // make sure we have the same instance of loadInfo on the newly created channel + nsCOMPtr loadInfo; + channel->GetLoadInfo(getter_AddRefs(loadInfo)); + if (aLoadInfo != loadInfo) { MOZ_ASSERT(false, "newly created channel must have a loadinfo attached"); return NS_ERROR_UNEXPECTED; @@ -706,7 +707,7 @@ nsIOService::NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI, // If we're sandboxed, make sure to clear any owner the channel // might already have. if (loadInfo->GetLoadingSandboxed()) { - (*result)->SetOwner(nullptr); + channel->SetOwner(nullptr); } } @@ -718,7 +719,7 @@ nsIOService::NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI, // implement the new interface. // See bug 529041 if (!gHasWarnedUploadChannel2 && scheme.EqualsLiteral("http")) { - nsCOMPtr uploadChannel2 = do_QueryInterface(*result); + nsCOMPtr uploadChannel2 = do_QueryInterface(channel); if (!uploadChannel2) { nsCOMPtr consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID); @@ -731,6 +732,7 @@ nsIOService::NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI, } } + channel.forget(result); return NS_OK; } From 6afd924f8487cfc617ef460a1aa134b4e40eca6d Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Tue, 26 May 2015 14:02:30 -0400 Subject: [PATCH 04/85] bug 1169376 - Allow getting the OuterDocAccessible for the tab's top level document r=davidb --- accessible/atk/AccessibleWrap.cpp | 9 ++++++++- accessible/ipc/ProxyAccessible.cpp | 18 ++++++++++++++++++ accessible/ipc/ProxyAccessible.h | 3 +++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/accessible/atk/AccessibleWrap.cpp b/accessible/atk/AccessibleWrap.cpp index 84e9d0c0802e..e52462ab7c37 100644 --- a/accessible/atk/AccessibleWrap.cpp +++ b/accessible/atk/AccessibleWrap.cpp @@ -800,7 +800,11 @@ getParentCB(AtkObject *aAtkObj) atkParent = parent ? AccessibleWrap::GetAtkObject(parent) : nullptr; } else if (ProxyAccessible* proxy = GetProxy(aAtkObj)) { ProxyAccessible* parent = proxy->Parent(); - atkParent = parent ? GetWrapperFor(parent) : nullptr; + if (parent) + atkParent = GetWrapperFor(parent); + + // Otherwise this should be the proxy for the tab's top level document. + atkParent = AccessibleWrap::GetAtkObject(proxy->OuterDocOfRemoteBrowser()); } if (atkParent) @@ -859,6 +863,9 @@ getIndexInParentCB(AtkObject* aAtkObj) if (ProxyAccessible* parent = proxy->Parent()) return parent->IndexOfEmbeddedChild(proxy); + if (proxy->OuterDocOfRemoteBrowser()) + return 0; + return -1; } diff --git a/accessible/ipc/ProxyAccessible.cpp b/accessible/ipc/ProxyAccessible.cpp index 877536601daf..6a16197a652f 100644 --- a/accessible/ipc/ProxyAccessible.cpp +++ b/accessible/ipc/ProxyAccessible.cpp @@ -6,6 +6,10 @@ #include "ProxyAccessible.h" #include "DocAccessibleParent.h" +#include "DocAccessible.h" +#include "mozilla/a11y/DocManager.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/TabParent.h" #include "mozilla/unused.h" #include "mozilla/a11y/Platform.h" #include "RelationType.h" @@ -963,5 +967,19 @@ ProxyAccessible::URLDocTypeMimeType(nsString& aURL, nsString& aDocType, unused << mDoc->SendURLDocTypeMimeType(mID, &aURL, &aDocType, &aMimeType); } +Accessible* +ProxyAccessible::OuterDocOfRemoteBrowser() const +{ + auto tab = static_cast(mDoc->Manager()); + dom::Element* frame = tab->GetOwnerElement(); + NS_ASSERTION(frame, "why isn't the tab in a frame!"); + if (!frame) + return nullptr; + + DocAccessible* chromeDoc = GetExistingDocAccessible(frame->OwnerDoc()); + NS_ASSERTION(chromeDoc, "accessible tab in not accessible chromeDocument"); + + return chromeDoc ? chromeDoc->GetAccessible(frame) : nullptr; +} } } diff --git a/accessible/ipc/ProxyAccessible.h b/accessible/ipc/ProxyAccessible.h index d53e48cbcfdd..e36c113fe043 100644 --- a/accessible/ipc/ProxyAccessible.h +++ b/accessible/ipc/ProxyAccessible.h @@ -18,6 +18,7 @@ namespace mozilla { namespace a11y { +class Accessible; class Attribute; class DocAccessibleParent; enum class RelationType; @@ -65,6 +66,8 @@ public: */ ProxyAccessible* Parent() const { return mParent; } + Accessible* OuterDocOfRemoteBrowser() const; + /** * Get the role of the accessible we're proxying. */ From 56337113ae2f84f37be8d71919faf84ae90d6099 Mon Sep 17 00:00:00 2001 From: Lorien Hu Date: Fri, 29 May 2015 11:41:54 -0400 Subject: [PATCH 05/85] bug 1169408 - Merge mozButtonAccessible and mozPopupButtonAccessible r=surkov --- accessible/mac/AccessibleWrap.h | 5 +- accessible/mac/AccessibleWrap.mm | 7 +- accessible/mac/mozActionElements.h | 7 +- accessible/mac/mozActionElements.mm | 129 ++++++++-------------------- 4 files changed, 40 insertions(+), 108 deletions(-) diff --git a/accessible/mac/AccessibleWrap.h b/accessible/mac/AccessibleWrap.h index 7871947f7c71..a62774d931ea 100644 --- a/accessible/mac/AccessibleWrap.h +++ b/accessible/mac/AccessibleWrap.h @@ -59,10 +59,7 @@ public: // construction, destruction * for it. */ bool IsIgnored(); - - inline bool HasPopup () - { return (NativeState() & mozilla::a11y::states::HASPOPUP); } - + /** * Returns this accessible's all children, adhering to "flat" accessibles by * not returning their children. diff --git a/accessible/mac/AccessibleWrap.mm b/accessible/mac/AccessibleWrap.mm index 16a38d7f18f4..9768b615e522 100644 --- a/accessible/mac/AccessibleWrap.mm +++ b/accessible/mac/AccessibleWrap.mm @@ -61,13 +61,13 @@ AccessibleWrap::GetNativeType () roles::Role role = Role(); switch (role) { + case roles::COMBOBOX: case roles::PUSHBUTTON: case roles::SPLITBUTTON: case roles::TOGGLE_BUTTON: { // if this button may show a popup, let's make it of the popupbutton type. - return HasPopup() ? [mozPopupButtonAccessible class] : - [mozButtonAccessible class]; + return [mozButtonAccessible class]; } case roles::PAGETAB: @@ -96,9 +96,6 @@ AccessibleWrap::GetNativeType () case roles::LINK: return [mozLinkAccessible class]; - case roles::COMBOBOX: - return [mozPopupButtonAccessible class]; - default: return [mozAccessible class]; } diff --git a/accessible/mac/mozActionElements.h b/accessible/mac/mozActionElements.h index d3769bbc7e40..a325921eb84f 100644 --- a/accessible/mac/mozActionElements.h +++ b/accessible/mac/mozActionElements.h @@ -9,6 +9,9 @@ /* Simple subclasses for things like checkboxes, buttons, etc. */ @interface mozButtonAccessible : mozAccessible + { + } +- (BOOL)hasPopup; - (void)click; - (BOOL)isTab; @end @@ -18,10 +21,6 @@ - (int)isChecked; @end -/* Used for buttons that may pop up a menu. */ -@interface mozPopupButtonAccessible : mozButtonAccessible -@end - /* Class for tabs - not individual tabs */ @interface mozTabsAccessible : mozAccessible { diff --git a/accessible/mac/mozActionElements.mm b/accessible/mac/mozActionElements.mm index b5593b62229e..98a15330a350 100644 --- a/accessible/mac/mozActionElements.mm +++ b/accessible/mac/mozActionElements.mm @@ -42,6 +42,7 @@ enum CheckboxValue { NSAccessibilityEnabledAttribute, // required NSAccessibilityFocusedAttribute, // required NSAccessibilityTitleAttribute, // required + NSAccessibilityChildrenAttribute, NSAccessibilityDescriptionAttribute, #if DEBUG @"AXMozDescription", @@ -57,15 +58,19 @@ enum CheckboxValue { { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; - if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) + if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { + if ([self hasPopup]) + return [self children]; return nil; + } + if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) { if ([self isTab]) return utils::LocalizedString(NS_LITERAL_STRING("tab")); - + return NSAccessibilityRoleDescription([self role], nil); } - + return [super accessibilityAttributeValue:attribute]; NS_OBJC_END_TRY_ABORT_BLOCK_NIL; @@ -80,36 +85,49 @@ enum CheckboxValue { { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; - if ([self isEnabled]) + if ([self isEnabled]) { + if ([self hasPopup]) + return [NSArray arrayWithObjects:NSAccessibilityPressAction, + NSAccessibilityShowMenuAction, + nil]; return [NSArray arrayWithObject:NSAccessibilityPressAction]; - + } return nil; NS_OBJC_END_TRY_ABORT_BLOCK_NIL; } -- (NSString*)accessibilityActionDescription:(NSString*)action +- (NSString*)accessibilityActionDescription:(NSString*)action { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; if ([action isEqualToString:NSAccessibilityPressAction]) { if ([self isTab]) return utils::LocalizedString(NS_LITERAL_STRING("switch")); - + return @"press button"; // XXX: localize this later? } - + + if ([self hasPopup]) { + if ([action isEqualToString:NSAccessibilityShowMenuAction]) + return @"show menu"; + } + return nil; NS_OBJC_END_TRY_ABORT_BLOCK_NIL; } -- (void)accessibilityPerformAction:(NSString*)action +- (void)accessibilityPerformAction:(NSString*)action { NS_OBJC_BEGIN_TRY_ABORT_BLOCK; - if ([action isEqualToString:NSAccessibilityPressAction]) + if ([self isEnabled] && [action isEqualToString:NSAccessibilityPressAction]) { + // TODO: this should bring up the menu, but currently doesn't. + // once msaa and atk have merged better, they will implement + // the action needed to show the menu. [self click]; + } NS_OBJC_END_TRY_ABORT_BLOCK; } @@ -127,6 +145,12 @@ enum CheckboxValue { return (accWrap && (accWrap->Role() == roles::PAGETAB)); } +- (BOOL)hasPopup +{ + AccessibleWrap* accWrap = [self getGeckoAccessible]; + return accWrap && (accWrap->NativeState() & mozilla::a11y::states::HASPOPUP); +} + @end @implementation mozCheckboxAccessible @@ -170,91 +194,6 @@ enum CheckboxValue { @end -@implementation mozPopupButtonAccessible - -- (NSArray *)accessibilityAttributeNames -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; - - static NSArray *attributes = nil; - - if (!attributes) { - attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required - NSAccessibilityPositionAttribute, // required - NSAccessibilityRoleAttribute, // required - NSAccessibilitySizeAttribute, // required - NSAccessibilityWindowAttribute, // required - NSAccessibilityTopLevelUIElementAttribute, // required - NSAccessibilityHelpAttribute, - NSAccessibilityEnabledAttribute, // required - NSAccessibilityFocusedAttribute, // required - NSAccessibilityTitleAttribute, // required for popupmenus, and for menubuttons with a title - NSAccessibilityChildrenAttribute, // required - NSAccessibilityDescriptionAttribute, // required if it has no title attr -#if DEBUG - @"AXMozDescription", -#endif - nil]; - } - return attributes; - - NS_OBJC_END_TRY_ABORT_BLOCK_NIL; -} - -- (id)accessibilityAttributeValue:(NSString *)attribute -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; - - if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { - return [super children]; - } - return [super accessibilityAttributeValue:attribute]; - - NS_OBJC_END_TRY_ABORT_BLOCK_NIL; -} - -- (NSArray *)accessibilityActionNames -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; - - if ([self isEnabled]) { - return [NSArray arrayWithObjects:NSAccessibilityPressAction, - NSAccessibilityShowMenuAction, - nil]; - } - return nil; - - NS_OBJC_END_TRY_ABORT_BLOCK_NIL; -} - -- (NSString *)accessibilityActionDescription:(NSString *)action -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; - - if ([action isEqualToString:NSAccessibilityShowMenuAction]) - return @"show menu"; - return [super accessibilityActionDescription:action]; - - NS_OBJC_END_TRY_ABORT_BLOCK_NIL; -} - -- (void)accessibilityPerformAction:(NSString *)action -{ - NS_OBJC_BEGIN_TRY_ABORT_BLOCK; - - // both the ShowMenu and Click action do the same thing. - if ([self isEnabled]) { - // TODO: this should bring up the menu, but currently doesn't. - // once msaa and atk have merged better, they will implement - // the action needed to show the menu. - [super click]; - } - - NS_OBJC_END_TRY_ABORT_BLOCK; -} - -@end - @implementation mozTabsAccessible - (void)dealloc From 3d8a360681c6d001b7a93e612f399681ac5138f4 Mon Sep 17 00:00:00 2001 From: Lorien Hu Date: Fri, 29 May 2015 13:42:23 -0400 Subject: [PATCH 06/85] bug 1168932 - Implement ProxyCreated and ProxyDestroyed to update mozAccessibles r=tbsaunde --- accessible/mac/AccessibleWrap.h | 2 + accessible/mac/AccessibleWrap.mm | 99 ++++++++++++++++++-------------- accessible/mac/Platform.mm | 15 ++++- accessible/mac/moz.build | 1 + accessible/mac/mozAccessible.h | 9 ++- accessible/mac/mozAccessible.mm | 20 +++++-- 6 files changed, 93 insertions(+), 53 deletions(-) diff --git a/accessible/mac/AccessibleWrap.h b/accessible/mac/AccessibleWrap.h index a62774d931ea..3a8ab84a0a36 100644 --- a/accessible/mac/AccessibleWrap.h +++ b/accessible/mac/AccessibleWrap.h @@ -105,6 +105,8 @@ private: bool mNativeInited; }; +Class GetTypeFromRole(roles::Role aRole); + } // namespace a11y } // namespace mozilla diff --git a/accessible/mac/AccessibleWrap.mm b/accessible/mac/AccessibleWrap.mm index 9768b615e522..10fded7ed969 100644 --- a/accessible/mac/AccessibleWrap.mm +++ b/accessible/mac/AccessibleWrap.mm @@ -15,6 +15,7 @@ #import "mozHTMLAccessible.h" #import "mozTextAccessible.h" +using namespace mozilla; using namespace mozilla::a11y; AccessibleWrap:: @@ -33,8 +34,10 @@ AccessibleWrap::GetNativeObject() { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; - if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat()) - mNativeObject = [[GetNativeType() alloc] initWithAccessible:this]; + if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat()) { + uintptr_t accWrap = reinterpret_cast(this); + mNativeObject = [[GetNativeType() alloc] initWithAccessible:accWrap]; + } mNativeInited = true; @@ -59,48 +62,7 @@ AccessibleWrap::GetNativeType () if (IsXULTabpanels()) return [mozPaneAccessible class]; - roles::Role role = Role(); - switch (role) { - case roles::COMBOBOX: - case roles::PUSHBUTTON: - case roles::SPLITBUTTON: - case roles::TOGGLE_BUTTON: - { - // if this button may show a popup, let's make it of the popupbutton type. - return [mozButtonAccessible class]; - } - - case roles::PAGETAB: - return [mozButtonAccessible class]; - - case roles::CHECKBUTTON: - return [mozCheckboxAccessible class]; - - case roles::HEADING: - return [mozHeadingAccessible class]; - - case roles::PAGETABLIST: - return [mozTabsAccessible class]; - - case roles::ENTRY: - case roles::STATICTEXT: - case roles::CAPTION: - case roles::ACCEL_LABEL: - case roles::PASSWORD_TEXT: - // normal textfield (static or editable) - return [mozTextAccessible class]; - - case roles::TEXT_LEAF: - return [mozTextLeafAccessible class]; - - case roles::LINK: - return [mozLinkAccessible class]; - - default: - return [mozAccessible class]; - } - - return nil; + return GetTypeFromRole(Role()); NS_OBJC_END_TRY_ABORT_BLOCK_NIL; } @@ -271,3 +233,52 @@ AccessibleWrap::AncestorIsFlat() // no parent was flat return false; } + +Class +a11y::GetTypeFromRole(roles::Role aRole) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; + + switch (aRole) { + case roles::COMBOBOX: + case roles::PUSHBUTTON: + case roles::SPLITBUTTON: + case roles::TOGGLE_BUTTON: + { + return [mozButtonAccessible class]; + } + + case roles::PAGETAB: + return [mozButtonAccessible class]; + + case roles::CHECKBUTTON: + return [mozCheckboxAccessible class]; + + case roles::HEADING: + return [mozHeadingAccessible class]; + + case roles::PAGETABLIST: + return [mozTabsAccessible class]; + + case roles::ENTRY: + case roles::STATICTEXT: + case roles::CAPTION: + case roles::ACCEL_LABEL: + case roles::PASSWORD_TEXT: + // normal textfield (static or editable) + return [mozTextAccessible class]; + + case roles::TEXT_LEAF: + return [mozTextLeafAccessible class]; + + case roles::LINK: + return [mozLinkAccessible class]; + + default: + return [mozAccessible class]; + } + + return nil; + + NS_OBJC_END_TRY_ABORT_BLOCK_NIL; +} diff --git a/accessible/mac/Platform.mm b/accessible/mac/Platform.mm index 8503159818c4..8c8423dd88e4 100644 --- a/accessible/mac/Platform.mm +++ b/accessible/mac/Platform.mm @@ -7,6 +7,7 @@ #import #include "Platform.h" +#include "ProxyAccessible.h" #include "nsAppShell.h" @@ -34,13 +35,23 @@ PlatformShutdown() } void -ProxyCreated(ProxyAccessible*, uint32_t) +ProxyCreated(ProxyAccessible* aProxy, uint32_t) { + // Pass in dummy state for now as retrieving proxy state requires IPC. + Class type = GetTypeFromRole(aProxy->Role()); + uintptr_t accWrap = reinterpret_cast(aProxy) | IS_PROXY; + mozAccessible* mozWrapper = [[type alloc] initWithAccessible:accWrap]; + aProxy->SetWrapper(reinterpret_cast(mozWrapper)); } void -ProxyDestroyed(ProxyAccessible*) +ProxyDestroyed(ProxyAccessible* aProxy) { + mozAccessible* wrapper = + reinterpret_cast(aProxy->GetWrapper()); + [wrapper expire]; + [wrapper release]; + aProxy->SetWrapper(0); } void diff --git a/accessible/mac/moz.build b/accessible/mac/moz.build index d5c6dce1ac22..2e582cad9762 100644 --- a/accessible/mac/moz.build +++ b/accessible/mac/moz.build @@ -30,6 +30,7 @@ LOCAL_INCLUDES += [ '/accessible/base', '/accessible/generic', '/accessible/html', + '/accessible/ipc', '/accessible/xul', '/layout/generic', '/layout/xul', diff --git a/accessible/mac/mozAccessible.h b/accessible/mac/mozAccessible.h index e24bde0fb7ba..b3989f60b163 100644 --- a/accessible/mac/mozAccessible.h +++ b/accessible/mac/mozAccessible.h @@ -57,11 +57,14 @@ static const uintptr_t IS_PROXY = 1; mozilla::a11y::role mRole; } -// return the Accessible for this mozAccessible. -- (mozilla::a11y::AccessibleWrap*) getGeckoAccessible; +// return the Accessible for this mozAccessible if it exists. +- (mozilla::a11y::AccessibleWrap*)getGeckoAccessible; + +// return the ProxyAccessible for this mozAccessible if it exists. +- (mozilla::a11y::ProxyAccessible*)getProxyAccessible; // inits with the gecko owner. -- (id)initWithAccessible:(mozilla::a11y::AccessibleWrap*)geckoParent; +- (id)initWithAccessible:(uintptr_t)aGeckoObj; // our accessible parent (AXParent) - (id )parent; diff --git a/accessible/mac/mozAccessible.mm b/accessible/mac/mozAccessible.mm index a6391faf0987..7b0632199369 100644 --- a/accessible/mac/mozAccessible.mm +++ b/accessible/mac/mozAccessible.mm @@ -60,15 +60,18 @@ GetClosestInterestingAccessible(id anObject) @implementation mozAccessible -- (id)initWithAccessible:(AccessibleWrap*)geckoAccessible +- (id)initWithAccessible:(uintptr_t)aGeckoAccessible { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; if ((self = [super init])) { - mGeckoAccessible = reinterpret_cast(geckoAccessible); - mRole = geckoAccessible->Role(); + mGeckoAccessible = aGeckoAccessible; + if (aGeckoAccessible & IS_PROXY) + mRole = [self getProxyAccessible]->Role(); + else + mRole = [self getGeckoAccessible]->Role(); } - + return self; NS_OBJC_END_TRY_ABORT_BLOCK_NIL; @@ -92,6 +95,15 @@ GetClosestInterestingAccessible(id anObject) return reinterpret_cast(mGeckoAccessible); } + +- (mozilla::a11y::ProxyAccessible*)getProxyAccessible +{ + // Check if mGeckoAccessible points at a proxy + if (!(mGeckoAccessible & IS_PROXY)) + return nil; + + return reinterpret_cast(mGeckoAccessible & ~IS_PROXY); +} #pragma mark - From 601518ec18e780b9e56e65b23fcfc1c1ec92557f Mon Sep 17 00:00:00 2001 From: Andrew Halberstadt Date: Fri, 29 May 2015 14:01:25 -0400 Subject: [PATCH 07/85] Bug 1169714 - Add requests to mach bootstrap SEARCH_PATH, r=jgriffin --HG-- extra : rebase_source : 7936ffa21f1429338566c2371e8683ef8b0367fc --- build/mach_bootstrap.py | 1 + 1 file changed, 1 insertion(+) diff --git a/build/mach_bootstrap.py b/build/mach_bootstrap.py index b2ed23e7515d..c57530d07138 100644 --- a/build/mach_bootstrap.py +++ b/build/mach_bootstrap.py @@ -37,6 +37,7 @@ SEARCH_PATHS = [ 'python/which', 'python/pystache', 'python/pyyaml/lib', + 'python/requests', 'build', 'build/pymake', 'config', From 7aa80fb5294482eb09b950b4366b5a0e1aad32b1 Mon Sep 17 00:00:00 2001 From: Andrew Halberstadt Date: Tue, 5 May 2015 16:41:59 -0400 Subject: [PATCH 08/85] Bug 1164597 - Consolidate all mochitest mach commands into single |mach mochitest|, r=chmanchester --HG-- extra : rebase_source : 0a0d8a454df10ae9df9678c98e11b5eaf8249f51 --- python/mach/mach/dispatcher.py | 9 +- python/mozbuild/mozbuild/testing.py | 4 + testing/mochitest/mach_commands.py | 717 ++++++++++++++-------------- testing/mochitest/runtestsb2g.py | 27 +- 4 files changed, 375 insertions(+), 382 deletions(-) diff --git a/python/mach/mach/dispatcher.py b/python/mach/mach/dispatcher.py index 076ac1f902f8..03206ea58a98 100644 --- a/python/mach/mach/dispatcher.py +++ b/python/mach/mach/dispatcher.py @@ -109,14 +109,17 @@ class CommandAction(argparse.Action): # Command suggestion if command not in self._mach_registrar.command_handlers: + # Make sure we don't suggest any deprecated commands. + names = [h.name for h in self._mach_registrar.command_handlers.values() + if h.cls.__name__ == 'DeprecatedCommands'] # We first try to look for a valid command that is very similar to the given command. - suggested_commands = difflib.get_close_matches(command, self._mach_registrar.command_handlers.keys(), cutoff=0.8) + suggested_commands = difflib.get_close_matches(command, names, cutoff=0.8) # If we find more than one matching command, or no command at all, we give command suggestions instead # (with a lower matching threshold). All commands that start with the given command (for instance: 'mochitest-plain', # 'mochitest-chrome', etc. for 'mochitest-') are also included. if len(suggested_commands) != 1: - suggested_commands = set(difflib.get_close_matches(command, self._mach_registrar.command_handlers.keys(), cutoff=0.5)) - suggested_commands |= {cmd for cmd in self._mach_registrar.command_handlers if cmd.startswith(command)} + suggested_commands = set(difflib.get_close_matches(command, names, cutoff=0.5)) + suggested_commands |= {cmd for cmd in names if cmd.startswith(command)} raise UnknownCommandError(command, 'run', suggested_commands) sys.stderr.write("We're assuming the '%s' command is '%s' and we're executing it for you.\n\n" % (command, suggested_commands[0])) command = suggested_commands[0] diff --git a/python/mozbuild/mozbuild/testing.py b/python/mozbuild/mozbuild/testing.py index 01b893732dfa..f625ec93426c 100644 --- a/python/mozbuild/mozbuild/testing.py +++ b/python/mozbuild/mozbuild/testing.py @@ -163,6 +163,10 @@ class TestResolver(MozbuildObject): 'mochitest', 'chrome'), 'mochitest': os.path.join(self.topobjdir, '_tests', 'testing', 'mochitest', 'tests'), + 'webapprt-chrome': os.path.join(self.topobjdir, '_tests', 'testing', + 'mochitest', 'webapprtChrome'), + 'webapprt-content': os.path.join(self.topobjdir, '_tests', 'testing', + 'mochitest', 'webapprtContent'), 'xpcshell': os.path.join(self.topobjdir, '_tests', 'xpcshell'), } diff --git a/testing/mochitest/mach_commands.py b/testing/mochitest/mach_commands.py index 741dd5436ef2..9890a727293b 100644 --- a/testing/mochitest/mach_commands.py +++ b/testing/mochitest/mach_commands.py @@ -5,8 +5,9 @@ from __future__ import unicode_literals from argparse import Namespace +from collections import defaultdict +from itertools import chain import logging -import mozpack.path as mozpath import os import shutil import sys @@ -24,20 +25,21 @@ from mach.decorators import ( CommandProvider, Command, ) +import mozpack.path as mozpath here = os.path.abspath(os.path.dirname(__file__)) ADB_NOT_FOUND = ''' -The %s command requires the adb binary to be on your path. +The mochitest command requires the adb binary to be on your path. If you have a B2G build, this can be found in -'%s/out/host//bin'. +'{}/out/host//bin'. '''.lstrip() GAIA_PROFILE_NOT_FOUND = ''' -The %s command requires a non-debug gaia profile. Either pass in --profile, -or set the GAIA_PROFILE environment variable. +The mochitest command requires a non-debug gaia profile. Either +pass in --profile, or set the GAIA_PROFILE environment variable. If you do not have a non-debug gaia profile, you can build one: $ git clone https://github.com/mozilla-b2g/gaia @@ -48,8 +50,8 @@ The profile should be generated in a directory called 'profile'. '''.lstrip() GAIA_PROFILE_IS_DEBUG = ''' -The %s command requires a non-debug gaia profile. The specified profile, -%s, is a debug profile. +The mochitest command requires a non-debug gaia profile. The +specified profile, {}, is a debug profile. If you do not have a non-debug gaia profile, you can build one: $ git clone https://github.com/mozilla-b2g/gaia @@ -60,26 +62,114 @@ The profile should be generated in a directory called 'profile'. '''.lstrip() ENG_BUILD_REQUIRED = ''' -The %s command requires an engineering build. It may be the case that +The mochitest command requires an engineering build. It may be the case that VARIANT=user or PRODUCTION=1 were set. Try re-building with VARIANT=eng: $ VARIANT=eng ./build.sh There should be an app called 'test-container.gaiamobile.org' located in -%s. +{}. '''.lstrip() -# Maps test flavors to mochitest suite type. -FLAVORS = { - 'mochitest': 'plain', - 'chrome': 'chrome', - 'browser-chrome': 'browser', - 'jetpack-package': 'jetpack-package', - 'jetpack-addon': 'jetpack-addon', - 'a11y': 'a11y', - 'webapprt-chrome': 'webapprt-chrome', +SUPPORTED_TESTS_NOT_FOUND = ''' +The mochitest command could not find any supported tests to run! The +following flavors and subsuites were found, but are either not supported on +{} builds, or were excluded on the command line: + +{} + +Double check the command line you used, and make sure you are running in +context of the proper build. To switch build contexts, either run |mach| +from the appropriate objdir, or export the correct mozconfig: + + $ export MOZCONFIG=path/to/mozconfig +'''.lstrip() + +TESTS_NOT_FOUND = ''' +The mochitest command could not find any mochitests under the following +test path(s): + +{} + +Please check spelling and make sure there are mochitests living there. +'''.lstrip() + +NOW_RUNNING = ''' +###### +### Now running mochitest-{}. +###### +''' + + +# Maps test flavors to data needed to run them +ALL_FLAVORS = { + 'mochitest': { + 'suite': 'plain', + 'aliases': ('plain', 'mochitest'), + 'enabled_apps': ('firefox', 'b2g', 'android', 'mulet', 'b2g_desktop'), + }, + 'chrome': { + 'suite': 'chrome', + 'aliases': ('chrome', 'mochitest-chrome'), + 'enabled_apps': ('firefox', 'mulet', 'b2g', 'android'), + 'extra_args': { + 'chrome': True, + } + }, + 'browser-chrome': { + 'suite': 'browser', + 'aliases': ('browser', 'browser-chrome', 'mochitest-browser-chrome', 'bc'), + 'enabled_apps': ('firefox',), + 'extra_args': { + 'browserChrome': True, + } + }, + 'jetpack-package': { + 'suite': 'jetpack-package', + 'aliases': ('jetpack-package', 'mochitest-jetpack-package', 'jpp'), + 'enabled_apps': ('firefox',), + 'extra_args': { + 'jetpackPackage': True, + } + }, + 'jetpack-addon': { + 'suite': 'jetpack-addon', + 'aliases': ('jetpack-addon', 'mochitest-jetpack-addon', 'jpa'), + 'enabled_apps': ('firefox',), + 'extra_args': { + 'jetpackAddon': True, + } + }, + 'a11y': { + 'suite': 'a11y', + 'aliases': ('a11y', 'mochitest-a11y', 'accessibility'), + 'enabled_apps': ('firefox',), + 'extra_args': { + 'a11y': True, + } + }, + 'webapprt-chrome': { + 'suite': 'webapprt-chrome', + 'aliases': ('webapprt-chrome', 'mochitest-webapprt-chrome'), + 'enabled_apps': ('firefox',), + 'extra_args': { + 'webapprtChrome': True, + } + }, + 'webapprt-content': { + 'suite': 'webapprt-content', + 'aliases': ('webapprt-content', 'mochitest-webapprt-content'), + 'enabled_apps': ('firefox',), + 'extra_args': { + 'webapprtContent': True, + } + }, } +SUPPORTED_APPS = ['firefox', 'b2g', 'android', 'mulet', 'b2g_desktop'] +SUPPORTED_FLAVORS = list(chain.from_iterable([f['aliases'] for f in ALL_FLAVORS.values()])) +CANONICAL_FLAVORS = sorted([f['aliases'][0] for f in ALL_FLAVORS.values()]) + class MochitestRunner(MozbuildObject): @@ -142,19 +232,37 @@ class MochitestRunner(MozbuildObject): 'mochitest') self.bin_dir = os.path.join(self.topobjdir, 'dist', 'bin') - def run_b2g_test(self, test_paths=None, **kwargs): - """Runs a b2g mochitest. + def resolve_tests(self, test_paths, test_objects=None, cwd=None): + if test_objects: + return test_objects - test_paths is an enumerable of paths to tests. It can be a relative path - from the top source directory, an absolute filename, or a directory - containing test files. - """ - # Need to call relpath before os.chdir() below. - test_path = '' - if test_paths: - if len(test_paths) > 1: - print('Warning: Only the first test path will be used.') - test_path = self._wrap_path_argument(test_paths[0]).relpath() + # Ensure test paths are relative to topobjdir or topsrcdir. + test_paths = test_paths or [] + test_paths = [self._wrap_path_argument(tp).relpath() for tp in test_paths] + + from mozbuild.testing import TestResolver + resolver = self._spawn(TestResolver) + tests = list(resolver.resolve_tests(paths=test_paths, cwd=cwd)) + return tests + + def run_b2g_test(self, context, tests=None, suite='mochitest', **kwargs): + """Runs a b2g mochitest.""" + if kwargs.get('desktop'): + kwargs['profile'] = kwargs.get('profile') or os.environ.get('GAIA_PROFILE') + if not kwargs['profile'] or not os.path.isdir(kwargs['profile']): + print(GAIA_PROFILE_NOT_FOUND) + sys.exit(1) + + if os.path.isfile(os.path.join(kwargs['profile'], 'extensions', + 'httpd@gaiamobile.org')): + print(GAIA_PROFILE_IS_DEBUG.format(kwargs['profile'])) + sys.exit(1) + elif context.target_out: + host_webapps_dir = os.path.join(context.target_out, 'data', 'local', 'webapps') + if not os.path.isdir(os.path.join( + host_webapps_dir, 'test-container.gaiamobile.org')): + print(ENG_BUILD_REQUIRED.format(host_webapps_dir)) + sys.exit(1) # TODO without os.chdir, chained imports fail below os.chdir(self.mochitest_dir) @@ -174,23 +282,10 @@ class MochitestRunner(MozbuildObject): options = Namespace(**kwargs) - if test_path: - if options.chrome: - test_root_file = mozpath.join( - self.mochitest_dir, - 'chrome', - test_path) - else: - test_root_file = mozpath.join( - self.mochitest_dir, - 'tests', - test_path) - if not os.path.exists(test_root_file): - print( - 'Specified test path does not exist: %s' % - test_root_file) - return 1 - options.testPath = test_path + from manifestparser import TestManifest + manifest = TestManifest() + manifest.tests.extend(tests) + options.manifestFile = manifest if options.desktop: return mochitest.run_desktop_mochitests(options) @@ -199,26 +294,18 @@ class MochitestRunner(MozbuildObject): which.which('adb') except which.WhichError: # TODO Find adb automatically if it isn't on the path - print(ADB_NOT_FOUND % ('mochitest-remote', options.b2gPath)) + print(ADB_NOT_FOUND.format(options.b2gPath)) return 1 return mochitest.run_remote_mochitests(options) - def run_desktop_test(self, context, suite=None, test_paths=None, **kwargs): + def run_desktop_test(self, context, tests=None, suite=None, **kwargs): """Runs a mochitest. suite is the type of mochitest to run. It can be one of ('plain', - 'chrome', 'browser', 'metro', 'a11y', 'jetpack-package', 'jetpack-addon'). - - test_paths are path to tests. They can be a relative path from the - top source directory, an absolute filename, or a directory containing - test files. + 'chrome', 'browser', 'a11y', 'jetpack-package', 'jetpack-addon', + 'webapprt-chrome', 'webapprt-content'). """ - # Make absolute paths relative before calling os.chdir() below. - if test_paths: - test_paths = [self._wrap_path_argument( - p).relpath() if os.path.isabs(p) else p for p in test_paths] - # runtests.py is ambiguous, so we load the file/module manually. if 'mochitest' not in sys.modules: import imp @@ -228,8 +315,6 @@ class MochitestRunner(MozbuildObject): ('.py', 'r', imp.PY_SOURCE)) import mochitest - from manifestparser import TestManifest - from mozbuild.testing import TestResolver # This is required to make other components happy. Sad, isn't it? os.chdir(self.topobjdir) @@ -243,64 +328,24 @@ class MochitestRunner(MozbuildObject): options = Namespace(**kwargs) - flavor = suite - - if suite == 'plain': - # Don't need additional options for plain. - flavor = 'mochitest' - elif suite == 'chrome': - options.chrome = True - elif suite == 'browser': - options.browserChrome = True - flavor = 'browser-chrome' - elif suite == 'devtools': - options.browserChrome = True - options.subsuite = 'devtools' - elif suite == 'jetpack-package': - options.jetpackPackage = True - elif suite == 'jetpack-addon': - options.jetpackAddon = True - elif suite == 'metro': - options.immersiveMode = True - options.browserChrome = True - elif suite == 'a11y': - options.a11y = True - elif suite == 'webapprt-content': - options.webapprtContent = True + if suite == 'webapprt-content': if not options.app or options.app == self.get_binary_path(): options.app = self.get_webapp_runtime_path() options.xrePath = self.get_webapp_runtime_xre_path() elif suite == 'webapprt-chrome': - options.webapprtChrome = True options.browserArgs.append("-test-mode") if not options.app or options.app == self.get_binary_path(): options.app = self.get_webapp_runtime_path() options.xrePath = self.get_webapp_runtime_xre_path() - else: - raise Exception('None or unrecognized mochitest suite type.') - if test_paths: - resolver = self._spawn(TestResolver) + from manifestparser import TestManifest + manifest = TestManifest() + manifest.tests.extend(tests) + options.manifestFile = manifest - tests = list( - resolver.resolve_tests( - paths=test_paths, - flavor=flavor)) - - if not tests: - print('No tests could be found in the path specified. Please ' - 'specify a path that is a test file or is a directory ' - 'containing tests.') - return 1 - - manifest = TestManifest() - manifest.tests.extend(tests) - - # XXX why is this such a special case? - if len(tests) == 1 and options.closeWhenDone and suite == 'plain': - options.closeWhenDone = False - - options.manifestFile = manifest + # XXX why is this such a special case? + if len(tests) == 1 and options.closeWhenDone and suite == 'plain': + options.closeWhenDone = False # We need this to enable colorization of output. self.log_manager.enable_unstructured() @@ -308,9 +353,11 @@ class MochitestRunner(MozbuildObject): self.log_manager.disable_unstructured() return result - def run_android_test(self, test_path, **kwargs): - self.tests_dir = os.path.join(self.topobjdir, '_tests') - self.mochitest_dir = os.path.join(self.tests_dir, 'testing', 'mochitest') + def run_android_test(self, context, tests, suite=None, **kwargs): + host_ret = verify_host_bin() + if host_ret != 0: + return host_ret + import imp path = os.path.join(self.mochitest_dir, 'runtestsremote.py') with open(path, 'r') as fh: @@ -319,21 +366,17 @@ class MochitestRunner(MozbuildObject): import runtestsremote options = Namespace(**kwargs) - if test_path: - options.testPath = test_path - sys.exit(runtestsremote.run_test_harness(options)) + from manifestparser import TestManifest + manifest = TestManifest() + manifest.tests.extend(tests) + options.manifestFile = manifest + + return runtestsremote.run_test_harness(options) # parser -def TestPathArg(func): - test_paths = CommandArgument('test_paths', nargs='*', metavar='TEST', default=None, - help='Test to run. Can be a single test file or a directory of tests to ' - '(run recursively). If omitted, the entire suite is run.') - return test_paths(func) - - def setup_argument_parser(): build_obj = MozbuildObject.from_environment(cwd=here) @@ -359,17 +402,17 @@ def setup_argument_parser(): # condition filters -def is_platform_in(*platforms): - def is_platform_supported(cls): - for p in platforms: - c = getattr(conditions, 'is_{}'.format(p), None) +def is_buildapp_in(*apps): + def is_buildapp_supported(cls): + for a in apps: + c = getattr(conditions, 'is_{}'.format(a), None) if c and c(cls): return True return False - is_platform_supported.__doc__ = 'Must have a {} build.'.format( - ' or '.join(platforms)) - return is_platform_supported + is_buildapp_supported.__doc__ = 'Must have a {} build.'.format( + ' or '.join(apps)) + return is_buildapp_supported def verify_host_bin(): @@ -389,263 +432,144 @@ def verify_host_bin(): @CommandProvider class MachCommands(MachCommandBase): - - def __init__(self, context): - MachCommandBase.__init__(self, context) - - for attr in ('device_name', 'target_out'): - setattr(self, attr, getattr(context, attr, None)) - - @Command( - 'mochitest-plain', - category='testing', - conditions=[is_platform_in('firefox', 'mulet', 'b2g', 'b2g_desktop', 'android')], - description='Run a plain mochitest (integration test, plain web page).', - parser=setup_argument_parser) - @TestPathArg - def run_mochitest_plain(self, test_paths, **kwargs): - if is_platform_in('firefox', 'mulet')(self): - return self.run_mochitest(test_paths, 'plain', **kwargs) - elif conditions.is_emulator(self): - return self.run_mochitest_remote(test_paths, **kwargs) - elif conditions.is_b2g_desktop(self): - return self.run_mochitest_b2g_desktop(test_paths, **kwargs) - elif conditions.is_android(self): - return self.run_mochitest_android(test_paths, **kwargs) - - @Command( - 'mochitest-chrome', - category='testing', - conditions=[is_platform_in('firefox', 'emulator', 'android')], - description='Run a chrome mochitest (integration test with some XUL).', - parser=setup_argument_parser) - @TestPathArg - def run_mochitest_chrome(self, test_paths, **kwargs): - kwargs['chrome'] = True - if conditions.is_firefox(self): - return self.run_mochitest(test_paths, 'chrome', **kwargs) - elif conditions.is_b2g(self) and conditions.is_emulator(self): - return self.run_mochitest_remote(test_paths, **kwargs) - elif conditions.is_android(self): - return self.run_mochitest_android(test_paths, **kwargs) - - @Command( - 'mochitest-browser', - category='testing', - conditions=[conditions.is_firefox], - description='Run a mochitest with browser chrome (integration test with a standard browser).', - parser=setup_argument_parser) - @TestPathArg - def run_mochitest_browser(self, test_paths, **kwargs): - return self.run_mochitest(test_paths, 'browser', **kwargs) - - @Command( - 'mochitest-devtools', - category='testing', - conditions=[conditions.is_firefox], - description='Run a devtools mochitest with browser chrome (integration test with a standard browser with the devtools frame).', - parser=setup_argument_parser) - @TestPathArg - def run_mochitest_devtools(self, test_paths, **kwargs): - return self.run_mochitest(test_paths, 'devtools', **kwargs) - - @Command('jetpack-package', category='testing', - conditions=[conditions.is_firefox], - description='Run a jetpack package test.', - parser=setup_argument_parser) - @TestPathArg - def run_mochitest_jetpack_package(self, test_paths, **kwargs): - return self.run_mochitest(test_paths, 'jetpack-package', **kwargs) - - @Command('jetpack-addon', category='testing', - conditions=[conditions.is_firefox], - description='Run a jetpack addon test.', - parser=setup_argument_parser) - @TestPathArg - def run_mochitest_jetpack_addon(self, test_paths, **kwargs): - return self.run_mochitest(test_paths, 'jetpack-addon', **kwargs) - - @Command( - 'mochitest-metro', - category='testing', - conditions=[conditions.is_firefox], - description='Run a mochitest with metro browser chrome (tests for Windows touch interface).', - parser=setup_argument_parser) - @TestPathArg - def run_mochitest_metro(self, test_paths, **kwargs): - return self.run_mochitest(test_paths, 'metro', **kwargs) - - @Command('mochitest-a11y', category='testing', - conditions=[conditions.is_firefox], - description='Run an a11y mochitest (accessibility tests).', - parser=setup_argument_parser) - @TestPathArg - def run_mochitest_a11y(self, test_paths, **kwargs): - return self.run_mochitest(test_paths, 'a11y', **kwargs) - - @Command( - 'webapprt-test-chrome', - category='testing', - conditions=[conditions.is_firefox], - description='Run a webapprt chrome mochitest (Web App Runtime with the browser chrome).', - parser=setup_argument_parser) - @TestPathArg - def run_mochitest_webapprt_chrome(self, test_paths, **kwargs): - return self.run_mochitest(test_paths, 'webapprt-chrome', **kwargs) - - @Command( - 'webapprt-test-content', - category='testing', - conditions=[conditions.is_firefox], - description='Run a webapprt content mochitest (Content rendering of the Web App Runtime).', - parser=setup_argument_parser) - @TestPathArg - def run_mochitest_webapprt_content(self, test_paths, **kwargs): - return self.run_mochitest(test_paths, 'webapprt-content', **kwargs) - @Command('mochitest', category='testing', - conditions=[conditions.is_firefox], + conditions=[is_buildapp_in(*SUPPORTED_APPS)], description='Run any flavor of mochitest (integration test).', parser=setup_argument_parser) - @CommandArgument('-f', '--flavor', choices=FLAVORS.keys(), + @CommandArgument('-f', '--flavor', + metavar='{{{}}}'.format(', '.join(CANONICAL_FLAVORS)), + choices=SUPPORTED_FLAVORS, help='Only run tests of this flavor.') - @TestPathArg + @CommandArgument('test_paths', nargs='*', metavar='TEST', default=None, + help='Test to run. Can be a single test file or a directory of tests ' + '(to run recursively). If omitted, the entire suite is run.') def run_mochitest_general(self, test_paths, flavor=None, test_objects=None, **kwargs): - self._preruntest() - from mozbuild.testing import TestResolver + buildapp = None + for app in SUPPORTED_APPS: + if is_buildapp_in(app)(self): + buildapp = app + break - if test_objects: - tests = test_objects + flavors = None + if flavor: + for fname, fobj in ALL_FLAVORS.iteritems(): + if flavor in fobj['aliases']: + if buildapp not in fobj['enabled_apps']: + continue + flavors = [fname] + break else: - resolver = self._spawn(TestResolver) - tests = list(resolver.resolve_tests(paths=test_paths, - cwd=self._mach_context.cwd)) + flavors = [f for f, v in ALL_FLAVORS.iteritems() if buildapp in v['enabled_apps']] - # Our current approach is to group the tests by suite and then perform - # an invocation for each suite. Ideally, this would be done - # automatically inside of core mochitest code. But it wasn't designed - # to do that. - # - # This does mean our output is less than ideal. When running tests from - # multiple suites, we see redundant summary lines. Hopefully once we - # have better machine readable output coming from mochitest land we can - # aggregate that here and improve the output formatting. + from mozbuild.controller.building import BuildDriver + self._ensure_state_subdir_exists('.') - suites = {} - for test in tests: - # Filter out non-mochitests. - if test['flavor'] not in FLAVORS: - continue + driver = self._spawn(BuildDriver) + driver.install_tests(remove=False) - if flavor and test['flavor'] != flavor: - continue - - suite = FLAVORS[test['flavor']] - suites.setdefault(suite, []).append(test) + if test_paths and buildapp == 'b2g': + # In B2G there is often a 'gecko' directory, though topsrcdir is actually + # elsewhere. This little hack makes test paths like 'gecko/dom' work, even if + # GECKO_PATH is set in the .userconfig + gecko_path = mozpath.abspath(mozpath.join(kwargs['b2gPath'], 'gecko')) + if gecko_path != self.topsrcdir: + old_paths = test_paths[:] + test_paths = [] + for tp in old_paths: + if mozpath.abspath(tp).startswith(gecko_path): + test_paths.append(mozpath.relpath(tp, gecko_path)) + else: + test_paths.append(tp) mochitest = self._spawn(MochitestRunner) + tests = mochitest.resolve_tests(test_paths, test_objects, cwd=self._mach_context.cwd) + + subsuite = kwargs.get('subsuite') + if subsuite == 'default': + kwargs['subsuite'] = None + + suites = defaultdict(list) + unsupported = set() + for test in tests: + # Filter out non-mochitests and unsupported flavors. + if test['flavor'] not in ALL_FLAVORS: + continue + + key = (test['flavor'], test['subsuite']) + if test['flavor'] not in flavors: + unsupported.add(key) + continue + + if subsuite == 'default': + # "--subsuite default" means only run tests that don't have a subsuite + if test['subsuite']: + unsupported.add(key) + continue + elif subsuite and test['subsuite'] != subsuite: + unsupported.add(key) + continue + + suites[key].append(test) + + if not suites: + # Make it very clear why no tests were found + if not unsupported: + print(TESTS_NOT_FOUND.format('\n'.join( + sorted(list(test_paths or test_objects))))) + return 1 + + msg = [] + for f, s in unsupported: + fobj = ALL_FLAVORS[f] + apps = fobj['enabled_apps'] + name = fobj['aliases'][0] + if s: + name = '{} --subsuite {}'.format(name, s) + + if buildapp not in apps: + reason = 'requires {}'.format(' or '.join(apps)) + else: + reason = 'excluded by the command line' + msg.append(' mochitest -f {} ({})'.format(name, reason)) + print(SUPPORTED_TESTS_NOT_FOUND.format( + buildapp, '\n'.join(sorted(msg)))) + return 1 + + if buildapp in ('b2g', 'b2g_desktop'): + run_mochitest = mochitest.run_b2g_test + elif buildapp == 'android': + run_mochitest = mochitest.run_android_test + else: + run_mochitest = mochitest.run_desktop_test + overall = None - for suite, tests in sorted(suites.items()): - result = mochitest.run_desktop_test( + for (flavor, subsuite), tests in sorted(suites.items()): + fobj = ALL_FLAVORS[flavor] + msg = fobj['aliases'][0] + if subsuite: + msg = '{} with subsuite {}'.format(msg, subsuite) + print(NOW_RUNNING.format(msg)) + + harness_args = kwargs.copy() + harness_args.update(fobj.get('extra_args', {})) + + result = run_mochitest( self._mach_context, - test_paths=[ - test['file_relpath'] for test in tests], - suite=suite, - **kwargs) + tests=tests, + suite=fobj['suite'], + **harness_args) + if result: overall = result + # TODO consolidate summaries from all suites return overall - def _preruntest(self): - from mozbuild.controller.building import BuildDriver - - self._ensure_state_subdir_exists('.') - - driver = self._spawn(BuildDriver) - driver.install_tests(remove=False) - - def run_mochitest(self, test_paths, flavor, **kwargs): - self._preruntest() - - mochitest = self._spawn(MochitestRunner) - - return mochitest.run_desktop_test( - self._mach_context, - test_paths=test_paths, - suite=flavor, - **kwargs) - - def run_mochitest_remote(self, test_paths, **kwargs): - if self.target_out: - host_webapps_dir = os.path.join( - self.target_out, - 'data', - 'local', - 'webapps') - if not os.path.isdir( - os.path.join( - host_webapps_dir, - 'test-container.gaiamobile.org')): - print( - ENG_BUILD_REQUIRED % - ('mochitest-remote', host_webapps_dir)) - return 1 - - from mozbuild.controller.building import BuildDriver - - self._ensure_state_subdir_exists('.') - - driver = self._spawn(BuildDriver) - driver.install_tests(remove=False) - - mochitest = self._spawn(MochitestRunner) - return mochitest.run_b2g_test( - test_paths=test_paths, - **kwargs) - - def run_mochitest_b2g_desktop(self, test_paths, **kwargs): - kwargs['profile'] = kwargs.get( - 'profile') or os.environ.get('GAIA_PROFILE') - if not kwargs['profile'] or not os.path.isdir(kwargs['profile']): - print(GAIA_PROFILE_NOT_FOUND % 'mochitest-b2g-desktop') - return 1 - - if os.path.isfile(os.path.join(kwargs['profile'], 'extensions', - 'httpd@gaiamobile.org')): - print(GAIA_PROFILE_IS_DEBUG % ('mochitest-b2g-desktop', - kwargs['profile'])) - return 1 - - from mozbuild.controller.building import BuildDriver - - self._ensure_state_subdir_exists('.') - - driver = self._spawn(BuildDriver) - driver.install_tests(remove=False) - - mochitest = self._spawn(MochitestRunner) - return mochitest.run_b2g_test(test_paths=test_paths, **kwargs) - - def run_mochitest_android(self, test_paths, **kwargs): - host_ret = verify_host_bin() - if host_ret != 0: - return host_ret - - test_path = None - if test_paths: - if len(test_paths) > 1: - print('Warning: Only the first test path will be used.') - test_path = self._wrap_path_argument(test_paths[0]).relpath() - - mochitest = self._spawn(MochitestRunner) - return mochitest.run_android_test(test_path, **kwargs) - @CommandProvider -class AndroidCommands(MachCommandBase): +class RobocopCommands(MachCommandBase): @Command('robocop', category='testing', conditions=[conditions.is_android], @@ -659,10 +583,6 @@ class AndroidCommands(MachCommandBase): help='Test to run. Can be specified as a Robocop test name (like "testLoad"), ' 'or omitted. If omitted, the entire test suite is executed.') def run_robocop(self, test_path, **kwargs): - host_ret = verify_host_bin() - if host_ret != 0: - return host_ret - if not kwargs.get('robocopIni'): kwargs['robocopIni'] = os.path.join(self.topobjdir, '_tests', 'testing', 'mochitest', 'robocop.ini') @@ -670,5 +590,66 @@ class AndroidCommands(MachCommandBase): if not kwargs.get('robocopApk'): kwargs['robocopApk'] = os.path.join(self.topobjdir, 'build', 'mobile', 'robocop', 'robocop-debug.apk') + + if isinstance(test_path, basestring): + test_path = [test_path] + mochitest = self._spawn(MochitestRunner) - return mochitest.run_android_test(test_path, **kwargs) + tests = mochitest.resolve_tests(test_path, cwd=self._mach_context.cwd) + return mochitest.run_android_test(self._mach_context, tests, 'robocop', **kwargs) + + +def REMOVED(cls): + """Command no longer exists! Use |mach mochitest| instead. + + The |mach mochitest| command will automatically detect which flavors and + subsuites exist in a given directory. If desired, flavors and subsuites + can be restricted using `--flavor` and `--subsuite` respectively. E.g: + + $ ./mach mochitest dom/indexedDB + + will run all of the plain, chrome and browser-chrome mochitests in that + directory. To only run the plain mochitests: + + $ ./mach mochitest -f plain dom/indexedDB + """ + return False + + +@CommandProvider +class DeprecatedCommands(MachCommandBase): + @Command('mochitest-plain', category='testing', conditions=[REMOVED]) + def mochitest_plain(self): + pass + + @Command('mochitest-chrome', category='testing', conditions=[REMOVED]) + def mochitest_chrome(self): + pass + + @Command('mochitest-browser', category='testing', conditions=[REMOVED]) + def mochitest_browser(self): + pass + + @Command('mochitest-devtools', category='testing', conditions=[REMOVED]) + def mochitest_devtools(self): + pass + + @Command('mochitest-a11y', category='testing', conditions=[REMOVED]) + def mochitest_a11y(self): + pass + + @Command('jetpack-addon', category='testing', conditions=[REMOVED]) + def jetpack_addon(self): + pass + + @Command('jetpack-package', category='testing', conditions=[REMOVED]) + def jetpack_package(self): + pass + + @Command('webapprt-test-chrome', category='testing', conditions=[REMOVED]) + def webapprt_chrome(self): + pass + + @Command('webapprt-test-content', category='testing', conditions=[REMOVED]) + def webapprt_content(self): + pass diff --git a/testing/mochitest/runtestsb2g.py b/testing/mochitest/runtestsb2g.py index b4a1f634d678..788dcd79f5f2 100644 --- a/testing/mochitest/runtestsb2g.py +++ b/testing/mochitest/runtestsb2g.py @@ -73,12 +73,7 @@ class B2GMochitest(MochitestUtilsMixin): def buildTestPath(self, options, testsToFilter=None): if options.manifestFile != 'tests.json': - super( - B2GMochitest, - self).buildTestPath( - options, - testsToFilter, - disabled=False) + super(B2GMochitest, self).buildTestPath(options, testsToFilter, disabled=False) return self.buildTestURL(options) def build_profile(self, options): @@ -199,7 +194,17 @@ class B2GMochitest(MochitestUtilsMixin): self.killNamedOrphans('xpcshell') self.startServers(options, None) + + # In desktop mochitests buildTestPath is called before buildURLOptions. This + # means options.manifestFile has already been converted to the proper json + # style manifest. Not so with B2G, that conversion along with updating the URL + # option will happen later. So backup and restore options.manifestFile to + # prevent us from trying to pass in an instance of TestManifest via url param. + manifestFile = options.manifestFile + options.manifestFile = None self.buildURLOptions(options, {'MOZ_HIDE_RESULTS_TABLE': '1'}) + options.manifestFile = manifestFile + self.test_script_args.append(not options.emulator) self.test_script_args.append(options.wifi) self.test_script_args.append(options.chrome) @@ -479,7 +484,7 @@ def run_remote_mochitests(options): mochitest.message_logger.finish() - sys.exit(retVal) + return retVal def run_desktop_mochitests(options): @@ -510,7 +515,7 @@ def run_desktop_mochitests(options): retVal = mochitest.runTests(options, onLaunch=mochitest.startTests) mochitest.message_logger.finish() - sys.exit(retVal) + return retVal def main(): @@ -518,9 +523,9 @@ def main(): options = parser.parse_args() if options.desktop: - run_desktop_mochitests(options) + return run_desktop_mochitests(options) else: - run_remote_mochitests(options) + return run_remote_mochitests(options) if __name__ == "__main__": - main() + sys.exit(main()) From 0df96b945eb55a91b1b65a4ea2a5f57c50e74cd5 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Fri, 29 May 2015 13:10:39 -0700 Subject: [PATCH 09/85] Bug 1168903 part 1: Give nsSMILValue a move constructor & move reassignment operator. r=birtles --- dom/smil/nsSMILValue.cpp | 29 +++++++++++++++++++++++++++++ dom/smil/nsSMILValue.h | 4 ++++ 2 files changed, 33 insertions(+) diff --git a/dom/smil/nsSMILValue.cpp b/dom/smil/nsSMILValue.cpp index c701fcda4f16..134d48e4d872 100644 --- a/dom/smil/nsSMILValue.cpp +++ b/dom/smil/nsSMILValue.cpp @@ -44,6 +44,35 @@ nsSMILValue::operator=(const nsSMILValue& aVal) return *this; } +// Move constructor / reassignment operator: +nsSMILValue::nsSMILValue(nsSMILValue&& aVal) + : mU(aVal.mU), // Copying union is only OK because we clear aVal.mType below. + mType(aVal.mType) +{ + // Leave aVal with a null type, so that it's safely destructible (and won't + // mess with anything referenced by its union, which we've copied). + aVal.mType = nsSMILNullType::Singleton(); +} + +nsSMILValue& +nsSMILValue::operator=(nsSMILValue&& aVal) +{ + if (!IsNull()) { + // Clean up any data we're currently tracking. + DestroyAndCheckPostcondition(); + } + + // Copy the union (which could include a pointer to external memory) & mType: + mU = aVal.mU; + mType = aVal.mType; + + // Leave aVal with a null type, so that it's safely destructible (and won't + // mess with anything referenced by its union, which we've now copied). + aVal.mType = nsSMILNullType::Singleton(); + + return *this; +} + bool nsSMILValue::operator==(const nsSMILValue& aVal) const { diff --git a/dom/smil/nsSMILValue.h b/dom/smil/nsSMILValue.h index 1649eb85c5a9..da5bcd9f050e 100644 --- a/dom/smil/nsSMILValue.h +++ b/dom/smil/nsSMILValue.h @@ -33,6 +33,10 @@ public: const nsSMILValue& operator=(const nsSMILValue& aVal); + // Move constructor / reassignment operator: + nsSMILValue(nsSMILValue&& aVal); + nsSMILValue& operator=(nsSMILValue&& aVal); + // Equality operators. These are allowed to be conservative (return false // more than you'd expect) - see comment above nsISMILType::IsEqual. bool operator==(const nsSMILValue& aVal) const; From dfc8e242f9ae798f76c9edf04cca1cea9e60cb69 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Fri, 29 May 2015 13:10:41 -0700 Subject: [PATCH 10/85] Bug 1168903 part 2: Use Move() instead of nsSMILValue::Swap() to populate outparams from temp variables in SMIL functions. r=birtles --- dom/smil/nsSMILAnimationFunction.cpp | 8 ++++---- dom/smil/nsSMILCSSProperty.cpp | 6 ++++-- dom/smil/nsSMILValue.cpp | 13 ------------- dom/smil/nsSMILValue.h | 3 --- dom/svg/SVGAnimatedLengthList.cpp | 6 ++++-- dom/svg/SVGAnimatedNumberList.cpp | 6 ++++-- dom/svg/SVGAnimatedPathSegList.cpp | 6 ++++-- dom/svg/SVGAnimatedPointList.cpp | 6 ++++-- dom/svg/nsSVGAngle.cpp | 7 ++++--- dom/svg/nsSVGAnimatedTransformList.cpp | 4 +++- dom/svg/nsSVGClass.cpp | 6 ++++-- dom/svg/nsSVGString.cpp | 4 +++- dom/svg/nsSVGViewBox.cpp | 4 +++- 13 files changed, 41 insertions(+), 38 deletions(-) diff --git a/dom/smil/nsSMILAnimationFunction.cpp b/dom/smil/nsSMILAnimationFunction.cpp index c7d19db56b88..276a85f48b1d 100644 --- a/dom/smil/nsSMILAnimationFunction.cpp +++ b/dom/smil/nsSMILAnimationFunction.cpp @@ -4,8 +4,10 @@ * 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 "mozilla/dom/SVGAnimationElement.h" #include "nsSMILAnimationFunction.h" + +#include "mozilla/dom/SVGAnimationElement.h" +#include "mozilla/Move.h" #include "nsISMILAttr.h" #include "nsSMILParserUtils.h" #include "nsSMILNullType.h" @@ -267,9 +269,7 @@ nsSMILAnimationFunction::ComposeResult(const nsISMILAttr& aSMILAttr, // If additive animation isn't required or isn't supported, set the value. if (!isAdditive || NS_FAILED(aResult.SandwichAdd(result))) { - aResult.Swap(result); - // Note: The old value of aResult is now in |result|, and it will get - // cleaned up when |result| goes out of scope, when this function returns. + aResult = Move(result); } } diff --git a/dom/smil/nsSMILCSSProperty.cpp b/dom/smil/nsSMILCSSProperty.cpp index 5d42c8bf5df0..b0e6bc9e0ba7 100644 --- a/dom/smil/nsSMILCSSProperty.cpp +++ b/dom/smil/nsSMILCSSProperty.cpp @@ -7,11 +7,13 @@ /* representation of a SMIL-animatable CSS property on an element */ #include "nsSMILCSSProperty.h" + +#include "mozilla/dom/Element.h" +#include "mozilla/Move.h" #include "nsSMILCSSValueType.h" #include "nsSMILValue.h" #include "nsComputedDOMStyle.h" #include "nsCSSProps.h" -#include "mozilla/dom/Element.h" #include "nsIDOMElement.h" #include "nsIDocument.h" @@ -81,7 +83,7 @@ nsSMILCSSProperty::GetBaseValue() const // In either case, just return a dummy value (initialized with the right // type, so as not to indicate failure). nsSMILValue tmpVal(&nsSMILCSSValueType::sSingleton); - baseValue.Swap(tmpVal); + Swap(baseValue, tmpVal); return baseValue; } diff --git a/dom/smil/nsSMILValue.cpp b/dom/smil/nsSMILValue.cpp index 134d48e4d872..cd881b0b016d 100644 --- a/dom/smil/nsSMILValue.cpp +++ b/dom/smil/nsSMILValue.cpp @@ -82,19 +82,6 @@ nsSMILValue::operator==(const nsSMILValue& aVal) const return mType == aVal.mType && mType->IsEqual(*this, aVal); } -void -nsSMILValue::Swap(nsSMILValue& aOther) -{ - nsSMILValue tmp; - memcpy(&tmp, &aOther, sizeof(nsSMILValue)); // tmp = aOther - memcpy(&aOther, this, sizeof(nsSMILValue)); // aOther = this - memcpy(this, &tmp, sizeof(nsSMILValue)); // this = tmp - - // |tmp| is about to die -- we need to clear its mType, so that its - // destructor doesn't muck with the data we just transferred out of it. - tmp.mType = nsSMILNullType::Singleton(); -} - nsresult nsSMILValue::Add(const nsSMILValue& aValueToAdd, uint32_t aCount) { diff --git a/dom/smil/nsSMILValue.h b/dom/smil/nsSMILValue.h index da5bcd9f050e..c0998d61dbe8 100644 --- a/dom/smil/nsSMILValue.h +++ b/dom/smil/nsSMILValue.h @@ -49,9 +49,6 @@ public: return (mType == nsSMILNullType::Singleton()); } - // Swaps the member data (mU & mPtr) of |this| with |aOther| - void Swap(nsSMILValue& aOther); - nsresult Add(const nsSMILValue& aValueToAdd, uint32_t aCount = 1); nsresult SandwichAdd(const nsSMILValue& aValueToAdd); nsresult ComputeDistance(const nsSMILValue& aTo, double& aDistance) const; diff --git a/dom/svg/SVGAnimatedLengthList.cpp b/dom/svg/SVGAnimatedLengthList.cpp index a759329d8abc..91702a16b416 100644 --- a/dom/svg/SVGAnimatedLengthList.cpp +++ b/dom/svg/SVGAnimatedLengthList.cpp @@ -5,7 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SVGAnimatedLengthList.h" + #include "DOMSVGAnimatedLengthList.h" +#include "mozilla/Move.h" #include "nsSVGElement.h" #include "nsSVGAttrTearoffTable.h" #include "nsSMILValue.h" @@ -138,7 +140,7 @@ SVGAnimatedLengthList:: nsresult rv = llai->SetValueFromString(aStr); if (NS_SUCCEEDED(rv)) { llai->SetInfo(mElement, mAxis, mCanZeroPadList); - aValue.Swap(val); + aValue = Move(val); // If any of the lengths in the list depend on their context, then we must // prevent caching of the entire animation sandwich. This is because the @@ -181,7 +183,7 @@ SVGAnimatedLengthList::SMILAnimatedLengthList::GetBaseValue() const nsresult rv = llai->CopyFrom(mVal->mBaseVal); if (NS_SUCCEEDED(rv)) { llai->SetInfo(mElement, mAxis, mCanZeroPadList); - val.Swap(tmp); + val = Move(tmp); } return val; } diff --git a/dom/svg/SVGAnimatedNumberList.cpp b/dom/svg/SVGAnimatedNumberList.cpp index 7e566a0d33dd..9be7ffadd80b 100644 --- a/dom/svg/SVGAnimatedNumberList.cpp +++ b/dom/svg/SVGAnimatedNumberList.cpp @@ -5,7 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SVGAnimatedNumberList.h" + #include "DOMSVGAnimatedNumberList.h" +#include "mozilla/Move.h" #include "nsSVGElement.h" #include "nsSVGAttrTearoffTable.h" #include "nsSMILValue.h" @@ -138,7 +140,7 @@ SVGAnimatedNumberList:: nsresult rv = nlai->SetValueFromString(aStr); if (NS_SUCCEEDED(rv)) { nlai->SetInfo(mElement); - aValue.Swap(val); + aValue = Move(val); } aPreventCachingOfSandwich = false; return rv; @@ -157,7 +159,7 @@ SVGAnimatedNumberList::SMILAnimatedNumberList::GetBaseValue() const nsresult rv = nlai->CopyFrom(mVal->mBaseVal); if (NS_SUCCEEDED(rv)) { nlai->SetInfo(mElement); - val.Swap(tmp); + Swap(val, tmp); } return val; } diff --git a/dom/svg/SVGAnimatedPathSegList.cpp b/dom/svg/SVGAnimatedPathSegList.cpp index 5f3f7a0da3b0..4f07d20404d6 100644 --- a/dom/svg/SVGAnimatedPathSegList.cpp +++ b/dom/svg/SVGAnimatedPathSegList.cpp @@ -5,7 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SVGAnimatedPathSegList.h" + #include "DOMSVGPathSegList.h" +#include "mozilla/Move.h" #include "nsSVGElement.h" #include "nsSVGAttrTearoffTable.h" #include "nsSMILValue.h" @@ -160,7 +162,7 @@ SVGAnimatedPathSegList:: nsresult rv = list->SetValueFromString(aStr); if (NS_SUCCEEDED(rv)) { list->SetElement(mElement); - aValue.Swap(val); + aValue = Move(val); } aPreventCachingOfSandwich = false; return rv; @@ -179,7 +181,7 @@ SVGAnimatedPathSegList::SMILAnimatedPathSegList::GetBaseValue() const nsresult rv = list->CopyFrom(mVal->mBaseVal); if (NS_SUCCEEDED(rv)) { list->SetElement(mElement); - val.Swap(tmp); + val = Move(tmp); } return val; } diff --git a/dom/svg/SVGAnimatedPointList.cpp b/dom/svg/SVGAnimatedPointList.cpp index c411b53b891d..13031901d77a 100644 --- a/dom/svg/SVGAnimatedPointList.cpp +++ b/dom/svg/SVGAnimatedPointList.cpp @@ -5,7 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SVGAnimatedPointList.h" + #include "DOMSVGPointList.h" +#include "mozilla/Move.h" #include "nsSVGElement.h" #include "nsSVGAttrTearoffTable.h" #include "nsSMILValue.h" @@ -163,7 +165,7 @@ SVGAnimatedPointList:: nsresult rv = list->SetValueFromString(aStr); if (NS_SUCCEEDED(rv)) { list->SetInfo(mElement); - aValue.Swap(val); + aValue = Move(val); } aPreventCachingOfSandwich = false; return rv; @@ -182,7 +184,7 @@ SVGAnimatedPointList::SMILAnimatedPointList::GetBaseValue() const nsresult rv = list->CopyFrom(mVal->mBaseVal); if (NS_SUCCEEDED(rv)) { list->SetInfo(mElement); - val.Swap(tmp); + Swap(val, tmp); } return val; } diff --git a/dom/svg/nsSVGAngle.cpp b/dom/svg/nsSVGAngle.cpp index 15a9301ac15f..2c3c5f94cd36 100644 --- a/dom/svg/nsSVGAngle.cpp +++ b/dom/svg/nsSVGAngle.cpp @@ -4,10 +4,11 @@ * 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 "mozilla/ArrayUtils.h" - #include "nsSVGAngle.h" + +#include "mozilla/ArrayUtils.h" #include "mozilla/dom/SVGMarkerElement.h" +#include "mozilla/Move.h" #include "nsContentUtils.h" // NS_ENSURE_FINITE #include "nsSMILValue.h" #include "nsSVGAttrTearoffTable.h" @@ -383,7 +384,7 @@ nsSVGAngle::SMILOrient::ValueFromString(const nsAString& aStr, val.mU.mOrient.mUnit = unitType; val.mU.mOrient.mOrientType = SVG_MARKER_ORIENT_ANGLE; } - aValue.Swap(val); + aValue = Move(val); aPreventCachingOfSandwich = false; return NS_OK; diff --git a/dom/svg/nsSVGAnimatedTransformList.cpp b/dom/svg/nsSVGAnimatedTransformList.cpp index 1da21c0fc863..dd4d550e5f40 100644 --- a/dom/svg/nsSVGAnimatedTransformList.cpp +++ b/dom/svg/nsSVGAnimatedTransformList.cpp @@ -5,8 +5,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsSVGAnimatedTransformList.h" + #include "mozilla/dom/SVGAnimatedTransformList.h" #include "mozilla/dom/SVGAnimationElement.h" +#include "mozilla/Move.h" #include "nsCharSeparatedTokenizer.h" #include "nsSVGTransform.h" #include "nsSMILValue.h" @@ -248,7 +250,7 @@ nsSVGAnimatedTransformList::SMILAnimatedTransformList::ParseValue( } // Success! Populate our outparam with parsed value. - aResult.Swap(val); + aResult = Move(val); } int32_t diff --git a/dom/svg/nsSVGClass.cpp b/dom/svg/nsSVGClass.cpp index 826fa0d0886b..bb114b9a8629 100644 --- a/dom/svg/nsSVGClass.cpp +++ b/dom/svg/nsSVGClass.cpp @@ -5,10 +5,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsSVGClass.h" + +#include "mozilla/dom/SVGAnimatedString.h" +#include "mozilla/Move.h" #include "nsSVGElement.h" #include "nsSMILValue.h" #include "SMILStringType.h" -#include "mozilla/dom/SVGAnimatedString.h" using namespace mozilla; using namespace mozilla::dom; @@ -130,7 +132,7 @@ nsSVGClass::SMILString::ValueFromString(const nsAString& aStr, nsSMILValue val(SMILStringType::Singleton()); *static_cast(val.mU.mPtr) = aStr; - aValue.Swap(val); + aValue = Move(val); aPreventCachingOfSandwich = false; return NS_OK; } diff --git a/dom/svg/nsSVGString.cpp b/dom/svg/nsSVGString.cpp index 041e013de16e..7c3de686808d 100644 --- a/dom/svg/nsSVGString.cpp +++ b/dom/svg/nsSVGString.cpp @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsSVGString.h" + +#include "mozilla/Move.h" #include "nsSVGAttrTearoffTable.h" #include "nsSMILValue.h" #include "SMILStringType.h" @@ -110,7 +112,7 @@ nsSVGString::SMILString::ValueFromString(const nsAString& aStr, nsSMILValue val(SMILStringType::Singleton()); *static_cast(val.mU.mPtr) = aStr; - aValue.Swap(val); + aValue = Move(val); aPreventCachingOfSandwich = false; return NS_OK; } diff --git a/dom/svg/nsSVGViewBox.cpp b/dom/svg/nsSVGViewBox.cpp index ff11939b9bd6..61e345a37fec 100644 --- a/dom/svg/nsSVGViewBox.cpp +++ b/dom/svg/nsSVGViewBox.cpp @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsSVGViewBox.h" + +#include "mozilla/Move.h" #include "nsCharSeparatedTokenizer.h" #include "nsSMILValue.h" #include "nsTextFormatter.h" @@ -300,7 +302,7 @@ nsSVGViewBox::SMILViewBox } nsSMILValue val(&SVGViewBoxSMILType::sSingleton); *static_cast(val.mU.mPtr) = viewBox; - aValue.Swap(val); + aValue = Move(val); aPreventCachingOfSandwich = false; return NS_OK; From da2e41f0edc450dc4d44a235da81ae63982d14eb Mon Sep 17 00:00:00 2001 From: Magnus Melin Date: Fri, 29 May 2015 23:12:26 +0300 Subject: [PATCH 11/85] Bug 1167422 - don't log it as an error that telemetry can't get a browser shell. r=gfritzsche Error: 1432246297697 Toolkit.Telemetry ERROR TelemetryEnvironment::_isDefaultBrowser - Could not obtain shell service Source File: resource://gre/modules/Log.jsm Line: 749. --- .../telemetry/TelemetryEnvironment.jsm | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/toolkit/components/telemetry/TelemetryEnvironment.jsm b/toolkit/components/telemetry/TelemetryEnvironment.jsm index da5bcbdfa097..b072c8e1ae40 100644 --- a/toolkit/components/telemetry/TelemetryEnvironment.jsm +++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm @@ -928,7 +928,7 @@ EnvironmentCache.prototype = { }, /** - * Determine if Firefox is the default browser. + * Determine if we're the default browser. * @returns null on error, true if we are the default browser, or false otherwise. */ _isDefaultBrowser: function () { @@ -936,7 +936,7 @@ EnvironmentCache.prototype = { return true; #else if (!("@mozilla.org/browser/shell-service;1" in Cc)) { - this._log.error("_isDefaultBrowser - Could not obtain shell service"); + this._log.info("_isDefaultBrowser - Could not obtain browser shell service"); return null; } @@ -949,14 +949,12 @@ EnvironmentCache.prototype = { return null; } - if (shellService) { - try { - // This uses the same set of flags used by the pref pane. - return shellService.isDefaultBrowser(false, true) ? true : false; - } catch (ex) { - this._log.error("_isDefaultBrowser - Could not determine if default browser", ex); - return null; - } + try { + // This uses the same set of flags used by the pref pane. + return shellService.isDefaultBrowser(false, true) ? true : false; + } catch (ex) { + this._log.error("_isDefaultBrowser - Could not determine if default browser", ex); + return null; } return null; From 10075d7753560254a361a459a9862702e4815637 Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Fri, 29 May 2015 14:29:50 -0600 Subject: [PATCH 12/85] Bug 1166678 - Optimize Array.prototype.slice in Ion, r=jandem. --- js/src/jit/BaselineIC.cpp | 2 +- js/src/jit/CodeGenerator.cpp | 35 ++++++++++++ js/src/jit/CodeGenerator.h | 1 + js/src/jit/IonBuilder.h | 1 + js/src/jit/LIR-Common.h | 33 +++++++++++ js/src/jit/LOpcodes.h | 1 + js/src/jit/Lowering.cpp | 17 ++++++ js/src/jit/Lowering.h | 1 + js/src/jit/MCallOptimize.cpp | 103 ++++++++++++++++++++++++++++++++++ js/src/jit/MIR.h | 64 +++++++++++++++++++++ js/src/jit/MOpcodes.h | 1 + js/src/jsarray.cpp | 94 ++++++++++++++++++++++--------- js/src/jsarray.h | 3 + js/src/vm/TypeInference.cpp | 4 +- js/src/vm/UnboxedObject-inl.h | 18 +++++- 15 files changed, 349 insertions(+), 29 deletions(-) diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index a8d490e549cf..4b3b3cbc4226 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -9948,7 +9948,7 @@ GetTemplateObjectForNative(JSContext* cx, HandleScript script, jsbytecode* pc, return true; } - if (native == js::array_concat) { + if (native == js::array_concat || native == js::array_slice) { if (args.thisv().isObject() && !args.thisv().toObject().isSingleton()) { res.set(NewFullyAllocatedArrayTryReuseGroup(cx, &args.thisv().toObject(), 0, TenuredObject, /* forceAnalyze = */ true)); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index b425f2599555..ef24bf0db382 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -7148,6 +7148,41 @@ CodeGenerator::visitArrayConcat(LArrayConcat* lir) callVM(ArrayConcatDenseInfo, lir); } +typedef JSObject* (*ArraySliceDenseFn)(JSContext*, HandleObject, int32_t, int32_t, HandleObject); +static const VMFunction ArraySliceDenseInfo = FunctionInfo(array_slice_dense); + +void +CodeGenerator::visitArraySlice(LArraySlice* lir) +{ + Register object = ToRegister(lir->object()); + Register begin = ToRegister(lir->begin()); + Register end = ToRegister(lir->end()); + Register temp1 = ToRegister(lir->temp1()); + Register temp2 = ToRegister(lir->temp2()); + + Label call, fail; + + // Try to allocate an object. + masm.createGCObject(temp1, temp2, lir->mir()->templateObj(), lir->mir()->initialHeap(), &fail); + + // Fixup the group of the result in case it doesn't match the template object. + masm.loadPtr(Address(object, JSObject::offsetOfGroup()), temp2); + masm.storePtr(temp2, Address(temp1, JSObject::offsetOfGroup())); + + masm.jump(&call); + { + masm.bind(&fail); + masm.movePtr(ImmPtr(nullptr), temp1); + } + masm.bind(&call); + + pushArg(temp1); + pushArg(end); + pushArg(begin); + pushArg(object); + callVM(ArraySliceDenseInfo, lir); +} + typedef JSString* (*ArrayJoinFn)(JSContext*, HandleObject, HandleString); static const VMFunction ArrayJoinInfo = FunctionInfo(jit::ArrayJoin); diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index f26504c79685..189cc84e895b 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -265,6 +265,7 @@ class CodeGenerator : public CodeGeneratorSpecific void visitArrayPushV(LArrayPushV* lir); void visitArrayPushT(LArrayPushT* lir); void visitArrayConcat(LArrayConcat* lir); + void visitArraySlice(LArraySlice* lir); void visitArrayJoin(LArrayJoin* lir); void visitLoadUnboxedScalar(LLoadUnboxedScalar* lir); void visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole* lir); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 74489b1b78f0..a11a02780340 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -745,6 +745,7 @@ class IonBuilder InliningStatus inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode); InliningStatus inlineArrayPush(CallInfo& callInfo); InliningStatus inlineArrayConcat(CallInfo& callInfo); + InliningStatus inlineArraySlice(CallInfo& callInfo); InliningStatus inlineArrayJoin(CallInfo& callInfo); InliningStatus inlineArraySplice(CallInfo& callInfo); diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 1b8aa8811825..d0ffc6c8033e 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -4945,6 +4945,39 @@ class LArrayConcat : public LCallInstructionHelper<1, 2, 2> } }; +class LArraySlice : public LCallInstructionHelper<1, 3, 2> +{ + public: + LIR_HEADER(ArraySlice) + + LArraySlice(const LAllocation& obj, const LAllocation& begin, const LAllocation& end, + const LDefinition& temp1, const LDefinition& temp2) { + setOperand(0, obj); + setOperand(1, begin); + setOperand(2, end); + setTemp(0, temp1); + setTemp(1, temp2); + } + const MArraySlice* mir() const { + return mir_->toArraySlice(); + } + const LAllocation* object() { + return getOperand(0); + } + const LAllocation* begin() { + return getOperand(1); + } + const LAllocation* end() { + return getOperand(2); + } + const LDefinition* temp1() { + return getTemp(0); + } + const LDefinition* temp2() { + return getTemp(1); + } +}; + class LArrayJoin : public LCallInstructionHelper<1, 2, 0> { public: diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index e0876c501f4e..7babe1467daf 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -238,6 +238,7 @@ _(ArrayPushV) \ _(ArrayPushT) \ _(ArrayConcat) \ + _(ArraySlice) \ _(ArrayJoin) \ _(StoreElementHoleV) \ _(StoreElementHoleT) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 39668aebfd13..f9a860fdcaaa 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2904,6 +2904,23 @@ LIRGenerator::visitArrayConcat(MArrayConcat* ins) assignSafepoint(lir, ins); } +void +LIRGenerator::visitArraySlice(MArraySlice* ins) +{ + MOZ_ASSERT(ins->type() == MIRType_Object); + MOZ_ASSERT(ins->object()->type() == MIRType_Object); + MOZ_ASSERT(ins->begin()->type() == MIRType_Int32); + MOZ_ASSERT(ins->end()->type() == MIRType_Int32); + + LArraySlice* lir = new(alloc()) LArraySlice(useFixed(ins->object(), CallTempReg0), + useFixed(ins->begin(), CallTempReg1), + useFixed(ins->end(), CallTempReg2), + tempFixed(CallTempReg3), + tempFixed(CallTempReg4)); + defineReturn(lir, ins); + assignSafepoint(lir, ins); +} + void LIRGenerator::visitArrayJoin(MArrayJoin* ins) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 0712babafc64..a4fd6a11ddc5 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -207,6 +207,7 @@ class LIRGenerator : public LIRGeneratorSpecific void visitArrayPopShift(MArrayPopShift* ins); void visitArrayPush(MArrayPush* ins); void visitArrayConcat(MArrayConcat* ins); + void visitArraySlice(MArraySlice* ins); void visitArrayJoin(MArrayJoin* ins); void visitLoadUnboxedScalar(MLoadUnboxedScalar* ins); void visitLoadTypedArrayElementHole(MLoadTypedArrayElementHole* ins); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 84860d2bd518..5c867650f07b 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -82,6 +82,8 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target) return inlineArrayPush(callInfo); if (native == js::array_concat) return inlineArrayConcat(callInfo); + if (native == js::array_slice) + return inlineArraySlice(callInfo); if (native == js::array_splice) return inlineArraySplice(callInfo); @@ -981,6 +983,107 @@ IonBuilder::inlineArrayConcat(CallInfo& callInfo) return InliningStatus_Inlined; } +IonBuilder::InliningStatus +IonBuilder::inlineArraySlice(CallInfo& callInfo) +{ + if (callInfo.constructing()) { + trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm); + return InliningStatus_NotInlined; + } + + // Ensure |this| and result are objects. + if (getInlineReturnType() != MIRType_Object) + return InliningStatus_NotInlined; + if (callInfo.thisArg()->type() != MIRType_Object) + return InliningStatus_NotInlined; + + // Arguments for the sliced region must be integers. + if (callInfo.argc() > 0) { + if (callInfo.getArg(0)->type() != MIRType_Int32) + return InliningStatus_NotInlined; + if (callInfo.argc() > 1) { + if (callInfo.getArg(1)->type() != MIRType_Int32) + return InliningStatus_NotInlined; + } + } + + // |this| must be a dense array. + TemporaryTypeSet* thisTypes = callInfo.thisArg()->resultTypeSet(); + if (!thisTypes) + return InliningStatus_NotInlined; + + const Class* clasp = thisTypes->getKnownClass(constraints()); + if (clasp != &ArrayObject::class_ && clasp != &UnboxedArrayObject::class_) + return InliningStatus_NotInlined; + if (thisTypes->hasObjectFlags(constraints(), OBJECT_FLAG_SPARSE_INDEXES | + OBJECT_FLAG_LENGTH_OVERFLOW)) + { + trackOptimizationOutcome(TrackedOutcome::ArrayBadFlags); + return InliningStatus_NotInlined; + } + + JSValueType unboxedType = JSVAL_TYPE_MAGIC; + if (clasp == &UnboxedArrayObject::class_) { + unboxedType = UnboxedArrayElementType(constraints(), callInfo.thisArg(), nullptr); + if (unboxedType == JSVAL_TYPE_MAGIC) + return InliningStatus_NotInlined; + } + + // Watch out for indexed properties on the prototype. + if (ArrayPrototypeHasIndexedProperty(constraints(), script())) { + trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps); + return InliningStatus_NotInlined; + } + + // The group of the result will be dynamically fixed up to match the input + // object, allowing us to handle 'this' objects that might have more than + // one group. Make sure that no singletons can be sliced here. + for (unsigned i = 0; i < thisTypes->getObjectCount(); i++) { + TypeSet::ObjectKey* key = thisTypes->getObject(i); + if (key && key->isSingleton()) + return InliningStatus_NotInlined; + } + + // Inline the call. + JSObject* templateObj = inspector->getTemplateObjectForNative(pc, js::array_slice); + if (!templateObj) + return InliningStatus_NotInlined; + + callInfo.setImplicitlyUsedUnchecked(); + + MDefinition* begin; + if (callInfo.argc() > 0) + begin = callInfo.getArg(0); + else + begin = constant(Int32Value(0)); + + MDefinition* end; + if (callInfo.argc() > 1) { + end = callInfo.getArg(1); + } else if (clasp == &ArrayObject::class_) { + MElements* elements = MElements::New(alloc(), callInfo.thisArg()); + current->add(elements); + + end = MArrayLength::New(alloc(), elements); + current->add(end->toInstruction()); + } else { + end = MUnboxedArrayLength::New(alloc(), callInfo.thisArg()); + current->add(end->toInstruction()); + } + + MArraySlice* ins = MArraySlice::New(alloc(), constraints(), + callInfo.thisArg(), begin, end, + templateObj, + templateObj->group()->initialHeap(constraints()), + unboxedType); + current->add(ins); + current->push(ins); + + if (!resumeAfter(ins)) + return InliningStatus_Error; + return InliningStatus_Inlined; +} + IonBuilder::InliningStatus IonBuilder::inlineMathAbs(CallInfo& callInfo) { diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 5130eabc918e..48598032c5ab 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -9153,6 +9153,70 @@ class MArrayConcat } }; +// Array.prototype.slice on a dense array. +class MArraySlice + : public MTernaryInstruction, + public Mix3Policy, IntPolicy<1>, IntPolicy<2>>::Data +{ + AlwaysTenuredObject templateObj_; + gc::InitialHeap initialHeap_; + JSValueType unboxedType_; + + MArraySlice(CompilerConstraintList* constraints, MDefinition* obj, + MDefinition* begin, MDefinition* end, + JSObject* templateObj, gc::InitialHeap initialHeap, JSValueType unboxedType) + : MTernaryInstruction(obj, begin, end), + templateObj_(templateObj), + initialHeap_(initialHeap), + unboxedType_(unboxedType) + { + setResultType(MIRType_Object); + setResultTypeSet(obj->resultTypeSet()); + } + + public: + INSTRUCTION_HEADER(ArraySlice) + + static MArraySlice* New(TempAllocator& alloc, CompilerConstraintList* constraints, + MDefinition* obj, MDefinition* begin, MDefinition* end, + JSObject* templateObj, gc::InitialHeap initialHeap, + JSValueType unboxedType) + { + return new(alloc) MArraySlice(constraints, obj, begin, end, templateObj, + initialHeap, unboxedType); + } + + MDefinition* object() const { + return getOperand(0); + } + MDefinition* begin() const { + return getOperand(1); + } + MDefinition* end() const { + return getOperand(2); + } + + JSObject* templateObj() const { + return templateObj_; + } + + gc::InitialHeap initialHeap() const { + return initialHeap_; + } + + JSValueType unboxedType() const { + return unboxedType_; + } + + AliasSet getAliasSet() const override { + return AliasSet::Store(AliasSet::BoxedOrUnboxedElements(unboxedType()) | + AliasSet::ObjectFields); + } + bool possiblyCalls() const override { + return true; + } +}; + class MArrayJoin : public MBinaryInstruction, public MixPolicy, StringPolicy<1> >::Data diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index fcdc789bdbe4..76d00e2f4233 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -200,6 +200,7 @@ namespace jit { _(ArrayPopShift) \ _(ArrayPush) \ _(ArrayConcat) \ + _(ArraySlice) \ _(ArrayJoin) \ _(LoadTypedArrayElementHole) \ _(LoadTypedArrayElementStatic) \ diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index a0ac77868461..393b349bfded 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -2642,15 +2642,8 @@ ArrayConcatDenseKernel(JSContext* cx, JSObject* obj1, JSObject* obj2, JSObject* MOZ_ASSERT(GetBoxedOrUnboxedInitializedLength(result) == 0); - if (Type == JSVAL_TYPE_MAGIC) { - if (!result->as().ensureElements(cx, len)) - return DenseElementResult::Failure; - } else { - if (result->as().capacity() < len) { - if (!result->as().growElements(cx, len)) - return DenseElementResult::Failure; - } - } + if (!EnsureBoxedOrUnboxedDenseElements(cx, result, len)) + return DenseElementResult::Failure; CopyBoxedOrUnboxedDenseElements(cx, result, obj1, 0, 0, initlen1); CopyBoxedOrUnboxedDenseElements(cx, result, obj2, initlen1, 0, initlen2); @@ -2899,6 +2892,20 @@ SliceSparse(JSContext* cx, HandleObject obj, uint32_t begin, uint32_t end, Handl return true; } +template +static inline uint32_t +NormalizeSliceTerm(T value, uint32_t length) +{ + if (value < 0) { + value += length; + if (value < 0) + return 0; + } else if (double(value) > double(length)) { + return length; + } + return uint32_t(value); +} + bool js::array_slice(JSContext* cx, unsigned argc, Value* vp) { @@ -2918,26 +2925,12 @@ js::array_slice(JSContext* cx, unsigned argc, Value* vp) double d; if (!ToInteger(cx, args[0], &d)) return false; - if (d < 0) { - d += length; - if (d < 0) - d = 0; - } else if (d > length) { - d = length; - } - begin = (uint32_t)d; + begin = NormalizeSliceTerm(d, length); if (args.hasDefined(1)) { if (!ToInteger(cx, args[1], &d)) return false; - if (d < 0) { - d += length; - if (d < 0) - d = 0; - } else if (d > length) { - d = length; - } - end = (uint32_t)d; + end = NormalizeSliceTerm(d, length); } } @@ -3000,6 +2993,57 @@ js::array_slice(JSContext* cx, unsigned argc, Value* vp) return true; } +template +DenseElementResult +ArraySliceDenseKernel(JSContext* cx, JSObject* obj, int32_t beginArg, int32_t endArg, JSObject* result) +{ + int32_t length = GetAnyBoxedOrUnboxedArrayLength(obj); + + uint32_t begin = NormalizeSliceTerm(beginArg, length); + uint32_t end = NormalizeSliceTerm(endArg, length); + + if (begin > end) + begin = end; + + size_t initlen = GetBoxedOrUnboxedInitializedLength(obj); + if (initlen > begin) { + size_t count = Min(initlen - begin, end - begin); + if (count) { + if (!EnsureBoxedOrUnboxedDenseElements(cx, result, count)) + return DenseElementResult::Failure; + CopyBoxedOrUnboxedDenseElements(cx, result, obj, 0, begin, count); + } + } + + SetAnyBoxedOrUnboxedArrayLength(cx, result, end - begin); + return DenseElementResult::Success; +} + +DefineBoxedOrUnboxedFunctor5(ArraySliceDenseKernel, + JSContext*, JSObject*, int32_t, int32_t, JSObject*); + +JSObject* +js::array_slice_dense(JSContext* cx, HandleObject obj, int32_t begin, int32_t end, + HandleObject result) +{ + if (result) { + ArraySliceDenseKernelFunctor functor(cx, obj, begin, end, result); + DenseElementResult rv = CallBoxedOrUnboxedSpecialization(functor, result); + MOZ_ASSERT(rv != DenseElementResult::Incomplete); + return rv == DenseElementResult::Success ? result : nullptr; + } + + // Slower path if the JIT wasn't able to allocate an object inline. + JS::AutoValueArray<4> argv(cx); + argv[0].setUndefined(); + argv[1].setObject(*obj); + argv[2].setInt32(begin); + argv[3].setInt32(end); + if (!array_slice(cx, 2, argv.begin())) + return nullptr; + return &argv[0].toObject(); +} + /* ES5 15.4.4.20. */ static bool array_filter(JSContext* cx, unsigned argc, Value* vp) diff --git a/js/src/jsarray.h b/js/src/jsarray.h index 24b6711a7c7e..797884a61538 100644 --- a/js/src/jsarray.h +++ b/js/src/jsarray.h @@ -180,6 +180,9 @@ array_unshift(JSContext* cx, unsigned argc, js::Value* vp); extern bool array_slice(JSContext* cx, unsigned argc, js::Value* vp); +extern JSObject* +array_slice_dense(JSContext* cx, HandleObject obj, int32_t begin, int32_t end, HandleObject result); + /* * Append the given (non-hole) value to the end of an array. The array must be * a newborn array -- that is, one which has not been exposed to script for diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp index a820318a5f3a..55b4e3644c38 100644 --- a/js/src/vm/TypeInference.cpp +++ b/js/src/vm/TypeInference.cpp @@ -205,9 +205,9 @@ TypeSet::TypeString(TypeSet::Type type) which = (which + 1) & 3; if (type.isSingleton()) - JS_snprintf(bufs[which], 40, "<0x%p>", (void*) type.singleton()); + JS_snprintf(bufs[which], 40, "<0x%p>", (void*) type.singletonNoBarrier()); else - JS_snprintf(bufs[which], 40, "[0x%p]", (void*) type.group()); + JS_snprintf(bufs[which], 40, "[0x%p]", (void*) type.groupNoBarrier()); return bufs[which]; } diff --git a/js/src/vm/UnboxedObject-inl.h b/js/src/vm/UnboxedObject-inl.h index 3934ab17071a..7fdf616ae98b 100644 --- a/js/src/vm/UnboxedObject-inl.h +++ b/js/src/vm/UnboxedObject-inl.h @@ -387,6 +387,22 @@ SetBoxedOrUnboxedDenseElementNoTypeChange(JSObject* obj, size_t index, const Val obj->as().setElementNoTypeChangeSpecific(index, value); } +template +static inline bool +EnsureBoxedOrUnboxedDenseElements(JSContext* cx, JSObject* obj, size_t count) +{ + if (Type == JSVAL_TYPE_MAGIC) { + if (!obj->as().ensureElements(cx, count)) + return false; + } else { + if (obj->as().capacity() < count) { + if (!obj->as().growElements(cx, count)) + return false; + } + } + return true; +} + enum ShouldUpdateTypes { UpdateTypes = true, @@ -532,7 +548,7 @@ CopyBoxedOrUnboxedDenseElements(JSContext* cx, JSObject* dst, JSObject* src, srcData + srcStart * elementSize, length * elementSize); - // Add a post barrier if we might have copied a nursery pointer to dst. + // Add a store buffer entry if we might have copied a nursery pointer to dst. if (UnboxedTypeNeedsPostBarrier(Type) && !IsInsideNursery(dst)) dst->runtimeFromMainThread()->gc.storeBuffer.putWholeCellFromMainThread(dst); } From 40aab925cb792cc4ce8fec81088d30ea612385d5 Mon Sep 17 00:00:00 2001 From: Sean Stangl Date: Thu, 28 May 2015 15:29:29 -0700 Subject: [PATCH 13/85] Bug 1023297 - Use explicit constructors for ARM-specific classes. r=jandem --- js/src/jit/arm/Assembler-arm.cpp | 108 +++---- js/src/jit/arm/Assembler-arm.h | 410 +++++++++++++++----------- js/src/jit/arm/CodeGenerator-arm.cpp | 24 +- js/src/jit/arm/MacroAssembler-arm.cpp | 170 +++++------ js/src/jit/arm/MacroAssembler-arm.h | 88 +++--- js/src/jit/arm/MoveEmitter-arm.cpp | 82 ++---- js/src/jit/arm/MoveEmitter-arm.h | 6 +- 7 files changed, 447 insertions(+), 441 deletions(-) diff --git a/js/src/jit/arm/Assembler-arm.cpp b/js/src/jit/arm/Assembler-arm.cpp index 305feba0d1a0..e13ef026aa0c 100644 --- a/js/src/jit/arm/Assembler-arm.cpp +++ b/js/src/jit/arm/Assembler-arm.cpp @@ -26,12 +26,12 @@ void dbg_break() {} // Note this is used for inter-AsmJS calls and may pass arguments and results in // floating point registers even if the system ABI does not. -ABIArgGenerator::ABIArgGenerator() : - intRegIndex_(0), +ABIArgGenerator::ABIArgGenerator() + : intRegIndex_(0), floatRegIndex_(0), stackOffset_(0), current_() -{} +{ } ABIArg ABIArgGenerator::next(MIRType type) @@ -498,15 +498,17 @@ InstMOV::IsTHIS(const Instruction& i) } Op2Reg -Operand2::toOp2Reg() { +Operand2::toOp2Reg() const { return *(Op2Reg*)this; } + O2RegImmShift -Op2Reg::toO2RegImmShift() { +Op2Reg::toO2RegImmShift() const { return *(O2RegImmShift*)this; } + O2RegRegShift -Op2Reg::toO2RegRegShift() { +Op2Reg::toO2RegRegShift() const { return *(O2RegRegShift*)this; } @@ -1257,7 +1259,7 @@ BOffImm::BOffImm(Instruction& inst) } Instruction* -BOffImm::getDest(Instruction* src) +BOffImm::getDest(Instruction* src) const { // TODO: It is probably worthwhile to verify that src is actually a branch. // NOTE: This does not explicitly shift the offset of the destination left by 2, @@ -1716,7 +1718,8 @@ Assembler::as_dtr_patch(LoadStore ls, int size, Index mode, Register rt, DTRAddr WriteInstStatic(EncodeDtr(ls, size, mode, rt, addr, c), dest); } -class PoolHintData { +class PoolHintData +{ public: enum LoadType { // Set 0 to bogus, since that is the value most likely to be @@ -1759,19 +1762,19 @@ class PoolHintData { destReg_ = destReg.id(); destType_ = destReg.isDouble(); } - Assembler::Condition getCond() { + Assembler::Condition getCond() const { return Assembler::Condition(cond_ << 28); } - Register getReg() { + Register getReg() const { return Register::FromCode(destReg_); } - VFPRegister getVFPReg() { + VFPRegister getVFPReg() const { VFPRegister r = VFPRegister(destReg_, destType_ ? VFPRegister::Double : VFPRegister::Single); return r; } - int32_t getIndex() { + int32_t getIndex() const { return index_; } void setIndex(uint32_t index) { @@ -1780,7 +1783,7 @@ class PoolHintData { MOZ_ASSERT(index_ == index); } - LoadType getLoadType() { + LoadType getLoadType() const { // If this *was* a PoolBranch, but the branch has already been bound // then this isn't going to look like a real poolhintdata, but we still // want to lie about it so everyone knows it *used* to be a branch. @@ -1789,7 +1792,7 @@ class PoolHintData { return loadType_; } - bool isValidPoolHint() { + bool isValidPoolHint() const { // Most instructions cannot have a condition that is 0xf. Notable // exceptions are blx and the entire NEON instruction set. For the // purposes of pool loads, and possibly patched branches, the possible @@ -1799,7 +1802,8 @@ class PoolHintData { } }; -union PoolHintPun { +union PoolHintPun +{ PoolHintData phd; uint32_t raw; }; @@ -1844,8 +1848,7 @@ BufferOffset Assembler::as_dtm(LoadStore ls, Register rn, uint32_t mask, DTMMode mode, DTMWriteBack wb, Condition c) { - return writeInst(0x08000000 | RN(rn) | ls | - mode | mask | c | wb); + return writeInst(0x08000000 | RN(rn) | ls | mode | mask | c | wb); } BufferOffset @@ -2056,12 +2059,14 @@ Assembler::as_bx(Register r, Condition c) BufferOffset ret = writeInst(((int) c) | OpBx | r.code()); return ret; } + void Assembler::WritePoolGuard(BufferOffset branch, Instruction* dest, BufferOffset afterPool) { BOffImm off = afterPool.diffB(branch); *dest = InstBImm(off, Always); } + // Branch can branch to an immediate *or* to a register. // Branches to immediates are pc relative, branches to registers are absolute. BufferOffset @@ -2106,6 +2111,7 @@ Assembler::as_b(Label* l, Condition c) MOZ_ASSERT(check == old); return ret; } + BufferOffset Assembler::as_b(BOffImm off, Condition c, BufferOffset inst) { @@ -2168,6 +2174,7 @@ Assembler::as_bl(Label* l, Condition c) MOZ_ASSERT(check == old); return ret; } + BufferOffset Assembler::as_bl(BOffImm off, Condition c, BufferOffset inst) { @@ -2195,6 +2202,7 @@ enum vfp_tags { VfpTag = 0x0C000A00, VfpArith = 0x02000000 }; + BufferOffset Assembler::writeVFPInst(vfp_size sz, uint32_t blob) { @@ -2225,43 +2233,37 @@ Assembler::as_vfp_float(VFPRegister vd, VFPRegister vn, VFPRegister vm, } BufferOffset -Assembler::as_vadd(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vadd(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { return as_vfp_float(vd, vn, vm, OpvAdd, c); } BufferOffset -Assembler::as_vdiv(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vdiv(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { return as_vfp_float(vd, vn, vm, OpvDiv, c); } BufferOffset -Assembler::as_vmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { return as_vfp_float(vd, vn, vm, OpvMul, c); } BufferOffset -Assembler::as_vnmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vnmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { return as_vfp_float(vd, vn, vm, OpvMul, c); } BufferOffset -Assembler::as_vnmla(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vnmla(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { MOZ_CRASH("Feature NYI"); } BufferOffset -Assembler::as_vnmls(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vnmls(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { MOZ_CRASH("Feature NYI"); } @@ -2285,18 +2287,17 @@ Assembler::as_vabs(VFPRegister vd, VFPRegister vm, Condition c) } BufferOffset -Assembler::as_vsub(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vsub(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { return as_vfp_float(vd, vn, vm, OpvSub, c); } BufferOffset -Assembler::as_vcmp(VFPRegister vd, VFPRegister vm, - Condition c) +Assembler::as_vcmp(VFPRegister vd, VFPRegister vm, Condition c) { return as_vfp_float(vd, NoVFPRegister, vm, OpvCmp, c); } + BufferOffset Assembler::as_vcmpz(VFPRegister vd, Condition c) { @@ -2309,6 +2310,7 @@ Assembler::as_vmov(VFPRegister vd, VFPRegister vsrc, Condition c) { return as_vfp_float(vd, NoVFPRegister, vsrc, OpvMov, c); } + // Transfer between Core and VFP. // Unlike the next function, moving between the core registers and vfp registers @@ -2339,15 +2341,13 @@ Assembler::as_vxfer(Register vt1, Register vt2, VFPRegister vm, FloatToCore_ f2c MOZ_ASSERT(idx == 0); } - if (vt2 == InvalidReg) { - return writeVFPInst(sz, WordTransfer | f2c | c | - RT(vt1) | maybeRN(vt2) | VN(vm) | idx); - } else { - // We are doing a 64 bit transfer. - return writeVFPInst(sz, DoubleTransfer | f2c | c | - RT(vt1) | maybeRN(vt2) | VM(vm) | idx); - } + if (vt2 == InvalidReg) + return writeVFPInst(sz, WordTransfer | f2c | c | RT(vt1) | maybeRN(vt2) | VN(vm) | idx); + + // We are doing a 64 bit transfer. + return writeVFPInst(sz, DoubleTransfer | f2c | c | RT(vt1) | maybeRN(vt2) | VM(vm) | idx); } + enum vcvt_destFloatness { VcvtToInteger = 1 << 18, VcvtToFloat = 0 << 18 @@ -2384,9 +2384,9 @@ Assembler::as_vcvt(VFPRegister vd, VFPRegister vm, bool useFPSCR, vcvt_Signedness opSign; vcvt_toZero doToZero = VcvtToFPSCR; MOZ_ASSERT(vd.isFloat() || vm.isFloat()); - if (vd.isSingle() || vm.isSingle()) { + if (vd.isSingle() || vm.isSingle()) sz = IsSingle; - } + if (vd.isFloat()) { destFloat = VcvtToFloat; opSign = (vm.isSInt()) ? VcvtFromSigned : VcvtFromUnsigned; @@ -2459,6 +2459,7 @@ Assembler::as_vimm(VFPRegister vd, VFPImm imm, Condition c) return writeVFPInst(sz, c | imm.encode() | VD(vd) | 0x02B00000); } + BufferOffset Assembler::as_vmrs(Register r, Condition c) { @@ -2577,7 +2578,6 @@ Assembler::retarget(Label* label, Label* target) } - static int stopBKPT = -1; void Assembler::as_bkpt() @@ -2632,6 +2632,7 @@ Assembler::GetBranchOffset(const Instruction* i_) i->extractImm(&dest); return dest.decode(); } + void Assembler::RetargetNearBranch(Instruction* i, int offset, bool final) { @@ -2667,7 +2668,8 @@ Assembler::RetargetFarBranch(Instruction* i, uint8_t** slot, uint8_t* dest, Cond } -struct PoolHeader : Instruction { +struct PoolHeader : Instruction +{ struct Header { // The size should take into account the pool header. @@ -2708,6 +2710,7 @@ struct PoolHeader : Instruction { Header tmp(this); return tmp.isNatural; } + static bool IsTHIS(const Instruction& i) { return (*i.raw() & 0xffff0000) == 0xffff0000; } @@ -2718,12 +2721,10 @@ struct PoolHeader : Instruction { } }; - void Assembler::WritePoolHeader(uint8_t* start, Pool* p, bool isNatural) { - static_assert(sizeof(PoolHeader) == 4, - "PoolHandler must have the correct size."); + static_assert(sizeof(PoolHeader) == 4, "PoolHandler must have the correct size."); uint8_t* pool = start + 4; // Go through the usual rigmarole to get the size of the pool. pool += p->getPoolSize(); @@ -2735,7 +2736,6 @@ Assembler::WritePoolHeader(uint8_t* start, Pool* p, bool isNatural) *(PoolHeader*)start = header; } - // The size of an arbitrary 32-bit call in the instruction stream. On ARM this // sequence is |pc = ldr pc - 4; imm32| given that we never reach the imm32. uint32_t @@ -2743,6 +2743,7 @@ Assembler::PatchWrite_NearCallSize() { return sizeof(uint32_t); } + void Assembler::PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall) { @@ -2754,8 +2755,8 @@ Assembler::PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall new (inst) InstBLImm(BOffImm(dest - (uint8_t*)inst) , Always); // Ensure everyone sees the code that was just written into memory. AutoFlushICache::flush(uintptr_t(inst), 4); - } + void Assembler::PatchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newValue, PatchedImmPtr expectedValue) @@ -2796,7 +2797,6 @@ Assembler::PatchWrite_Imm32(CodeLocationLabel label, Imm32 imm) { *(raw - 1) = imm.value; } - uint8_t* Assembler::NextInstruction(uint8_t* inst_, uint32_t* count) { @@ -2821,7 +2821,8 @@ InstIsGuard(Instruction* inst, const PoolHeader** ph) } static bool -InstIsBNop(Instruction* inst) { +InstIsBNop(Instruction* inst) +{ // In some special situations, it is necessary to insert a NOP into the // instruction stream that nobody knows about, since nobody should know // about it, make sure it gets skipped when Instruction::next() is called. @@ -3030,7 +3031,8 @@ void Assembler::UpdateBoundsCheck(uint32_t heapSize, Instruction* inst) // for us. Don't call this! } -InstructionIterator::InstructionIterator(Instruction* i_) : i(i_) +InstructionIterator::InstructionIterator(Instruction* i_) + : i(i_) { // Work around pools with an artificial pool guard and around nop-fill. i = i->skipPool(); diff --git a/js/src/jit/arm/Assembler-arm.h b/js/src/jit/arm/Assembler-arm.h index 66262de8250c..e27cb98d5e2d 100644 --- a/js/src/jit/arm/Assembler-arm.h +++ b/js/src/jit/arm/Assembler-arm.h @@ -74,9 +74,11 @@ class ABIArgGenerator public: ABIArgGenerator(); + ABIArg next(MIRType argType); ABIArg& current() { return current_; } uint32_t stackBytesConsumedSoFar() const { return stackOffset_; } + static const Register NonArgReturnReg0; static const Register NonArgReturnReg1; static const Register NonReturn_VolatileReg0; @@ -237,7 +239,6 @@ enum IsImmEDTR_ { IsNotImmEDTR = 0 << 22 }; - enum ShiftType { LSL = 0, // << 5 LSR = 1, // << 5 @@ -281,6 +282,7 @@ enum LoadStore { IsLoad = 1 << 20, IsStore = 0 << 20 }; + // You almost never want to use this directly. Instead, you wantto pass in a // signed constant, and let this bit be implicitly set for you. This is however, // necessary if we want a negative index. @@ -341,16 +343,19 @@ enum VFPOp { OpvCmp = 0xB << 20 | 0x1 << 6 | 0x4 << 16, OpvCmpz = 0xB << 20 | 0x1 << 6 | 0x5 << 16 }; + // Negate the operation, AND negate the immediate that we were passed in. ALUOp ALUNeg(ALUOp op, Register dest, Imm32* imm, Register* negDest); bool can_dbl(ALUOp op); bool condsAreSafe(ALUOp op); + // If there is a variant of op that has a dest (think cmp/sub) return that // variant of it. ALUOp getDestVariant(ALUOp op); static const ValueOperand JSReturnOperand = ValueOperand(JSReturnReg_Type, JSReturnReg_Data); static const ValueOperand softfpReturnOperand = ValueOperand(r1, r0); + // All of these classes exist solely to shuffle data into the various operands. // For example Operand2 can be an imm8, a register-shifted-by-a-constant or a // register-shifted-by-a-register. We represent this in C++ by having a base @@ -372,7 +377,9 @@ static const ValueOperand softfpReturnOperand = ValueOperand(r1, r0); class Op2Reg; class O2RegImmShift; class O2RegRegShift; + namespace datastore { + struct Reg { // The "second register". @@ -389,12 +396,13 @@ struct Reg : RM(rm), RRS(rsr), Type(type), ShiftAmount(shiftamount), pad(0) { } - uint32_t encode() { - return RM | RRS << 4 | Type << 5 | ShiftAmount << 7; - } explicit Reg(const Op2Reg& op) { memcpy(this, &op, sizeof(*this)); } + + uint32_t encode() const { + return RM | RRS << 4 | Type << 5 | ShiftAmount << 7; + } }; // Op2 has a mode labelled "", which is arm's magical immediate encoding. @@ -409,10 +417,12 @@ struct Imm8mData // if we can encode it properly, a simple "|" will still suffice to meld it // into the instruction. uint32_t buff : 19; + public: uint32_t invalid : 1; - uint32_t encode() { + public: + uint32_t encode() const { MOZ_ASSERT(!invalid); return data | rot << 8; }; @@ -438,12 +448,16 @@ struct Imm8Data uint32_t imm4H : 4; public: - uint32_t encode() { - return imm4L | (imm4H << 8); - }; - Imm8Data(uint32_t imm) : imm4L(imm & 0xf), imm4H(imm >> 4) { + Imm8Data(uint32_t imm) + : imm4L(imm & 0xf), imm4H(imm >> 4) + { MOZ_ASSERT(imm <= 0xff); } + + public: + uint32_t encode() const { + return imm4L | (imm4H << 8); + }; }; // VLDR/VSTR take an 8 bit offset, which is implicitly left shifted by 2. @@ -453,12 +467,16 @@ struct Imm8VFPOffData uint32_t data; public: - uint32_t encode() { - return data; - }; - Imm8VFPOffData(uint32_t imm) : data (imm) { + Imm8VFPOffData(uint32_t imm) + : data (imm) + { MOZ_ASSERT((imm & ~(0xff)) == 0); } + + public: + uint32_t encode() const { + return data; + }; }; // ARM can magically encode 256 very special immediates to be moved into a @@ -478,7 +496,7 @@ struct Imm8VFPImmData uint32_t imm4H : 4; int32_t isInvalid : 24; - uint32_t encode() { + uint32_t encode() const { // This assert is an attempting at ensuring that we don't create random // instances of this structure and then asking to encode() it. MOZ_ASSERT(isInvalid == 0); @@ -489,9 +507,6 @@ struct Imm8VFPImmData struct Imm12Data { uint32_t data : 12; - uint32_t encode() { - return data; - } Imm12Data(uint32_t imm) : data(imm) @@ -499,21 +514,28 @@ struct Imm12Data MOZ_ASSERT(data == imm); } + uint32_t encode() const { + return data; + } }; struct RIS { uint32_t ShiftAmount : 5; - uint32_t encode () { - return ShiftAmount; - } RIS(uint32_t imm) : ShiftAmount(imm) { MOZ_ASSERT(ShiftAmount == imm); } - explicit RIS(Reg r) : ShiftAmount(r.ShiftAmount) {} + + explicit RIS(Reg r) + : ShiftAmount(r.ShiftAmount) + { } + + uint32_t encode() const { + return ShiftAmount; + } }; struct RRS @@ -528,7 +550,7 @@ struct RRS MOZ_ASSERT(rs == RS); } - uint32_t encode () { + uint32_t encode() const { return RS << 1; } }; @@ -542,40 +564,49 @@ class Operand2 friend class Operand; friend class MacroAssemblerARM; friend class InstALU; + public: uint32_t oper : 31; uint32_t invalid : 1; - bool isO2Reg() { - return !(oper & IsImmOp2); - } - Op2Reg toOp2Reg(); - bool isImm8() { - return oper & IsImmOp2; - } protected: - Operand2(datastore::Imm8mData base) + explicit Operand2(datastore::Imm8mData base) : oper(base.invalid ? -1 : (base.encode() | (uint32_t)IsImmOp2)), invalid(base.invalid) { } - Operand2(datastore::Reg base) + explicit Operand2(datastore::Reg base) : oper(base.encode() | (uint32_t)IsNotImmOp2) { } private: - Operand2(int blob) + explicit Operand2(int blob) : oper(blob) { } public: - uint32_t encode() { + bool isO2Reg() const { + return !(oper & IsImmOp2); + } + + Op2Reg toOp2Reg() const; + + bool isImm8() const { + return oper & IsImmOp2; + } + + uint32_t encode() const { return oper; } }; class Imm8 : public Operand2 { + public: + explicit Imm8(uint32_t imm) + : Operand2(EncodeImm(imm)) + { } + public: static datastore::Imm8mData EncodeImm(uint32_t imm) { // mozilla::CountLeadingZeroes32(imm) requires imm != 0. @@ -607,6 +638,7 @@ class Imm8 : public Operand2 return datastore::Imm8mData(mask, (8 - right) >> 1); return datastore::Imm8mData(); } + // Pair template? struct TwoImm8mData { @@ -622,41 +654,41 @@ class Imm8 : public Operand2 }; static TwoImm8mData EncodeTwoImms(uint32_t); - Imm8(uint32_t imm) - : Operand2(EncodeImm(imm)) - { } }; class Op2Reg : public Operand2 { public: - Op2Reg(Register rm, ShiftType type, datastore::RIS shiftImm) + explicit Op2Reg(Register rm, ShiftType type, datastore::RIS shiftImm) : Operand2(datastore::Reg(rm.code(), type, 0, shiftImm.encode())) { } - Op2Reg(Register rm, ShiftType type, datastore::RRS shiftReg) + explicit Op2Reg(Register rm, ShiftType type, datastore::RRS shiftReg) : Operand2(datastore::Reg(rm.code(), type, 1, shiftReg.encode())) { } - bool isO2RegImmShift() { + + public: + bool isO2RegImmShift() const { datastore::Reg r(*this); return !r.RRS; } - O2RegImmShift toO2RegImmShift(); - bool isO2RegRegShift() { + O2RegImmShift toO2RegImmShift() const; + + bool isO2RegRegShift() const { datastore::Reg r(*this); return r.RRS; } - O2RegRegShift toO2RegRegShift(); + O2RegRegShift toO2RegRegShift() const; - bool checkType(ShiftType type) { + bool checkType(ShiftType type) const { datastore::Reg r(*this); return r.Type == type; } - bool checkRM(Register rm) { + bool checkRM(Register rm) const { datastore::Reg r(*this); return r.RM == rm.code(); } - bool getRM(Register* rm) { + bool getRM(Register* rm) const { datastore::Reg r(*this); *rm = Register::FromCode(r.RM); return true; @@ -666,10 +698,12 @@ class Op2Reg : public Operand2 class O2RegImmShift : public Op2Reg { public: - O2RegImmShift(Register rn, ShiftType type, uint32_t shift) + explicit O2RegImmShift(Register rn, ShiftType type, uint32_t shift) : Op2Reg(rn, type, datastore::RIS(shift)) { } - int getShift() { + + public: + int getShift() const { datastore::Reg r(*this); datastore::RIS ris(r); return ris.ShiftAmount; @@ -679,22 +713,22 @@ class O2RegImmShift : public Op2Reg class O2RegRegShift : public Op2Reg { public: - O2RegRegShift(Register rn, ShiftType type, Register rs) + explicit O2RegRegShift(Register rn, ShiftType type, Register rs) : Op2Reg(rn, type, datastore::RRS(rs.code())) { } }; O2RegImmShift O2Reg(Register r); -O2RegImmShift lsl (Register r, int amt); -O2RegImmShift lsr (Register r, int amt); -O2RegImmShift asr (Register r, int amt); -O2RegImmShift rol (Register r, int amt); -O2RegImmShift ror (Register r, int amt); +O2RegImmShift lsl(Register r, int amt); +O2RegImmShift lsr(Register r, int amt); +O2RegImmShift asr(Register r, int amt); +O2RegImmShift rol(Register r, int amt); +O2RegImmShift ror(Register r, int amt); -O2RegRegShift lsl (Register r, Register amt); -O2RegRegShift lsr (Register r, Register amt); -O2RegRegShift asr (Register r, Register amt); -O2RegRegShift ror (Register r, Register amt); +O2RegRegShift lsl(Register r, Register amt); +O2RegRegShift lsr(Register r, Register amt); +O2RegRegShift asr(Register r, Register amt); +O2RegRegShift ror(Register r, Register amt); // An offset from a register to be used for ldr/str. This should include the // sign bit, since ARM has "signed-magnitude" offsets. That is it encodes an @@ -706,22 +740,22 @@ class DtrOff uint32_t data; protected: - DtrOff(datastore::Imm12Data immdata, IsUp_ iu) + explicit DtrOff(datastore::Imm12Data immdata, IsUp_ iu) : data(immdata.encode() | (uint32_t)IsImmDTR | ((uint32_t)iu)) { } - DtrOff(datastore::Reg reg, IsUp_ iu = IsUp) + explicit DtrOff(datastore::Reg reg, IsUp_ iu = IsUp) : data(reg.encode() | (uint32_t) IsNotImmDTR | iu) { } public: - uint32_t encode() { return data; } + uint32_t encode() const { return data; } }; class DtrOffImm : public DtrOff { public: - DtrOffImm(int32_t imm) + explicit DtrOffImm(int32_t imm) : DtrOff(datastore::Imm12Data(mozilla::Abs(imm)), imm >= 0 ? IsUp : IsDown) { MOZ_ASSERT(mozilla::Abs(imm) < 4096); @@ -733,11 +767,11 @@ class DtrOffReg : public DtrOff // These are designed to be called by a constructor of a subclass. // Constructing the necessary RIS/RRS structures are annoying. protected: - DtrOffReg(Register rn, ShiftType type, datastore::RIS shiftImm, IsUp_ iu = IsUp) + explicit DtrOffReg(Register rn, ShiftType type, datastore::RIS shiftImm, IsUp_ iu = IsUp) : DtrOff(datastore::Reg(rn.code(), type, 0, shiftImm.encode()), iu) { } - DtrOffReg(Register rn, ShiftType type, datastore::RRS shiftReg, IsUp_ iu = IsUp) + explicit DtrOffReg(Register rn, ShiftType type, datastore::RRS shiftReg, IsUp_ iu = IsUp) : DtrOff(datastore::Reg(rn.code(), type, 1, shiftReg.encode()), iu) { } }; @@ -745,7 +779,7 @@ class DtrOffReg : public DtrOff class DtrRegImmShift : public DtrOffReg { public: - DtrRegImmShift(Register rn, ShiftType type, uint32_t shift, IsUp_ iu = IsUp) + explicit DtrRegImmShift(Register rn, ShiftType type, uint32_t shift, IsUp_ iu = IsUp) : DtrOffReg(rn, type, datastore::RIS(shift), iu) { } }; @@ -753,7 +787,7 @@ class DtrRegImmShift : public DtrOffReg class DtrRegRegShift : public DtrOffReg { public: - DtrRegRegShift(Register rn, ShiftType type, Register rs, IsUp_ iu = IsUp) + explicit DtrRegRegShift(Register rn, ShiftType type, Register rs, IsUp_ iu = IsUp) : DtrOffReg(rn, type, datastore::RRS(rs.code()), iu) { } }; @@ -762,24 +796,28 @@ class DtrRegRegShift : public DtrOffReg // an "operand" to a load instruction. class DTRAddr { + friend class Operand; + uint32_t data; public: - DTRAddr(Register reg, DtrOff dtr) + explicit DTRAddr(Register reg, DtrOff dtr) : data(dtr.encode() | (reg.code() << 16)) { } - uint32_t encode() { - return data; - } - Register getBase() { - return Register::FromCode((data >> 16) &0xf); - } private: - friend class Operand; - DTRAddr(uint32_t blob) + explicit DTRAddr(uint32_t blob) : data(blob) { } + + public: + uint32_t encode() const { + return data; + } + + Register getBase() const { + return Register::FromCode((data >> 16) &0xf); + } }; // Offsets for the extended data transfer instructions: @@ -789,16 +827,16 @@ class EDtrOff uint32_t data; protected: - EDtrOff(datastore::Imm8Data imm8, IsUp_ iu = IsUp) + explicit EDtrOff(datastore::Imm8Data imm8, IsUp_ iu = IsUp) : data(imm8.encode() | IsImmEDTR | (uint32_t)iu) { } - EDtrOff(Register rm, IsUp_ iu = IsUp) + explicit EDtrOff(Register rm, IsUp_ iu = IsUp) : data(rm.code() | IsNotImmEDTR | iu) { } public: - uint32_t encode() { + uint32_t encode() const { return data; } }; @@ -806,7 +844,7 @@ class EDtrOff class EDtrOffImm : public EDtrOff { public: - EDtrOffImm(int32_t imm) + explicit EDtrOffImm(int32_t imm) : EDtrOff(datastore::Imm8Data(mozilla::Abs(imm)), (imm >= 0) ? IsUp : IsDown) { MOZ_ASSERT(mozilla::Abs(imm) < 256); @@ -818,7 +856,7 @@ class EDtrOffImm : public EDtrOff class EDtrOffReg : public EDtrOff { public: - EDtrOffReg(Register rm) + explicit EDtrOffReg(Register rm) : EDtrOff(rm) { } }; @@ -828,11 +866,11 @@ class EDtrAddr uint32_t data; public: - EDtrAddr(Register r, EDtrOff off) + explicit EDtrAddr(Register r, EDtrOff off) : data(RN(r) | off.encode()) { } - uint32_t encode() { + uint32_t encode() const { return data; } }; @@ -842,12 +880,12 @@ class VFPOff uint32_t data; protected: - VFPOff(datastore::Imm8VFPOffData imm, IsUp_ isup) + explicit VFPOff(datastore::Imm8VFPOffData imm, IsUp_ isup) : data(imm.encode() | (uint32_t)isup) { } public: - uint32_t encode() { + uint32_t encode() const { return data; } }; @@ -855,45 +893,49 @@ class VFPOff class VFPOffImm : public VFPOff { public: - VFPOffImm(int32_t imm) + explicit VFPOffImm(int32_t imm) : VFPOff(datastore::Imm8VFPOffData(mozilla::Abs(imm) / 4), imm < 0 ? IsDown : IsUp) { MOZ_ASSERT(mozilla::Abs(imm) <= 255 * 4); } }; + class VFPAddr { friend class Operand; uint32_t data; + public: + explicit VFPAddr(Register base, VFPOff off) + : data(RN(base) | off.encode()) + { } + protected: VFPAddr(uint32_t blob) : data(blob) { } public: - VFPAddr(Register base, VFPOff off) - : data(RN(base) | off.encode()) - { } - - uint32_t encode() { + uint32_t encode() const { return data; } }; -class VFPImm { +class VFPImm +{ uint32_t data; + public: + explicit VFPImm(uint32_t topWordOfDouble); + public: static const VFPImm One; - VFPImm(uint32_t topWordOfDouble); - - uint32_t encode() { + uint32_t encode() const { return data; } - bool isValid() { + bool isValid() const { return data != -1U; } }; @@ -903,16 +945,11 @@ class VFPImm { // constructing a branch. class BOffImm { + friend class InstBranchImm; + uint32_t data; public: - uint32_t encode() { - return data; - } - int32_t decode() { - return ((((int32_t)data) << 8) >> 6) + 8; - } - explicit BOffImm(int offset) : data ((offset - 8) >> 2 & 0x00ffffff) { @@ -920,27 +957,36 @@ class BOffImm if (!IsInRange(offset)) CrashAtUnhandlableOOM("BOffImm"); } - static bool IsInRange(int offset) - { + + explicit BOffImm() + : data(INVALID) + { } + + private: + BOffImm(Instruction& inst); + + public: + static const int INVALID = 0x00800000; + + uint32_t encode() const { + return data; + } + int32_t decode() const { + return ((((int32_t)data) << 8) >> 6) + 8; + } + + static bool IsInRange(int offset) { if ((offset - 8) < -33554432) return false; if ((offset - 8) > 33554428) return false; return true; } - static const int INVALID = 0x00800000; - BOffImm() - : data(INVALID) - { } - bool isInvalid() { + bool isInvalid() const { return data == uint32_t(INVALID); } - Instruction* getDest(Instruction* src); - - private: - friend class InstBranchImm; - BOffImm(Instruction& inst); + Instruction* getDest(Instruction* src) const; }; class Imm16 @@ -951,18 +997,18 @@ class Imm16 uint32_t invalid : 12; public: - Imm16(); - Imm16(uint32_t imm); - Imm16(Instruction& inst); + explicit Imm16(); + explicit Imm16(uint32_t imm); + explicit Imm16(Instruction& inst); - uint32_t encode() { + uint32_t encode() const { return lower | upper << 16; } - uint32_t decode() { + uint32_t decode() const { return lower | upper << 12; } - bool isInvalid () { + bool isInvalid () const { return invalid; } }; @@ -988,26 +1034,27 @@ class Operand uint32_t data; public: - Operand (Register reg_) + explicit Operand(Register reg_) : Tag(OP2), reg(reg_.code()) { } - Operand (FloatRegister freg) + explicit Operand(FloatRegister freg) : Tag(FOP), reg(freg.code()) { } - Operand (Register base, Imm32 off) + explicit Operand(Register base, Imm32 off) : Tag(MEM), reg(base.code()), offset(off.value) { } - Operand (Register base, int32_t off) + explicit Operand(Register base, int32_t off) : Tag(MEM), reg(base.code()), offset(off) { } - Operand (const Address& addr) + explicit Operand(const Address& addr) : Tag(MEM), reg(addr.base.code()), offset(addr.offset) { } + public: Tag_ getTag() const { return Tag; } @@ -1028,6 +1075,7 @@ class Operand *dest = Imm32(offset); } Address toAddress() const { + MOZ_ASSERT(Tag == MEM); return Address(Register::FromCode(reg), offset); } int32_t disp() const { @@ -1052,6 +1100,7 @@ class Operand void PatchJump(CodeLocationJump& jump_, CodeLocationLabel label); + static inline void PatchBackedge(CodeLocationJump& jump_, CodeLocationLabel label, JitRuntime::BackedgeTarget target) { @@ -1179,8 +1228,8 @@ class Assembler : public AssemblerShared static uint32_t GetNopFill(); static uint32_t AsmPoolMaxOffset; static uint32_t GetPoolMaxOffset(); - protected: + protected: // Structure for fixing up pc-relative loads/jumps when a the machine code // gets moved (executable copy, gc, etc.). struct RelativePatch @@ -1214,8 +1263,7 @@ class Assembler : public AssemblerShared isFinished(false), dtmActive(false), dtmCond(Always) - { - } + { } // We need to wait until an AutoJitContextAlloc is created by the // MacroAssembler, before allocating any space. @@ -1352,14 +1400,11 @@ class Assembler : public AssemblerShared BufferOffset as_rsc(Register dest, Register src1, Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); // Test operations: - BufferOffset as_cmn(Register src1, Operand2 op2, - Condition c = Always); - BufferOffset as_cmp(Register src1, Operand2 op2, - Condition c = Always); - BufferOffset as_teq(Register src1, Operand2 op2, - Condition c = Always); - BufferOffset as_tst(Register src1, Operand2 op2, - Condition c = Always); + BufferOffset as_cmn(Register src1, Operand2 op2, Condition c = Always); + BufferOffset as_cmp(Register src1, Operand2 op2, Condition c = Always); + BufferOffset as_teq(Register src1, Operand2 op2, Condition c = Always); + BufferOffset as_tst(Register src1, Operand2 op2, Condition c = Always); + // Sign extension operations: BufferOffset as_sxtb(Register dest, Register src, int rotate, Condition c = Always); BufferOffset as_sxth(Register dest, Register src, int rotate, Condition c = Always); @@ -1367,8 +1412,7 @@ class Assembler : public AssemblerShared BufferOffset as_uxth(Register dest, Register src, int rotate, Condition c = Always); // Not quite ALU worthy, but useful none the less: These also have the issue - // of these being formatted completly differently from the standard ALU - // operations. + // of these being formatted completly differently from the standard ALU operations. BufferOffset as_movw(Register dest, Imm16 imm, Condition c = Always); BufferOffset as_movt(Register dest, Imm16 imm, Condition c = Always); @@ -1420,7 +1464,8 @@ class Assembler : public AssemblerShared // Load a 32 bit immediate from a pool into a register. BufferOffset as_Imm32Pool(Register dest, uint32_t value, Condition c = Always); // Make a patchable jump that can target the entire 32 bit address space. - BufferOffset as_BranchPool(uint32_t value, RepatchLabel* label, ARMBuffer::PoolEntry* pe = nullptr, Condition c = Always); + BufferOffset as_BranchPool(uint32_t value, RepatchLabel* label, + ARMBuffer::PoolEntry* pe = nullptr, Condition c = Always); // Load a 64 bit floating point immediate from a pool into a register. BufferOffset as_FImm64Pool(VFPRegister dest, double value, Condition c = Always); @@ -1444,10 +1489,8 @@ class Assembler : public AssemblerShared BufferOffset as_strexh(Register rd, Register rt, Register rn, Condition c = Always); BufferOffset as_strexb(Register rd, Register rt, Register rn, Condition c = Always); - // Memory synchronization: dmb, dsb, isb. - // + // Memory synchronization. // These are available from ARMv7 forward. - BufferOffset as_dmb(BarrierOption option = BarrierSY); BufferOffset as_dsb(BarrierOption option = BarrierSY); BufferOffset as_isb(); @@ -1487,9 +1530,9 @@ class Assembler : public AssemblerShared BufferOffset as_mrs(Register r, Condition c = Always); BufferOffset as_msr(Register r, Condition c = Always); + // VFP instructions! private: - enum vfp_size { IsDouble = 1 << 8, IsSingle = 0 << 8 @@ -1505,39 +1548,22 @@ class Assembler : public AssemblerShared VFPOp op, Condition c = Always); public: - BufferOffset as_vadd(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vdiv(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vnmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vnmla(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vnmls(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - + BufferOffset as_vadd(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vdiv(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vnmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vnmla(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vnmls(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); BufferOffset as_vneg(VFPRegister vd, VFPRegister vm, Condition c = Always); - BufferOffset as_vsqrt(VFPRegister vd, VFPRegister vm, Condition c = Always); - BufferOffset as_vabs(VFPRegister vd, VFPRegister vm, Condition c = Always); - - BufferOffset as_vsub(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vcmp(VFPRegister vd, VFPRegister vm, - Condition c = Always); + BufferOffset as_vsub(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vcmp(VFPRegister vd, VFPRegister vm, Condition c = Always); BufferOffset as_vcmpz(VFPRegister vd, Condition c = Always); // Specifically, a move between two same sized-registers. BufferOffset as_vmov(VFPRegister vd, VFPRegister vsrc, Condition c = Always); + // Transfer between Core and VFP. enum FloatToCore_ { FloatToCore = 1 << 20, @@ -1564,26 +1590,29 @@ class Assembler : public AssemblerShared // to uniquely specify the encoding that we are going to use. BufferOffset as_vcvt(VFPRegister vd, VFPRegister vm, bool useFPSCR = false, Condition c = Always); + // Hard coded to a 32 bit fixed width result for now. - BufferOffset as_vcvtFixed(VFPRegister vd, bool isSigned, uint32_t fixedPoint, bool toFixed, Condition c = Always); + BufferOffset as_vcvtFixed(VFPRegister vd, bool isSigned, uint32_t fixedPoint, + bool toFixed, Condition c = Always); // Transfer between VFP and memory. BufferOffset as_vdtr(LoadStore ls, VFPRegister vd, VFPAddr addr, Condition c = Always /* vfp doesn't have a wb option*/); static void as_vdtr_patch(LoadStore ls, VFPRegister vd, VFPAddr addr, - Condition c /* vfp doesn't have a wb option*/, uint32_t* dest); + Condition c /* vfp doesn't have a wb option */, uint32_t* dest); // VFP's ldm/stm work differently from the standard arm ones. You can only // transfer a range. BufferOffset as_vdtm(LoadStore st, Register rn, VFPRegister vd, int length, - /*also has update conditions*/Condition c = Always); + /* also has update conditions */ Condition c = Always); BufferOffset as_vimm(VFPRegister vd, VFPImm imm, Condition c = Always); BufferOffset as_vmrs(Register r, Condition c = Always); BufferOffset as_vmsr(Register r, Condition c = Always); + // Label operations. bool nextLink(BufferOffset b, BufferOffset* next); void bind(Label* label, BufferOffset boff = BufferOffset()); @@ -1911,6 +1940,7 @@ class InstLDR : public InstDTR InstLDR(Index mode, Register rt, DTRAddr addr, Assembler::Condition c) : InstDTR(IsLoad, IsWord, mode, rt, addr, c) { } + static bool IsTHIS(const Instruction& i); static InstLDR* AsTHIS(const Instruction& i); @@ -1939,13 +1969,17 @@ class InstBranchReg : public Instruction IsBX = 0x012fff10, IsBLX = 0x012fff30 }; + static const uint32_t IsBRegMask = 0x0ffffff0; + InstBranchReg(BranchTag tag, Register rm, Assembler::Condition c) : Instruction(tag | rm.code(), c) { } + public: static bool IsTHIS (const Instruction& i); static InstBranchReg* AsTHIS (const Instruction& i); + // Get the register that is being branched to void extractDest(Register* dest); // Make sure we are branching to a pre-known register @@ -1961,6 +1995,7 @@ class InstBranchImm : public Instruction IsB = 0x0a000000, IsBL = 0x0b000000 }; + static const uint32_t IsBImmMask = 0x0f000000; InstBranchImm(BranchTag tag, BOffImm off, Assembler::Condition c) @@ -1970,6 +2005,7 @@ class InstBranchImm : public Instruction public: static bool IsTHIS (const Instruction& i); static InstBranchImm* AsTHIS (const Instruction& i); + void extractImm(BOffImm* dest); }; JS_STATIC_ASSERT(sizeof(InstBranchImm) == sizeof(Instruction)); @@ -1981,6 +2017,7 @@ class InstBXReg : public InstBranchReg static bool IsTHIS (const Instruction& i); static InstBXReg* AsTHIS (const Instruction& i); }; + class InstBLXReg : public InstBranchReg { public: @@ -1991,6 +2028,7 @@ class InstBLXReg : public InstBranchReg static bool IsTHIS (const Instruction& i); static InstBLXReg* AsTHIS (const Instruction& i); }; + class InstBImm : public InstBranchImm { public: @@ -2001,6 +2039,7 @@ class InstBImm : public InstBranchImm static bool IsTHIS (const Instruction& i); static InstBImm* AsTHIS (const Instruction& i); }; + class InstBLImm : public InstBranchImm { public: @@ -2056,6 +2095,7 @@ class InstMovT : public InstMovWT InstMovT (Register rd, Imm16 imm, Assembler::Condition c) : InstMovWT(rd, imm, IsT, c) { } + static bool IsTHIS (const Instruction& i); static InstMovT* AsTHIS (const Instruction& i); }; @@ -2063,12 +2103,15 @@ class InstMovT : public InstMovWT class InstALU : public Instruction { static const int32_t ALUMask = 0xc << 24; + public: InstALU (Register rd, Register rn, Operand2 op2, ALUOp op, SetCond_ sc, Assembler::Condition c) : Instruction(maybeRD(rd) | maybeRN(rn) | op2.encode() | op | sc, c) { } + static bool IsTHIS (const Instruction& i); static InstALU* AsTHIS (const Instruction& i); + void extractOp(ALUOp* ret); bool checkOp(ALUOp op); void extractDest(Register* ret); @@ -2093,11 +2136,14 @@ class InstMOV : public InstALU }; -class InstructionIterator { +class InstructionIterator +{ private: Instruction* i; + public: - InstructionIterator(Instruction* i_); + explicit InstructionIterator(Instruction* i_); + Instruction* next() { i = i->next(); return cur(); @@ -2108,6 +2154,7 @@ class InstructionIterator { }; static const uint32_t NumIntArgRegs = 4; + // There are 16 *float* registers available for arguments // If doubles are used, only half the number of registers are available. static const uint32_t NumFloatArgRegs = 16; @@ -2117,6 +2164,7 @@ GetIntArgReg(uint32_t usedIntArgs, uint32_t usedFloatArgs, Register* out) { if (usedIntArgs >= NumIntArgRegs) return false; + *out = Register::FromCode(usedIntArgs); return true; } @@ -2131,12 +2179,14 @@ GetTempRegForIntArg(uint32_t usedIntArgs, uint32_t usedFloatArgs, Register* out) { if (GetIntArgReg(usedIntArgs, usedFloatArgs, out)) return true; + // Unfortunately, we have to assume things about the point at which // GetIntArgReg returns false, because we need to know how many registers it // can allocate. usedIntArgs -= NumIntArgRegs; if (usedIntArgs >= NumCallTempNonArgRegs) return false; + *out = CallTempNonArgRegs[usedIntArgs]; return true; } @@ -2220,7 +2270,8 @@ GetDoubleArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t* pa -class DoubleEncoder { +class DoubleEncoder +{ struct DoubleEntry { uint32_t dblTop; @@ -2230,7 +2281,7 @@ class DoubleEncoder { static const DoubleEntry table[256]; public: - bool lookup(uint32_t top, datastore::Imm8VFPImmData* ret) { + bool lookup(uint32_t top, datastore::Imm8VFPImmData* ret) const { for (int i = 0; i < 256; i++) { if (table[i].dblTop == top) { *ret = table[i].data; @@ -2241,8 +2292,10 @@ class DoubleEncoder { } }; -class AutoForbidPools { +class AutoForbidPools +{ Assembler* masm_; + public: // The maxInst argument is the maximum number of word sized instructions // that will be allocated within this context. It is used to determine if @@ -2251,9 +2304,12 @@ class AutoForbidPools { // // Allocation of pool entries is not supported within this content so the // code can not use large integers or float constants etc. - AutoForbidPools(Assembler* masm, size_t maxInst) : masm_(masm) { + AutoForbidPools(Assembler* masm, size_t maxInst) + : masm_(masm) + { masm_->enterNoPool(maxInst); } + ~AutoForbidPools() { masm_->leaveNoPool(); } diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index 5694e2525ffc..bc3e66378e16 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -1793,9 +1793,9 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap* ins) if (isFloat) { VFPRegister vd(ToFloatRegister(ins->output())); if (size == 32) - masm.ma_vldr(Operand(HeapReg, ptrImm), vd.singleOverlay(), Assembler::Always); + masm.ma_vldr(Address(HeapReg, ptrImm), vd.singleOverlay(), Assembler::Always); else - masm.ma_vldr(Operand(HeapReg, ptrImm), vd, Assembler::Always); + masm.ma_vldr(Address(HeapReg, ptrImm), vd, Assembler::Always); } else { masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, Imm32(ptrImm), ToRegister(ins->output()), Offset, Assembler::Always); @@ -1826,11 +1826,11 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap* ins) FloatRegister dst = ToFloatRegister(ins->output()); VFPRegister vd(dst); if (size == 32) { - masm.ma_vldr(Operand(GlobalReg, AsmJSNaN32GlobalDataOffset - AsmJSGlobalRegBias), + masm.ma_vldr(Address(GlobalReg, AsmJSNaN32GlobalDataOffset - AsmJSGlobalRegBias), vd.singleOverlay(), Assembler::AboveOrEqual); masm.ma_vldr(vd.singleOverlay(), HeapReg, ptrReg, 0, Assembler::Below); } else { - masm.ma_vldr(Operand(GlobalReg, AsmJSNaN64GlobalDataOffset - AsmJSGlobalRegBias), + masm.ma_vldr(Address(GlobalReg, AsmJSNaN64GlobalDataOffset - AsmJSGlobalRegBias), vd, Assembler::AboveOrEqual); masm.ma_vldr(vd, HeapReg, ptrReg, 0, Assembler::Below); } @@ -1870,9 +1870,9 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap* ins) if (isFloat) { VFPRegister vd(ToFloatRegister(ins->value())); if (size == 32) - masm.ma_vstr(vd.singleOverlay(), Operand(HeapReg, ptrImm), Assembler::Always); + masm.ma_vstr(vd.singleOverlay(), Address(HeapReg, ptrImm), Assembler::Always); else - masm.ma_vstr(vd, Operand(HeapReg, ptrImm), Assembler::Always); + masm.ma_vstr(vd, Address(HeapReg, ptrImm), Assembler::Always); } else { masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, Imm32(ptrImm), ToRegister(ins->value()), Offset, Assembler::Always); @@ -2089,7 +2089,7 @@ void CodeGeneratorARM::visitAsmJSPassStackArg(LAsmJSPassStackArg* ins) { const MAsmJSPassStackArg* mir = ins->mir(); - Operand dst(StackPointer, mir->spOffset()); + Address dst(StackPointer, mir->spOffset()); if (ins->arg()->isConstant()) { //masm.as_bkpt(); masm.ma_storeImm(Imm32(ToInt32(ins->arg())), dst); @@ -2231,9 +2231,9 @@ CodeGeneratorARM::visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar* ins) masm.ma_dtr(IsLoad, GlobalReg, Imm32(addr), ToRegister(ins->output())); } else if (mir->type() == MIRType_Float32) { VFPRegister vd(ToFloatRegister(ins->output())); - masm.ma_vldr(Operand(GlobalReg, addr), vd.singleOverlay()); + masm.ma_vldr(Address(GlobalReg, addr), vd.singleOverlay()); } else { - masm.ma_vldr(Operand(GlobalReg, addr), ToFloatRegister(ins->output())); + masm.ma_vldr(Address(GlobalReg, addr), ToFloatRegister(ins->output())); } } @@ -2250,9 +2250,9 @@ CodeGeneratorARM::visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar* ins) masm.ma_dtr(IsStore, GlobalReg, Imm32(addr), ToRegister(ins->value())); } else if (type == MIRType_Float32) { VFPRegister vd(ToFloatRegister(ins->value())); - masm.ma_vstr(vd.singleOverlay(), Operand(GlobalReg, addr)); + masm.ma_vstr(vd.singleOverlay(), Address(GlobalReg, addr)); } else { - masm.ma_vstr(ToFloatRegister(ins->value()), Operand(GlobalReg, addr)); + masm.ma_vstr(ToFloatRegister(ins->value()), Address(GlobalReg, addr)); } } @@ -2275,7 +2275,7 @@ CodeGeneratorARM::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc* ins) { const MAsmJSLoadFFIFunc* mir = ins->mir(); - masm.ma_ldr(Operand(GlobalReg, mir->globalDataOffset() - AsmJSGlobalRegBias), + masm.ma_ldr(Address(GlobalReg, mir->globalDataOffset() - AsmJSGlobalRegBias), ToRegister(ins->output())); } diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 222125d59215..4c7271bb09c7 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -57,7 +57,7 @@ MacroAssemblerARM::convertInt32ToDouble(Register src, FloatRegister dest_) void MacroAssemblerARM::convertInt32ToDouble(const Address& src, FloatRegister dest) { - ma_vldr(Operand(src), ScratchDoubleReg); + ma_vldr(src, ScratchDoubleReg); as_vcvt(dest, VFPRegister(ScratchDoubleReg).sintOverlay()); } @@ -214,7 +214,7 @@ MacroAssemblerARM::convertInt32ToFloat32(Register src, FloatRegister dest) { void MacroAssemblerARM::convertInt32ToFloat32(const Address& src, FloatRegister dest) { - ma_vldr(Operand(src), ScratchFloat32Reg); + ma_vldr(src, ScratchFloat32Reg); as_vcvt(dest, VFPRegister(ScratchFloat32Reg).sintOverlay()); } @@ -282,8 +282,8 @@ MacroAssemblerARM::alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, // doesn't have a dest, such as check for overflow by doing first operation // don't do second operation if first operation overflowed. This preserves // the overflow condition code. Unfortunately, it is horribly brittle. - as_alu(ScratchRegister, src1, both.fst, interop, NoSetCond, c); - as_alu(dest, ScratchRegister, both.snd, op, sc, c); + as_alu(ScratchRegister, src1, Operand2(both.fst), interop, NoSetCond, c); + as_alu(dest, ScratchRegister, Operand2(both.snd), op, sc, c); return true; } @@ -332,7 +332,7 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // bits in tact, so it is unsuitable to move a constant that if (op == OpMov && ((imm.value & ~ 0xffff) == 0)) { MOZ_ASSERT(src1 == InvalidReg); - as_movw(dest, (uint16_t)imm.value, c); + as_movw(dest, Imm16((uint16_t)imm.value), c); return; } @@ -340,7 +340,7 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // then do it. if (op == OpMvn && (((~imm.value) & ~ 0xffff) == 0)) { MOZ_ASSERT(src1 == InvalidReg); - as_movw(dest, (uint16_t)~imm.value, c); + as_movw(dest, Imm16((uint16_t)~imm.value), c); return; } @@ -354,8 +354,8 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // src1. if (op == OpMvn) imm.value = ~imm.value; - as_movw(dest, imm.value & 0xffff, c); - as_movt(dest, (imm.value >> 16) & 0xffff, c); + as_movw(dest, Imm16(imm.value & 0xffff), c); + as_movt(dest, Imm16((imm.value >> 16) & 0xffff), c); return; } // If we weren't doing a movalike, a 16 bit immediate will require 2 @@ -392,9 +392,9 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // single load from a pool then op. if (HasMOVWT()) { // Try to load the immediate into a scratch register then use that - as_movw(ScratchRegister, imm.value & 0xffff, c); + as_movw(ScratchRegister, Imm16(imm.value & 0xffff), c); if ((imm.value >> 16) != 0) - as_movt(ScratchRegister, (imm.value >> 16) & 0xffff, c); + as_movt(ScratchRegister, Imm16((imm.value >> 16) & 0xffff), c); } else { // Going to have to use a load. If the operation is a move, then just // move it into the destination register @@ -847,7 +847,7 @@ MacroAssemblerARM::ma_cmp(Register src1, Operand op, Condition c) as_cmp(src1, op.toOp2(), c); break; case Operand::MEM: - ma_ldr(op, ScratchRegister); + ma_ldr(op.toAddress(), ScratchRegister); as_cmp(src1, O2Reg(ScratchRegister), c); break; default: @@ -1068,15 +1068,13 @@ MacroAssemblerARM::ma_str(Register rt, DTRAddr addr, Index mode, Condition cc) } void -MacroAssemblerARM::ma_dtr(LoadStore ls, Register rt, const Operand& addr, Index mode, Condition cc) +MacroAssemblerARM::ma_dtr(LoadStore ls, Register rt, const Address& addr, Index mode, Condition cc) { - ma_dataTransferN(ls, 32, true, - Register::FromCode(addr.base()), Imm32(addr.disp()), - rt, mode, cc); + ma_dataTransferN(ls, 32, true, addr.base, Imm32(addr.offset), rt, mode, cc); } void -MacroAssemblerARM::ma_str(Register rt, const Operand& addr, Index mode, Condition cc) +MacroAssemblerARM::ma_str(Register rt, const Address& addr, Index mode, Condition cc) { ma_dtr(IsStore, rt, addr, mode, cc); } @@ -1094,7 +1092,7 @@ MacroAssemblerARM::ma_ldr(DTRAddr addr, Register rt, Index mode, Condition cc) as_dtr(IsLoad, 32, mode, rt, addr, cc); } void -MacroAssemblerARM::ma_ldr(const Operand& addr, Register rt, Index mode, Condition cc) +MacroAssemblerARM::ma_ldr(const Address& addr, Register rt, Index mode, Condition cc) { ma_dtr(IsLoad, rt, addr, mode, cc); } @@ -1709,13 +1707,13 @@ MacroAssemblerARM::ma_vxfer(Register src1, Register src2, FloatRegister dest, Co } BufferOffset -MacroAssemblerARM::ma_vdtr(LoadStore ls, const Operand& addr, VFPRegister rt, Condition cc) +MacroAssemblerARM::ma_vdtr(LoadStore ls, const Address& addr, VFPRegister rt, Condition cc) { - int off = addr.disp(); + int off = addr.offset; MOZ_ASSERT((off & 3) == 0); - Register base = Register::FromCode(addr.base()); + Register base = addr.base; if (off > -1024 && off < 1024) - return as_vdtr(ls, rt, addr.toVFPAddr(), cc); + return as_vdtr(ls, rt, Operand(addr).toVFPAddr(), cc); // We cannot encode this offset in a a single ldr. Try to encode it as an // add scratch, base, imm; ldr dest, [scratch, +offset]. @@ -1772,7 +1770,7 @@ MacroAssemblerARM::ma_vldr(VFPAddr addr, VFPRegister dest, Condition cc) return as_vdtr(IsLoad, dest, addr, cc); } BufferOffset -MacroAssemblerARM::ma_vldr(const Operand& addr, VFPRegister dest, Condition cc) +MacroAssemblerARM::ma_vldr(const Address& addr, VFPRegister dest, Condition cc) { return ma_vdtr(IsLoad, addr, dest, cc); } @@ -1780,7 +1778,7 @@ BufferOffset MacroAssemblerARM::ma_vldr(VFPRegister src, Register base, Register index, int32_t shift, Condition cc) { as_add(ScratchRegister, base, lsl(index, shift), NoSetCond, cc); - return ma_vldr(Operand(ScratchRegister, 0), src, cc); + return ma_vldr(Address(ScratchRegister, 0), src, cc); } BufferOffset @@ -1790,7 +1788,7 @@ MacroAssemblerARM::ma_vstr(VFPRegister src, VFPAddr addr, Condition cc) } BufferOffset -MacroAssemblerARM::ma_vstr(VFPRegister src, const Operand& addr, Condition cc) +MacroAssemblerARM::ma_vstr(VFPRegister src, const Address& addr, Condition cc) { return ma_vdtr(IsStore, addr, src, cc); } @@ -1799,7 +1797,7 @@ MacroAssemblerARM::ma_vstr(VFPRegister src, Register base, Register index, int32 int32_t offset, Condition cc) { as_add(ScratchRegister, base, lsl(index, shift), NoSetCond, cc); - return ma_vstr(src, Operand(ScratchRegister, offset), cc); + return ma_vstr(src, Address(ScratchRegister, offset), cc); } void @@ -2232,7 +2230,7 @@ MacroAssemblerARMCompat::load32(AbsoluteAddress address, Register dest) void MacroAssemblerARMCompat::loadPtr(const Address& address, Register dest) { - ma_ldr(Operand(address), dest); + ma_ldr(address, dest); } void @@ -2261,23 +2259,16 @@ MacroAssemblerARMCompat::loadPtr(AsmJSAbsoluteAddress address, Register dest) loadPtr(Address(ScratchRegister, 0x0), dest); } -Operand payloadOf(const Address& address) { - return Operand(address.base, address.offset); -} -Operand tagOf(const Address& address) { - return Operand(address.base, address.offset + 4); -} - void MacroAssemblerARMCompat::loadPrivate(const Address& address, Register dest) { - ma_ldr(payloadOf(address), dest); + ma_ldr(ToPayload(address), dest); } void MacroAssemblerARMCompat::loadDouble(const Address& address, FloatRegister dest) { - ma_vldr(Operand(address), dest); + ma_vldr(address, dest); } void @@ -2291,14 +2282,14 @@ MacroAssemblerARMCompat::loadDouble(const BaseIndex& src, FloatRegister dest) int32_t offset = src.offset; as_add(ScratchRegister, base, lsl(index, scale)); - ma_vldr(Operand(ScratchRegister, offset), dest); + ma_vldr(Address(ScratchRegister, offset), dest); } void MacroAssemblerARMCompat::loadFloatAsDouble(const Address& address, FloatRegister dest) { VFPRegister rt = dest; - ma_vldr(Operand(address), rt.singleOverlay()); + ma_vldr(address, rt.singleOverlay()); as_vcvt(rt, rt.singleOverlay()); } @@ -2314,14 +2305,14 @@ MacroAssemblerARMCompat::loadFloatAsDouble(const BaseIndex& src, FloatRegister d VFPRegister rt = dest; as_add(ScratchRegister, base, lsl(index, scale)); - ma_vldr(Operand(ScratchRegister, offset), rt.singleOverlay()); + ma_vldr(Address(ScratchRegister, offset), rt.singleOverlay()); as_vcvt(rt, rt.singleOverlay()); } void MacroAssemblerARMCompat::loadFloat32(const Address& address, FloatRegister dest) { - ma_vldr(Operand(address), VFPRegister(dest).singleOverlay()); + ma_vldr(address, VFPRegister(dest).singleOverlay()); } void @@ -2335,7 +2326,7 @@ MacroAssemblerARMCompat::loadFloat32(const BaseIndex& src, FloatRegister dest) int32_t offset = src.offset; as_add(ScratchRegister, base, lsl(index, scale)); - ma_vldr(Operand(ScratchRegister, offset), VFPRegister(dest).singleOverlay()); + ma_vldr(Address(ScratchRegister, offset), VFPRegister(dest).singleOverlay()); } void @@ -2488,7 +2479,7 @@ template void MacroAssemblerARMCompat::storePtr(ImmGCPtr imm, BaseInd void MacroAssemblerARMCompat::storePtr(Register src, const Address& address) { - ma_str(src, Operand(address)); + ma_str(src, address); } void @@ -3147,19 +3138,19 @@ MacroAssemblerARMCompat::branchTestValue(Condition cond, const Address& valaddr, // Check payload before tag, since payload is more likely to differ. if (cond == NotEqual) { - ma_ldr(payloadOf(valaddr), ScratchRegister); + ma_ldr(ToPayload(valaddr), ScratchRegister); branchPtr(NotEqual, ScratchRegister, value.payloadReg(), label); - ma_ldr(tagOf(valaddr), ScratchRegister); + ma_ldr(ToType(valaddr), ScratchRegister); branchPtr(NotEqual, ScratchRegister, value.typeReg(), label); } else { Label fallthrough; - ma_ldr(payloadOf(valaddr), ScratchRegister); + ma_ldr(ToPayload(valaddr), ScratchRegister); branchPtr(NotEqual, ScratchRegister, value.payloadReg(), &fallthrough); - ma_ldr(tagOf(valaddr), ScratchRegister); + ma_ldr(ToType(valaddr), ScratchRegister); branchPtr(Equal, ScratchRegister, value.typeReg(), label); bind(&fallthrough); @@ -3177,7 +3168,7 @@ MacroAssemblerARMCompat::unboxNonDouble(const ValueOperand& operand, Register de void MacroAssemblerARMCompat::unboxNonDouble(const Address& src, Register dest) { - ma_ldr(payloadOf(src), dest); + ma_ldr(ToPayload(src), dest); } void @@ -3199,7 +3190,7 @@ void MacroAssemblerARMCompat::unboxDouble(const Address& src, FloatRegister dest) { MOZ_ASSERT(dest.isDouble()); - ma_vldr(Operand(src), dest); + ma_vldr(src, dest); } void @@ -3286,7 +3277,7 @@ MacroAssemblerARMCompat::loadConstantFloat32(float f, FloatRegister dest) } void -MacroAssemblerARMCompat::loadInt32OrDouble(const Operand& src, FloatRegister dest) +MacroAssemblerARMCompat::loadInt32OrDouble(const Address& src, FloatRegister dest) { Label notInt32, end; // If it's an int, convert it to double. @@ -3365,14 +3356,14 @@ MacroAssemblerARMCompat::testDoubleTruthy(bool truthy, FloatRegister reg) Register MacroAssemblerARMCompat::extractObject(const Address& address, Register scratch) { - ma_ldr(payloadOf(address), scratch); + ma_ldr(ToPayload(address), scratch); return scratch; } Register MacroAssemblerARMCompat::extractTag(const Address& address, Register scratch) { - ma_ldr(tagOf(address), scratch); + ma_ldr(ToType(address), scratch); return scratch; } @@ -3432,7 +3423,7 @@ MacroAssemblerARMCompat::moveValue(const Value& val, const ValueOperand& dest) // X86/X64-common (ARM too now) interface. ///////////////////////////////////////////////////////////////// void -MacroAssemblerARMCompat::storeValue(ValueOperand val, Operand dst) +MacroAssemblerARMCompat::storeValue(ValueOperand val, const Address& dst) { ma_str(val.payloadReg(), ToPayload(dst)); ma_str(val.typeReg(), ToType(dst)); @@ -3489,17 +3480,17 @@ MacroAssemblerARMCompat::loadValue(const BaseIndex& addr, ValueOperand val) void MacroAssemblerARMCompat::loadValue(Address src, ValueOperand val) { - Operand srcOp = Operand(src); - Operand payload = ToPayload(srcOp); - Operand type = ToType(srcOp); + Address payload = ToPayload(src); + Address type = ToType(src); + // TODO: copy this code into a generic function that acts on all sequences // of memory accesses if (isValueDTRDCandidate(val)) { // If the value we want is in two consecutive registers starting with an // even register, they can be combined as a single ldrd. - int offset = srcOp.disp(); + int offset = src.offset; if (offset < 256 && offset > -256) { - ma_ldrd(EDtrAddr(Register::FromCode(srcOp.base()), EDtrOffImm(srcOp.disp())), val.payloadReg(), val.typeReg()); + ma_ldrd(EDtrAddr(src.base, EDtrOffImm(src.offset)), val.payloadReg(), val.typeReg()); return; } } @@ -3507,11 +3498,11 @@ MacroAssemblerARMCompat::loadValue(Address src, ValueOperand val) // instruction. if (val.payloadReg().code() < val.typeReg().code()) { - if (srcOp.disp() <= 4 && srcOp.disp() >= -8 && (srcOp.disp() & 3) == 0) { + if (src.offset <= 4 && src.offset >= -8 && (src.offset & 3) == 0) { // Turns out each of the 4 value -8, -4, 0, 4 corresponds exactly // with one of LDM{DB, DA, IA, IB} DTMMode mode; - switch(srcOp.disp()) { + switch (src.offset) { case -8: mode = DB; break; @@ -3527,7 +3518,7 @@ MacroAssemblerARMCompat::loadValue(Address src, ValueOperand val) default: MOZ_CRASH("Bogus Offset for LoadValue as DTM"); } - startDataTransferM(IsLoad, Register::FromCode(srcOp.base()), mode); + startDataTransferM(IsLoad, src.base, mode); transferReg(val.payloadReg()); transferReg(val.typeReg()); finishDataTransfer(); @@ -3536,7 +3527,7 @@ MacroAssemblerARMCompat::loadValue(Address src, ValueOperand val) } // Ensure that loading the payload does not erase the pointer to the Value // in memory. - if (Register::FromCode(type.base()) != val.payloadReg()) { + if (type.base != val.payloadReg()) { ma_ldr(payload, val.payloadReg()); ma_ldr(type, val.typeReg()); } else { @@ -3562,13 +3553,9 @@ MacroAssemblerARMCompat::pushValue(ValueOperand val) { void MacroAssemblerARMCompat::pushValue(const Address& addr) { - Operand srcOp = Operand(addr); - Operand type = ToType(srcOp); - Operand payload = ToPayloadAfterStackPush(srcOp); - - ma_ldr(type, ScratchRegister); + ma_ldr(ToType(addr), ScratchRegister); ma_push(ScratchRegister); - ma_ldr(payload, ScratchRegister); + ma_ldr(ToPayloadAfterStackPush(addr), ScratchRegister); ma_push(ScratchRegister); } @@ -3578,7 +3565,7 @@ MacroAssemblerARMCompat::popValue(ValueOperand val) { ma_pop(val.typeReg()); } void -MacroAssemblerARMCompat::storePayload(const Value& val, Operand dest) +MacroAssemblerARMCompat::storePayload(const Value& val, const Address& dest) { jsval_layout jv = JSVAL_TO_IMPL(val); if (val.isMarkable()) @@ -3587,15 +3574,11 @@ MacroAssemblerARMCompat::storePayload(const Value& val, Operand dest) ma_mov(Imm32(jv.s.payload.i32), secondScratchReg_); ma_str(secondScratchReg_, ToPayload(dest)); } -void -MacroAssemblerARMCompat::storePayload(Register src, Operand dest) -{ - if (dest.getTag() == Operand::MEM) { - ma_str(src, ToPayload(dest)); - return; - } - MOZ_CRASH("why do we do all of these things?"); +void +MacroAssemblerARMCompat::storePayload(Register src, const Address& dest) +{ + ma_str(src, ToPayload(dest)); } void @@ -3651,15 +3634,10 @@ MacroAssemblerARMCompat::storePayload(Register src, const BaseIndex& dest) } void -MacroAssemblerARMCompat::storeTypeTag(ImmTag tag, Operand dest) { - if (dest.getTag() == Operand::MEM) { - ma_mov(tag, secondScratchReg_); - ma_str(secondScratchReg_, ToType(dest)); - return; - } - - MOZ_CRASH("why do we do all of these things?"); - +MacroAssemblerARMCompat::storeTypeTag(ImmTag tag, const Address& dest) +{ + ma_mov(tag, secondScratchReg_); + ma_str(secondScratchReg_, ToType(dest)); } void @@ -4210,7 +4188,7 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) Label return_; Label bailout; - ma_ldr(Operand(sp, offsetof(ResumeFromException, kind)), r0); + ma_ldr(Address(sp, offsetof(ResumeFromException, kind)), r0); branch32(Assembler::Equal, r0, Imm32(ResumeFromException::RESUME_ENTRY_FRAME), &entryFrame); branch32(Assembler::Equal, r0, Imm32(ResumeFromException::RESUME_CATCH), &catch_); branch32(Assembler::Equal, r0, Imm32(ResumeFromException::RESUME_FINALLY), &finally); @@ -4223,7 +4201,7 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) // and return from the entry frame. bind(&entryFrame); moveValue(MagicValue(JS_ION_ERROR), JSReturnOperand); - ma_ldr(Operand(sp, offsetof(ResumeFromException, stackPointer)), sp); + ma_ldr(Address(sp, offsetof(ResumeFromException, stackPointer)), sp); // We're going to be returning by the ion calling convention, which returns // by ??? (for now, I think ldr pc, [sp]!) @@ -4232,9 +4210,9 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) // If we found a catch handler, this must be a baseline frame. Restore state // and jump to the catch block. bind(&catch_); - ma_ldr(Operand(sp, offsetof(ResumeFromException, target)), r0); - ma_ldr(Operand(sp, offsetof(ResumeFromException, framePointer)), r11); - ma_ldr(Operand(sp, offsetof(ResumeFromException, stackPointer)), sp); + ma_ldr(Address(sp, offsetof(ResumeFromException, target)), r0); + ma_ldr(Address(sp, offsetof(ResumeFromException, framePointer)), r11); + ma_ldr(Address(sp, offsetof(ResumeFromException, stackPointer)), sp); jump(r0); // If we found a finally block, this must be a baseline frame. Push two @@ -4243,9 +4221,9 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) ValueOperand exception = ValueOperand(r1, r2); loadValue(Operand(sp, offsetof(ResumeFromException, exception)), exception); - ma_ldr(Operand(sp, offsetof(ResumeFromException, target)), r0); - ma_ldr(Operand(sp, offsetof(ResumeFromException, framePointer)), r11); - ma_ldr(Operand(sp, offsetof(ResumeFromException, stackPointer)), sp); + ma_ldr(Address(sp, offsetof(ResumeFromException, target)), r0); + ma_ldr(Address(sp, offsetof(ResumeFromException, framePointer)), r11); + ma_ldr(Address(sp, offsetof(ResumeFromException, stackPointer)), sp); pushValue(BooleanValue(true)); pushValue(exception); @@ -4254,8 +4232,8 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) // Only used in debug mode. Return BaselineFrame->returnValue() to the // caller. bind(&return_); - ma_ldr(Operand(sp, offsetof(ResumeFromException, framePointer)), r11); - ma_ldr(Operand(sp, offsetof(ResumeFromException, stackPointer)), sp); + ma_ldr(Address(sp, offsetof(ResumeFromException, framePointer)), r11); + ma_ldr(Address(sp, offsetof(ResumeFromException, stackPointer)), sp); loadValue(Address(r11, BaselineFrame::reverseOffsetOfReturnValue()), JSReturnOperand); ma_mov(r11, sp); pop(r11); @@ -4276,9 +4254,9 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) // If we are bailing out to baseline to handle an exception, jump to the // bailout tail stub. bind(&bailout); - ma_ldr(Operand(sp, offsetof(ResumeFromException, bailoutInfo)), r2); + ma_ldr(Address(sp, offsetof(ResumeFromException, bailoutInfo)), r2); ma_mov(Imm32(BAILOUT_RETURN_OK), r0); - ma_ldr(Operand(sp, offsetof(ResumeFromException, target)), r1); + ma_ldr(Address(sp, offsetof(ResumeFromException, target)), r1); jump(r1); } diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 2ab97f300a59..480a79e5db56 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -40,28 +40,27 @@ class MacroAssemblerARM : public Assembler public: // Higher level tag testing code. - Operand ToPayload(Operand base) { + // TODO: Can probably remove the Operand versions. + Operand ToPayload(Operand base) const { return Operand(Register::FromCode(base.base()), base.disp()); } - Address ToPayload(Address base) { - return ToPayload(Operand(base)).toAddress(); + Address ToPayload(const Address& base) const { + return base; } protected: - Operand ToType(Operand base) { + Operand ToType(Operand base) const { return Operand(Register::FromCode(base.base()), base.disp() + sizeof(void*)); } - Address ToType(Address base) { + Address ToType(const Address& base) const { return ToType(Operand(base)).toAddress(); } - Operand ToPayloadAfterStackPush(Operand base) { - Register baseReg = Register::FromCode(base.base()); + Address ToPayloadAfterStackPush(const Address& base) const { // If we are based on StackPointer, pass over the type tag just pushed. - if (baseReg == StackPointer) - return Operand(Register::FromCode(base.base()), base.disp() + sizeof(void*)); - else - return ToPayload(base); + if (base.base == StackPointer) + return Address(base.base, base.offset + sizeof(void *)); + return ToPayload(base); } public: @@ -309,11 +308,11 @@ class MacroAssemblerARM : public Assembler void ma_str(Register rt, DTRAddr addr, Index mode = Offset, Condition cc = Always); - void ma_str(Register rt, const Operand& addr, Index mode = Offset, Condition cc = Always); - void ma_dtr(LoadStore ls, Register rt, const Operand& addr, Index mode, Condition cc); + void ma_str(Register rt, const Address& addr, Index mode = Offset, Condition cc = Always); + void ma_dtr(LoadStore ls, Register rt, const Address& addr, Index mode, Condition cc); void ma_ldr(DTRAddr addr, Register rt, Index mode = Offset, Condition cc = Always); - void ma_ldr(const Operand& addr, Register rt, Index mode = Offset, Condition cc = Always); + void ma_ldr(const Address& addr, Register rt, Index mode = Offset, Condition cc = Always); void ma_ldrb(DTRAddr addr, Register rt, Index mode = Offset, Condition cc = Always); void ma_ldrh(EDtrAddr addr, Register rt, Index mode = Offset, Condition cc = Always); @@ -407,15 +406,15 @@ class MacroAssemblerARM : public Assembler void ma_vxfer(Register src1, Register src2, FloatRegister dest, Condition cc = Always); - BufferOffset ma_vdtr(LoadStore ls, const Operand& addr, VFPRegister dest, Condition cc = Always); + BufferOffset ma_vdtr(LoadStore ls, const Address& addr, VFPRegister dest, Condition cc = Always); BufferOffset ma_vldr(VFPAddr addr, VFPRegister dest, Condition cc = Always); - BufferOffset ma_vldr(const Operand& addr, VFPRegister dest, Condition cc = Always); + BufferOffset ma_vldr(const Address& addr, VFPRegister dest, Condition cc = Always); BufferOffset ma_vldr(VFPRegister src, Register base, Register index, int32_t shift = defaultShift, Condition cc = Always); BufferOffset ma_vstr(VFPRegister src, VFPAddr addr, Condition cc = Always); - BufferOffset ma_vstr(VFPRegister src, const Operand& addr, Condition cc = Always); + BufferOffset ma_vstr(VFPRegister src, const Address& addr, Condition cc = Always); BufferOffset ma_vstr(VFPRegister src, Register base, Register index, int32_t shift, int32_t offset, Condition cc = Always); @@ -665,8 +664,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void push(ImmMaybeNurseryPtr imm) { push(noteMaybeNurseryPtr(imm)); } - void push(const Address& address) { - ma_ldr(Operand(address.base, address.offset), ScratchRegister); + void push(const Address& addr) { + ma_ldr(addr, ScratchRegister); ma_push(ScratchRegister); } void push(Register reg) { @@ -729,8 +728,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void jump(Register reg) { ma_bx(reg); } - void jump(const Address& address) { - ma_ldr(Operand(address.base, address.offset), ScratchRegister); + void jump(const Address& addr) { + ma_ldr(addr, ScratchRegister); ma_bx(ScratchRegister); } @@ -746,8 +745,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void test32(Register lhs, Imm32 imm) { ma_tst(lhs, imm); } - void test32(const Address& address, Imm32 imm) { - ma_ldr(Operand(address.base, address.offset), ScratchRegister); + void test32(const Address& addr, Imm32 imm) { + ma_ldr(addr, ScratchRegister); ma_tst(ScratchRegister, imm); } void testPtr(Register lhs, Register rhs) { @@ -873,7 +872,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void boolValueToDouble(const ValueOperand& operand, FloatRegister dest); void int32ValueToDouble(const ValueOperand& operand, FloatRegister dest); - void loadInt32OrDouble(const Operand& src, FloatRegister dest); + void loadInt32OrDouble(const Address& src, FloatRegister dest); void loadInt32OrDouble(Register base, Register index, FloatRegister dest, int32_t shift = defaultShift); void loadConstantDouble(double dp, FloatRegister dest); @@ -909,7 +908,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM if (lhs.getTag() == Operand::OP2) { branch32(cond, lhs.toReg(), rhs, label); } else { - ma_ldr(lhs, ScratchRegister); + ma_ldr(lhs.toAddress(), ScratchRegister); branch32(cond, ScratchRegister, rhs, label); } } @@ -918,7 +917,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM branch32(cond, lhs.toReg(), rhs, label); } else { // branch32 will use ScratchRegister. - ma_ldr(lhs, secondScratchReg_); + ma_ldr(lhs.toAddress(), secondScratchReg_); branch32(cond, secondScratchReg_, rhs, label); } } @@ -1137,7 +1136,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void loadUnboxedValue(Address address, MIRType type, AnyRegister dest) { if (dest.isFloat()) - loadInt32OrDouble(Operand(address), dest.fpu()); + loadInt32OrDouble(address, dest.fpu()); else ma_ldr(address, dest.gpr()); } @@ -1195,29 +1194,26 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_mov(s1, d1); } - void storeValue(ValueOperand val, Operand dst); + void storeValue(ValueOperand val, const Address& dst); void storeValue(ValueOperand val, const BaseIndex& dest); void storeValue(JSValueType type, Register reg, BaseIndex dest) { ma_alu(dest.base, lsl(dest.index, dest.scale), ScratchRegister, OpAdd); storeValue(type, reg, Address(ScratchRegister, dest.offset)); } - void storeValue(ValueOperand val, const Address& dest) { - storeValue(val, Operand(dest)); - } void storeValue(JSValueType type, Register reg, Address dest) { ma_str(reg, dest); ma_mov(ImmTag(JSVAL_TYPE_TO_TAG(type)), secondScratchReg_); ma_str(secondScratchReg_, Address(dest.base, dest.offset + 4)); } - void storeValue(const Value& val, Address dest) { + void storeValue(const Value& val, const Address& dest) { jsval_layout jv = JSVAL_TO_IMPL(val); ma_mov(Imm32(jv.s.tag), secondScratchReg_); - ma_str(secondScratchReg_, Address(dest.base, dest.offset + 4)); + ma_str(secondScratchReg_, ToType(dest)); if (val.isMarkable()) ma_mov(ImmGCPtr(reinterpret_cast(val.toGCThing())), secondScratchReg_); else ma_mov(Imm32(jv.s.payload.i32), secondScratchReg_); - ma_str(secondScratchReg_, dest); + ma_str(secondScratchReg_, ToPayload(dest)); } void storeValue(const Value& val, BaseIndex dest) { ma_alu(dest.base, lsl(dest.index, dest.scale), ScratchRegister, OpAdd); @@ -1247,11 +1243,11 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM } void pushValue(const Address& addr); - void storePayload(const Value& val, Operand dest); - void storePayload(Register src, Operand dest); + void storePayload(const Value& val, const Address& dest); + void storePayload(Register src, const Address& dest); void storePayload(const Value& val, const BaseIndex& dest); void storePayload(Register src, const BaseIndex& dest); - void storeTypeTag(ImmTag tag, Operand dest); + void storeTypeTag(ImmTag tag, const Address& dest); void storeTypeTag(ImmTag tag, const BaseIndex& dest); void makeFrameDescriptor(Register frameSizeReg, FrameType type) { @@ -1443,7 +1439,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void storePtr(Register src, const BaseIndex& address); void storePtr(Register src, AbsoluteAddress dest); void storeDouble(FloatRegister src, Address addr) { - ma_vstr(src, Operand(addr)); + ma_vstr(src, addr); } void storeDouble(FloatRegister src, BaseIndex addr) { uint32_t scale = Imm32::ShiftOf(addr.scale).value; @@ -1453,10 +1449,10 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_vmov(src, dest); } - void storeFloat32(FloatRegister src, Address addr) { - ma_vstr(VFPRegister(src).singleOverlay(), Operand(addr)); + void storeFloat32(FloatRegister src, const Address& addr) { + ma_vstr(VFPRegister(src).singleOverlay(), addr); } - void storeFloat32(FloatRegister src, BaseIndex addr) { + void storeFloat32(FloatRegister src, const BaseIndex& addr) { uint32_t scale = Imm32::ShiftOf(addr.scale).value; ma_vstr(VFPRegister(src).singleOverlay(), addr.base, addr.index, scale, addr.offset); } @@ -1901,19 +1897,11 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_add(addr.baseReg(), Imm32(addr.disp()), dest); } - void stackCheck(ImmWord limitAddr, Label* label) { - int* foo = 0; - *foo = 5; - movePtr(limitAddr, ScratchRegister); - ma_ldr(Address(ScratchRegister, 0), ScratchRegister); - ma_cmp(ScratchRegister, StackPointer); - ma_b(label, Assembler::AboveOrEqual); - } void abiret() { as_bx(lr); } - void ma_storeImm(Imm32 c, const Operand& dest) { + void ma_storeImm(Imm32 c, const Address& dest) { ma_mov(c, lr); ma_str(lr, dest); } diff --git a/js/src/jit/arm/MoveEmitter-arm.cpp b/js/src/jit/arm/MoveEmitter-arm.cpp index df054c82178b..92f2352b1ed0 100644 --- a/js/src/jit/arm/MoveEmitter-arm.cpp +++ b/js/src/jit/arm/MoveEmitter-arm.cpp @@ -38,43 +38,36 @@ MoveEmitterARM::~MoveEmitterARM() assertDone(); } -Operand +Address MoveEmitterARM::cycleSlot(uint32_t slot, uint32_t subslot) const { int32_t offset = masm.framePushed() - pushedAtCycle_; MOZ_ASSERT(offset < 4096 && offset > -4096); - return Operand(StackPointer, offset + slot * sizeof(double) + subslot); + return Address(StackPointer, offset + slot * sizeof(double) + subslot); } -// THIS IS ALWAYS AN LDRAddr. It should not be wrapped in an operand, methinks. -Operand +Address MoveEmitterARM::spillSlot() const { int32_t offset = masm.framePushed() - pushedAtSpill_; MOZ_ASSERT(offset < 4096 && offset > -4096); - return Operand(StackPointer, offset); + return Address(StackPointer, offset); } -Operand -MoveEmitterARM::toOperand(const MoveOperand& operand, bool isFloat) const +Address +MoveEmitterARM::toAddress(const MoveOperand& operand) const { - if (operand.isMemoryOrEffectiveAddress()) { - if (operand.base() != StackPointer) { - MOZ_ASSERT(operand.disp() < 1024 && operand.disp() > -1024); - return Operand(operand.base(), operand.disp()); - } + MOZ_ASSERT(operand.isMemoryOrEffectiveAddress()); - MOZ_ASSERT(operand.disp() >= 0); - - // Otherwise, the stack offset may need to be adjusted. - return Operand(StackPointer, operand.disp() + (masm.framePushed() - pushedAtStart_)); + if (operand.base() != StackPointer) { + MOZ_ASSERT(operand.disp() < 1024 && operand.disp() > -1024); + return Operand(operand.base(), operand.disp()).toAddress(); } - if (operand.isGeneralReg()) - return Operand(operand.reg()); + MOZ_ASSERT(operand.disp() >= 0); - MOZ_ASSERT(operand.isFloatReg()); - return Operand(operand.floatReg()); + // Otherwise, the stack offset may need to be adjusted. + return Address(StackPointer, operand.disp() + (masm.framePushed() - pushedAtStart_)); } Register @@ -113,7 +106,7 @@ MoveEmitterARM::breakCycle(const MoveOperand& from, const MoveOperand& to, case MoveOp::FLOAT32: if (to.isMemory()) { VFPRegister temp = ScratchFloat32Reg; - masm.ma_vldr(toOperand(to, true), temp); + masm.ma_vldr(toAddress(to), temp); // Since it is uncertain if the load will be aligned or not // just fill both of them with the same value. masm.ma_vstr(temp, cycleSlot(slotId, 0)); @@ -128,7 +121,7 @@ MoveEmitterARM::breakCycle(const MoveOperand& from, const MoveOperand& to, case MoveOp::DOUBLE: if (to.isMemory()) { FloatRegister temp = ScratchDoubleReg; - masm.ma_vldr(toOperand(to, true), temp); + masm.ma_vldr(toAddress(to), temp); masm.ma_vstr(temp, cycleSlot(slotId, 0)); } else { masm.ma_vstr(to.floatReg().doubleOverlay(), cycleSlot(slotId, 0)); @@ -139,7 +132,7 @@ MoveEmitterARM::breakCycle(const MoveOperand& from, const MoveOperand& to, // an non-vfp value if (to.isMemory()) { Register temp = tempReg(); - masm.ma_ldr(toOperand(to, false), temp); + masm.ma_ldr(toAddress(to), temp); masm.ma_str(temp, cycleSlot(0,0)); } else { if (to.reg() == spilledReg_) { @@ -170,7 +163,7 @@ MoveEmitterARM::completeCycle(const MoveOperand& from, const MoveOperand& to, Mo if (to.isMemory()) { FloatRegister temp = ScratchDoubleReg; masm.ma_vldr(cycleSlot(slotId, 0), temp); - masm.ma_vstr(temp, toOperand(to, true)); + masm.ma_vstr(temp, toAddress(to)); } else { uint32_t offset = 0; if ((!from.isMemory()) && from.floatReg().numAlignedAliased() == 1) @@ -184,7 +177,7 @@ MoveEmitterARM::completeCycle(const MoveOperand& from, const MoveOperand& to, Mo if (to.isMemory()) { Register temp = tempReg(); masm.ma_ldr(cycleSlot(slotId, 0), temp); - masm.ma_str(temp, toOperand(to, false)); + masm.ma_str(temp, toAddress(to)); } else { if (to.reg() == spilledReg_) { // Make sure we don't re-clobber the spilled register later. @@ -214,21 +207,14 @@ MoveEmitterARM::emitMove(const MoveOperand& from, const MoveOperand& to) masm.ma_ldr(spillSlot(), spilledReg_); spilledReg_ = InvalidReg; } - switch (toOperand(to, false).getTag()) { - case Operand::OP2: - // secretly must be a register + if (to.isMemoryOrEffectiveAddress()) + masm.ma_str(from.reg(), toAddress(to)); + else masm.ma_mov(from.reg(), to.reg()); - break; - case Operand::MEM: - masm.ma_str(from.reg(), toOperand(to, false)); - break; - default: - MOZ_CRASH("strange move!"); - } } else if (to.isGeneralReg()) { MOZ_ASSERT(from.isMemoryOrEffectiveAddress()); if (from.isMemory()) - masm.ma_ldr(toOperand(from, false), to.reg()); + masm.ma_ldr(toAddress(from), to.reg()); else masm.ma_add(from.base(), Imm32(from.disp()), to.reg()); } else { @@ -237,11 +223,11 @@ MoveEmitterARM::emitMove(const MoveOperand& from, const MoveOperand& to) MOZ_ASSERT(from.isMemoryOrEffectiveAddress()); if (from.isMemory()) - masm.ma_ldr(toOperand(from, false), reg); + masm.ma_ldr(toAddress(from), reg); else masm.ma_add(from.base(), Imm32(from.disp()), reg); MOZ_ASSERT(to.base() != reg); - masm.ma_str(reg, toOperand(to, false)); + masm.ma_str(reg, toAddress(to)); } } @@ -252,19 +238,15 @@ MoveEmitterARM::emitFloat32Move(const MoveOperand& from, const MoveOperand& to) if (to.isFloatReg()) masm.ma_vmov_f32(from.floatReg(), to.floatReg()); else - masm.ma_vstr(VFPRegister(from.floatReg()).singleOverlay(), - toOperand(to, true)); + masm.ma_vstr(VFPRegister(from.floatReg()).singleOverlay(), toAddress(to)); } else if (to.isFloatReg()) { - masm.ma_vldr(toOperand(from, true), - VFPRegister(to.floatReg()).singleOverlay()); + masm.ma_vldr(toAddress(from), VFPRegister(to.floatReg()).singleOverlay()); } else { // Memory to memory move. MOZ_ASSERT(from.isMemory()); FloatRegister reg = ScratchFloat32Reg; - masm.ma_vldr(toOperand(from, true), - VFPRegister(reg).singleOverlay()); - masm.ma_vstr(VFPRegister(reg).singleOverlay(), - toOperand(to, true)); + masm.ma_vldr(toAddress(from), VFPRegister(reg).singleOverlay()); + masm.ma_vstr(VFPRegister(reg).singleOverlay(), toAddress(to)); } } @@ -275,15 +257,15 @@ MoveEmitterARM::emitDoubleMove(const MoveOperand& from, const MoveOperand& to) if (to.isFloatReg()) masm.ma_vmov(from.floatReg(), to.floatReg()); else - masm.ma_vstr(from.floatReg(), toOperand(to, true)); + masm.ma_vstr(from.floatReg(), toAddress(to)); } else if (to.isFloatReg()) { - masm.ma_vldr(toOperand(from, true), to.floatReg()); + masm.ma_vldr(toAddress(from), to.floatReg()); } else { // Memory to memory move. MOZ_ASSERT(from.isMemory()); FloatRegister reg = ScratchDoubleReg; - masm.ma_vldr(toOperand(from, true), reg); - masm.ma_vstr(reg, toOperand(to, true)); + masm.ma_vldr(toAddress(from), reg); + masm.ma_vstr(reg, toAddress(to)); } } diff --git a/js/src/jit/arm/MoveEmitter-arm.h b/js/src/jit/arm/MoveEmitter-arm.h index fb7e6460f1de..70aafbdf6c0f 100644 --- a/js/src/jit/arm/MoveEmitter-arm.h +++ b/js/src/jit/arm/MoveEmitter-arm.h @@ -36,9 +36,9 @@ class MoveEmitterARM void assertDone(); Register tempReg(); FloatRegister tempFloatReg(); - Operand cycleSlot(uint32_t slot, uint32_t subslot) const; - Operand spillSlot() const; - Operand toOperand(const MoveOperand& operand, bool isFloat) const; + Address cycleSlot(uint32_t slot, uint32_t subslot) const; + Address spillSlot() const; + Address toAddress(const MoveOperand& operand) const; void emitMove(const MoveOperand& from, const MoveOperand& to); void emitFloat32Move(const MoveOperand& from, const MoveOperand& to); From 354ba1f4fb5aff76af0fd31d7bf21b9b36e8b1be Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Fri, 29 May 2015 14:42:59 -0600 Subject: [PATCH 14/85] Bug 1169503 - Allow sutagent to build on Android M; r=snorp --- build/mobile/sutagent/android/fencp/FileCursor.java | 1 - build/mobile/sutagent/android/ffxcp/FileCursor.java | 1 - 2 files changed, 2 deletions(-) diff --git a/build/mobile/sutagent/android/fencp/FileCursor.java b/build/mobile/sutagent/android/fencp/FileCursor.java index d04870c92cce..036f36a0f9b7 100644 --- a/build/mobile/sutagent/android/fencp/FileCursor.java +++ b/build/mobile/sutagent/android/fencp/FileCursor.java @@ -65,7 +65,6 @@ public class FileCursor extends AbstractWindowedCursor { nCount = 1; } - mRowIdColumnIndex = 0; } } } diff --git a/build/mobile/sutagent/android/ffxcp/FileCursor.java b/build/mobile/sutagent/android/ffxcp/FileCursor.java index af0e0eb4456a..52b15e6aa10e 100644 --- a/build/mobile/sutagent/android/ffxcp/FileCursor.java +++ b/build/mobile/sutagent/android/ffxcp/FileCursor.java @@ -66,7 +66,6 @@ public class FileCursor extends AbstractWindowedCursor { nCount = 1; } - mRowIdColumnIndex = 0; } } } From 6580e192db2b8b96cbffe170ab794c0d329c520e Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Wed, 20 May 2015 09:14:29 -0700 Subject: [PATCH 15/85] Bug 1166789 - Cleanup javascript.options.mem.log formatting; r=sfink, r=mccr8 --HG-- extra : rebase_source : 23f05745a2bfffbebab21fdcba4f7adf47616e8a --- dom/base/nsJSEnvironment.cpp | 11 ++- js/public/GCAPI.h | 3 +- js/src/gc/Statistics.cpp | 135 ++++++++++++++++++++++++++++++----- js/src/gc/Statistics.h | 12 ++-- js/src/jsgc.cpp | 28 +++++++- 5 files changed, 165 insertions(+), 24 deletions(-) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index fae2251523c0..a83d1995b3fa 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -2228,7 +2228,7 @@ DOMGCSliceCallback(JSRuntime *aRt, JS::GCProgress aProgress, const JS::GCDescrip if (sPostGCEventsToConsole) { NS_NAMED_LITERAL_STRING(kFmt, "GC(T+%.1f) "); nsString prefix, gcstats; - gcstats.Adopt(aDesc.formatMessage(aRt)); + gcstats.Adopt(aDesc.formatSummaryMessage(aRt)); prefix.Adopt(nsTextFormatter::smprintf(kFmt.get(), double(delta) / PR_USEC_PER_SEC)); nsString msg = prefix + gcstats; @@ -2304,6 +2304,15 @@ DOMGCSliceCallback(JSRuntime *aRt, JS::GCProgress aProgress, const JS::GCDescrip nsCycleCollector_dispatchDeferredDeletion(); } + if (sPostGCEventsToConsole) { + nsString gcstats; + gcstats.Adopt(aDesc.formatSliceMessage(aRt)); + nsCOMPtr cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID); + if (cs) { + cs->LogStringMessage(gcstats.get()); + } + } + break; default: diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index 571888de5260..3482048d9098 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -336,7 +336,8 @@ struct JS_PUBLIC_API(GCDescription) { GCDescription(bool isCompartment, JSGCInvocationKind kind) : isCompartment_(isCompartment), invocationKind_(kind) {} - char16_t* formatMessage(JSRuntime* rt) const; + char16_t* formatSliceMessage(JSRuntime* rt) const; + char16_t* formatSummaryMessage(JSRuntime* rt) const; char16_t* formatJSON(JSRuntime* rt, uint64_t timestamp) const; JS::dbg::GarbageCollectionEvent::Ptr toGCEvent(JSRuntime* rt) const; diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp index f00e71c8b650..c5a80e8221d3 100644 --- a/js/src/gc/Statistics.cpp +++ b/js/src/gc/Statistics.cpp @@ -86,7 +86,7 @@ class gcstats::StatisticsSerializer if (d < 0) d = 0; if (asJSON_) - appendNumber(name, "%d.%03d", units, (int)d, (int)(d * 1000.) % 1000); + appendNumber(name, "%d.%03d", units, int(d), int(d * 1000.) % 1000); else appendNumber(name, "%.1f", units, d); } @@ -458,10 +458,10 @@ FormatPhaseTimes(StatisticsSerializer& ss, const char* name, Statistics::PhaseTi } void -Statistics::gcDuration(int64_t* total, int64_t* maxPause) +Statistics::gcDuration(int64_t* total, int64_t* maxPause) const { *total = *maxPause = 0; - for (SliceData* slice = slices.begin(); slice != slices.end(); slice++) { + for (const SliceData* slice = slices.begin(); slice != slices.end(); slice++) { *total += slice->duration(); if (slice->duration() > *maxPause) *maxPause = slice->duration(); @@ -617,6 +617,119 @@ SumChildTimes(size_t phaseSlot, Phase phase, Statistics::PhaseTimeTable phaseTim return total; } +UniqueChars +Statistics::formatCompactSliceMessage() const +{ + // Skip if we OOM'ed. + if (slices.length() == 0) + return UniqueChars(nullptr); + + const size_t index = slices.length() - 1; + const SliceData& slice = slices[index]; + + char budgetDescription[200]; + slice.budget.describe(budgetDescription, sizeof(budgetDescription) - 1); + + const char* format = + "GC Slice %u - Pause: %.3fms of %s budget (@ %.3fms); Reason: %s; Reset: %s%s; Times: "; + char buffer[1024]; + memset(buffer, 0, sizeof(buffer)); + JS_snprintf(buffer, sizeof(buffer), format, index, + t(slice.duration()), budgetDescription, t(slice.start - slices[0].start), + ExplainReason(slice.reason), + slice.resetReason ? "yes - " : "no", slice.resetReason ? slice.resetReason : ""); + + FragmentVector fragments; + if (!fragments.append(make_string_copy(buffer)) || + !fragments.append(formatCompactSlicePhaseTimes(slices[index].phaseTimes))) + { + return UniqueChars(nullptr); + } + return Join(fragments); +} + +UniqueChars +Statistics::formatCompactSummaryMessage() const +{ + const double bytesPerMiB = 1024 * 1024; + + FragmentVector fragments; + if (!fragments.append(make_string_copy("Summary - "))) + return UniqueChars(nullptr); + + int64_t total, longest; + gcDuration(&total, &longest); + + const double mmu20 = computeMMU(20 * PRMJ_USEC_PER_MSEC); + const double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC); + + char buffer[1024]; + if (!nonincrementalReason_) { + JS_snprintf(buffer, sizeof(buffer), + "Max Pause: %.3fms; MMU 20ms: %.1f%%; MMU 50ms: %.1f%%; Total: %.3fms; ", + t(longest), mmu20 * 100., mmu50 * 100., t(total)); + } else { + JS_snprintf(buffer, sizeof(buffer), "Non-Incremental: %.3fms; ", t(total)); + } + if (!fragments.append(make_string_copy(buffer))) + return UniqueChars(nullptr); + + JS_snprintf(buffer, sizeof(buffer), + "Zones: %d of %d; Compartments: %d of %d; HeapSize: %.3f MiB; "\ + "HeapChange (abs): %+d (%d); ", + zoneStats.collectedZoneCount, zoneStats.zoneCount, + zoneStats.collectedCompartmentCount, zoneStats.compartmentCount, + double(preBytes) / bytesPerMiB, + counts[STAT_NEW_CHUNK] - counts[STAT_DESTROY_CHUNK], + counts[STAT_NEW_CHUNK] + counts[STAT_DESTROY_CHUNK]); + if (!fragments.append(make_string_copy(buffer))) + return UniqueChars(nullptr); + + MOZ_ASSERT_IF(counts[STAT_ARENA_RELOCATED], gckind == GC_SHRINK); + if (gckind == GC_SHRINK) { + JS_snprintf(buffer, sizeof(buffer), + "Kind: %s; Relocated: %.3f MiB; ", + ExplainInvocationKind(gckind), + double(ArenaSize * counts[STAT_ARENA_RELOCATED]) / bytesPerMiB); + if (!fragments.append(make_string_copy(buffer))) + return UniqueChars(nullptr); + } + + return Join(fragments); +} + +UniqueChars +Statistics::formatCompactSlicePhaseTimes(PhaseTimeTable phaseTimes) const +{ + static const int64_t MaxUnaccountedTimeUS = 100; + + FragmentVector fragments; + char buffer[128]; + for (AllPhaseIterator iter(phaseTimes); !iter.done(); iter.advance()) { + Phase phase; + size_t dagSlot; + size_t level; + iter.get(&phase, &dagSlot, &level); + MOZ_ASSERT(level < 4); + + int64_t ownTime = phaseTimes[dagSlot][phase]; + int64_t childTime = SumChildTimes(dagSlot, phase, phaseTimes); + if (ownTime > MaxUnaccountedTimeUS) { + JS_snprintf(buffer, sizeof(buffer), "%s: %.3fms", phases[phase].name, t(ownTime)); + if (!fragments.append(make_string_copy(buffer))) + return UniqueChars(nullptr); + + if (childTime && (ownTime - childTime) > MaxUnaccountedTimeUS) { + MOZ_ASSERT(level < 3); + JS_snprintf(buffer, sizeof(buffer), "%s: %.3fms", "Other", t(ownTime - childTime)); + if (!fragments.append(make_string_copy(buffer))) + return UniqueChars(nullptr); + } + } + } + return Join(fragments, ", "); +} + UniqueChars Statistics::formatDetailedMessage() { @@ -1012,18 +1125,8 @@ Statistics::Statistics(JSRuntime* rt) Statistics::~Statistics() { - if (fp) { - StatisticsSerializer ss(StatisticsSerializer::AsText); - FormatPhaseTimes(ss, "", phaseTotals); - char* msg = ss.finishCString(); - if (msg) { - fprintf(fp, "TOTALS\n%s\n\n-------\n", msg); - js_free(msg); - } - - if (fp != stdout && fp != stderr) - fclose(fp); - } + if (fp && fp != stdout && fp != stderr) + fclose(fp); } JS::GCSliceCallback @@ -1314,7 +1417,7 @@ Statistics::endSCC(unsigned scc, int64_t start) * as long as the total time it spends is at most 10ms. */ double -Statistics::computeMMU(int64_t window) +Statistics::computeMMU(int64_t window) const { MOZ_ASSERT(!slices.empty()); diff --git a/js/src/gc/Statistics.h b/js/src/gc/Statistics.h index 8357ab244151..6f6e8bb49f56 100644 --- a/js/src/gc/Statistics.h +++ b/js/src/gc/Statistics.h @@ -187,6 +187,8 @@ struct Statistics void endSCC(unsigned scc, int64_t start); char16_t* formatMessage(); + UniqueChars formatCompactSliceMessage() const; + UniqueChars formatCompactSummaryMessage() const; UniqueChars formatJsonMessage(uint64_t timestamp); UniqueChars formatDetailedMessage(); @@ -233,7 +235,7 @@ struct Statistics size_t slicesLength() const { return slices.length(); } /* Create a convenient typedef for referring tables of phase times. */ - typedef int64_t (*PhaseTimeTable)[PHASE_LIMIT]; + typedef int64_t const (*PhaseTimeTable)[PHASE_LIMIT]; private: JSRuntime* runtime; @@ -277,7 +279,7 @@ struct Statistics size_t preBytes; /* Records the maximum GC pause in an API-controlled interval (in us). */ - int64_t maxPauseInInterval; + mutable int64_t maxPauseInInterval; /* Phases that are currently on stack. */ Phase phaseNesting[MAX_NESTING]; @@ -309,11 +311,13 @@ struct Statistics void recordPhaseEnd(Phase phase); - void gcDuration(int64_t* total, int64_t* maxPause); + void gcDuration(int64_t* total, int64_t* maxPause) const; void sccDurations(int64_t* total, int64_t* maxPause); void printStats(); bool formatData(StatisticsSerializer& ss, uint64_t timestamp); + UniqueChars formatCompactSlicePhaseTimes(PhaseTimeTable phaseTimes) const; + UniqueChars formatDetailedDescription(); UniqueChars formatDetailedSliceDescription(unsigned i, const SliceData& slice); UniqueChars formatDetailedPhaseTimes(PhaseTimeTable phaseTimes); @@ -323,7 +327,7 @@ struct Statistics UniqueChars formatJsonSliceDescription(unsigned i, const SliceData& slice); UniqueChars formatJsonPhaseTimes(PhaseTimeTable phaseTimes); - double computeMMU(int64_t resolution); + double computeMMU(int64_t resolution) const; }; struct AutoGCSlice diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index f561d414e1d7..7c2f13c1c81c 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -7092,9 +7092,33 @@ JS::AbortIncrementalGC(JSRuntime* rt) } char16_t* -JS::GCDescription::formatMessage(JSRuntime* rt) const +JS::GCDescription::formatSliceMessage(JSRuntime* rt) const { - return rt->gc.stats.formatMessage(); + UniqueChars cstr = rt->gc.stats.formatCompactSliceMessage(); + + size_t nchars = strlen(cstr.get()); + UniquePtr out(js_pod_malloc(nchars + 1)); + if (!out) + return nullptr; + out.get()[nchars] = 0; + + CopyAndInflateChars(out.get(), cstr.get(), nchars); + return out.release(); +} + +char16_t* +JS::GCDescription::formatSummaryMessage(JSRuntime* rt) const +{ + UniqueChars cstr = rt->gc.stats.formatCompactSummaryMessage(); + + size_t nchars = strlen(cstr.get()); + UniquePtr out(js_pod_malloc(nchars + 1)); + if (!out) + return nullptr; + out.get()[nchars] = 0; + + CopyAndInflateChars(out.get(), cstr.get(), nchars); + return out.release(); } JS::dbg::GarbageCollectionEvent::Ptr From 5842a35cb6e4157e13196161475dbac524ebf21b Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Wed, 20 May 2015 09:14:29 -0700 Subject: [PATCH 16/85] Bug 1166790 - Remove old Statistics formatting code; r=sfink --HG-- extra : rebase_source : 72ed0c4fd820b972bbce6fe93cc103456efbd1b5 --- js/src/gc/Statistics.cpp | 310 --------------------------------------- js/src/gc/Statistics.h | 4 - 2 files changed, 314 deletions(-) diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp index c5a80e8221d3..539454ab3345 100644 --- a/js/src/gc/Statistics.cpp +++ b/js/src/gc/Statistics.cpp @@ -33,210 +33,6 @@ using mozilla::PodZero; /* Except for the first and last, slices of less than 10ms are not reported. */ static const int64_t SLICE_MIN_REPORT_TIME = 10 * PRMJ_USEC_PER_MSEC; -class gcstats::StatisticsSerializer -{ - typedef Vector CharBuffer; - CharBuffer buf_; - bool asJSON_; - bool needComma_; - bool oom_; - - static const int MaxFieldValueLength = 128; - - public: - enum Mode { - AsJSON = true, - AsText = false - }; - - explicit StatisticsSerializer(Mode asJSON) - : buf_(), asJSON_(asJSON), needComma_(false), oom_(false) - {} - - bool isJSON() { return asJSON_; } - - bool isOOM() { return oom_; } - - void endLine() { - if (!asJSON_) { - p("\n"); - needComma_ = false; - } - } - - void extra(const char* str) { - if (!asJSON_) { - needComma_ = false; - p(str); - } - } - - void appendString(const char* name, const char* value) { - put(name, value, "", true); - } - - void appendNumber(const char* name, const char* vfmt, const char* units, ...) { - va_list va; - va_start(va, units); - append(name, vfmt, va, units); - va_end(va); - } - - void appendDecimal(const char* name, const char* units, double d) { - if (d < 0) - d = 0; - if (asJSON_) - appendNumber(name, "%d.%03d", units, int(d), int(d * 1000.) % 1000); - else - appendNumber(name, "%.1f", units, d); - } - - void appendIfNonzeroMS(const char* name, double v) { - if (asJSON_ || v >= 0.1) - appendDecimal(name, "ms", v); - } - - void beginObject(const char* name) { - if (needComma_) - pJSON(", "); - if (asJSON_ && name) { - putKey(name); - pJSON(": "); - } - pJSON("{"); - needComma_ = false; - } - - void endObject() { - needComma_ = false; - pJSON("}"); - needComma_ = true; - } - - void beginArray(const char* name) { - if (needComma_) - pJSON(", "); - if (asJSON_) - putKey(name); - pJSON(": ["); - needComma_ = false; - } - - void endArray() { - needComma_ = false; - pJSON("]"); - needComma_ = true; - } - - char16_t* finishJSString() { - char* buf = finishCString(); - if (!buf) - return nullptr; - - size_t nchars = strlen(buf); - char16_t* out = js_pod_malloc(nchars + 1); - if (!out) { - oom_ = true; - js_free(buf); - return nullptr; - } - - CopyAndInflateChars(out, buf, nchars); - js_free(buf); - - out[nchars] = 0; - return out; - } - - char* finishCString() { - if (oom_) - return nullptr; - - buf_.append('\0'); - - char* buf = buf_.extractRawBuffer(); - if (!buf) - oom_ = true; - - return buf; - } - - private: - void append(const char* name, const char* vfmt, - va_list va, const char* units) - { - char val[MaxFieldValueLength]; - JS_vsnprintf(val, MaxFieldValueLength, vfmt, va); - put(name, val, units, false); - } - - void p(const char* cstr) { - if (oom_) - return; - - if (!buf_.append(cstr, strlen(cstr))) - oom_ = true; - } - - void p(const char c) { - if (oom_) - return; - - if (!buf_.append(c)) - oom_ = true; - } - - void pJSON(const char* str) { - if (asJSON_) - p(str); - } - - void put(const char* name, const char* val, const char* units, bool valueIsQuoted) { - if (needComma_) - p(", "); - needComma_ = true; - - putKey(name); - p(": "); - if (valueIsQuoted) - putQuoted(val); - else - p(val); - if (!asJSON_) - p(units); - } - - void putQuoted(const char* str) { - pJSON("\""); - p(str); - pJSON("\""); - } - - void putKey(const char* str) { - if (!asJSON_) { - p(str); - return; - } - - p("\""); - const char* c = str; - while (*c) { - if (*c == ' ' || *c == '\t') - p('_'); - else if (isupper(*c)) - p(tolower(*c)); - else if (*c == '+') - p("added_"); - else if (*c == '-') - p("removed_"); - else if (*c != '(' && *c != ')') - p(*c); - c++; - } - p("\""); - } -}; - /* * If this fails, then you can either delete this assertion and allow all * larger-numbered reasons to pile up in the last telemetry bucket, or switch @@ -443,20 +239,6 @@ struct AllPhaseIterator { } }; -static void -FormatPhaseTimes(StatisticsSerializer& ss, const char* name, Statistics::PhaseTimeTable times) -{ - ss.beginObject(name); - - for (AllPhaseIterator iter(times); !iter.done(); iter.advance()) { - Phase phase; - size_t dagSlot; - iter.get(&phase, &dagSlot); - ss.appendIfNonzeroMS(phases[phase].name, t(times[dagSlot][phase])); - } - ss.endObject(); -} - void Statistics::gcDuration(int64_t* total, int64_t* maxPause) const { @@ -480,90 +262,6 @@ Statistics::sccDurations(int64_t* total, int64_t* maxPause) } } -bool -Statistics::formatData(StatisticsSerializer& ss, uint64_t timestamp) -{ - MOZ_ASSERT(!aborted); - - int64_t total, longest; - gcDuration(&total, &longest); - - int64_t sccTotal, sccLongest; - sccDurations(&sccTotal, &sccLongest); - - double mmu20 = computeMMU(20 * PRMJ_USEC_PER_MSEC); - double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC); - - ss.beginObject(nullptr); - if (ss.isJSON()) - ss.appendNumber("Timestamp", "%llu", "", (unsigned long long)timestamp); - if (slices.length() > 1 || ss.isJSON()) - ss.appendDecimal("Max Pause", "ms", t(longest)); - else - ss.appendString("Reason", ExplainReason(slices[0].reason)); - ss.appendDecimal("Total Time", "ms", t(total)); - ss.appendNumber("Zones Collected", "%d", "", zoneStats.collectedZoneCount); - ss.appendNumber("Total Zones", "%d", "", zoneStats.zoneCount); - ss.appendNumber("Total Compartments", "%d", "", zoneStats.compartmentCount); - ss.appendNumber("Minor GCs", "%d", "", counts[STAT_MINOR_GC]); - ss.appendNumber("Store Buffer Overflows", "%d", "", counts[STAT_STOREBUFFER_OVERFLOW]); - ss.appendNumber("MMU (20ms)", "%d", "%", int(mmu20 * 100)); - ss.appendNumber("MMU (50ms)", "%d", "%", int(mmu50 * 100)); - ss.appendDecimal("SCC Sweep Total", "ms", t(sccTotal)); - ss.appendDecimal("SCC Sweep Max Pause", "ms", t(sccLongest)); - if (nonincrementalReason_ || ss.isJSON()) { - ss.appendString("Nonincremental Reason", - nonincrementalReason_ ? nonincrementalReason_ : "none"); - } - ss.appendNumber("Allocated", "%u", "MB", unsigned(preBytes / 1024 / 1024)); - ss.appendNumber("+Chunks", "%d", "", counts[STAT_NEW_CHUNK]); - ss.appendNumber("-Chunks", "%d", "", counts[STAT_DESTROY_CHUNK]); - ss.endLine(); - - if (slices.length() > 1 || ss.isJSON()) { - ss.beginArray("Slices"); - for (size_t i = 0; i < slices.length(); i++) { - int64_t width = slices[i].duration(); - if (i != 0 && i != slices.length() - 1 && width < SLICE_MIN_REPORT_TIME && - !slices[i].resetReason && !ss.isJSON()) - { - continue; - } - - char budgetDescription[200]; - slices[i].budget.describe(budgetDescription, sizeof(budgetDescription) - 1); - - ss.beginObject(nullptr); - ss.extra(" "); - ss.appendNumber("Slice", "%d", "", i); - ss.appendDecimal("Pause", "", t(width)); - ss.extra(" ("); - ss.appendDecimal("When", "ms", t(slices[i].start - slices[0].start)); - ss.appendString("Reason", ExplainReason(slices[i].reason)); - ss.appendString("Budget", budgetDescription); - if (ss.isJSON()) { - ss.appendDecimal("Page Faults", "", - double(slices[i].endFaults - slices[i].startFaults)); - - ss.appendNumber("Start Timestamp", "%llu", "", (unsigned long long)slices[i].start); - ss.appendNumber("End Timestamp", "%llu", "", (unsigned long long)slices[i].end); - } - if (slices[i].resetReason) - ss.appendString("Reset", slices[i].resetReason); - ss.extra("): "); - FormatPhaseTimes(ss, "Times", slices[i].phaseTimes); - ss.endLine(); - ss.endObject(); - } - ss.endArray(); - } - ss.extra(" Totals: "); - FormatPhaseTimes(ss, "Totals", phaseTimes); - ss.endObject(); - - return !ss.isOOM(); -} - typedef Vector FragmentVector; static UniqueChars @@ -1032,14 +730,6 @@ Statistics::formatJsonPhaseTimes(PhaseTimeTable phaseTimes) return Join(fragments, ","); } -char16_t* -Statistics::formatMessage() -{ - StatisticsSerializer ss(StatisticsSerializer::AsText); - formatData(ss, 0); - return ss.finishJSString(); -} - Statistics::Statistics(JSRuntime* rt) : runtime(rt), startupTime(PRMJ_Now()), diff --git a/js/src/gc/Statistics.h b/js/src/gc/Statistics.h index 6f6e8bb49f56..c97d3bf64559 100644 --- a/js/src/gc/Statistics.h +++ b/js/src/gc/Statistics.h @@ -101,8 +101,6 @@ enum Stat { STAT_LIMIT }; -class StatisticsSerializer; - struct ZoneGCStats { /* Number of zones collected in this GC. */ @@ -186,7 +184,6 @@ struct Statistics int64_t beginSCC(); void endSCC(unsigned scc, int64_t start); - char16_t* formatMessage(); UniqueChars formatCompactSliceMessage() const; UniqueChars formatCompactSummaryMessage() const; UniqueChars formatJsonMessage(uint64_t timestamp); @@ -314,7 +311,6 @@ struct Statistics void gcDuration(int64_t* total, int64_t* maxPause) const; void sccDurations(int64_t* total, int64_t* maxPause); void printStats(); - bool formatData(StatisticsSerializer& ss, uint64_t timestamp); UniqueChars formatCompactSlicePhaseTimes(PhaseTimeTable phaseTimes) const; From 4fd7d3e21a3b5b4d753fc6d7551f75589fbdf980 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Fri, 29 May 2015 14:00:15 -0700 Subject: [PATCH 17/85] Bug 1169420: add crashtests. (no review) --- layout/generic/crashtests/1169420-1.html | 8 ++++++++ layout/generic/crashtests/1169420-2.html | 8 ++++++++ layout/generic/crashtests/crashtests.list | 2 ++ 3 files changed, 18 insertions(+) create mode 100644 layout/generic/crashtests/1169420-1.html create mode 100644 layout/generic/crashtests/1169420-2.html diff --git a/layout/generic/crashtests/1169420-1.html b/layout/generic/crashtests/1169420-1.html new file mode 100644 index 000000000000..73b8f8d64eb8 --- /dev/null +++ b/layout/generic/crashtests/1169420-1.html @@ -0,0 +1,8 @@ + + + +
+
+
+ + diff --git a/layout/generic/crashtests/1169420-2.html b/layout/generic/crashtests/1169420-2.html new file mode 100644 index 000000000000..e096ed7f9250 --- /dev/null +++ b/layout/generic/crashtests/1169420-2.html @@ -0,0 +1,8 @@ + + + +
+
+
+ + diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index 3de7b00f946d..1660a837a22b 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -585,3 +585,5 @@ load 1146107.html load 1146114.html load 1156222.html load 1157011.html +load 1169420-1.html +load 1169420-2.html From 911576aab65bf883f51b45153b5f56692a9cd492 Mon Sep 17 00:00:00 2001 From: Michal Novotny Date: Fri, 29 May 2015 23:28:54 +0200 Subject: [PATCH 18/85] Bug 1168221 - Assertion failure: !mDataStarted, r=hurley --- netwerk/protocol/websocket/WebSocketChannel.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp index 974607dce4c0..856c397f4082 100644 --- a/netwerk/protocol/websocket/WebSocketChannel.cpp +++ b/netwerk/protocol/websocket/WebSocketChannel.cpp @@ -2228,13 +2228,6 @@ WebSocketChannel::StopSession(nsresult reason) // normally this should be called on socket thread, but it is ok to call it // from OnStartRequest before the socket thread machine has gotten underway - if (NS_IsMainThread()) { - MOZ_DIAGNOSTIC_ASSERT(!mDataStarted); - } else { - MOZ_DIAGNOSTIC_ASSERT(PR_GetCurrentThread() == gSocketThread, - "Called on unexpected thread!"); - MOZ_DIAGNOSTIC_ASSERT(mDataStarted); - } mStopped = 1; @@ -2341,13 +2334,6 @@ WebSocketChannel::AbortSession(nsresult reason) // normally this should be called on socket thread, but it is ok to call it // from the main thread before StartWebsocketData() has completed - if (NS_IsMainThread()) { - MOZ_DIAGNOSTIC_ASSERT(!mDataStarted); - } else { - MOZ_DIAGNOSTIC_ASSERT(PR_GetCurrentThread() == gSocketThread, - "Called on unexpected thread!"); - MOZ_DIAGNOSTIC_ASSERT(mDataStarted); - } // When we are failing we need to close the TCP connection immediately // as per 7.1.1 From c1b689da45fda61c753646ec8600e8d8b3fda43f Mon Sep 17 00:00:00 2001 From: Andrew Halberstadt Date: Fri, 29 May 2015 17:05:34 -0400 Subject: [PATCH 19/85] Bug 1169799 - Update |mach test| suites to reflect new |mach mochitest| command, r=chmanchester --HG-- extra : rebase_source : 91c3bd23f5160e157b245ef504da03bd48cfc20a --- testing/mach_commands.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/testing/mach_commands.py b/testing/mach_commands.py index f3bcdb092c58..6aee62135343 100644 --- a/testing/mach_commands.py +++ b/testing/mach_commands.py @@ -68,7 +68,7 @@ TEST_SUITES = { }, 'mochitest-browser': { 'aliases': ('bc', 'BC', 'Bc'), - 'mach_command': 'mochitest-browser', + 'mach_command': 'mochitest', 'kwargs': {'flavor': 'browser-chrome', 'test_paths': None}, }, 'mochitest-chrome': { @@ -77,7 +77,7 @@ TEST_SUITES = { }, 'mochitest-devtools': { 'aliases': ('dt', 'DT', 'Dt'), - 'mach_command': 'mochitest-browser', + 'mach_command': 'mochitest', 'kwargs': {'subsuite': 'devtools', 'test_paths': None}, }, 'mochitest-ipcplugins': { @@ -85,7 +85,7 @@ TEST_SUITES = { }, 'mochitest-plain': { 'mach_command': 'mochitest', - 'kwargs': {'flavor': 'mochitest', 'test_paths': None}, + 'kwargs': {'flavor': 'plain', 'test_paths': None}, }, 'luciddream': { 'mach_command': 'luciddream', @@ -151,6 +151,7 @@ for i in range(1, MOCHITEST_TOTAL_CHUNKS + 1): 'mach_command': 'mochitest', 'kwargs': { 'flavor': 'mochitest', + 'subsuite': 'default', 'chunk_by_dir': MOCHITEST_CHUNK_BY_DIR, 'total_chunks': MOCHITEST_TOTAL_CHUNKS, 'this_chunk': i, From cc260b44cf94e9436230194a4bc610383f598ea3 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Wed, 27 May 2015 22:18:36 +0000 Subject: [PATCH 20/85] Bug 817406 part 1 - Let ApplyStyleFixups propogate 'direction' to the viewport. r=bz,heycam --- layout/base/nsCSSFrameConstructor.cpp | 9 +++++++++ layout/reftests/bidi/817406-1-ref.html | 4 ++++ layout/reftests/bidi/817406-1.html | 4 ++++ layout/reftests/bidi/817406-2-ref.html | 4 ++++ layout/reftests/bidi/817406-2.html | 4 ++++ layout/reftests/bidi/817406-3.html | 6 ++++++ layout/reftests/bidi/817406-4-ref.html | 6 ++++++ layout/reftests/bidi/817406-4.html | 6 ++++++ layout/reftests/bidi/reftest.list | 4 ++++ layout/style/nsStyleContext.cpp | 18 ++++++++++++++++++ 10 files changed, 65 insertions(+) create mode 100644 layout/reftests/bidi/817406-1-ref.html create mode 100644 layout/reftests/bidi/817406-1.html create mode 100644 layout/reftests/bidi/817406-2-ref.html create mode 100644 layout/reftests/bidi/817406-2.html create mode 100644 layout/reftests/bidi/817406-3.html create mode 100644 layout/reftests/bidi/817406-4-ref.html create mode 100644 layout/reftests/bidi/817406-4.html diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 667c9ad3cb5f..c2cc1e235571 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -2395,6 +2395,15 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle MOZ_ASSERT(!mDocElementContainingBlock, "Shouldn't have a doc element containing block here"); + // Resolve a new style context for the viewport since it may be affected + // by a new root element style (e.g. a propagated 'direction'). + // @see nsStyleContext::ApplyStyleFixups + { + nsRefPtr sc = mPresShell->StyleSet()-> + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::viewport, nullptr); + GetRootFrame()->SetStyleContextWithoutNotification(sc); + } + // Make sure to call PropagateScrollToViewport before // SetUpDocElementContainingBlock, since it sets up our scrollbar state // properly. diff --git a/layout/reftests/bidi/817406-1-ref.html b/layout/reftests/bidi/817406-1-ref.html new file mode 100644 index 000000000000..1e3e74702817 --- /dev/null +++ b/layout/reftests/bidi/817406-1-ref.html @@ -0,0 +1,4 @@ + + +
+ diff --git a/layout/reftests/bidi/817406-1.html b/layout/reftests/bidi/817406-1.html new file mode 100644 index 000000000000..d01fa724e540 --- /dev/null +++ b/layout/reftests/bidi/817406-1.html @@ -0,0 +1,4 @@ + + +
+ diff --git a/layout/reftests/bidi/817406-2-ref.html b/layout/reftests/bidi/817406-2-ref.html new file mode 100644 index 000000000000..fd1f20e0cff5 --- /dev/null +++ b/layout/reftests/bidi/817406-2-ref.html @@ -0,0 +1,4 @@ + + +
+ diff --git a/layout/reftests/bidi/817406-2.html b/layout/reftests/bidi/817406-2.html new file mode 100644 index 000000000000..ebc3ebb98c09 --- /dev/null +++ b/layout/reftests/bidi/817406-2.html @@ -0,0 +1,4 @@ + + +
+ diff --git a/layout/reftests/bidi/817406-3.html b/layout/reftests/bidi/817406-3.html new file mode 100644 index 000000000000..90313bde4a67 --- /dev/null +++ b/layout/reftests/bidi/817406-3.html @@ -0,0 +1,6 @@ + + + +
+ + diff --git a/layout/reftests/bidi/817406-4-ref.html b/layout/reftests/bidi/817406-4-ref.html new file mode 100644 index 000000000000..e6e1c8d1fa47 --- /dev/null +++ b/layout/reftests/bidi/817406-4-ref.html @@ -0,0 +1,6 @@ + + + +
+ + diff --git a/layout/reftests/bidi/817406-4.html b/layout/reftests/bidi/817406-4.html new file mode 100644 index 000000000000..3e90274248b0 --- /dev/null +++ b/layout/reftests/bidi/817406-4.html @@ -0,0 +1,6 @@ + + + +
+ + diff --git a/layout/reftests/bidi/reftest.list b/layout/reftests/bidi/reftest.list index 61ded927a9f8..7a0be8fa5795 100644 --- a/layout/reftests/bidi/reftest.list +++ b/layout/reftests/bidi/reftest.list @@ -139,6 +139,10 @@ skip-if(B2G||Mulet) == 726420-1.html 726420-1-ref.html # Initial mulet triage: p == 746987-4.html 746987-4-ref.html == 779003-1.html 779003-1-ref.html == 779003-1-dynamic.html 779003-1-ref.html +== 817406-1.html 817406-1-ref.html +== 817406-2.html 817406-2-ref.html +== 817406-3.html 817406-1-ref.html +== 817406-4.html 817406-4-ref.html == 847242-1.html 847242-1-ref.html skip-if((B2G&&browserIsRemote)||Mulet) == 869833-1.xul 869833-1-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop == 922530-1.html 922530-1-ref.html diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 7746215c9273..0205b37abed1 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -448,6 +448,7 @@ nsStyleContext::GetUniqueStyleData(const nsStyleStructID& aSID) UNIQUE_CASE(Display) UNIQUE_CASE(Text) UNIQUE_CASE(TextReset) + UNIQUE_CASE(Visibility) #undef UNIQUE_CASE @@ -593,6 +594,23 @@ nsStyleContext::ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup) mBits |= NS_STYLE_HAS_PSEUDO_ELEMENT_DATA; } + // CSS 2.1 10.1: Propagate the root element's 'direction' to the ICB. + // (PageContentFrame/CanvasFrame etc will inherit 'direction') + if (mPseudoTag == nsCSSAnonBoxes::viewport) { + nsPresContext* presContext = PresContext(); + mozilla::dom::Element* docElement = presContext->Document()->GetRootElement(); + if (docElement) { + nsRefPtr rootStyle = + presContext->StyleSet()->ResolveStyleFor(docElement, nullptr); + auto dir = rootStyle->StyleVisibility()->mDirection; + if (dir != StyleVisibility()->mDirection) { + nsStyleVisibility* uniqueVisibility = + (nsStyleVisibility*)GetUniqueStyleData(eStyleStruct_Visibility); + uniqueVisibility->mDirection = dir; + } + } + } + // Correct tables. const nsStyleDisplay* disp = StyleDisplay(); if (disp->mDisplay == NS_STYLE_DISPLAY_TABLE) { From ec7b323395a20be2ea48885826e71344342e0a48 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Wed, 27 May 2015 22:18:37 +0000 Subject: [PATCH 21/85] Bug 817406 part 2 - Tests for propagating 'direction' to the viewport. --- layout/reftests/bidi/1161752-1-embed.html | 34 +++++++++ layout/reftests/bidi/1161752-2-embed.html | 34 +++++++++ layout/reftests/bidi/1161752-3-embed.html | 32 ++++++++ layout/reftests/bidi/1161752-4-embed.html | 34 +++++++++ layout/reftests/bidi/1161752-5-embed-ref.html | 30 ++++++++ layout/reftests/bidi/1161752-5-embed.html | 34 +++++++++ layout/reftests/bidi/1161752-ref.html | 35 +++++++++ layout/reftests/bidi/1161752.html | 73 +++++++++++++++++++ layout/reftests/bidi/reftest.list | 2 + 9 files changed, 308 insertions(+) create mode 100644 layout/reftests/bidi/1161752-1-embed.html create mode 100644 layout/reftests/bidi/1161752-2-embed.html create mode 100644 layout/reftests/bidi/1161752-3-embed.html create mode 100644 layout/reftests/bidi/1161752-4-embed.html create mode 100644 layout/reftests/bidi/1161752-5-embed-ref.html create mode 100644 layout/reftests/bidi/1161752-5-embed.html create mode 100644 layout/reftests/bidi/1161752-ref.html create mode 100644 layout/reftests/bidi/1161752.html diff --git a/layout/reftests/bidi/1161752-1-embed.html b/layout/reftests/bidi/1161752-1-embed.html new file mode 100644 index 000000000000..f8bae49cc41f --- /dev/null +++ b/layout/reftests/bidi/1161752-1-embed.html @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+ + + diff --git a/layout/reftests/bidi/1161752-2-embed.html b/layout/reftests/bidi/1161752-2-embed.html new file mode 100644 index 000000000000..b6a24ce01db3 --- /dev/null +++ b/layout/reftests/bidi/1161752-2-embed.html @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+ + + diff --git a/layout/reftests/bidi/1161752-3-embed.html b/layout/reftests/bidi/1161752-3-embed.html new file mode 100644 index 000000000000..d18228fe026d --- /dev/null +++ b/layout/reftests/bidi/1161752-3-embed.html @@ -0,0 +1,32 @@ + + + + + + + + + + + +
+ + + diff --git a/layout/reftests/bidi/1161752-4-embed.html b/layout/reftests/bidi/1161752-4-embed.html new file mode 100644 index 000000000000..78e0e27a1f34 --- /dev/null +++ b/layout/reftests/bidi/1161752-4-embed.html @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+ + + diff --git a/layout/reftests/bidi/1161752-5-embed-ref.html b/layout/reftests/bidi/1161752-5-embed-ref.html new file mode 100644 index 000000000000..138bc0327aa9 --- /dev/null +++ b/layout/reftests/bidi/1161752-5-embed-ref.html @@ -0,0 +1,30 @@ + + + + Testcase for bug 1161752 + + + + +
+ + + diff --git a/layout/reftests/bidi/1161752-5-embed.html b/layout/reftests/bidi/1161752-5-embed.html new file mode 100644 index 000000000000..4dffa00682a2 --- /dev/null +++ b/layout/reftests/bidi/1161752-5-embed.html @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+ + + diff --git a/layout/reftests/bidi/1161752-ref.html b/layout/reftests/bidi/1161752-ref.html new file mode 100644 index 000000000000..c6ffce33fbd0 --- /dev/null +++ b/layout/reftests/bidi/1161752-ref.html @@ -0,0 +1,35 @@ + + + + Testcase for bug 1161752 + + + + +

Test passes if there are three filled green rectangles and no red.

+ + +
+
+
+
+
+ + + diff --git a/layout/reftests/bidi/1161752.html b/layout/reftests/bidi/1161752.html new file mode 100644 index 000000000000..e3fa245f56f0 --- /dev/null +++ b/layout/reftests/bidi/1161752.html @@ -0,0 +1,73 @@ + + + + Testcase for bug 1161752 + + + + + +

Test passes if there are three filled green rectangles and no red.

+ + +
This test requires a browser with capability to embed an HTML document thanks to the HTML <object> element.
+
+ +
This test requires a browser with capability to embed an HTML document thanks to the HTML <object> element.
+
+ +
This test requires a browser with capability to embed an HTML document thanks to the HTML <object> element.
+
+ +
This test requires a browser with capability to embed an HTML document thanks to the HTML <object> element.
+
+ +
This test requires a browser with capability to embed an HTML document thanks to the HTML <object> element.
+
+ + + diff --git a/layout/reftests/bidi/reftest.list b/layout/reftests/bidi/reftest.list index 7a0be8fa5795..40a1c196491d 100644 --- a/layout/reftests/bidi/reftest.list +++ b/layout/reftests/bidi/reftest.list @@ -152,3 +152,5 @@ skip-if((B2G&&browserIsRemote)||Mulet) == 869833-1.xul 869833-1-ref.xul # Initia == 1069941-inline-bidi-margin-1.html 1069941-inline-bidi-margin-1-ref.html skip-if(B2G||Mulet) != 1155359-1.xul 1155359-1-ref.xul == 1157726-1.html 1157726-1-ref.html +== 1161752.html 1161752-ref.html +== 1161752-5-embed.html 1161752-5-embed-ref.html From 5a7d8c1d7b8a543fef3d5d634926b909d4f82250 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Fri, 29 May 2015 21:40:55 +0000 Subject: [PATCH 22/85] Bug 817406 part 3 - Increase the fuzz factors slightly on a few tests for bug 1133905. --- layout/reftests/bugs/reftest.list | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index d5e4badb8264..3fd0122a6c21 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1902,11 +1902,11 @@ skip-if(!asyncPanZoom) == 1133905-3-rtl.html 1133905-ref-rtl.html skip-if(!asyncPanZoom) == 1133905-4-rtl.html 1133905-ref-rtl.html skip-if(!asyncPanZoom) == 1133905-5-rtl.html 1133905-ref-rtl.html skip-if(!asyncPanZoom) == 1133905-6-rtl.html 1133905-ref-rtl.html -skip-if(!asyncPanZoom) fuzzy-if(B2G,22,175) == 1133905-1-v-rtl.html 1133905-ref-v-rtl.html +skip-if(!asyncPanZoom) fuzzy-if(B2G,23,175) == 1133905-1-v-rtl.html 1133905-ref-v-rtl.html skip-if(!asyncPanZoom) fuzzy-if(B2G,18,175) == 1133905-2-v-rtl.html 1133905-ref-v-rtl.html -skip-if(!asyncPanZoom) fuzzy-if(B2G,64,180) == 1133905-3-v-rtl.html 1133905-ref-v-rtl.html +skip-if(!asyncPanZoom) fuzzy-if(B2G,64,181) == 1133905-3-v-rtl.html 1133905-ref-v-rtl.html skip-if(!asyncPanZoom) == 1133905-4-v-rtl.html 1133905-ref-v-rtl.html -skip-if(!asyncPanZoom) fuzzy-if(B2G,32,146) == 1133905-5-v-rtl.html 1133905-ref-v-rtl.html +skip-if(!asyncPanZoom) fuzzy-if(B2G,33,180) == 1133905-5-v-rtl.html 1133905-ref-v-rtl.html skip-if(!asyncPanZoom) fuzzy-if(B2G,62,222) == 1133905-6-v-rtl.html 1133905-ref-v-rtl.html skip-if(!asyncPanZoom) == 1133905-1-h-rtl.html 1133905-ref-h-rtl.html skip-if(!asyncPanZoom) == 1133905-2-h-rtl.html 1133905-ref-h-rtl.html @@ -1914,11 +1914,11 @@ skip-if(!asyncPanZoom) == 1133905-3-h-rtl.html 1133905-ref-h-rtl.html skip-if(!asyncPanZoom) == 1133905-4-h-rtl.html 1133905-ref-h-rtl.html skip-if(!asyncPanZoom) == 1133905-5-h-rtl.html 1133905-ref-h-rtl.html skip-if(!asyncPanZoom) == 1133905-6-h-rtl.html 1133905-ref-h-rtl.html -skip-if(!asyncPanZoom) fuzzy-if(B2G,22,175) == 1133905-1-vh-rtl.html 1133905-ref-vh-rtl.html +skip-if(!asyncPanZoom) fuzzy-if(B2G,23,175) == 1133905-1-vh-rtl.html 1133905-ref-vh-rtl.html skip-if(!asyncPanZoom) fuzzy-if(B2G,62,175) == 1133905-2-vh-rtl.html 1133905-ref-vh-rtl.html -skip-if(!asyncPanZoom) fuzzy-if(B2G,23,174) == 1133905-3-vh-rtl.html 1133905-ref-vh-rtl.html +skip-if(!asyncPanZoom) fuzzy-if(B2G,23,176) == 1133905-3-vh-rtl.html 1133905-ref-vh-rtl.html skip-if(!asyncPanZoom) == 1133905-4-vh-rtl.html 1133905-ref-vh-rtl.html -skip-if(!asyncPanZoom) fuzzy-if(B2G,102,545) == 1133905-5-vh-rtl.html 1133905-ref-vh-rtl.html +skip-if(!asyncPanZoom) fuzzy-if(B2G,102,577) == 1133905-5-vh-rtl.html 1133905-ref-vh-rtl.html skip-if(!asyncPanZoom) fuzzy-if(B2G,101,887) == 1133905-6-vh-rtl.html 1133905-ref-vh-rtl.html skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul == 1151145-1.html 1151145-1-ref.html From 9265d4998b862961f83498060ebf78fa6d5f12bb Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Wed, 27 May 2015 16:54:38 -0400 Subject: [PATCH 23/85] Bug 1169034 - include in ThreadStackHelper.cpp to declare correct overload for std::abs; r=jseward The integer-valued {,l,ll}abs functions come from , and so the integer-valued overload for std::abs comes from . --- xpcom/threads/ThreadStackHelper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/xpcom/threads/ThreadStackHelper.cpp b/xpcom/threads/ThreadStackHelper.cpp index 0ee31add4d46..ba40cd8f9244 100644 --- a/xpcom/threads/ThreadStackHelper.cpp +++ b/xpcom/threads/ThreadStackHelper.cpp @@ -44,6 +44,7 @@ #include #include +#include #ifdef XP_LINUX #ifdef ANDROID From a89e3a4841fb67c5dbbecde65bbddef782383b90 Mon Sep 17 00:00:00 2001 From: Jonathan Griffin Date: Fri, 29 May 2015 15:43:50 -0700 Subject: [PATCH 24/85] Bug 1169751 - Bump marionette-driver to 0.8, marionette-client to 0.15, r=dburns --- testing/marionette/client/requirements.txt | 2 +- testing/marionette/client/setup.py | 2 +- testing/marionette/driver/setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/marionette/client/requirements.txt b/testing/marionette/client/requirements.txt index 1a602c6d3d1f..9f02a667072a 100644 --- a/testing/marionette/client/requirements.txt +++ b/testing/marionette/client/requirements.txt @@ -1,5 +1,5 @@ marionette-transport >= 0.4 -marionette-driver >= 0.7 +marionette-driver >= 0.8 browsermob-proxy >= 0.6.0 manifestparser >= 1.1 mozhttpd >= 0.7 diff --git a/testing/marionette/client/setup.py b/testing/marionette/client/setup.py index 8f51f52dbc00..5199dfb3af78 100644 --- a/testing/marionette/client/setup.py +++ b/testing/marionette/client/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = '0.14' +version = '0.15' # dependencies with open('requirements.txt') as f: diff --git a/testing/marionette/driver/setup.py b/testing/marionette/driver/setup.py index a87c072d2f7f..ee3e108b0161 100644 --- a/testing/marionette/driver/setup.py +++ b/testing/marionette/driver/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = '0.7' +version = '0.8' # dependencies with open('requirements.txt') as f: From 8afb754daa96f2f6f870d452c3dac3878c84ab95 Mon Sep 17 00:00:00 2001 From: Sean Stangl Date: Tue, 12 May 2015 14:36:03 -0700 Subject: [PATCH 25/85] Bug 1164229 - Rename ARM SetCond_ to SBit. r=efaust --- js/src/jit/arm/Assembler-arm.cpp | 107 +++++---- js/src/jit/arm/Assembler-arm.h | 56 ++--- js/src/jit/arm/BaselineIC-arm.cpp | 10 +- js/src/jit/arm/CodeGenerator-arm.cpp | 36 +-- js/src/jit/arm/MacroAssembler-arm.cpp | 328 +++++++++++++------------- js/src/jit/arm/MacroAssembler-arm.h | 110 ++++----- js/src/jit/arm/Trampoline-arm.cpp | 8 +- 7 files changed, 328 insertions(+), 327 deletions(-) diff --git a/js/src/jit/arm/Assembler-arm.cpp b/js/src/jit/arm/Assembler-arm.cpp index e13ef026aa0c..45956d25deee 100644 --- a/js/src/jit/arm/Assembler-arm.cpp +++ b/js/src/jit/arm/Assembler-arm.cpp @@ -1427,120 +1427,119 @@ Assembler::as_nop() } static uint32_t -EncodeAlu(Register dest, Register src1, Operand2 op2, ALUOp op, SetCond_ sc, - Assembler::Condition c) +EncodeAlu(Register dest, Register src1, Operand2 op2, ALUOp op, SBit s, Assembler::Condition c) { - return (int)op | (int)sc | (int) c | op2.encode() | + return (int)op | (int)s | (int)c | op2.encode() | ((dest == InvalidReg) ? 0 : RD(dest)) | ((src1 == InvalidReg) ? 0 : RN(src1)); } BufferOffset Assembler::as_alu(Register dest, Register src1, Operand2 op2, - ALUOp op, SetCond_ sc, Condition c) + ALUOp op, SBit s, Condition c) { - return writeInst(EncodeAlu(dest, src1, op2, op, sc, c)); + return writeInst(EncodeAlu(dest, src1, op2, op, s, c)); } BufferOffset -Assembler::as_mov(Register dest, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_mov(Register dest, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, InvalidReg, op2, OpMov, sc, c); + return as_alu(dest, InvalidReg, op2, OpMov, s, c); } /* static */ void -Assembler::as_alu_patch(Register dest, Register src1, Operand2 op2, ALUOp op, SetCond_ sc, +Assembler::as_alu_patch(Register dest, Register src1, Operand2 op2, ALUOp op, SBit s, Condition c, uint32_t* pos) { - WriteInstStatic(EncodeAlu(dest, src1, op2, op, sc, c), pos); + WriteInstStatic(EncodeAlu(dest, src1, op2, op, s, c), pos); } /* static */ void -Assembler::as_mov_patch(Register dest, Operand2 op2, SetCond_ sc, Condition c, uint32_t* pos) +Assembler::as_mov_patch(Register dest, Operand2 op2, SBit s, Condition c, uint32_t* pos) { - as_alu_patch(dest, InvalidReg, op2, OpMov, sc, c, pos); + as_alu_patch(dest, InvalidReg, op2, OpMov, s, c, pos); } BufferOffset -Assembler::as_mvn(Register dest, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_mvn(Register dest, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, InvalidReg, op2, OpMvn, sc, c); + return as_alu(dest, InvalidReg, op2, OpMvn, s, c); } // Logical operations. BufferOffset -Assembler::as_and(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_and(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpAnd, sc, c); + return as_alu(dest, src1, op2, OpAnd, s, c); } BufferOffset -Assembler::as_bic(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_bic(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpBic, sc, c); + return as_alu(dest, src1, op2, OpBic, s, c); } BufferOffset -Assembler::as_eor(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_eor(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpEor, sc, c); + return as_alu(dest, src1, op2, OpEor, s, c); } BufferOffset -Assembler::as_orr(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_orr(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpOrr, sc, c); + return as_alu(dest, src1, op2, OpOrr, s, c); } // Mathematical operations. BufferOffset -Assembler::as_adc(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_adc(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpAdc, sc, c); + return as_alu(dest, src1, op2, OpAdc, s, c); } BufferOffset -Assembler::as_add(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_add(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpAdd, sc, c); + return as_alu(dest, src1, op2, OpAdd, s, c); } BufferOffset -Assembler::as_sbc(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_sbc(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpSbc, sc, c); + return as_alu(dest, src1, op2, OpSbc, s, c); } BufferOffset -Assembler::as_sub(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_sub(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpSub, sc, c); + return as_alu(dest, src1, op2, OpSub, s, c); } BufferOffset -Assembler::as_rsb(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_rsb(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpRsb, sc, c); + return as_alu(dest, src1, op2, OpRsb, s, c); } BufferOffset -Assembler::as_rsc(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_rsc(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpRsc, sc, c); + return as_alu(dest, src1, op2, OpRsc, s, c); } // Test operations. BufferOffset Assembler::as_cmn(Register src1, Operand2 op2, Condition c) { - return as_alu(InvalidReg, src1, op2, OpCmn, SetCond, c); + return as_alu(InvalidReg, src1, op2, OpCmn, SetCC, c); } BufferOffset Assembler::as_cmp(Register src1, Operand2 op2, Condition c) { - return as_alu(InvalidReg, src1, op2, OpCmp, SetCond, c); + return as_alu(InvalidReg, src1, op2, OpCmp, SetCC, c); } BufferOffset Assembler::as_teq(Register src1, Operand2 op2, Condition c) { - return as_alu(InvalidReg, src1, op2, OpTeq, SetCond, c); + return as_alu(InvalidReg, src1, op2, OpTeq, SetCC, c); } BufferOffset Assembler::as_tst(Register src1, Operand2 op2, Condition c) { - return as_alu(InvalidReg, src1, op2, OpTst, SetCond, c); + return as_alu(InvalidReg, src1, op2, OpTst, SetCC, c); } static MOZ_CONSTEXPR_VAR Register NoAddend = { Registers::pc }; @@ -1621,59 +1620,59 @@ static const int mull_tag = 0x90; BufferOffset Assembler::as_genmul(Register dhi, Register dlo, Register rm, Register rn, - MULOp op, SetCond_ sc, Condition c) + MULOp op, SBit s, Condition c) { - return writeInst(RN(dhi) | maybeRD(dlo) | RM(rm) | rn.code() | op | sc | c | mull_tag); + return writeInst(RN(dhi) | maybeRD(dlo) | RM(rm) | rn.code() | op | s | c | mull_tag); } BufferOffset -Assembler::as_mul(Register dest, Register src1, Register src2, SetCond_ sc, Condition c) +Assembler::as_mul(Register dest, Register src1, Register src2, SBit s, Condition c) { - return as_genmul(dest, InvalidReg, src1, src2, OpmMul, sc, c); + return as_genmul(dest, InvalidReg, src1, src2, OpmMul, s, c); } BufferOffset Assembler::as_mla(Register dest, Register acc, Register src1, Register src2, - SetCond_ sc, Condition c) + SBit s, Condition c) { - return as_genmul(dest, acc, src1, src2, OpmMla, sc, c); + return as_genmul(dest, acc, src1, src2, OpmMla, s, c); } BufferOffset Assembler::as_umaal(Register destHI, Register destLO, Register src1, Register src2, Condition c) { - return as_genmul(destHI, destLO, src1, src2, OpmUmaal, NoSetCond, c); + return as_genmul(destHI, destLO, src1, src2, OpmUmaal, LeaveCC, c); } BufferOffset Assembler::as_mls(Register dest, Register acc, Register src1, Register src2, Condition c) { - return as_genmul(dest, acc, src1, src2, OpmMls, NoSetCond, c); + return as_genmul(dest, acc, src1, src2, OpmMls, LeaveCC, c); } BufferOffset Assembler::as_umull(Register destHI, Register destLO, Register src1, Register src2, - SetCond_ sc, Condition c) + SBit s, Condition c) { - return as_genmul(destHI, destLO, src1, src2, OpmUmull, sc, c); + return as_genmul(destHI, destLO, src1, src2, OpmUmull, s, c); } BufferOffset Assembler::as_umlal(Register destHI, Register destLO, Register src1, Register src2, - SetCond_ sc, Condition c) + SBit s, Condition c) { - return as_genmul(destHI, destLO, src1, src2, OpmUmlal, sc, c); + return as_genmul(destHI, destLO, src1, src2, OpmUmlal, s, c); } BufferOffset Assembler::as_smull(Register destHI, Register destLO, Register src1, Register src2, - SetCond_ sc, Condition c) + SBit s, Condition c) { - return as_genmul(destHI, destLO, src1, src2, OpmSmull, sc, c); + return as_genmul(destHI, destLO, src1, src2, OpmSmull, s, c); } BufferOffset Assembler::as_smlal(Register destHI, Register destLO, Register src1, Register src2, - SetCond_ sc, Condition c) + SBit s, Condition c) { - return as_genmul(destHI, destLO, src1, src2, OpmSmlal, sc, c); + return as_genmul(destHI, destLO, src1, src2, OpmSmlal, s, c); } BufferOffset @@ -3025,7 +3024,7 @@ void Assembler::UpdateBoundsCheck(uint32_t heapSize, Instruction* inst) Imm8 imm8 = Imm8(heapSize); MOZ_ASSERT(!imm8.invalid); - *inst = InstALU(InvalidReg, index, imm8, OpCmp, SetCond, Always); + *inst = InstALU(InvalidReg, index, imm8, OpCmp, SetCC, Always); // NOTE: we don't update the Auto Flush Cache! this function is currently // only called from within AsmJSModule::patchHeapAccesses, which does that // for us. Don't call this! diff --git a/js/src/jit/arm/Assembler-arm.h b/js/src/jit/arm/Assembler-arm.h index e27cb98d5e2d..54b9a592bb0e 100644 --- a/js/src/jit/arm/Assembler-arm.h +++ b/js/src/jit/arm/Assembler-arm.h @@ -274,10 +274,12 @@ enum DTMWriteBack { NoWriteBack = 0 << 21 }; -enum SetCond_ { - SetCond = 1 << 20, - NoSetCond = 0 << 20 +// Condition code updating mode. +enum SBit { + SetCC = 1 << 20, // Set condition code. + LeaveCC = 0 << 20 // Leave condition code unchanged. }; + enum LoadStore { IsLoad = 1 << 20, IsStore = 0 << 20 @@ -1366,39 +1368,39 @@ class Assembler : public AssemblerShared void nopAlign(int alignment); BufferOffset as_nop(); BufferOffset as_alu(Register dest, Register src1, Operand2 op2, - ALUOp op, SetCond_ sc = NoSetCond, Condition c = Always); + ALUOp op, SBit s = LeaveCC, Condition c = Always); BufferOffset as_mov(Register dest, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_mvn(Register dest, Operand2 op2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); static void as_alu_patch(Register dest, Register src1, Operand2 op2, - ALUOp op, SetCond_ sc, Condition c, uint32_t* pos); + ALUOp op, SBit s, Condition c, uint32_t* pos); static void as_mov_patch(Register dest, - Operand2 op2, SetCond_ sc, Condition c, uint32_t* pos); + Operand2 op2, SBit s, Condition c, uint32_t* pos); // Logical operations: BufferOffset as_and(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_bic(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_eor(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_orr(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); // Mathematical operations: BufferOffset as_adc(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_add(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_sbc(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_sub(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_rsb(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_rsc(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); // Test operations: BufferOffset as_cmn(Register src1, Operand2 op2, Condition c = Always); BufferOffset as_cmp(Register src1, Operand2 op2, Condition c = Always); @@ -1420,23 +1422,23 @@ class Assembler : public AssemblerShared static void as_movt_patch(Register dest, Imm16 imm, Condition c, Instruction* pos); BufferOffset as_genmul(Register d1, Register d2, Register rm, Register rn, - MULOp op, SetCond_ sc, Condition c = Always); + MULOp op, SBit s, Condition c = Always); BufferOffset as_mul(Register dest, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_mla(Register dest, Register acc, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_umaal(Register dest1, Register dest2, Register src1, Register src2, Condition c = Always); BufferOffset as_mls(Register dest, Register acc, Register src1, Register src2, Condition c = Always); BufferOffset as_umull(Register dest1, Register dest2, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_umlal(Register dest1, Register dest2, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_smull(Register dest1, Register dest2, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_smlal(Register dest1, Register dest2, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_sdiv(Register dest, Register num, Register div, Condition c = Always); BufferOffset as_udiv(Register dest, Register num, Register div, Condition c = Always); @@ -2105,8 +2107,8 @@ class InstALU : public Instruction static const int32_t ALUMask = 0xc << 24; public: - InstALU (Register rd, Register rn, Operand2 op2, ALUOp op, SetCond_ sc, Assembler::Condition c) - : Instruction(maybeRD(rd) | maybeRN(rn) | op2.encode() | op | sc, c) + InstALU (Register rd, Register rn, Operand2 op2, ALUOp op, SBit s, Assembler::Condition c) + : Instruction(maybeRD(rd) | maybeRN(rn) | op2.encode() | op | s, c) { } static bool IsTHIS (const Instruction& i); diff --git a/js/src/jit/arm/BaselineIC-arm.cpp b/js/src/jit/arm/BaselineIC-arm.cpp index 91153b1ae065..bc7b51b9d973 100644 --- a/js/src/jit/arm/BaselineIC-arm.cpp +++ b/js/src/jit/arm/BaselineIC-arm.cpp @@ -29,8 +29,8 @@ ICCompare_Int32::Compiler::generateStubCode(MacroAssembler& masm) // Compare payload regs of R0 and R1. Assembler::Condition cond = JSOpToCondition(op, /* signed = */true); masm.cmp32(R0.payloadReg(), R1.payloadReg()); - masm.ma_mov(Imm32(1), R0.payloadReg(), NoSetCond, cond); - masm.ma_mov(Imm32(0), R0.payloadReg(), NoSetCond, Assembler::InvertCondition(cond)); + masm.ma_mov(Imm32(1), R0.payloadReg(), LeaveCC, cond); + masm.ma_mov(Imm32(0), R0.payloadReg(), LeaveCC, Assembler::InvertCondition(cond)); // Result is implicitly boxed already. masm.tagValue(JSVAL_TYPE_BOOLEAN, R0.payloadReg(), R0); @@ -57,7 +57,7 @@ ICCompare_Double::Compiler::generateStubCode(MacroAssembler& masm) masm.compareDouble(FloatReg0, FloatReg1); masm.ma_mov(Imm32(0), dest); - masm.ma_mov(Imm32(1), dest, NoSetCond, cond); + masm.ma_mov(Imm32(1), dest, LeaveCC, cond); masm.tagValue(JSVAL_TYPE_BOOLEAN, dest, R0); EmitReturnFromIC(masm); @@ -93,7 +93,7 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm) Label maybeNegZero, revertRegister; switch(op_) { case JSOP_ADD: - masm.ma_add(R0.payloadReg(), R1.payloadReg(), scratchReg, SetCond); + masm.ma_add(R0.payloadReg(), R1.payloadReg(), scratchReg, SetCC); // Just jump to failure on overflow. R0 and R1 are preserved, so we can // just jump to the next stub. @@ -104,7 +104,7 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm) masm.mov(scratchReg, R0.payloadReg()); break; case JSOP_SUB: - masm.ma_sub(R0.payloadReg(), R1.payloadReg(), scratchReg, SetCond); + masm.ma_sub(R0.payloadReg(), R1.payloadReg(), scratchReg, SetCC); masm.j(Assembler::Overflow, &failure); masm.mov(scratchReg, R0.payloadReg()); break; diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index bc3e66378e16..4f37397aaf73 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -135,7 +135,7 @@ CodeGeneratorARM::visitCompare(LCompare* comp) else masm.ma_cmp(ToRegister(left), ToOperand(right)); masm.ma_mov(Imm32(0), ToRegister(def)); - masm.ma_mov(Imm32(1), ToRegister(def), NoSetCond, cond); + masm.ma_mov(Imm32(1), ToRegister(def), LeaveCC, cond); } void @@ -380,9 +380,9 @@ CodeGeneratorARM::visitAddI(LAddI* ins) const LDefinition* dest = ins->getDef(0); if (rhs->isConstant()) - masm.ma_add(ToRegister(lhs), Imm32(ToInt32(rhs)), ToRegister(dest), SetCond); + masm.ma_add(ToRegister(lhs), Imm32(ToInt32(rhs)), ToRegister(dest), SetCC); else - masm.ma_add(ToRegister(lhs), ToOperand(rhs), ToRegister(dest), SetCond); + masm.ma_add(ToRegister(lhs), ToOperand(rhs), ToRegister(dest), SetCC); if (ins->snapshot()) bailoutIf(Assembler::Overflow, ins->snapshot()); @@ -396,9 +396,9 @@ CodeGeneratorARM::visitSubI(LSubI* ins) const LDefinition* dest = ins->getDef(0); if (rhs->isConstant()) - masm.ma_sub(ToRegister(lhs), Imm32(ToInt32(rhs)), ToRegister(dest), SetCond); + masm.ma_sub(ToRegister(lhs), Imm32(ToInt32(rhs)), ToRegister(dest), SetCC); else - masm.ma_sub(ToRegister(lhs), ToOperand(rhs), ToRegister(dest), SetCond); + masm.ma_sub(ToRegister(lhs), ToOperand(rhs), ToRegister(dest), SetCC); if (ins->snapshot()) bailoutIf(Assembler::Overflow, ins->snapshot()); @@ -426,7 +426,7 @@ CodeGeneratorARM::visitMulI(LMulI* ins) // TODO: move these to ma_mul. switch (constant) { case -1: - masm.ma_rsb(ToRegister(lhs), Imm32(0), ToRegister(dest), SetCond); + masm.ma_rsb(ToRegister(lhs), Imm32(0), ToRegister(dest), SetCC); break; case 0: masm.ma_mov(Imm32(0), ToRegister(dest)); @@ -436,7 +436,7 @@ CodeGeneratorARM::visitMulI(LMulI* ins) masm.ma_mov(ToRegister(lhs), ToRegister(dest)); return; // Escape overflow check; case 2: - masm.ma_add(ToRegister(lhs), ToRegister(lhs), ToRegister(dest), SetCond); + masm.ma_add(ToRegister(lhs), ToRegister(lhs), ToRegister(dest), SetCC); // Overflow is handled later. break; default: { @@ -646,7 +646,7 @@ CodeGeneratorARM::visitDivPowTwoI(LDivPowTwoI* ins) MDiv* mir = ins->mir(); if (!mir->isTruncated()) { // If the remainder is != 0, bailout since this must be a double. - masm.as_mov(ScratchRegister, lsl(lhs, 32 - shift), SetCond); + masm.as_mov(ScratchRegister, lsl(lhs, 32 - shift), SetCC); bailoutIf(Assembler::NonZero, ins->snapshot()); } @@ -811,11 +811,11 @@ CodeGeneratorARM::visitModPowTwoI(LModPowTwoI* ins) Label fin; // bug 739870, jbramley has a different sequence that may help with speed // here. - masm.ma_mov(in, out, SetCond); + masm.ma_mov(in, out, SetCC); masm.ma_b(&fin, Assembler::Zero); - masm.ma_rsb(Imm32(0), out, NoSetCond, Assembler::Signed); + masm.ma_rsb(Imm32(0), out, LeaveCC, Assembler::Signed); masm.ma_and(Imm32((1 << ins->shift()) - 1), out); - masm.ma_rsb(Imm32(0), out, SetCond, Assembler::Signed); + masm.ma_rsb(Imm32(0), out, SetCC, Assembler::Signed); if (mir->canBeNegativeDividend()) { if (!mir->isTruncated()) { MOZ_ASSERT(mir->fallible()); @@ -1100,8 +1100,8 @@ CodeGeneratorARM::emitTableSwitchDispatch(MTableSwitch* mir, Register index, Reg int32_t cases = mir->numCases(); // Lower value with low value. - masm.ma_sub(index, Imm32(mir->low()), index, SetCond); - masm.ma_rsb(index, Imm32(cases - 1), index, SetCond, Assembler::NotSigned); + masm.ma_sub(index, Imm32(mir->low()), index, SetCC); + masm.ma_rsb(index, Imm32(cases - 1), index, SetCC, Assembler::NotSigned); // Inhibit pools within the following sequence because we are indexing into // a pc relative table. The region will have one instruction for ma_ldr, one // for ma_b, and each table case takes one word. @@ -1612,8 +1612,8 @@ CodeGeneratorARM::visitNotD(LNotD* ins) } else { masm.as_vmrs(pc); masm.ma_mov(Imm32(0), dest); - masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal); - masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow); + masm.ma_mov(Imm32(1), dest, LeaveCC, Assembler::Equal); + masm.ma_mov(Imm32(1), dest, LeaveCC, Assembler::Overflow); } } @@ -1640,8 +1640,8 @@ CodeGeneratorARM::visitNotF(LNotF* ins) } else { masm.as_vmrs(pc); masm.ma_mov(Imm32(0), dest); - masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal); - masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow); + masm.ma_mov(Imm32(1), dest, LeaveCC, Assembler::Equal); + masm.ma_mov(Imm32(1), dest, LeaveCC, Assembler::Overflow); } } @@ -1836,7 +1836,7 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap* ins) } } else { Register d = ToRegister(ins->output()); - masm.ma_mov(Imm32(0), d, NoSetCond, Assembler::AboveOrEqual); + masm.ma_mov(Imm32(0), d, LeaveCC, Assembler::AboveOrEqual); masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg, d, Offset, Assembler::Below); } memoryBarrier(mir->barrierAfter()); diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 4c7271bb09c7..5afd47c989e3 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -258,8 +258,8 @@ MacroAssemblerARM::inc64(AbsoluteAddress dest) ma_ldrd(EDtrAddr(ScratchRegister, EDtrOffImm(0)), r0, r1); - ma_add(Imm32(1), r0, SetCond); - ma_adc(Imm32(0), r1, NoSetCond); + ma_add(Imm32(1), r0, SetCC); + ma_adc(Imm32(0), r1, LeaveCC); ma_strd(r0, r1, EDtrAddr(ScratchRegister, EDtrOffImm(0))); @@ -269,9 +269,9 @@ MacroAssemblerARM::inc64(AbsoluteAddress dest) bool MacroAssemblerARM::alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, - SetCond_ sc, Condition c) + SBit s, Condition c) { - if ((sc == SetCond && ! condsAreSafe(op)) || !can_dbl(op)) + if ((s == SetCC && ! condsAreSafe(op)) || !can_dbl(op)) return false; ALUOp interop = getDestVariant(op); Imm8::TwoImm8mData both = Imm8::EncodeTwoImms(imm.value); @@ -282,8 +282,8 @@ MacroAssemblerARM::alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, // doesn't have a dest, such as check for overflow by doing first operation // don't do second operation if first operation overflowed. This preserves // the overflow condition code. Unfortunately, it is horribly brittle. - as_alu(ScratchRegister, src1, Operand2(both.fst), interop, NoSetCond, c); - as_alu(dest, ScratchRegister, Operand2(both.snd), op, sc, c); + as_alu(ScratchRegister, src1, Operand2(both.fst), interop, LeaveCC, c); + as_alu(dest, ScratchRegister, Operand2(both.snd), op, s, c); return true; } @@ -291,18 +291,18 @@ MacroAssemblerARM::alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, void MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, ALUOp op, - SetCond_ sc, Condition c) + SBit s, Condition c) { // As it turns out, if you ask for a compare-like instruction you *probably* // want it to set condition codes. if (dest == InvalidReg) - MOZ_ASSERT(sc == SetCond); + MOZ_ASSERT(s == SetCC); // The operator gives us the ability to determine how this can be used. Imm8 imm8 = Imm8(imm.value); // One instruction: If we can encode it using an imm8m, then do so. if (!imm8.invalid) { - as_alu(dest, src1, imm8, op, sc, c); + as_alu(dest, src1, imm8, op, s, c); return; } // One instruction, negated: @@ -317,7 +317,7 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // but it will need to clobber *something*, and the scratch register isn't // being used, so... if (negOp != OpInvalid && !negImm8.invalid) { - as_alu(negDest, src1, negImm8, negOp, sc, c); + as_alu(negDest, src1, negImm8, negOp, s, c); return; } @@ -326,7 +326,7 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // the bits into the destination. Otherwise, we'll need to fall back on // a multi-instruction format :( // movw/movt does not set condition codes, so don't hold your breath. - if (sc == NoSetCond && (op == OpMov || op == OpMvn)) { + if (s == LeaveCC && (op == OpMov || op == OpMvn)) { // ARMv7 supports movw/movt. movw zero-extends its 16 bit argument, // so we can set the register this way. movt leaves the bottom 16 // bits in tact, so it is unsuitable to move a constant that @@ -380,12 +380,12 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // assume that the overflow flag will be checked and add{,s} dest, src, // 0xff00; add{,s} dest, dest, 0xff is not guaranteed to set the overflow // flag the same as the (theoretical) one instruction variant. - if (alu_dbl(src1, imm, dest, op, sc, c)) + if (alu_dbl(src1, imm, dest, op, s, c)) return; // And try with its negative. if (negOp != OpInvalid && - alu_dbl(src1, negImm, negDest, negOp, sc, c)) + alu_dbl(src1, negImm, negDest, negOp, s, c)) return; // Well, damn. We can use two 16 bit mov's, then do the op or we can do a @@ -407,21 +407,21 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, as_Imm32Pool(ScratchRegister, imm.value, c); } } - as_alu(dest, src1, O2Reg(ScratchRegister), op, sc, c); + as_alu(dest, src1, O2Reg(ScratchRegister), op, s, c); } void MacroAssemblerARM::ma_alu(Register src1, Operand op2, Register dest, ALUOp op, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { MOZ_ASSERT(op2.getTag() == Operand::OP2); - as_alu(dest, src1, op2.toOp2(), op, sc, c); + as_alu(dest, src1, op2.toOp2(), op, s, c); } void -MacroAssemblerARM::ma_alu(Register src1, Operand2 op2, Register dest, ALUOp op, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_alu(Register src1, Operand2 op2, Register dest, ALUOp op, SBit s, Condition c) { - as_alu(dest, src1, op2, op, sc, c); + as_alu(dest, src1, op2, op, s, c); } void @@ -484,24 +484,24 @@ MacroAssemblerARM::ma_mov_patch(ImmPtr imm, Register dest, Assembler::Condition } void -MacroAssemblerARM::ma_mov(Register src, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_mov(Register src, Register dest, SBit s, Assembler::Condition c) { - if (sc == SetCond || dest != src) - as_mov(dest, O2Reg(src), sc, c); + if (s == SetCC || dest != src) + as_mov(dest, O2Reg(src), s, c); } void MacroAssemblerARM::ma_mov(Imm32 imm, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - ma_alu(InvalidReg, imm, dest, OpMov, sc, c); + ma_alu(InvalidReg, imm, dest, OpMov, s, c); } void MacroAssemblerARM::ma_mov(ImmWord imm, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - ma_alu(InvalidReg, Imm32(imm.value), dest, OpMov, sc, c); + ma_alu(InvalidReg, Imm32(imm.value), dest, OpMov, s, c); } void @@ -576,230 +576,230 @@ MacroAssemblerARM::ma_rol(Register shift, Register src, Register dst) // Move not (dest <- ~src) void -MacroAssemblerARM::ma_mvn(Imm32 imm, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_mvn(Imm32 imm, Register dest, SBit s, Assembler::Condition c) { - ma_alu(InvalidReg, imm, dest, OpMvn, sc, c); + ma_alu(InvalidReg, imm, dest, OpMvn, s, c); } void -MacroAssemblerARM::ma_mvn(Register src1, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_mvn(Register src1, Register dest, SBit s, Assembler::Condition c) { - as_alu(dest, InvalidReg, O2Reg(src1), OpMvn, sc, c); + as_alu(dest, InvalidReg, O2Reg(src1), OpMvn, s, c); } // Negate (dest <- -src), src is a register, rather than a general op2. void -MacroAssemblerARM::ma_neg(Register src1, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_neg(Register src1, Register dest, SBit s, Assembler::Condition c) { - as_rsb(dest, src1, Imm8(0), sc, c); + as_rsb(dest, src1, Imm8(0), s, c); } // And. void -MacroAssemblerARM::ma_and(Register src, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_and(Register src, Register dest, SBit s, Assembler::Condition c) { ma_and(dest, src, dest); } void MacroAssemblerARM::ma_and(Register src1, Register src2, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - as_and(dest, src1, O2Reg(src2), sc, c); + as_and(dest, src1, O2Reg(src2), s, c); } void -MacroAssemblerARM::ma_and(Imm32 imm, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_and(Imm32 imm, Register dest, SBit s, Assembler::Condition c) { - ma_alu(dest, imm, dest, OpAnd, sc, c); + ma_alu(dest, imm, dest, OpAnd, s, c); } void MacroAssemblerARM::ma_and(Imm32 imm, Register src1, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - ma_alu(src1, imm, dest, OpAnd, sc, c); + ma_alu(src1, imm, dest, OpAnd, s, c); } // Bit clear (dest <- dest & ~imm) or (dest <- src1 & ~src2). void -MacroAssemblerARM::ma_bic(Imm32 imm, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_bic(Imm32 imm, Register dest, SBit s, Assembler::Condition c) { - ma_alu(dest, imm, dest, OpBic, sc, c); + ma_alu(dest, imm, dest, OpBic, s, c); } // Exclusive or. void -MacroAssemblerARM::ma_eor(Register src, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_eor(Register src, Register dest, SBit s, Assembler::Condition c) { - ma_eor(dest, src, dest, sc, c); + ma_eor(dest, src, dest, s, c); } void MacroAssemblerARM::ma_eor(Register src1, Register src2, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - as_eor(dest, src1, O2Reg(src2), sc, c); + as_eor(dest, src1, O2Reg(src2), s, c); } void -MacroAssemblerARM::ma_eor(Imm32 imm, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_eor(Imm32 imm, Register dest, SBit s, Assembler::Condition c) { - ma_alu(dest, imm, dest, OpEor, sc, c); + ma_alu(dest, imm, dest, OpEor, s, c); } void MacroAssemblerARM::ma_eor(Imm32 imm, Register src1, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - ma_alu(src1, imm, dest, OpEor, sc, c); + ma_alu(src1, imm, dest, OpEor, s, c); } // Or. void -MacroAssemblerARM::ma_orr(Register src, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_orr(Register src, Register dest, SBit s, Assembler::Condition c) { - ma_orr(dest, src, dest, sc, c); + ma_orr(dest, src, dest, s, c); } void MacroAssemblerARM::ma_orr(Register src1, Register src2, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - as_orr(dest, src1, O2Reg(src2), sc, c); + as_orr(dest, src1, O2Reg(src2), s, c); } void -MacroAssemblerARM::ma_orr(Imm32 imm, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_orr(Imm32 imm, Register dest, SBit s, Assembler::Condition c) { - ma_alu(dest, imm, dest, OpOrr, sc, c); + ma_alu(dest, imm, dest, OpOrr, s, c); } void MacroAssemblerARM::ma_orr(Imm32 imm, Register src1, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - ma_alu(src1, imm, dest, OpOrr, sc, c); + ma_alu(src1, imm, dest, OpOrr, s, c); } // Arithmetic-based ops. // Add with carry. void -MacroAssemblerARM::ma_adc(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_adc(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpAdc, sc, c); + ma_alu(dest, imm, dest, OpAdc, s, c); } void -MacroAssemblerARM::ma_adc(Register src, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_adc(Register src, Register dest, SBit s, Condition c) { - as_alu(dest, dest, O2Reg(src), OpAdc, sc, c); + as_alu(dest, dest, O2Reg(src), OpAdc, s, c); } void -MacroAssemblerARM::ma_adc(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_adc(Register src1, Register src2, Register dest, SBit s, Condition c) { - as_alu(dest, src1, O2Reg(src2), OpAdc, sc, c); + as_alu(dest, src1, O2Reg(src2), OpAdc, s, c); } // Add. void -MacroAssemblerARM::ma_add(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_add(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpAdd, sc, c); + ma_alu(dest, imm, dest, OpAdd, s, c); } void -MacroAssemblerARM::ma_add(Register src1, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_add(Register src1, Register dest, SBit s, Condition c) { - ma_alu(dest, O2Reg(src1), dest, OpAdd, sc, c); + ma_alu(dest, O2Reg(src1), dest, OpAdd, s, c); } void -MacroAssemblerARM::ma_add(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_add(Register src1, Register src2, Register dest, SBit s, Condition c) { - as_alu(dest, src1, O2Reg(src2), OpAdd, sc, c); + as_alu(dest, src1, O2Reg(src2), OpAdd, s, c); } void -MacroAssemblerARM::ma_add(Register src1, Operand op, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_add(Register src1, Operand op, Register dest, SBit s, Condition c) { - ma_alu(src1, op, dest, OpAdd, sc, c); + ma_alu(src1, op, dest, OpAdd, s, c); } void -MacroAssemblerARM::ma_add(Register src1, Imm32 op, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_add(Register src1, Imm32 op, Register dest, SBit s, Condition c) { - ma_alu(src1, op, dest, OpAdd, sc, c); + ma_alu(src1, op, dest, OpAdd, s, c); } // Subtract with carry. void -MacroAssemblerARM::ma_sbc(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sbc(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpSbc, sc, c); + ma_alu(dest, imm, dest, OpSbc, s, c); } void -MacroAssemblerARM::ma_sbc(Register src1, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sbc(Register src1, Register dest, SBit s, Condition c) { - as_alu(dest, dest, O2Reg(src1), OpSbc, sc, c); + as_alu(dest, dest, O2Reg(src1), OpSbc, s, c); } void -MacroAssemblerARM::ma_sbc(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sbc(Register src1, Register src2, Register dest, SBit s, Condition c) { - as_alu(dest, src1, O2Reg(src2), OpSbc, sc, c); + as_alu(dest, src1, O2Reg(src2), OpSbc, s, c); } // Subtract. void -MacroAssemblerARM::ma_sub(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sub(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpSub, sc, c); + ma_alu(dest, imm, dest, OpSub, s, c); } void -MacroAssemblerARM::ma_sub(Register src1, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sub(Register src1, Register dest, SBit s, Condition c) { - ma_alu(dest, Operand(src1), dest, OpSub, sc, c); + ma_alu(dest, Operand(src1), dest, OpSub, s, c); } void -MacroAssemblerARM::ma_sub(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sub(Register src1, Register src2, Register dest, SBit s, Condition c) { - ma_alu(src1, Operand(src2), dest, OpSub, sc, c); + ma_alu(src1, Operand(src2), dest, OpSub, s, c); } void -MacroAssemblerARM::ma_sub(Register src1, Operand op, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sub(Register src1, Operand op, Register dest, SBit s, Condition c) { - ma_alu(src1, op, dest, OpSub, sc, c); + ma_alu(src1, op, dest, OpSub, s, c); } void -MacroAssemblerARM::ma_sub(Register src1, Imm32 op, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sub(Register src1, Imm32 op, Register dest, SBit s, Condition c) { - ma_alu(src1, op, dest, OpSub, sc, c); + ma_alu(src1, op, dest, OpSub, s, c); } // Severse subtract. void -MacroAssemblerARM::ma_rsb(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsb(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpRsb, sc, c); + ma_alu(dest, imm, dest, OpRsb, s, c); } void -MacroAssemblerARM::ma_rsb(Register src1, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsb(Register src1, Register dest, SBit s, Condition c) { - as_alu(dest, dest, O2Reg(src1), OpAdd, sc, c); + as_alu(dest, dest, O2Reg(src1), OpAdd, s, c); } void -MacroAssemblerARM::ma_rsb(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsb(Register src1, Register src2, Register dest, SBit s, Condition c) { - as_alu(dest, src1, O2Reg(src2), OpRsb, sc, c); + as_alu(dest, src1, O2Reg(src2), OpRsb, s, c); } void -MacroAssemblerARM::ma_rsb(Register src1, Imm32 op2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsb(Register src1, Imm32 op2, Register dest, SBit s, Condition c) { - ma_alu(src1, op2, dest, OpRsb, sc, c); + ma_alu(src1, op2, dest, OpRsb, s, c); } // Reverse subtract with carry. void -MacroAssemblerARM::ma_rsc(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsc(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpRsc, sc, c); + ma_alu(dest, imm, dest, OpRsc, s, c); } void -MacroAssemblerARM::ma_rsc(Register src1, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsc(Register src1, Register dest, SBit s, Condition c) { - as_alu(dest, dest, O2Reg(src1), OpRsc, sc, c); + as_alu(dest, dest, O2Reg(src1), OpRsc, s, c); } void -MacroAssemblerARM::ma_rsc(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsc(Register src1, Register src2, Register dest, SBit s, Condition c) { - as_alu(dest, src1, O2Reg(src2), OpRsc, sc, c); + as_alu(dest, src1, O2Reg(src2), OpRsc, s, c); } // Compares/tests. @@ -807,12 +807,12 @@ MacroAssemblerARM::ma_rsc(Register src1, Register src2, Register dest, SetCond_ void MacroAssemblerARM::ma_cmn(Register src1, Imm32 imm, Condition c) { - ma_alu(src1, imm, InvalidReg, OpCmn, SetCond, c); + ma_alu(src1, imm, InvalidReg, OpCmn, SetCC, c); } void MacroAssemblerARM::ma_cmn(Register src1, Register src2, Condition c) { - as_alu(InvalidReg, src2, O2Reg(src1), OpCmn, SetCond, c); + as_alu(InvalidReg, src2, O2Reg(src1), OpCmn, SetCC, c); } void MacroAssemblerARM::ma_cmn(Register src1, Operand op, Condition c) @@ -824,7 +824,7 @@ MacroAssemblerARM::ma_cmn(Register src1, Operand op, Condition c) void MacroAssemblerARM::ma_cmp(Register src1, Imm32 imm, Condition c) { - ma_alu(src1, imm, InvalidReg, OpCmp, SetCond, c); + ma_alu(src1, imm, InvalidReg, OpCmp, SetCC, c); } void @@ -864,7 +864,7 @@ MacroAssemblerARM::ma_cmp(Register src1, Register src2, Condition c) void MacroAssemblerARM::ma_teq(Register src1, Imm32 imm, Condition c) { - ma_alu(src1, imm, InvalidReg, OpTeq, SetCond, c); + ma_alu(src1, imm, InvalidReg, OpTeq, SetCC, c); } void MacroAssemblerARM::ma_teq(Register src1, Register src2, Condition c) @@ -882,7 +882,7 @@ MacroAssemblerARM::ma_teq(Register src1, Operand op, Condition c) void MacroAssemblerARM::ma_tst(Register src1, Imm32 imm, Condition c) { - ma_alu(src1, imm, InvalidReg, OpTst, SetCond, c); + ma_alu(src1, imm, InvalidReg, OpTst, SetCC, c); } void MacroAssemblerARM::ma_tst(Register src1, Register src2, Condition c) @@ -914,7 +914,7 @@ MacroAssemblerARM::ma_check_mul(Register src1, Register src2, Register dest, Con // TODO: this operation is illegal on armv6 and earlier if src2 == // ScratchRegister or src2 == dest. if (cond == Equal || cond == NotEqual) { - as_smull(ScratchRegister, dest, src1, src2, SetCond); + as_smull(ScratchRegister, dest, src1, src2, SetCC); return cond; } @@ -932,7 +932,7 @@ MacroAssemblerARM::ma_check_mul(Register src1, Imm32 imm, Register dest, Conditi { ma_mov(imm, ScratchRegister); if (cond == Equal || cond == NotEqual) { - as_smull(ScratchRegister, dest, ScratchRegister, src1, SetCond); + as_smull(ScratchRegister, dest, ScratchRegister, src1, SetCC); return cond; } @@ -979,13 +979,13 @@ MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, Regis // Note that we cannot use ScratchRegister in place of tmp here, as ma_and // below on certain architectures move the mask into ScratchRegister before // performing the bitwise and. - as_mov(tmp, O2Reg(src), SetCond); + as_mov(tmp, O2Reg(src), SetCC); // Zero out the dest. ma_mov(Imm32(0), dest); // Set the hold appropriately. ma_mov(Imm32(1), hold); - ma_mov(Imm32(-1), hold, NoSetCond, Signed); - ma_rsb(Imm32(0), tmp, SetCond, Signed); + ma_mov(Imm32(-1), hold, LeaveCC, Signed); + ma_rsb(Imm32(0), tmp, SetCC, Signed); // Begin the main loop. bind(&head); @@ -995,11 +995,11 @@ MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, Regis ma_add(secondScratchReg_, dest, dest); // Do a trial subtraction, this is the same operation as cmp, but we store // the dest. - ma_sub(dest, Imm32(mask), secondScratchReg_, SetCond); + ma_sub(dest, Imm32(mask), secondScratchReg_, SetCC); // If (sum - C) > 0, store sum - C back into sum, thus performing a modulus. - ma_mov(secondScratchReg_, dest, NoSetCond, NotSigned); + ma_mov(secondScratchReg_, dest, LeaveCC, NotSigned); // Get rid of the bits that we extracted before, and set the condition codes. - as_mov(tmp, lsr(tmp, shift), SetCond); + as_mov(tmp, lsr(tmp, shift), SetCC); // If the shift produced zero, finish, otherwise, continue in the loop. ma_b(&head, NonZero); // Check the hold to see if we need to negate the result. Hold can only be @@ -1007,7 +1007,7 @@ MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, Regis ma_cmp(hold, Imm32(0)); // If the hold was non-zero, negate the result to be in line with what JS // wants this will set the condition codes if we try to negate. - ma_rsb(Imm32(0), dest, SetCond, Signed); + ma_rsb(Imm32(0), dest, SetCC, Signed); // Since the Zero flag is not set by the compare, we can *only* set the Zero // flag in the rsb, so Zero is set iff we negated zero (e.g. the result of // the computation was -0.0). @@ -1232,7 +1232,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, Operand2 sub_off = Imm8(-(off - bottom)); // sub_off = bottom - off if (!sub_off.invalid) { // - sub_off = off - bottom - as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(bottom)), cc); } // sub_off = -neg_bottom - off @@ -1241,7 +1241,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x1000); // - sub_off = neg_bottom + off - as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(-neg_bottom)), cc); } } else { @@ -1249,7 +1249,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, Operand2 sub_off = Imm8(off - bottom); if (!sub_off.invalid) { // sub_off = off - bottom - as_add(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_add(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(bottom)), cc); } // sub_off = neg_bottom + off @@ -1258,7 +1258,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x1000); // sub_off = neg_bottom + off - as_add(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_add(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(-neg_bottom)), cc); } } @@ -1284,7 +1284,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, Operand2 sub_off = Imm8(-(off - bottom)); if (!sub_off.invalid) { // - sub_off = off - bottom - as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_extdtr(ls, size, IsSigned, Offset, rt, EDtrAddr(ScratchRegister, EDtrOffImm(bottom)), cc); @@ -1295,7 +1295,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x100); // - sub_off = neg_bottom + off - as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_extdtr(ls, size, IsSigned, Offset, rt, EDtrAddr(ScratchRegister, EDtrOffImm(-neg_bottom)), cc); @@ -1305,7 +1305,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, Operand2 sub_off = Imm8(off - bottom); if (!sub_off.invalid) { // sub_off = off - bottom - as_add(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_add(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_extdtr(ls, size, IsSigned, Offset, rt, EDtrAddr(ScratchRegister, EDtrOffImm(bottom)), cc); @@ -1316,7 +1316,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x100); // sub_off = neg_bottom + off - as_add(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_add(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_extdtr(ls, size, IsSigned, Offset, rt, EDtrAddr(ScratchRegister, EDtrOffImm(-neg_bottom)), cc); @@ -1730,7 +1730,7 @@ MacroAssemblerARM::ma_vdtr(LoadStore ls, const Address& addr, VFPRegister rt, Co Operand2 sub_off = Imm8(-(off - bottom)); if (!sub_off.invalid) { // - sub_off = off - bottom - as_sub(ScratchRegister, base, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, base, sub_off, LeaveCC, cc); return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(bottom)), cc); } // sub_off = -neg_bottom - off @@ -1739,7 +1739,7 @@ MacroAssemblerARM::ma_vdtr(LoadStore ls, const Address& addr, VFPRegister rt, Co // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x400); // - sub_off = neg_bottom + off - as_sub(ScratchRegister, base, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, base, sub_off, LeaveCC, cc); return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(-neg_bottom)), cc); } } else { @@ -1747,7 +1747,7 @@ MacroAssemblerARM::ma_vdtr(LoadStore ls, const Address& addr, VFPRegister rt, Co Operand2 sub_off = Imm8(off - bottom); if (!sub_off.invalid) { // sub_off = off - bottom - as_add(ScratchRegister, base, sub_off, NoSetCond, cc); + as_add(ScratchRegister, base, sub_off, LeaveCC, cc); return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(bottom)), cc); } // sub_off = neg_bottom + off @@ -1756,11 +1756,11 @@ MacroAssemblerARM::ma_vdtr(LoadStore ls, const Address& addr, VFPRegister rt, Co // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x400); // sub_off = neg_bottom + off - as_add(ScratchRegister, base, sub_off, NoSetCond, cc); + as_add(ScratchRegister, base, sub_off, LeaveCC, cc); return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(-neg_bottom)), cc); } } - ma_add(base, Imm32(off), ScratchRegister, NoSetCond, cc); + ma_add(base, Imm32(off), ScratchRegister, LeaveCC, cc); return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(0)), cc); } @@ -1777,7 +1777,7 @@ MacroAssemblerARM::ma_vldr(const Address& addr, VFPRegister dest, Condition cc) BufferOffset MacroAssemblerARM::ma_vldr(VFPRegister src, Register base, Register index, int32_t shift, Condition cc) { - as_add(ScratchRegister, base, lsl(index, shift), NoSetCond, cc); + as_add(ScratchRegister, base, lsl(index, shift), LeaveCC, cc); return ma_vldr(Address(ScratchRegister, 0), src, cc); } @@ -1796,7 +1796,7 @@ BufferOffset MacroAssemblerARM::ma_vstr(VFPRegister src, Register base, Register index, int32_t shift, int32_t offset, Condition cc) { - as_add(ScratchRegister, base, lsl(index, shift), NoSetCond, cc); + as_add(ScratchRegister, base, lsl(index, shift), LeaveCC, cc); return ma_vstr(src, Address(ScratchRegister, offset), cc); } @@ -1929,58 +1929,58 @@ MacroAssemblerARMCompat::freeStack(Register amount) void MacroAssemblerARMCompat::add32(Register src, Register dest) { - ma_add(src, dest, SetCond); + ma_add(src, dest, SetCC); } void MacroAssemblerARMCompat::add32(Imm32 imm, Register dest) { - ma_add(imm, dest, SetCond); + ma_add(imm, dest, SetCC); } void MacroAssemblerARMCompat::xor32(Imm32 imm, Register dest) { - ma_eor(imm, dest, SetCond); + ma_eor(imm, dest, SetCC); } void MacroAssemblerARMCompat::add32(Imm32 imm, const Address& dest) { load32(dest, ScratchRegister); - ma_add(imm, ScratchRegister, SetCond); + ma_add(imm, ScratchRegister, SetCC); store32(ScratchRegister, dest); } void MacroAssemblerARMCompat::sub32(Imm32 imm, Register dest) { - ma_sub(imm, dest, SetCond); + ma_sub(imm, dest, SetCC); } void MacroAssemblerARMCompat::sub32(Register src, Register dest) { - ma_sub(src, dest, SetCond); + ma_sub(src, dest, SetCC); } void MacroAssemblerARMCompat::and32(Register src, Register dest) { - ma_and(src, dest, SetCond); + ma_and(src, dest, SetCC); } void MacroAssemblerARMCompat::and32(Imm32 imm, Register dest) { - ma_and(imm, dest, SetCond); + ma_and(imm, dest, SetCC); } void MacroAssemblerARMCompat::and32(const Address& src, Register dest) { load32(src, ScratchRegister); - ma_and(ScratchRegister, dest, SetCond); + ma_and(ScratchRegister, dest, SetCC); } void @@ -1993,7 +1993,7 @@ void MacroAssemblerARMCompat::addPtr(const Address& src, Register dest) { load32(src, ScratchRegister); - ma_add(ScratchRegister, dest, SetCond); + ma_add(ScratchRegister, dest, SetCC); } void @@ -2522,7 +2522,7 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) ma_cmp(ScratchRegister, Imm32(0)); // If the lower 32 bits of the double were 0, then this was an exact number, // and it should be even. - ma_bic(Imm32(1), output, NoSetCond, Zero); + ma_bic(Imm32(1), output, LeaveCC, Zero); bind(¬Split); } else { Label outOfRange; @@ -2534,17 +2534,17 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) // Copy the converted value out. as_vxfer(output, InvalidReg, ScratchDoubleReg, FloatToCore); as_vmrs(pc); - ma_mov(Imm32(0), output, NoSetCond, Overflow); // NaN => 0 + ma_mov(Imm32(0), output, LeaveCC, Overflow); // NaN => 0 ma_b(&outOfRange, Overflow); // NaN ma_cmp(output, Imm32(0xff)); - ma_mov(Imm32(0xff), output, NoSetCond, Above); + ma_mov(Imm32(0xff), output, LeaveCC, Above); ma_b(&outOfRange, Above); // Convert it back to see if we got the same value back. as_vcvt(ScratchDoubleReg, VFPRegister(ScratchDoubleReg).uintOverlay()); // Do the check. as_vcmp(ScratchDoubleReg, input); as_vmrs(pc); - ma_bic(Imm32(1), output, NoSetCond, Zero); + ma_bic(Imm32(1), output, LeaveCC, Zero); bind(&outOfRange); } } @@ -3370,7 +3370,7 @@ MacroAssemblerARMCompat::extractTag(const Address& address, Register scratch) Register MacroAssemblerARMCompat::extractTag(const BaseIndex& address, Register scratch) { - ma_alu(address.base, lsl(address.index, address.scale), scratch, OpAdd, NoSetCond); + ma_alu(address.base, lsl(address.index, address.scale), scratch, OpAdd, LeaveCC); return extractTag(Address(scratch, address.offset), scratch); } @@ -4287,7 +4287,7 @@ MacroAssemblerARMCompat::floor(FloatRegister input, Register output, Label* bail // that clamps to INT_MAX. ma_vcvt_F64_U32(input, ScratchDoubleReg.uintOverlay()); ma_vxfer(ScratchDoubleReg.uintOverlay(), output); - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(&fin); @@ -4306,10 +4306,10 @@ MacroAssemblerARMCompat::floor(FloatRegister input, Register output, Label* bail ma_vxfer(ScratchDoubleReg.uintOverlay(), output); ma_vcvt_U32_F64(ScratchDoubleReg.uintOverlay(), ScratchDoubleReg); compareDouble(ScratchDoubleReg, input); - ma_add(output, Imm32(1), output, NoSetCond, NotEqual); + ma_add(output, Imm32(1), output, LeaveCC, NotEqual); // Negate the output. Since INT_MIN < -INT_MAX, even after adding 1, the // result will still be a negative number. - ma_rsb(output, Imm32(0), output, SetCond); + ma_rsb(output, Imm32(0), output, SetCC); // Flip the negated input back to its original value. ma_vneg(input, input); // If the result looks non-negative, then this value didn't actually fit @@ -4338,7 +4338,7 @@ MacroAssemblerARMCompat::floorf(FloatRegister input, Register output, Label* bai // that clamps to INT_MAX. ma_vcvt_F32_U32(input, ScratchFloat32Reg.uintOverlay()); ma_vxfer(VFPRegister(ScratchFloat32Reg).uintOverlay(), output); - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(&fin); @@ -4357,10 +4357,10 @@ MacroAssemblerARMCompat::floorf(FloatRegister input, Register output, Label* bai ma_vxfer(VFPRegister(ScratchFloat32Reg).uintOverlay(), output); ma_vcvt_U32_F32(ScratchFloat32Reg.uintOverlay(), ScratchFloat32Reg); compareFloat(ScratchFloat32Reg, input); - ma_add(output, Imm32(1), output, NoSetCond, NotEqual); + ma_add(output, Imm32(1), output, LeaveCC, NotEqual); // Negate the output. Since INT_MIN < -INT_MAX, even after adding 1, the // result will still be a negative number. - ma_rsb(output, Imm32(0), output, SetCond); + ma_rsb(output, Imm32(0), output, SetCC); // Flip the negated input back to its original value. ma_vneg_f32(input, input); // If the result looks non-negative, then this value didn't actually fit @@ -4396,7 +4396,7 @@ MacroAssemblerARMCompat::ceil(FloatRegister input, Register output, Label* bail) FloatRegister ScratchUIntReg = ScratchDoubleReg.uintOverlay(); ma_vcvt_F64_U32(ScratchDoubleReg, ScratchUIntReg); ma_vxfer(ScratchUIntReg, output); - ma_neg(output, output, SetCond); + ma_neg(output, output, SetCC); ma_b(bail, NotSigned); ma_b(&fin); @@ -4415,9 +4415,9 @@ MacroAssemblerARMCompat::ceil(FloatRegister input, Register output, Label* bail) ma_vxfer(ScratchUIntReg, output); ma_vcvt_U32_F64(ScratchUIntReg, ScratchDoubleReg); compareDouble(ScratchDoubleReg, input); - ma_add(output, Imm32(1), output, NoSetCond, NotEqual); + ma_add(output, Imm32(1), output, LeaveCC, NotEqual); // Bail out if the add overflowed or the result is non positive. - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(bail, Zero); @@ -4449,7 +4449,7 @@ MacroAssemblerARMCompat::ceilf(FloatRegister input, Register output, Label* bail FloatRegister ScratchUIntReg = ScratchDoubleReg.uintOverlay(); ma_vcvt_F32_U32(ScratchFloat32Reg, ScratchUIntReg); ma_vxfer(ScratchUIntReg, output); - ma_neg(output, output, SetCond); + ma_neg(output, output, SetCC); ma_b(bail, NotSigned); ma_b(&fin); @@ -4468,9 +4468,9 @@ MacroAssemblerARMCompat::ceilf(FloatRegister input, Register output, Label* bail ma_vxfer(ScratchUIntReg, output); ma_vcvt_U32_F32(ScratchUIntReg, ScratchFloat32Reg); compareFloat(ScratchFloat32Reg, input); - ma_add(output, Imm32(1), output, NoSetCond, NotEqual); + ma_add(output, Imm32(1), output, LeaveCC, NotEqual); // Bail out if the add overflowed or the result is non positive. - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(bail, Zero); @@ -4530,7 +4530,7 @@ MacroAssemblerARMCompat::round(FloatRegister input, Register output, Label* bail ma_vcvt_F64_U32(tmp, ScratchDoubleReg.uintOverlay()); ma_vxfer(VFPRegister(ScratchDoubleReg).uintOverlay(), output); - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(&fin); @@ -4558,10 +4558,10 @@ MacroAssemblerARMCompat::round(FloatRegister input, Register output, Label* bail // away from zero, when it should be rounded towards \infty. ma_vcvt_U32_F64(ScratchDoubleReg.uintOverlay(), ScratchDoubleReg); compareDouble(ScratchDoubleReg, tmp); - ma_sub(output, Imm32(1), output, NoSetCond, Equal); + ma_sub(output, Imm32(1), output, LeaveCC, Equal); // Negate the output. Since INT_MIN < -INT_MAX, even after adding 1, the // result will still be a negative number. - ma_rsb(output, Imm32(0), output, SetCond); + ma_rsb(output, Imm32(0), output, SetCC); // If the result looks non-negative, then this value didn't actually fit // into the int range, and special handling is required, or it was zero, @@ -4604,7 +4604,7 @@ MacroAssemblerARMCompat::roundf(FloatRegister input, Register output, Label* bai // we are not applying any fixup after the operation). ma_vcvt_F32_U32(tmp, ScratchFloat32Reg.uintOverlay()); ma_vxfer(VFPRegister(ScratchFloat32Reg).uintOverlay(), output); - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(&fin); @@ -4644,12 +4644,12 @@ MacroAssemblerARMCompat::roundf(FloatRegister input, Register output, Label* bai // away from zero, when it should be rounded towards \infty. ma_vcvt_U32_F32(tmp.uintOverlay(), tmp); compareFloat(tmp, ScratchFloat32Reg); - ma_sub(output, Imm32(1), output, NoSetCond, Equal); + ma_sub(output, Imm32(1), output, LeaveCC, Equal); // Negate the output. Since INT_MIN < -INT_MAX, even after adding 1, the // result will still be a negative number. bind(&flipSign); - ma_rsb(output, Imm32(0), output, SetCond); + ma_rsb(output, Imm32(0), output, SetCC); // If the result looks non-negative, then this value didn't actually fit // into the int range, and special handling is required, or it was zero, diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 480a79e5db56..d7e0e12e4c73 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -105,17 +105,17 @@ class MacroAssemblerARM : public Assembler // instructions. private: bool alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, - SetCond_ sc, Condition c); + SBit s, Condition c); public: void ma_alu(Register src1, Operand2 op2, Register dest, ALUOp op, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_alu(Register src1, Imm32 imm, Register dest, ALUOp op, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_alu(Register src1, Operand op2, Register dest, ALUOp op, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_nop(); void ma_movPatchable(Imm32 imm, Register dest, Assembler::Condition c, @@ -135,12 +135,12 @@ class MacroAssemblerARM : public Assembler // ALU based ops // mov void ma_mov(Register src, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_mov(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_mov(ImmWord imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_mov(ImmGCPtr ptr, Register dest); @@ -159,98 +159,98 @@ class MacroAssemblerARM : public Assembler // Move not (dest <- ~src) void ma_mvn(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_mvn(Register src1, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // Negate (dest <- -src) implemented as rsb dest, src, 0 void ma_neg(Register src, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // And void ma_and(Register src, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_and(Register src1, Register src2, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_and(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_and(Imm32 imm, Register src1, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // Bit clear (dest <- dest & ~imm) or (dest <- src1 & ~src2) void ma_bic(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // Exclusive or void ma_eor(Register src, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_eor(Register src1, Register src2, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_eor(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_eor(Imm32 imm, Register src1, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // Or void ma_orr(Register src, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_orr(Register src1, Register src2, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_orr(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_orr(Imm32 imm, Register src1, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // Arithmetic based ops. // Add with carry: - void ma_adc(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_adc(Register src, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_adc(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_adc(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_adc(Register src, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_adc(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); // Add: - void ma_add(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_add(Register src1, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_add(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_add(Register src1, Operand op, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_add(Register src1, Imm32 op, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_add(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_add(Register src1, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_add(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_add(Register src1, Operand op, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_add(Register src1, Imm32 op, Register dest, SBit s = LeaveCC, Condition c = Always); // Subtract with carry: - void ma_sbc(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sbc(Register src1, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sbc(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_sbc(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sbc(Register src1, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sbc(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); // Subtract: - void ma_sub(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sub(Register src1, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sub(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sub(Register src1, Operand op, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sub(Register src1, Imm32 op, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_sub(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sub(Register src1, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sub(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sub(Register src1, Operand op, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sub(Register src1, Imm32 op, Register dest, SBit s = LeaveCC, Condition c = Always); // Reverse subtract: - void ma_rsb(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_rsb(Register src1, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_rsb(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_rsb(Register src1, Imm32 op2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_rsb(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_rsb(Register src1, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_rsb(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_rsb(Register src1, Imm32 op2, Register dest, SBit s = LeaveCC, Condition c = Always); // Reverse subtract with carry: - void ma_rsc(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_rsc(Register src1, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_rsc(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_rsc(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_rsc(Register src1, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_rsc(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); // Compares/tests. // Compare negative (sets condition codes as src1 + src2 would): @@ -734,10 +734,10 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM } void neg32(Register reg) { - ma_neg(reg, reg, SetCond); + ma_neg(reg, reg, SetCC); } void negl(Register reg) { - ma_neg(reg, reg, SetCond); + ma_neg(reg, reg, SetCC); } void test32(Register lhs, Register rhs) { ma_tst(lhs, rhs); @@ -1698,9 +1698,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void clampIntToUint8(Register reg) { // Look at (reg >> 8) if it is 0, then reg shouldn't be clamped if it is // <0, then we want to clamp to 0, otherwise, we wish to clamp to 255 - as_mov(ScratchRegister, asr(reg, 8), SetCond); - ma_mov(Imm32(0xff), reg, NoSetCond, NotEqual); - ma_mov(Imm32(0), reg, NoSetCond, Signed); + as_mov(ScratchRegister, asr(reg, 8), SetCC); + ma_mov(Imm32(0xff), reg, LeaveCC, NotEqual); + ma_mov(Imm32(0), reg, LeaveCC, Signed); } void incrementInt32Value(const Address& addr) { @@ -1778,7 +1778,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM emitSet(Assembler::Condition cond, Register dest) { ma_mov(Imm32(0), dest); - ma_mov(Imm32(1), dest, NoSetCond, cond); + ma_mov(Imm32(1), dest, LeaveCC, cond); } template @@ -1855,12 +1855,12 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM } void computeEffectiveAddress(const Address& address, Register dest) { - ma_add(address.base, Imm32(address.offset), dest, NoSetCond); + ma_add(address.base, Imm32(address.offset), dest, LeaveCC); } void computeEffectiveAddress(const BaseIndex& address, Register dest) { - ma_alu(address.base, lsl(address.index, address.scale), dest, OpAdd, NoSetCond); + ma_alu(address.base, lsl(address.index, address.scale), dest, OpAdd, LeaveCC); if (address.offset) - ma_add(dest, Imm32(address.offset), dest, NoSetCond); + ma_add(dest, Imm32(address.offset), dest, LeaveCC); } void floor(FloatRegister input, Register output, Label* handleNotAnInt); void floorf(FloatRegister input, Register output, Label* handleNotAnInt); diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp index 86773134f5ee..15dab0d1f79f 100644 --- a/js/src/jit/arm/Trampoline-arm.cpp +++ b/js/src/jit/arm/Trampoline-arm.cpp @@ -171,7 +171,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type) // Get a copy of the number of args to use as a decrement counter, also set // the zero condition code. - aasm->as_mov(r5, O2Reg(r1), SetCond); + aasm->as_mov(r5, O2Reg(r1), SetCC); // Loop over arguments, copying them from an unknown buffer onto the Ion // stack so they can be accessed from JIT'ed code. @@ -181,7 +181,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type) aasm->as_b(&footer, Assembler::Zero); // Get the top of the loop. masm.bind(&header); - aasm->as_sub(r5, r5, Imm8(1), SetCond); + aasm->as_sub(r5, r5, Imm8(1), SetCC); // We could be more awesome, and unroll this, using a loadm // (particularly since the offset is effectively 0) but that seems more // error prone, and complex. @@ -473,7 +473,7 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut) Label undefLoopTop; masm.bind(&undefLoopTop); masm.ma_dataTransferN(IsStore, 64, true, sp, Imm32(-8), r4, PreIndex); - masm.ma_sub(r2, Imm32(1), r2, SetCond); + masm.ma_sub(r2, Imm32(1), r2, SetCC); masm.ma_b(&undefLoopTop, Assembler::NonZero); } @@ -490,7 +490,7 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut) masm.ma_dataTransferN(IsLoad, 64, true, r3, Imm32(-8), r4, PostIndex); masm.ma_dataTransferN(IsStore, 64, true, sp, Imm32(-8), r4, PreIndex); - masm.ma_sub(r8, Imm32(1), r8, SetCond); + masm.ma_sub(r8, Imm32(1), r8, SetCC); masm.ma_b(©LoopTop, Assembler::NotSigned); } From 29ba8d4eb16d6c2e8efbd4c48a72dbd886ab8615 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Fri, 29 May 2015 22:07:17 -0700 Subject: [PATCH 26/85] Bug 1168747: Skip reftests 336736-1a.html and 336736-1b.html on b2g, since they randomly timeout the harness for no clear reason ever since a recent chunking change. --- layout/reftests/marquee/reftest.list | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/reftests/marquee/reftest.list b/layout/reftests/marquee/reftest.list index da1d2f118b9a..298a02b0b5d8 100644 --- a/layout/reftests/marquee/reftest.list +++ b/layout/reftests/marquee/reftest.list @@ -1,6 +1,6 @@ random-if((B2G&&browserIsRemote)||Mulet) == 166591-dynamic-1.html 166591-dynamic-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop -fuzzy-if(Android&&AndroidVersion>=15,8,50) == 336736-1a.html 336736-1-ref.html -fuzzy-if(Android&&AndroidVersion>=15,8,50) == 336736-1b.html 336736-1-ref.html +skip-if(B2G) fuzzy-if(Android&&AndroidVersion>=15,8,50) == 336736-1a.html 336736-1-ref.html # Bug 1168747 for random b2g timeouts +skip-if(B2G) fuzzy-if(Android&&AndroidVersion>=15,8,50) == 336736-1b.html 336736-1-ref.html # Bug 1168747 for random b2g timeouts == 406073-1.html 406073-1-ref.html == 407016-2.html 407016-2-ref.html fuzzy-if(Android&&AndroidVersion>=15,8,220) == 413027-4.html 413027-4-ref.html From 900c174944de08f7aeabd61a96a1d38923a75b04 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Fri, 29 May 2015 22:33:37 -0700 Subject: [PATCH 27/85] Bug 1169879 - Use only the critical displayport when computing image visibility. r=tn --- layout/base/nsLayoutUtils.cpp | 7 +++++++ layout/base/nsLayoutUtils.h | 10 ++++++++++ layout/base/nsPresShell.cpp | 4 +++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index aedd782e4aed..d8098e6a498c 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1065,6 +1065,13 @@ nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult) return GetDisplayPortImpl(aContent, aResult, 1.0f); } +/* static */ bool +nsLayoutUtils::GetDisplayPortForVisibilityTesting(nsIContent* aContent, + nsRect* aResult) +{ + return GetDisplayPortImpl(aContent, aResult, 1.0f); +} + bool nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent, nsIPresShell* aPresShell, diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 42b174071864..057765dd2b09 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -165,6 +165,16 @@ public: */ static bool GetDisplayPort(nsIContent* aContent, nsRect *aResult = nullptr); + /** + * @return the display port for the given element which should be used for + * visibility testing purposes. + * + * If low-precision buffers are enabled, this is the critical display port; + * otherwise, it's the same display port returned by GetDisplayPort(). + */ + static bool GetDisplayPortForVisibilityTesting(nsIContent* aContent, + nsRect* aResult = nullptr); + enum class RepaintMode : uint8_t { Repaint, DoNotRepaint diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 7ca1e72ca316..fd7de8f05e07 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -5940,7 +5940,9 @@ PresShell::MarkImagesInSubtreeVisible(nsIFrame* aFrame, const nsRect& aRect) nsIScrollableFrame* scrollFrame = do_QueryFrame(aFrame); if (scrollFrame) { nsRect displayPort; - bool usingDisplayport = nsLayoutUtils::GetDisplayPort(aFrame->GetContent(), &displayPort); + bool usingDisplayport = + nsLayoutUtils::GetDisplayPortForVisibilityTesting(aFrame->GetContent(), + &displayPort); if (usingDisplayport) { rect = displayPort; } else { From 6d33a9a76e0053d9a28002f58883ecda3789340f Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Fri, 29 May 2015 23:50:51 -0700 Subject: [PATCH 28/85] Bug 1169880 - Recompute image visibility on a timer if layout or style flushes have occurred. r=tn --- layout/base/nsRefreshDriver.cpp | 30 ++++++++++++++++++++++++++++++ layout/base/nsRefreshDriver.h | 10 ++++++++++ 2 files changed, 40 insertions(+) diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index cf052519adeb..5380c238fd56 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -78,6 +78,7 @@ static PRLogModuleInfo *gLog = nullptr; #define DEFAULT_FRAME_RATE 60 #define DEFAULT_THROTTLED_FRAME_RATE 1 +#define DEFAULT_RECOMPUTE_VISIBILITY_INTERVAL_MS 1000 // after 10 minutes, stop firing off inactive timers #define DEFAULT_INACTIVE_TIMER_DISABLE_SECONDS 600 @@ -970,6 +971,17 @@ nsRefreshDriver::GetThrottledTimerInterval() return 1000.0 / rate; } +/* static */ mozilla::TimeDuration +nsRefreshDriver::GetMinRecomputeVisibilityInterval() +{ + int32_t interval = + Preferences::GetInt("layout.visibility.min-recompute-interval-ms", -1); + if (interval <= 0) { + interval = DEFAULT_RECOMPUTE_VISIBILITY_INTERVAL_MS; + } + return TimeDuration::FromMilliseconds(interval); +} + double nsRefreshDriver::GetRefreshTimerInterval() const { @@ -1016,7 +1028,9 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext) mFreezeCount(0), mThrottledFrameRequestInterval(TimeDuration::FromMilliseconds( GetThrottledTimerInterval())), + mMinRecomputeVisibilityInterval(GetMinRecomputeVisibilityInterval()), mThrottled(false), + mNeedToRecomputeVisibility(false), mTestControllingRefreshes(false), mViewManagerFlushIsPending(false), mRequestedHighPrecision(false), @@ -1028,6 +1042,7 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext) mMostRecentRefresh = TimeStamp::Now(); mMostRecentTick = mMostRecentRefresh; mNextThrottledFrameRequestTick = mMostRecentTick; + mNextRecomputeVisibilityTick = mMostRecentTick; } nsRefreshDriver::~nsRefreshDriver() @@ -1676,6 +1691,8 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) NS_RELEASE(shell); } + mNeedToRecomputeVisibility = true; + if (tracingStyleFlush) { profiler_tracing("Paint", "Styles", TRACING_INTERVAL_END); } @@ -1721,6 +1738,8 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) NS_RELEASE(shell); } + mNeedToRecomputeVisibility = true; + if (tracingLayoutFlush) { profiler_tracing("Paint", "Reflow", TRACING_INTERVAL_END); } @@ -1728,6 +1747,17 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) } } + // Recompute image visibility if it's necessary and enough time has passed + // since the last time we did it. + if (mNeedToRecomputeVisibility && !mThrottled && + aNowTime >= mNextRecomputeVisibilityTick && + !presShell->IsPaintingSuppressed()) { + mNextRecomputeVisibilityTick = aNowTime + mMinRecomputeVisibilityInterval; + mNeedToRecomputeVisibility = false; + + presShell->ScheduleImageVisibilityUpdate(); + } + /* * Perform notification to imgIRequests subscribed to listen * for refresh events. diff --git a/layout/base/nsRefreshDriver.h b/layout/base/nsRefreshDriver.h index 3dc86c4031a4..9f051a764120 100644 --- a/layout/base/nsRefreshDriver.h +++ b/layout/base/nsRefreshDriver.h @@ -339,6 +339,8 @@ private: double GetRegularTimerInterval(bool *outIsDefault = nullptr) const; static double GetThrottledTimerInterval(); + static mozilla::TimeDuration GetMinRecomputeVisibilityInterval(); + bool HaveFrameRequestCallbacks() const { return mFrameRequestCallbackDocs.Length() != 0; } @@ -367,7 +369,14 @@ private: // non-visible) documents registered with a non-throttled refresh driver. const mozilla::TimeDuration mThrottledFrameRequestInterval; + // How long we wait, at a minimum, before recomputing image visibility + // information. This is a minimum because, regardless of this interval, we + // only recompute visibility when we've seen a layout or style flush since the + // last time we did it. + const mozilla::TimeDuration mMinRecomputeVisibilityInterval; + bool mThrottled; + bool mNeedToRecomputeVisibility; bool mTestControllingRefreshes; bool mViewManagerFlushIsPending; bool mRequestedHighPrecision; @@ -386,6 +395,7 @@ private: mozilla::TimeStamp mMostRecentTick; mozilla::TimeStamp mTickStart; mozilla::TimeStamp mNextThrottledFrameRequestTick; + mozilla::TimeStamp mNextRecomputeVisibilityTick; // separate arrays for each flush type we support ObserverArray mObservers[3]; From 115caea9d3c5aab8b8c4d473994216764d9c0069 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Fri, 29 May 2015 23:50:53 -0700 Subject: [PATCH 29/85] Bug 1169881 - Recompute image visibility when display port margins change. r=tn --- layout/base/nsLayoutUtils.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index d8098e6a498c..c42dc8ecc4db 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1110,6 +1110,10 @@ nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent, } } + // Display port margins changing means that the set of visible images may + // have drastically changed. Schedule an update. + aPresShell->ScheduleImageVisibilityUpdate(); + return true; } From d10c9e388ee80a671919b50b63946b77f4d33bbe Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sat, 30 May 2015 11:56:44 +0200 Subject: [PATCH 30/85] Bug 1169611 - Rewrite IonBuilder::getPropTryConstant to not require a singleton result. r=bhackett --- js/src/jit/IonBuilder.cpp | 50 +++++++++++++++++++++++---------------- js/src/jit/IonBuilder.h | 4 ++-- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 92729dd4561e..e7b0bd05b31c 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -7194,8 +7194,8 @@ IonBuilder::testSingletonProperty(JSObject* obj, PropertyName* name) return nullptr; } -bool -IonBuilder::testSingletonPropertyTypes(MDefinition* obj, JSObject* singleton, PropertyName* name, +JSObject* +IonBuilder::testSingletonPropertyTypes(MDefinition* obj, PropertyName* name, bool* testObject, bool* testString) { // As for TestSingletonProperty, but the input is any value in a type set @@ -7207,11 +7207,11 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, JSObject* singleton, Pr TemporaryTypeSet* types = obj->resultTypeSet(); if (types && types->unknownObject()) - return false; + return nullptr; JSObject* objectSingleton = types ? types->maybeSingleton() : nullptr; if (objectSingleton) - return testSingletonProperty(objectSingleton, name) == singleton; + return testSingletonProperty(objectSingleton, name); JSProtoKey key; switch (obj->type()) { @@ -7235,7 +7235,7 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, JSObject* singleton, Pr case MIRType_Object: case MIRType_Value: { if (!types) - return false; + return nullptr; if (types->hasType(TypeSet::StringType())) { key = JSProto_String; @@ -7244,11 +7244,12 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, JSObject* singleton, Pr } if (!types->maybeObject()) - return false; + return nullptr; // For property accesses which may be on many objects, we just need to // find a prototype common to all the objects; if that prototype // has the singleton property, the access will not be on a missing property. + JSObject* singleton = nullptr; for (unsigned i = 0; i < types->getObjectCount(); i++) { TypeSet::ObjectKey* key = types->getObject(i); if (!key) @@ -7258,35 +7259,42 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, JSObject* singleton, Pr const Class* clasp = key->clasp(); if (!ClassHasEffectlessLookup(clasp) || ObjectHasExtraOwnProperty(compartment, key, name)) - return false; + return nullptr; if (key->unknownProperties()) - return false; + return nullptr; HeapTypeSetKey property = key->property(NameToId(name)); if (property.isOwnProperty(constraints())) - return false; + return nullptr; if (JSObject* proto = key->proto().toObjectOrNull()) { // Test this type. - if (testSingletonProperty(proto, name) != singleton) - return false; + JSObject* thisSingleton = testSingletonProperty(proto, name); + if (!thisSingleton) + return nullptr; + if (singleton) { + if (thisSingleton != singleton) + return nullptr; + } else { + singleton = thisSingleton; + } } else { // Can't be on the prototype chain with no prototypes... - return false; + return nullptr; } } // If this is not a known object, a test will be needed. *testObject = (obj->type() != MIRType_Object); - return true; + return singleton; } default: - return false; + return nullptr; } JSObject* proto = GetBuiltinPrototypePure(&script()->global(), key); if (proto) - return testSingletonProperty(proto, name) == singleton; + return testSingletonProperty(proto, name); - return false; + return nullptr; } bool @@ -10301,14 +10309,16 @@ IonBuilder::getPropTryConstant(bool* emitted, MDefinition* obj, PropertyName* na { MOZ_ASSERT(*emitted == false); - JSObject* singleton = types ? types->maybeSingleton() : nullptr; - if (!singleton) { - trackOptimizationOutcome(TrackedOutcome::NotSingleton); + if (!types->mightBeMIRType(MIRType_Object)) { + // If we have not observed an object result here, don't look for a + // singleton constant. + trackOptimizationOutcome(TrackedOutcome::NotObject); return true; } bool testObject, testString; - if (!testSingletonPropertyTypes(obj, singleton, name, &testObject, &testString)) + JSObject* singleton = testSingletonPropertyTypes(obj, name, &testObject, &testString); + if (!singleton) return true; // Property access is a known constant -- safe to emit. diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index a11a02780340..aeeed8f01380 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -941,8 +941,8 @@ class IonBuilder MGetPropertyCache* getInlineableGetPropertyCache(CallInfo& callInfo); JSObject* testSingletonProperty(JSObject* obj, PropertyName* name); - bool testSingletonPropertyTypes(MDefinition* obj, JSObject* singleton, PropertyName* name, - bool* testObject, bool* testString); + JSObject* testSingletonPropertyTypes(MDefinition* obj, PropertyName* name, + bool* testObject, bool* testString); uint32_t getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_t* pnfixed, BaselineInspector::ObjectGroupVector& convertUnboxedGroups); MDefinition* convertUnboxedObjects(MDefinition* obj, From 4a4a54ff49e684e3e754c3e29e8146e43a709a3a Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Thu, 28 May 2015 02:33:00 +0800 Subject: [PATCH 31/85] Bug 1169151 - Update carets after long tapping on empty input. r=mtseng This fixed AccessibleCarets remain on the screen when long tapping on an empty input. --- layout/base/AccessibleCaretManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/layout/base/AccessibleCaretManager.cpp b/layout/base/AccessibleCaretManager.cpp index 00c3f661b40d..284f8dbf3e2c 100644 --- a/layout/base/AccessibleCaretManager.cpp +++ b/layout/base/AccessibleCaretManager.cpp @@ -350,6 +350,7 @@ AccessibleCaretManager::SelectWordOrShortcut(const nsPoint& aPoint) // Content is empty. No need to select word. AC_LOG("%s, Cannot select word bacause content is empty", __FUNCTION__); DispatchCaretStateChangedEvent(CaretChangedReason::Longpressonemptycontent); + UpdateCarets(); return NS_OK; } From f6f76086ef5eec91a11f4f4a13c512bca6002091 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Sat, 30 May 2015 14:07:16 +0100 Subject: [PATCH 32/85] Bug 1107096 - Suppress improper drawing of zero-width invisible glyphs in canvas. r=roc --- dom/canvas/CanvasRenderingContext2D.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 597276cbbdc9..e58e817406ab 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -3454,17 +3454,21 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess const gfxTextRun::DetailedGlyph *d = mTextRun->GetDetailedGlyphs(i); - if (glyphs[i].IsMissing() && d->mAdvance > 0) { - newGlyph.mIndex = 0; - if (rtl) { - inlinePos = baselineOriginInline - advanceSum - - d->mAdvance * devUnitsPerAppUnit; - } else { - inlinePos = baselineOriginInline + advanceSum; + if (glyphs[i].IsMissing()) { + if (d->mAdvance > 0) { + // Perhaps we should render a hexbox here, but for now + // we just draw the font's .notdef glyph. (See bug 808288.) + newGlyph.mIndex = 0; + if (rtl) { + inlinePos = baselineOriginInline - advanceSum - + d->mAdvance * devUnitsPerAppUnit; + } else { + inlinePos = baselineOriginInline + advanceSum; + } + blockPos = baselineOriginBlock; + advanceSum += d->mAdvance * devUnitsPerAppUnit; + glyphBuf.push_back(newGlyph); } - blockPos = baselineOriginBlock; - advanceSum += d->mAdvance * devUnitsPerAppUnit; - glyphBuf.push_back(newGlyph); continue; } From f86e3e2bb9d873b5cf18daa821ee53b0f0b488db Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Sat, 30 May 2015 14:07:18 +0100 Subject: [PATCH 33/85] Bug 1107096 - Reftest for zero-width invisible glyphs in canvas. --- .../canvas/1107096-invisibles-ref.html | 23 +++++++++++++++++++ .../reftests/canvas/1107096-invisibles.html | 23 +++++++++++++++++++ layout/reftests/canvas/reftest.list | 2 +- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 layout/reftests/canvas/1107096-invisibles-ref.html create mode 100644 layout/reftests/canvas/1107096-invisibles.html diff --git a/layout/reftests/canvas/1107096-invisibles-ref.html b/layout/reftests/canvas/1107096-invisibles-ref.html new file mode 100644 index 000000000000..4c6698d28268 --- /dev/null +++ b/layout/reftests/canvas/1107096-invisibles-ref.html @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/layout/reftests/canvas/1107096-invisibles.html b/layout/reftests/canvas/1107096-invisibles.html new file mode 100644 index 000000000000..78f3b98562fc --- /dev/null +++ b/layout/reftests/canvas/1107096-invisibles.html @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/layout/reftests/canvas/reftest.list b/layout/reftests/canvas/reftest.list index 77546e57d2d4..e36b697758db 100644 --- a/layout/reftests/canvas/reftest.list +++ b/layout/reftests/canvas/reftest.list @@ -103,5 +103,5 @@ fails-if(azureQuartz&&OSX==1006) == 672646-alpha-radial-gradient.html 672646-alp fuzzy-if(azureQuartz,2,128) fuzzy-if(d2d,12,21) == 784573-1.html 784573-1-ref.html == 802658-1.html 802658-1-ref.html - +== 1107096-invisibles.html 1107096-invisibles-ref.html == 1151821-1.html 1151821-1-ref.html From 21241a6bbf08342c9349fa725222d501c07b0a71 Mon Sep 17 00:00:00 2001 From: Tom Klein Date: Sat, 30 May 2015 16:07:48 +0100 Subject: [PATCH 34/85] Bug 1063486 - Track current point in _cairo_path_bounder_curve_to r=jmuizelaar --- gfx/2d/unittest/TestCairo.cpp | 43 +++++++++++++++++++++++++ gfx/cairo/cairo/src/cairo-path-bounds.c | 1 + gfx/tests/gtest/moz.build | 1 + 3 files changed, 45 insertions(+) diff --git a/gfx/2d/unittest/TestCairo.cpp b/gfx/2d/unittest/TestCairo.cpp index f73e1772d394..1ea4626b886d 100644 --- a/gfx/2d/unittest/TestCairo.cpp +++ b/gfx/2d/unittest/TestCairo.cpp @@ -49,5 +49,48 @@ TEST(Cairo, Bug825721) { TryCircle(0.0, 1.0, 5761126469220696064.0); } +TEST(Cairo, Bug1063486) { + + double x1, y1, x2, y2; + const double epsilon = .01; + + cairo_surface_t *surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); + ASSERT_TRUE(surf != nullptr); + + cairo_t *cairo = cairo_create(surf); + ASSERT_TRUE(cairo != nullptr); + + printf("Path 1\n"); + cairo_move_to(cairo, -20, -10); + cairo_line_to(cairo, 20, -10); + cairo_line_to(cairo, 20, 10); + cairo_curve_to(cairo, 10,10, -10,10, -20,10); + cairo_curve_to(cairo, -30,10, -30,-10, -20,-10); + + cairo_path_extents(cairo, &x1, &y1, &x2, &y2); + + ASSERT_LT(std::abs(-27.5 - x1), epsilon); // the failing coordinate + ASSERT_LT(std::abs(-10 - y1), epsilon); + ASSERT_LT(std::abs(20 - x2), epsilon); + ASSERT_LT(std::abs(10 - y2), epsilon); + + printf("Path 2\n"); + cairo_new_path(cairo); + cairo_move_to(cairo, 10, 30); + cairo_line_to(cairo, 90, 30); + cairo_curve_to(cairo, 30,30, 30,30, 10,30); + cairo_curve_to(cairo, 0,30, 0,0, 30,5); + + cairo_path_extents(cairo, &x1, &y1, &x2, &y2); + + ASSERT_LT(std::abs(4.019531 - x1), epsilon); // the failing coordinate + ASSERT_LT(std::abs(4.437500 - y1), epsilon); + ASSERT_LT(std::abs(90. - x2), epsilon); + ASSERT_LT(std::abs(30. - y2), epsilon); + + cairo_surface_destroy(surf); + cairo_destroy(cairo); +} + } } diff --git a/gfx/cairo/cairo/src/cairo-path-bounds.c b/gfx/cairo/cairo/src/cairo-path-bounds.c index b7766494e316..8ca80fa137a6 100644 --- a/gfx/cairo/cairo/src/cairo-path-bounds.c +++ b/gfx/cairo/cairo/src/cairo-path-bounds.c @@ -131,6 +131,7 @@ _cairo_path_bounder_curve_to (void *closure, else { /* All control points are within the current extents. */ + bounder->current_point = *d; return CAIRO_STATUS_SUCCESS; } } diff --git a/gfx/tests/gtest/moz.build b/gfx/tests/gtest/moz.build index f84118748afb..9295bb4b4820 100644 --- a/gfx/tests/gtest/moz.build +++ b/gfx/tests/gtest/moz.build @@ -32,6 +32,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'windows': UNIFIED_SOURCES += [ '/gfx/2d/unittest/%s' % p for p in [ 'TestBase.cpp', 'TestBugs.cpp', + 'TestCairo.cpp', 'TestPoint.cpp', 'TestScaling.cpp', ]] From 9b3006d86a6eda735d5af8463f955e286bfc7af2 Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Sat, 30 May 2015 08:06:35 -0700 Subject: [PATCH 35/85] Bug 1169391 - Use a ReservedRooted class for optimized Rooted use in vm/Interpreter.cpp, r=terrence --HG-- extra : rebase_source : bd8ac525a0f5a3a65da1371d31df4654517f6575 --- js/public/RootingAPI.h | 4 +- js/src/vm/Interpreter.cpp | 459 +++++++++++++++++--------------------- 2 files changed, 210 insertions(+), 253 deletions(-) diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index acf48f8e9ab2..85d29e2460a8 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -76,7 +76,7 @@ * - MutableHandle is a non-const reference to Rooted. It is used in the * same way as Handle and includes a |set(const T& v)| method to allow * updating the value of the referenced Rooted. A MutableHandle can be - * created from a Rooted by using |Rooted::operator&()|. + * created with an implicit cast from a Rooted*. * * In some cases the small performance overhead of exact rooting (measured to * be a few nanoseconds on desktop) is too much. In these cases, try the @@ -1185,7 +1185,5 @@ CallTraceCallbackOnNonHeap(T* v, const TraceCallbacks& aCallbacks, const char* a } /* namespace js */ #undef DELETE_ASSIGNMENT_OPS -#undef DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS -#undef DECLARE_NONPOINTER_ACCESSOR_METHODS #endif /* js_RootingAPI_h */ diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 88e9db9e29f5..836ee0e23131 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -13,6 +13,7 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/DebugOnly.h" #include "mozilla/FloatingPoint.h" +#include "mozilla/Maybe.h" #include "mozilla/PodOperations.h" #include @@ -1655,6 +1656,58 @@ SetObjectElementOperation(JSContext* cx, HandleObject obj, HandleValue receiver, result.checkStrictErrorOrWarning(cx, obj, id, strict); } +/* + * As an optimization, the interpreter creates a handful of reserved Rooted + * variables at the beginning, thus inserting them into the Rooted list once + * upon entry. ReservedRooted "borrows" a reserved Rooted variable and uses it + * within a local scope, resetting the value to nullptr (or the appropriate + * equivalent for T) at scope end. This avoids inserting/removing the Rooted + * from the rooter list, while preventing stale values from being kept alive + * unnecessarily. + */ + +template +class ReservedRootedBase { +}; + +template +class ReservedRooted : public ReservedRootedBase +{ + Rooted* savedRoot; + + public: + ReservedRooted(Rooted* root, const T& ptr) : savedRoot(root) { + *root = ptr; + } + + explicit ReservedRooted(Rooted* root) : savedRoot(root) { + *root = js::GCMethods::initial(); + } + + ~ReservedRooted() { + *savedRoot = js::GCMethods::initial(); + } + + void set(const T& p) const { *savedRoot = p; } + operator Handle() { return *savedRoot; } + operator Rooted&() { return *savedRoot; } + MutableHandle operator&() { return &*savedRoot; } + + DECLARE_NONPOINTER_ACCESSOR_METHODS(savedRoot->get()) + DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(savedRoot->get()) + DECLARE_POINTER_CONSTREF_OPS(T) + DECLARE_POINTER_ASSIGN_OPS(ReservedRooted, T) +}; + +template <> +class ReservedRootedBase : public ValueOperations> +{ + friend class ValueOperations>; + const Value* extract() const { + return static_cast*>(this)->address(); + } +}; + static MOZ_NEVER_INLINE bool Interpret(JSContext* cx, RunState& state) { @@ -2039,11 +2092,9 @@ END_CASE(JSOP_SETRVAL) CASE(JSOP_ENTERWITH) { - RootedValue& val = rootValue0; - RootedObject& staticWith = rootObject0; - val = REGS.sp[-1]; + ReservedRooted val(&rootValue0, REGS.sp[-1]); REGS.sp--; - staticWith = script->getObject(REGS.pc); + ReservedRooted staticWith(&rootObject0, script->getObject(REGS.pc)); if (!EnterWithOperation(cx, REGS.fp(), val, staticWith)) goto error; @@ -2171,13 +2222,14 @@ CASE(JSOP_IN) ReportValueError(cx, JSMSG_IN_NOT_OBJECT, -1, rref, nullptr); goto error; } - RootedObject& obj = rootObject0; - obj = &rref.toObject(); - RootedId& id = rootId0; - FETCH_ELEMENT_ID(-2, id); bool found; - if (!HasProperty(cx, obj, id, &found)) - goto error; + { + ReservedRooted obj(&rootObject0, &rref.toObject()); + ReservedRooted id(&rootId0); + FETCH_ELEMENT_ID(-2, id); + if (!HasProperty(cx, obj, id, &found)) + goto error; + } TRY_BRANCH_AFTER_COND(found, 2); REGS.sp--; REGS.sp[-1].setBoolean(found); @@ -2200,8 +2252,7 @@ CASE(JSOP_MOREITER) MOZ_ASSERT(REGS.stackDepth() >= 1); MOZ_ASSERT(REGS.sp[-1].isObject()); PUSH_NULL(); - RootedObject& obj = rootObject0; - obj = ®S.sp[-2].toObject(); + ReservedRooted obj(&rootObject0, ®S.sp[-2].toObject()); if (!IteratorMore(cx, obj, REGS.stackHandleAt(-1))) goto error; } @@ -2217,8 +2268,7 @@ END_CASE(JSOP_ISNOITER) CASE(JSOP_ENDITER) { MOZ_ASSERT(REGS.stackDepth() >= 1); - RootedObject& obj = rootObject0; - obj = ®S.sp[-1].toObject(); + ReservedRooted obj(&rootObject0, ®S.sp[-1].toObject()); bool ok = CloseIterator(cx, obj); REGS.sp--; if (!ok) @@ -2265,14 +2315,9 @@ END_CASE(JSOP_PICK) CASE(JSOP_SETCONST) { - RootedPropertyName& name = rootName0; - name = script->getName(REGS.pc); - - RootedValue& rval = rootValue0; - rval = REGS.sp[-1]; - - RootedObject& obj = rootObject0; - obj = ®S.fp()->varObj(); + ReservedRooted name(&rootName0, script->getName(REGS.pc)); + ReservedRooted rval(&rootValue0, REGS.sp[-1]); + ReservedRooted obj(&rootObject0, ®S.fp()->varObj()); if (!SetConstOperation(cx, obj, name, rval)) goto error; @@ -2288,14 +2333,11 @@ CASE(JSOP_BINDNAME) { JSOp op = JSOp(*REGS.pc); if (op == JSOP_BINDNAME || script->hasPollutedGlobalScope()) { - RootedObject& scopeChain = rootObject0; - scopeChain = REGS.fp()->scopeChain(); - - RootedPropertyName& name = rootName0; - name = script->getName(REGS.pc); + ReservedRooted scopeChain(&rootObject0, REGS.fp()->scopeChain()); + ReservedRooted name(&rootName0, script->getName(REGS.pc)); /* Assigning to an undeclared name adds a property to the global object. */ - RootedObject& scope = rootObject1; + ReservedRooted scope(&rootObject1); if (!LookupNameUnqualified(cx, name, scopeChain, &scope)) goto error; @@ -2483,10 +2525,8 @@ END_CASE(JSOP_ADD) CASE(JSOP_SUB) { - RootedValue& lval = rootValue0; - RootedValue& rval = rootValue1; - lval = REGS.sp[-2]; - rval = REGS.sp[-1]; + ReservedRooted lval(&rootValue0, REGS.sp[-2]); + ReservedRooted rval(&rootValue1, REGS.sp[-1]); MutableHandleValue res = REGS.stackHandleAt(-2); if (!SubOperation(cx, lval, rval, res)) goto error; @@ -2496,10 +2536,8 @@ END_CASE(JSOP_SUB) CASE(JSOP_MUL) { - RootedValue& lval = rootValue0; - RootedValue& rval = rootValue1; - lval = REGS.sp[-2]; - rval = REGS.sp[-1]; + ReservedRooted lval(&rootValue0, REGS.sp[-2]); + ReservedRooted rval(&rootValue1, REGS.sp[-1]); MutableHandleValue res = REGS.stackHandleAt(-2); if (!MulOperation(cx, lval, rval, res)) goto error; @@ -2509,10 +2547,8 @@ END_CASE(JSOP_MUL) CASE(JSOP_DIV) { - RootedValue& lval = rootValue0; - RootedValue& rval = rootValue1; - lval = REGS.sp[-2]; - rval = REGS.sp[-1]; + ReservedRooted lval(&rootValue0, REGS.sp[-2]); + ReservedRooted rval(&rootValue1, REGS.sp[-1]); MutableHandleValue res = REGS.stackHandleAt(-2); if (!DivOperation(cx, lval, rval, res)) goto error; @@ -2522,10 +2558,8 @@ END_CASE(JSOP_DIV) CASE(JSOP_MOD) { - RootedValue& lval = rootValue0; - RootedValue& rval = rootValue1; - lval = REGS.sp[-2]; - rval = REGS.sp[-1]; + ReservedRooted lval(&rootValue0, REGS.sp[-2]); + ReservedRooted rval(&rootValue1, REGS.sp[-1]); MutableHandleValue res = REGS.stackHandleAt(-2); if (!ModOperation(cx, lval, rval, res)) goto error; @@ -2553,8 +2587,7 @@ END_CASE(JSOP_BITNOT) CASE(JSOP_NEG) { - RootedValue& val = rootValue0; - val = REGS.sp[-1]; + ReservedRooted val(&rootValue0, REGS.sp[-1]); MutableHandleValue res = REGS.stackHandleAt(-1); if (!NegOperation(cx, script, REGS.pc, val, res)) goto error; @@ -2568,11 +2601,8 @@ END_CASE(JSOP_POS) CASE(JSOP_DELNAME) { - RootedPropertyName& name = rootName0; - name = script->getName(REGS.pc); - - RootedObject& scopeObj = rootObject0; - scopeObj = REGS.fp()->scopeChain(); + ReservedRooted name(&rootName0, script->getName(REGS.pc)); + ReservedRooted scopeObj(&rootObject0, REGS.fp()->scopeChain()); PUSH_BOOLEAN(true); MutableHandleValue res = REGS.stackHandleAt(-1); @@ -2586,10 +2616,8 @@ CASE(JSOP_STRICTDELPROP) { static_assert(JSOP_DELPROP_LENGTH == JSOP_STRICTDELPROP_LENGTH, "delprop and strictdelprop must be the same size"); - RootedId& id = rootId0; - id = NameToId(script->getName(REGS.pc)); - - RootedObject& obj = rootObject0; + ReservedRooted id(&rootId0, NameToId(script->getName(REGS.pc))); + ReservedRooted obj(&rootObject0); FETCH_OBJECT(cx, -1, obj); ObjectOpResult result; @@ -2610,14 +2638,13 @@ CASE(JSOP_STRICTDELELEM) static_assert(JSOP_DELELEM_LENGTH == JSOP_STRICTDELELEM_LENGTH, "delelem and strictdelelem must be the same size"); /* Fetch the left part and resolve it to a non-null object. */ - RootedObject& obj = rootObject0; + ReservedRooted obj(&rootObject0); FETCH_OBJECT(cx, -2, obj); - RootedValue& propval = rootValue0; - propval = REGS.sp[-1]; + ReservedRooted propval(&rootValue0, REGS.sp[-1]); ObjectOpResult result; - RootedId& id = rootId0; + ReservedRooted id(&rootId0); if (!ValueToId(cx, propval, &id)) goto error; if (!DeleteProperty(cx, obj, id, result)) @@ -2640,11 +2667,8 @@ CASE(JSOP_TOID) * but we need to avoid the observable stringification the second time. * There must be an object value below the id, which will not be popped. */ - RootedValue& objval = rootValue0; - RootedValue& idval = rootValue1; - objval = REGS.sp[-2]; - idval = REGS.sp[-1]; - + ReservedRooted objval(&rootValue0, REGS.sp[-2]); + ReservedRooted idval(&rootValue1, REGS.sp[-1]); MutableHandleValue res = REGS.stackHandleAt(-1); if (!ToIdOperation(cx, script, REGS.pc, objval, idval, res)) goto error; @@ -2683,12 +2707,9 @@ END_CASE(JSOP_GETPROP) CASE(JSOP_GETPROP_SUPER) { - RootedObject& receiver = rootObject0; - RootedObject& obj = rootObject1; - + ReservedRooted receiver(&rootObject0); FETCH_OBJECT(cx, -2, receiver); - obj = ®S.sp[-1].toObject(); - + ReservedRooted obj(&rootObject1, ®S.sp[-1].toObject()); MutableHandleValue rref = REGS.stackHandleAt(-2); if (!GetProperty(cx, obj, receiver, script->getName(REGS.pc), rref)) @@ -2700,10 +2721,8 @@ END_CASE(JSOP_GETPROP_SUPER) CASE(JSOP_GETXPROP) { - RootedObject& obj = rootObject0; - obj = ®S.sp[-1].toObject(); - RootedId& id = rootId0; - id = NameToId(script->getName(REGS.pc)); + ReservedRooted obj(&rootObject0, ®S.sp[-1].toObject()); + ReservedRooted id(&rootId0, NameToId(script->getName(REGS.pc))); MutableHandleValue rval = REGS.stackHandleAt(-1); if (!GetPropertyForNameLookup(cx, obj, id, rval)) goto error; @@ -2737,8 +2756,7 @@ CASE(JSOP_STRICTSETNAME) static_assert(JSOP_SETNAME_LENGTH == JSOP_SETGNAME_LENGTH, "We're sharing the END_CASE so the lengths better match"); - RootedObject& scope = rootObject0; - scope = ®S.sp[-2].toObject(); + ReservedRooted scope(&rootObject0, ®S.sp[-2].toObject()); HandleValue value = REGS.stackHandleAt(-1); if (!SetNameOperation(cx, script, REGS.pc, scope, value)) @@ -2757,8 +2775,7 @@ CASE(JSOP_STRICTSETPROP) HandleValue lval = REGS.stackHandleAt(-2); HandleValue rval = REGS.stackHandleAt(-1); - RootedId& id = rootId0; - id = NameToId(script->getName(REGS.pc)); + ReservedRooted id(&rootId0, NameToId(script->getName(REGS.pc))); if (!SetPropertyOperation(cx, JSOp(*REGS.pc), lval, id, rval)) goto error; @@ -2774,17 +2791,10 @@ CASE(JSOP_STRICTSETPROP_SUPER) "setprop-super and strictsetprop-super must be the same size"); - RootedValue& receiver = rootValue0; - receiver = REGS.sp[-3]; - - RootedObject& obj = rootObject0; - obj = ®S.sp[-2].toObject(); - - RootedValue& rval = rootValue1; - rval = REGS.sp[-1]; - - RootedId& id = rootId0; - id = NameToId(script->getName(REGS.pc)); + ReservedRooted receiver(&rootValue0, REGS.sp[-3]); + ReservedRooted obj(&rootObject0, ®S.sp[-2].toObject()); + ReservedRooted rval(&rootValue1, REGS.sp[-1]); + ReservedRooted id(&rootId0, NameToId(script->getName(REGS.pc))); ObjectOpResult result; if (!SetProperty(cx, obj, id, rval, receiver, result)) @@ -2823,10 +2833,9 @@ END_CASE(JSOP_GETELEM) CASE(JSOP_GETELEM_SUPER) { HandleValue rval = REGS.stackHandleAt(-3); - RootedObject& receiver = rootObject0; + ReservedRooted receiver(&rootObject0); FETCH_OBJECT(cx, -2, receiver); - RootedObject& obj = rootObject1; - obj = ®S.sp[-1].toObject(); + ReservedRooted obj(&rootObject1, ®S.sp[-1].toObject()); MutableHandleValue res = REGS.stackHandleAt(-3); @@ -2846,13 +2855,12 @@ CASE(JSOP_STRICTSETELEM) { static_assert(JSOP_SETELEM_LENGTH == JSOP_STRICTSETELEM_LENGTH, "setelem and strictsetelem must be the same size"); - RootedObject& obj = rootObject0; + ReservedRooted obj(&rootObject0); FETCH_OBJECT(cx, -3, obj); - RootedId& id = rootId0; + ReservedRooted id(&rootId0); FETCH_ELEMENT_ID(-2, id); Value& value = REGS.sp[-1]; - RootedValue& receiver = rootValue0; - receiver = ObjectValue(*obj); + ReservedRooted receiver(&rootValue0, ObjectValue(*obj)); if (!SetObjectElementOperation(cx, obj, receiver, id, value, *REGS.pc == JSOP_STRICTSETELEM)) goto error; REGS.sp[-3] = value; @@ -2866,12 +2874,10 @@ CASE(JSOP_STRICTSETELEM_SUPER) static_assert(JSOP_SETELEM_SUPER_LENGTH == JSOP_STRICTSETELEM_SUPER_LENGTH, "setelem-super and strictsetelem-super must be the same size"); - RootedId& id = rootId0; + ReservedRooted id(&rootId0); FETCH_ELEMENT_ID(-4, id); - RootedValue& receiver = rootValue0; - receiver = REGS.sp[-3]; - RootedObject& obj = rootObject1; - obj = ®S.sp[-2].toObject(); + ReservedRooted receiver(&rootValue0, REGS.sp[-3]); + ReservedRooted obj(&rootObject1, ®S.sp[-2].toObject()); Value& value = REGS.sp[-1]; bool strict = JSOp(*REGS.pc) == JSOP_STRICTSETELEM_SUPER; @@ -2944,11 +2950,11 @@ CASE(JSOP_FUNCALL) bool construct = (*REGS.pc == JSOP_NEW); - RootedFunction& fun = rootFunction0; - bool isFunction = IsFunctionObject(args.calleev(), fun.address()); + JSFunction* maybeFun; + bool isFunction = IsFunctionObject(args.calleev(), &maybeFun); /* Don't bother trying to fast-path calls to scripted non-constructors. */ - if (!isFunction || !fun->isInterpreted() || !fun->isConstructor()) { + if (!isFunction || !maybeFun->isInterpreted() || !maybeFun->isConstructor()) { if (construct) { if (!InvokeConstructor(cx, args)) goto error; @@ -2962,27 +2968,30 @@ CASE(JSOP_FUNCALL) ADVANCE_AND_DISPATCH(JSOP_CALL_LENGTH); } - RootedScript& funScript = rootScript0; - funScript = fun->getOrCreateScript(cx); - if (!funScript) - goto error; - - InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE; - bool createSingleton = ObjectGroup::useSingletonForNewObject(cx, script, REGS.pc); - - TypeMonitorCall(cx, args, construct); - { - InvokeState state(cx, args, initial); + MOZ_ASSERT(maybeFun); + ReservedRooted fun(&rootFunction0, maybeFun); + ReservedRooted funScript(&rootScript0, fun->getOrCreateScript(cx)); + if (!funScript) + goto error; + + InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE; + bool createSingleton = ObjectGroup::useSingletonForNewObject(cx, script, REGS.pc); + + TypeMonitorCall(cx, args, construct); + + mozilla::Maybe state; + state.emplace(cx, args, initial); + if (createSingleton) - state.setCreateSingleton(); + state->setCreateSingleton(); if (!createSingleton && jit::IsIonEnabled(cx)) { - jit::MethodStatus status = jit::CanEnter(cx, state); + jit::MethodStatus status = jit::CanEnter(cx, state.ref()); if (status == jit::Method_Error) goto error; if (status == jit::Method_Compiled) { - jit::JitExecStatus exec = jit::IonCannon(cx, state); + jit::JitExecStatus exec = jit::IonCannon(cx, state.ref()); CHECK_BRANCH(); REGS.sp = args.spAfterCall(); interpReturnOK = !IsErrorStatus(exec); @@ -2991,26 +3000,28 @@ CASE(JSOP_FUNCALL) } if (jit::IsBaselineEnabled(cx)) { - jit::MethodStatus status = jit::CanEnterBaselineMethod(cx, state); + jit::MethodStatus status = jit::CanEnterBaselineMethod(cx, state.ref()); if (status == jit::Method_Error) goto error; if (status == jit::Method_Compiled) { - jit::JitExecStatus exec = jit::EnterBaselineMethod(cx, state); + jit::JitExecStatus exec = jit::EnterBaselineMethod(cx, state.ref()); CHECK_BRANCH(); REGS.sp = args.spAfterCall(); interpReturnOK = !IsErrorStatus(exec); goto jit_return; } } + + state.reset(); + funScript = fun->nonLazyScript(); + + if (!activation.pushInlineFrame(args, funScript, initial)) + goto error; + + if (createSingleton) + REGS.fp()->setCreateSingleton(); } - funScript = fun->nonLazyScript(); - if (!activation.pushInlineFrame(args, funScript, initial)) - goto error; - - if (createSingleton) - REGS.fp()->setCreateSingleton(); - SET_SCRIPT(REGS.fp()->script()); { @@ -3052,17 +3063,13 @@ CASE(JSOP_GIMPLICITTHIS) { JSOp op = JSOp(*REGS.pc); if (op == JSOP_IMPLICITTHIS || script->hasPollutedGlobalScope()) { - RootedPropertyName& name = rootName0; - name = script->getName(REGS.pc); - - RootedObject& scopeObj = rootObject0; - scopeObj = REGS.fp()->scopeChain(); - - RootedObject& scope = rootObject1; + ReservedRooted name(&rootName0, script->getName(REGS.pc)); + ReservedRooted scopeObj(&rootObject0, REGS.fp()->scopeChain()); + ReservedRooted scope(&rootObject1); if (!LookupNameWithGlobalDefault(cx, name, scopeObj, &scope)) goto error; - RootedValue& v = rootValue0; + ReservedRooted v(&rootValue0); if (!ComputeImplicitThis(cx, scope, &v)) goto error; PUSH_COPY(v); @@ -3078,8 +3085,7 @@ END_CASE(JSOP_IMPLICITTHIS) CASE(JSOP_GETGNAME) CASE(JSOP_GETNAME) { - RootedValue& rval = rootValue0; - + ReservedRooted rval(&rootValue0); if (!GetNameOperation(cx, REGS.fp(), REGS.pc, &rval)) goto error; @@ -3092,8 +3098,7 @@ END_CASE(JSOP_GETNAME) CASE(JSOP_GETINTRINSIC) { - RootedValue& rval = rootValue0; - + ReservedRooted rval(&rootValue0); if (!GetIntrinsicOperation(cx, REGS.pc, &rval)) goto error; @@ -3149,8 +3154,7 @@ END_CASE(JSOP_SYMBOL) CASE(JSOP_OBJECT) { - RootedObject& ref = rootObject0; - ref = script->getObject(REGS.pc); + ReservedRooted ref(&rootObject0, script->getObject(REGS.pc)); if (JS::CompartmentOptionsRef(cx).cloneSingletons()) { JSObject* obj = DeepCloneObjectLiteral(cx, ref, TenuredObject); if (!obj) @@ -3166,12 +3170,9 @@ END_CASE(JSOP_OBJECT) CASE(JSOP_CALLSITEOBJ) { - RootedObject& cso = rootObject0; - cso = script->getObject(REGS.pc); - RootedObject& raw = rootObject1; - raw = script->getObject(GET_UINT32_INDEX(REGS.pc) + 1); - RootedValue& rawValue = rootValue0; - rawValue.setObject(*raw); + ReservedRooted cso(&rootObject0, script->getObject(REGS.pc)); + ReservedRooted raw(&rootObject1, script->getObject(GET_UINT32_INDEX(REGS.pc) + 1)); + ReservedRooted rawValue(&rootValue0, ObjectValue(*raw)); if (!ProcessCallSiteObjOperation(cx, cso, raw, rawValue)) goto error; @@ -3271,8 +3272,7 @@ END_CASE(JSOP_RUNONCE) CASE(JSOP_REST) { - RootedObject& rest = rootObject0; - rest = REGS.fp()->createRestParameter(cx); + ReservedRooted rest(&rootObject0, REGS.fp()->createRestParameter(cx)); if (!rest) goto error; PUSH_COPY(ObjectValue(*rest)); @@ -3282,8 +3282,7 @@ END_CASE(JSOP_REST) CASE(JSOP_GETALIASEDVAR) { ScopeCoordinate sc = ScopeCoordinate(REGS.pc); - RootedValue& val = rootValue0; - val = REGS.fp()->aliasedVarScope(sc).aliasedVar(sc); + ReservedRooted val(&rootValue0, REGS.fp()->aliasedVarScope(sc).aliasedVar(sc)); MOZ_ASSERT(!IsUninitializedLexical(val)); PUSH_COPY(val); TypeScript::Monitor(cx, script, REGS.pc, REGS.sp[-1]); @@ -3301,8 +3300,7 @@ END_CASE(JSOP_SETALIASEDVAR) CASE(JSOP_CHECKLEXICAL) { uint32_t i = GET_LOCALNO(REGS.pc); - RootedValue& val = rootValue0; - val = REGS.fp()->unaliasedLocal(i); + ReservedRooted val(&rootValue0, REGS.fp()->unaliasedLocal(i)); if (!CheckUninitializedLexical(cx, script, REGS.pc, val)) goto error; } @@ -3318,8 +3316,7 @@ END_CASE(JSOP_INITLEXICAL) CASE(JSOP_CHECKALIASEDLEXICAL) { ScopeCoordinate sc = ScopeCoordinate(REGS.pc); - RootedValue& val = rootValue0; - val = REGS.fp()->aliasedVarScope(sc).aliasedVar(sc); + ReservedRooted val(&rootValue0, REGS.fp()->aliasedVarScope(sc).aliasedVar(sc)); if (!CheckUninitializedLexical(cx, script, REGS.pc, val)) goto error; } @@ -3393,11 +3390,8 @@ CASE(JSOP_DEFVAR) attrs |= JSPROP_PERMANENT; /* Step 8b. */ - RootedObject& obj = rootObject0; - obj = ®S.fp()->varObj(); - - RootedPropertyName& name = rootName0; - name = script->getName(REGS.pc); + ReservedRooted obj(&rootObject0, ®S.fp()->varObj()); + ReservedRooted name(&rootName0, script->getName(REGS.pc)); if (!DefVarOrConstOperation(cx, obj, name, attrs)) goto error; @@ -3412,9 +3406,7 @@ CASE(JSOP_DEFFUN) * a compound statement (not at the top statement level of global code, or * at the top level of a function body). */ - RootedFunction& fun = rootFunction0; - fun = script->getFunction(GET_UINT32_INDEX(REGS.pc)); - + ReservedRooted fun(&rootFunction0, script->getFunction(GET_UINT32_INDEX(REGS.pc))); if (!DefFunOperation(cx, script, REGS.fp()->scopeChain(), fun)) goto error; } @@ -3423,9 +3415,7 @@ END_CASE(JSOP_DEFFUN) CASE(JSOP_LAMBDA) { /* Load the specified function object literal. */ - RootedFunction& fun = rootFunction0; - fun = script->getFunction(GET_UINT32_INDEX(REGS.pc)); - + ReservedRooted fun(&rootFunction0, script->getFunction(GET_UINT32_INDEX(REGS.pc))); JSObject* obj = Lambda(cx, fun, REGS.fp()->scopeChain()); if (!obj) goto error; @@ -3437,10 +3427,8 @@ END_CASE(JSOP_LAMBDA) CASE(JSOP_LAMBDA_ARROW) { /* Load the specified function object literal. */ - RootedFunction& fun = rootFunction0; - fun = script->getFunction(GET_UINT32_INDEX(REGS.pc)); - RootedValue& thisv = rootValue0; - thisv = REGS.sp[-1]; + ReservedRooted fun(&rootFunction0, script->getFunction(GET_UINT32_INDEX(REGS.pc))); + ReservedRooted thisv(&rootValue0, REGS.sp[-1]); JSObject* obj = LambdaArrow(cx, fun, REGS.fp()->scopeChain(), thisv); if (!obj) goto error; @@ -3457,14 +3445,11 @@ END_CASE(JSOP_CALLEE) CASE(JSOP_INITPROP_GETTER) CASE(JSOP_INITPROP_SETTER) { - RootedObject& obj = rootObject0; - RootedPropertyName& name = rootName0; - RootedObject& val = rootObject1; - MOZ_ASSERT(REGS.stackDepth() >= 2); - obj = ®S.sp[-2].toObject(); - name = script->getName(REGS.pc); - val = ®S.sp[-1].toObject(); + + ReservedRooted obj(&rootObject0, ®S.sp[-2].toObject()); + ReservedRooted name(&rootName0, script->getName(REGS.pc)); + ReservedRooted val(&rootObject1, ®S.sp[-1].toObject()); if (!InitGetterSetterOperation(cx, REGS.pc, obj, name, val)) goto error; @@ -3476,14 +3461,11 @@ END_CASE(JSOP_INITPROP_GETTER) CASE(JSOP_INITELEM_GETTER) CASE(JSOP_INITELEM_SETTER) { - RootedObject& obj = rootObject0; - RootedValue& idval = rootValue0; - RootedObject& val = rootObject1; - MOZ_ASSERT(REGS.stackDepth() >= 3); - obj = ®S.sp[-3].toObject(); - idval = REGS.sp[-2]; - val = ®S.sp[-1].toObject(); + + ReservedRooted obj(&rootObject0, ®S.sp[-3].toObject()); + ReservedRooted idval(&rootValue0, REGS.sp[-2]); + ReservedRooted val(&rootObject1, ®S.sp[-1].toObject()); if (!InitGetterSetterOperation(cx, REGS.pc, obj, idval, val)) goto error; @@ -3525,13 +3507,11 @@ END_CASE(JSOP_NEWARRAY) CASE(JSOP_NEWARRAY_COPYONWRITE) { - RootedObject& baseobj = rootObject0; - baseobj = ObjectGroup::getOrFixupCopyOnWriteObject(cx, script, REGS.pc); + ReservedRooted baseobj(&rootObject0, ObjectGroup::getOrFixupCopyOnWriteObject(cx, script, REGS.pc)); if (!baseobj) goto error; - RootedObject& obj = rootObject1; - obj = NewDenseCopyOnWriteArray(cx, baseobj.as(), gc::DefaultHeap); + ReservedRooted obj(&rootObject1, NewDenseCopyOnWriteArray(cx, ((RootedObject&)(baseobj)).as(), gc::DefaultHeap)); if (!obj) goto error; @@ -3553,11 +3533,8 @@ CASE(JSOP_MUTATEPROTO) MOZ_ASSERT(REGS.stackDepth() >= 2); if (REGS.sp[-1].isObjectOrNull()) { - RootedObject& newProto = rootObject1; - rootObject1 = REGS.sp[-1].toObjectOrNull(); - - RootedObject& obj = rootObject0; - obj = ®S.sp[-2].toObject(); + ReservedRooted newProto(&rootObject1, REGS.sp[-1].toObjectOrNull()); + ReservedRooted obj(&rootObject0, ®S.sp[-2].toObject()); MOZ_ASSERT(obj->is()); if (!SetPrototype(cx, obj, newProto)) @@ -3578,12 +3555,10 @@ CASE(JSOP_INITHIDDENPROP) "initprop and inithiddenprop must be the same size"); /* Load the property's initial value into rval. */ MOZ_ASSERT(REGS.stackDepth() >= 2); - RootedValue& rval = rootValue0; - rval = REGS.sp[-1]; + ReservedRooted rval(&rootValue0, REGS.sp[-1]); /* Load the object being initialized into lval/obj. */ - RootedObject& obj = rootObject0; - obj = ®S.sp[-2].toObject(); + ReservedRooted obj(&rootObject0, ®S.sp[-2].toObject()); PropertyName* name = script->getName(REGS.pc); @@ -3603,8 +3578,7 @@ CASE(JSOP_INITELEM) HandleValue val = REGS.stackHandleAt(-1); HandleValue id = REGS.stackHandleAt(-2); - RootedObject& obj = rootObject0; - obj = ®S.sp[-3].toObject(); + ReservedRooted obj(&rootObject0, ®S.sp[-3].toObject()); if (!InitElemOperation(cx, obj, id, val)) goto error; @@ -3618,8 +3592,7 @@ CASE(JSOP_INITELEM_ARRAY) MOZ_ASSERT(REGS.stackDepth() >= 2); HandleValue val = REGS.stackHandleAt(-1); - RootedObject& obj = rootObject0; - obj = ®S.sp[-2].toObject(); + ReservedRooted obj(&rootObject0, ®S.sp[-2].toObject()); uint32_t index = GET_UINT24(REGS.pc); if (!InitArrayElemOperation(cx, REGS.pc, obj, index, val)) @@ -3634,8 +3607,7 @@ CASE(JSOP_INITELEM_INC) MOZ_ASSERT(REGS.stackDepth() >= 3); HandleValue val = REGS.stackHandleAt(-1); - RootedObject& obj = rootObject0; - obj = ®S.sp[-3].toObject(); + ReservedRooted obj(&rootObject0, ®S.sp[-3].toObject()); uint32_t index = REGS.sp[-2].toInt32(); if (!InitArrayElemOperation(cx, REGS.pc, obj, index, val)) @@ -3694,7 +3666,7 @@ END_CASE(JSOP_FINALLY) CASE(JSOP_THROWING) { - RootedValue& v = rootValue0; + ReservedRooted v(&rootValue0); POP_COPY_TO(v); MOZ_ALWAYS_TRUE(ThrowingOperation(cx, v)); } @@ -3703,7 +3675,7 @@ END_CASE(JSOP_THROWING) CASE(JSOP_THROW) { CHECK_BRANCH(); - RootedValue& v = rootValue0; + ReservedRooted v(&rootValue0); POP_COPY_TO(v); JS_ALWAYS_FALSE(Throw(cx, v)); /* let the code at error try to catch the exception. */ @@ -3712,14 +3684,12 @@ CASE(JSOP_THROW) CASE(JSOP_INSTANCEOF) { - RootedValue& rref = rootValue0; - rref = REGS.sp[-1]; - if (rref.isPrimitive()) { + ReservedRooted rref(&rootValue0, REGS.sp[-1]); + if (HandleValue(rref).isPrimitive()) { ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, -1, rref, nullptr); goto error; } - RootedObject& obj = rootObject0; - obj = &rref.toObject(); + ReservedRooted obj(&rootObject0, &rref.toObject()); bool cond = false; if (!HasInstance(cx, obj, REGS.stackHandleAt(-2), &cond)) goto error; @@ -3815,8 +3785,7 @@ CASE(JSOP_INITIALYIELD) { MOZ_ASSERT(!cx->isExceptionPending()); MOZ_ASSERT(REGS.fp()->isNonEvalFunctionFrame()); - RootedObject& obj = rootObject0; - obj = ®S.sp[-1].toObject(); + ReservedRooted obj(&rootObject0, ®S.sp[-1].toObject()); POP_RETURN_VALUE(); MOZ_ASSERT(REGS.stackDepth() == 0); if (!GeneratorObject::initialSuspend(cx, obj, REGS.fp(), REGS.pc)) @@ -3828,8 +3797,7 @@ CASE(JSOP_YIELD) { MOZ_ASSERT(!cx->isExceptionPending()); MOZ_ASSERT(REGS.fp()->isNonEvalFunctionFrame()); - RootedObject& obj = rootObject0; - obj = ®S.sp[-1].toObject(); + ReservedRooted obj(&rootObject0, ®S.sp[-1].toObject()); if (!GeneratorObject::normalSuspend(cx, obj, REGS.fp(), REGS.pc, REGS.spForStackDepth(0), REGS.stackDepth() - 2)) { @@ -3844,19 +3812,18 @@ CASE(JSOP_YIELD) CASE(JSOP_RESUME) { - RootedObject& gen = rootObject0; - RootedValue& val = rootValue0; - val = REGS.sp[-1]; - gen = ®S.sp[-2].toObject(); - // popInlineFrame expects there to be an additional value on the stack to - // pop off, so leave "gen" on the stack. - - GeneratorObject::ResumeKind resumeKind = GeneratorObject::getResumeKind(REGS.pc); - bool ok = GeneratorObject::resume(cx, activation, gen, val, resumeKind); - SET_SCRIPT(REGS.fp()->script()); - if (!ok) - goto error; + { + ReservedRooted gen(&rootObject0, ®S.sp[-2].toObject()); + ReservedRooted val(&rootValue0, REGS.sp[-1]); + // popInlineFrame expects there to be an additional value on the stack + // to pop off, so leave "gen" on the stack. + GeneratorObject::ResumeKind resumeKind = GeneratorObject::getResumeKind(REGS.pc); + bool ok = GeneratorObject::resume(cx, activation, gen, val, resumeKind); + SET_SCRIPT(REGS.fp()->script()); + if (!ok) + goto error; + } ADVANCE_AND_DISPATCH(0); } @@ -3870,8 +3837,7 @@ END_CASE(JSOP_DEBUGAFTERYIELD) CASE(JSOP_FINALYIELDRVAL) { - RootedObject& gen = rootObject0; - gen = ®S.sp[-1].toObject(); + ReservedRooted gen(&rootObject0, ®S.sp[-1].toObject()); REGS.sp--; if (!GeneratorObject::finalSuspend(cx, gen)) { @@ -3884,8 +3850,7 @@ CASE(JSOP_FINALYIELDRVAL) CASE(JSOP_ARRAYPUSH) { - RootedObject& obj = rootObject0; - obj = ®S.sp[-1].toObject(); + ReservedRooted obj(&rootObject0, ®S.sp[-1].toObject()); if (!NewbornArrayPush(cx, obj, REGS.sp[-2])) goto error; REGS.sp -= 2; @@ -3894,13 +3859,12 @@ END_CASE(JSOP_ARRAYPUSH) CASE(JSOP_CLASSHERITAGE) { - RootedValue& val = rootValue0; - val = REGS.sp[-1]; + ReservedRooted val(&rootValue0, REGS.sp[-1]); - RootedValue& objProto = rootValue1; - RootedObject& funcProto = rootObject0; + ReservedRooted objProto(&rootValue1); + ReservedRooted funcProto(&rootObject0); if (val.isNull()) { - objProto.setNull(); + objProto = NullValue(); if (!GetBuiltinPrototype(cx, JSProto_Function, &funcProto)) goto error; } else { @@ -3927,12 +3891,10 @@ END_CASE(JSOP_CLASSHERITAGE) CASE(JSOP_FUNWITHPROTO) { - RootedObject& proto = rootObject1; - proto = ®S.sp[-1].toObject(); + ReservedRooted proto(&rootObject1, ®S.sp[-1].toObject()); /* Load the specified function object literal. */ - RootedFunction& fun = rootFunction0; - fun = script->getFunction(GET_UINT32_INDEX(REGS.pc)); + ReservedRooted fun(&rootFunction0, script->getFunction(GET_UINT32_INDEX(REGS.pc))); JSObject* obj = CloneFunctionObjectIfNotSingleton(cx, fun, REGS.fp()->scopeChain(), proto, GenericObject); @@ -3945,8 +3907,7 @@ END_CASE(JSOP_FUNWITHPROTO) CASE(JSOP_OBJWITHPROTO) { - RootedObject& proto = rootObject0; - proto = REGS.sp[-1].toObjectOrNull(); + ReservedRooted proto(&rootObject0, REGS.sp[-1].toObjectOrNull()); JSObject* obj = NewObjectWithGivenProto(cx, proto); if (!obj) @@ -3962,12 +3923,11 @@ CASE(JSOP_INITHOMEOBJECT) MOZ_ASSERT(REGS.stackDepth() >= skipOver + 2); /* Load the function to be initialized */ - RootedFunction& func = rootFunction0; - func = ®S.sp[-1].toObject().as(); + ReservedRooted func(&rootFunction0, ®S.sp[-1].toObject().as()); MOZ_ASSERT(func->allowSuperProperty()); /* Load the home object */ - RootedNativeObject& obj = rootNativeObject0; + ReservedRooted obj(&rootNativeObject0); obj = ®S.sp[int(-2 - skipOver)].toObject().as(); MOZ_ASSERT(obj->is() || obj->is()); @@ -3992,10 +3952,8 @@ CASE(JSOP_SUPERBASE) MOZ_ASSERT(callee.nonLazyScript()->needsHomeObject()); const Value& homeObjVal = callee.getExtendedSlot(FunctionExtended::METHOD_HOMEOBJECT_SLOT); - RootedObject& homeObj = rootObject0; - homeObj = &homeObjVal.toObject(); - - RootedObject& superBase = rootObject1; + ReservedRooted homeObj(&rootObject0, &homeObjVal.toObject()); + ReservedRooted superBase(&rootObject1); if (!GetPrototype(cx, homeObj, &superBase)) goto error; @@ -4038,12 +3996,12 @@ DEFAULT() case CatchContinuation: ADVANCE_AND_DISPATCH(0); - case FinallyContinuation: + case FinallyContinuation: { /* * Push (true, exception) pair for finally to indicate that [retsub] * should rethrow the exception. */ - RootedValue& exception = rootValue0; + ReservedRooted exception(&rootValue0); if (!cx->getPendingException(&exception)) { interpReturnOK = false; goto return_continuation; @@ -4051,7 +4009,8 @@ DEFAULT() PUSH_BOOLEAN(true); PUSH_COPY(exception); cx->clearPendingException(); - ADVANCE_AND_DISPATCH(0); + } + ADVANCE_AND_DISPATCH(0); } MOZ_CRASH("Invalid HandleError continuation"); From f6f47533e7725f72322d69b8cac59d032bd09ff5 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Sat, 30 May 2015 17:49:46 +0100 Subject: [PATCH 36/85] Bug 1107096 followup - reftest shows a couple of pixels of fuzz on Mulet. r=orange --- layout/reftests/canvas/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/canvas/reftest.list b/layout/reftests/canvas/reftest.list index e36b697758db..1ff7f122566e 100644 --- a/layout/reftests/canvas/reftest.list +++ b/layout/reftests/canvas/reftest.list @@ -103,5 +103,5 @@ fails-if(azureQuartz&&OSX==1006) == 672646-alpha-radial-gradient.html 672646-alp fuzzy-if(azureQuartz,2,128) fuzzy-if(d2d,12,21) == 784573-1.html 784573-1-ref.html == 802658-1.html 802658-1-ref.html -== 1107096-invisibles.html 1107096-invisibles-ref.html +fuzzy-if(Mulet,45,2) == 1107096-invisibles.html 1107096-invisibles-ref.html == 1151821-1.html 1151821-1-ref.html From 525e5c213243df0fec1677691bd0f85c28a6a0b4 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sun, 31 May 2015 00:50:21 -0500 Subject: [PATCH 37/85] Bug 1168629. Always make sure that there is at least one layer with the metrics for the root scroll frame/root element. r=botond,kats We do this by looking at the layer tree after it has been made to see if the root metrics are in it already. This is needed to ensure that there is always a root AZPC in a process. --- layout/base/nsDisplayList.cpp | 54 +++++++++++++++++++++++------------ layout/base/nsLayoutUtils.cpp | 16 +++++++++++ layout/base/nsLayoutUtils.h | 6 ++++ 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 57c4e566e4c4..11167a83ac22 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1547,31 +1547,47 @@ already_AddRefed nsDisplayList::PaintRoot(nsDisplayListBuilder* aB // want the root container layer to have metrics. If the parent process is // using XUL windows, there is no root scrollframe, and without explicitly // creating metrics there will be no guaranteed top-level APZC. - if (gfxPrefs::LayoutUseContainersForRootFrames() || - (XRE_IsParentProcess() && !presShell->GetRootScrollFrame())) - { + bool addMetrics = gfxPrefs::LayoutUseContainersForRootFrames() || + (XRE_IsParentProcess() && !presShell->GetRootScrollFrame()); + + // Add metrics if there are none in the layer tree with the id (create an id + // if there isn't one already) of the root scroll frame/root content. + bool ensureMetricsForRootId = + gfxPrefs::AsyncPanZoomEnabled() && + !gfxPrefs::LayoutUseContainersForRootFrames() && + aBuilder->IsPaintingToWindow() && + !presContext->GetParentPresContext(); + + nsIContent* content = nullptr; + nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame(); + if (rootScrollFrame) { + content = rootScrollFrame->GetContent(); + } else { + // If there is no root scroll frame, pick the document element instead. + // The only case we don't want to do this is in non-APZ fennec, where + // we want the root xul document to get a null scroll id so that the root + // content document gets the first non-null scroll id. +#if !defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ANDROID_APZ) + content = document->GetDocumentElement(); +#endif + } + + + if (ensureMetricsForRootId && content) { + ViewID scrollId = nsLayoutUtils::FindOrCreateIDFor(content); + if (nsLayoutUtils::ContainsMetricsWithId(root, scrollId)) { + ensureMetricsForRootId = false; + } + } + + if (addMetrics || ensureMetricsForRootId) { bool isRoot = presContext->IsRootContentDocument(); nsRect viewport(aBuilder->ToReferenceFrame(frame), frame->GetSize()); - nsIFrame* scrollFrame = presShell->GetRootScrollFrame(); - nsIContent* content = nullptr; - if (scrollFrame) { - content = scrollFrame->GetContent(); - } else { - // If there is no root scroll frame, pick the document element instead. - // The only case we don't want to do this is in non-APZ fennec, where - // we want the root xul document to get a null scroll id so that the root - // content document gets the first non-null scroll id. -#if !defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ANDROID_APZ) - content = document->GetDocumentElement(); -#endif - } - root->SetFrameMetrics( nsLayoutUtils::ComputeFrameMetrics(frame, - presShell->GetRootScrollFrame(), - content, + rootScrollFrame, content, aBuilder->FindReferenceFrameFor(frame), root, FrameMetrics::NULL_SCROLL_ID, viewport, Nothing(), isRoot, containerParameters)); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index c42dc8ecc4db..fd5dd6936674 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -8343,6 +8343,22 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame, return metrics; } +/* static */ bool +nsLayoutUtils::ContainsMetricsWithId(const Layer* aLayer, const ViewID& aScrollId) +{ + for (uint32_t i = aLayer->GetFrameMetricsCount(); i > 0; i--) { + if (aLayer->GetFrameMetrics(i-1).GetScrollId() == aScrollId) { + return true; + } + } + for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { + if (ContainsMetricsWithId(child, aScrollId)) { + return true; + } + } + return false; +} + /* static */ uint32_t nsLayoutUtils::GetTouchActionFromFrame(nsIFrame* aFrame) { diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 057765dd2b09..e6592b06f174 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2660,6 +2660,12 @@ public: */ static nsMargin ScrollbarAreaToExcludeFromCompositionBoundsFor(nsIFrame* aScrollFrame); + /** + * Looks in the layer subtree rooted at aLayer for a metrics with scroll id + * aScrollId. Returns true if such is found. + */ + static bool ContainsMetricsWithId(const Layer* aLayer, const ViewID& aScrollId); + private: static uint32_t sFontSizeInflationEmPerLine; static uint32_t sFontSizeInflationMinTwips; From 06103d7e87b4dbcded8dd9b6019f1af61514906c Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sun, 31 May 2015 00:50:21 -0500 Subject: [PATCH 38/85] Bug 1168629. Clear frame metrics on the root layer if we aren't setting new frame metrics because the layer may be recycled and still have frame metrics from last time. r=mstange --- layout/base/nsDisplayList.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 11167a83ac22..638eb93f9d8e 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1591,6 +1591,9 @@ already_AddRefed nsDisplayList::PaintRoot(nsDisplayListBuilder* aB aBuilder->FindReferenceFrameFor(frame), root, FrameMetrics::NULL_SCROLL_ID, viewport, Nothing(), isRoot, containerParameters)); + } else { + // Set empty metrics to clear any metrics that might be on a recycled layer. + root->SetFrameMetrics(nsTArray()); } // NS_WARNING is debug-only, so don't even bother checking the conditions in From 8f75dcfa54e4289d6e81a8f1c342d0c3e6fd27a5 Mon Sep 17 00:00:00 2001 From: Gabor Krizsanits Date: Sun, 31 May 2015 10:46:46 +0200 Subject: [PATCH 39/85] Bug 1164014 - Fixing defaultShims. r=billm --- browser/installer/package-manifest.in | 1 + toolkit/components/addoncompat/moz.build | 1 + 2 files changed, 2 insertions(+) diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 4a57e538473e..9206a5255086 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -436,6 +436,7 @@ @RESPATH@/components/nsUpdateTimerManager.js @RESPATH@/components/addoncompat.manifest @RESPATH@/components/multiprocessShims.js +@RESPATH@/components/defaultShims.js @RESPATH@/components/remoteTagService.js @RESPATH@/components/pluginGlue.manifest @RESPATH@/components/ProcessSingleton.manifest diff --git a/toolkit/components/addoncompat/moz.build b/toolkit/components/addoncompat/moz.build index 411c28399e84..a7ad54b3ed71 100644 --- a/toolkit/components/addoncompat/moz.build +++ b/toolkit/components/addoncompat/moz.build @@ -8,6 +8,7 @@ TEST_DIRS += ['tests'] EXTRA_COMPONENTS += [ 'addoncompat.manifest', + 'defaultShims.js', 'multiprocessShims.js', 'remoteTagService.js', ] From e0bd57ba62a061b3195f839d29f9da658c783536 Mon Sep 17 00:00:00 2001 From: Gabor Krizsanits Date: Sun, 31 May 2015 10:46:49 +0200 Subject: [PATCH 40/85] Bug 1164014 - Shim optimization. r=billm --- js/xpconnect/idl/nsIAddonInterposition.idl | 12 +- js/xpconnect/src/XPCComponents.cpp | 4 +- js/xpconnect/src/XPCWrappedNativeScope.cpp | 115 +++++++++++++++++- js/xpconnect/src/nsXPConnect.cpp | 19 ++- js/xpconnect/src/xpcprivate.h | 20 ++- js/xpconnect/tests/unit/test_interposition.js | 5 + js/xpconnect/wrappers/AddonWrapper.cpp | 9 +- .../components/addoncompat/defaultShims.js | 4 + .../addoncompat/multiprocessShims.js | 30 +++++ 9 files changed, 200 insertions(+), 18 deletions(-) diff --git a/js/xpconnect/idl/nsIAddonInterposition.idl b/js/xpconnect/idl/nsIAddonInterposition.idl index 9ed0f9b7a370..1d1166ef239b 100644 --- a/js/xpconnect/idl/nsIAddonInterposition.idl +++ b/js/xpconnect/idl/nsIAddonInterposition.idl @@ -20,7 +20,7 @@ * property, it should return a replacement property descriptor for it. If not, * it should return null. */ -[scriptable,uuid(215353cb-6e77-462f-a791-6891f42e593f)] +[scriptable,uuid(d05cc5fd-ad88-41a6-854c-36fd94d69ddb)] interface nsIAddonInterposition : nsISupports { /** @@ -54,4 +54,14 @@ interface nsIAddonInterposition : nsISupports in jsval originalFunc, in jsval originalThis, in jsval args); + + /** + * For the first time when the interposition is registered the engine + * calls getWhitelist and expects an array of strings. The strings are + * the name of properties the interposition wants interposeProperty + * to be called. It can be an empty array. + * Note: for CPOWs interposeProperty is always called regardless if + * the name of the property is on the whitelist or not. + */ + jsval getWhitelist(); }; diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index 4c3290dc07d5..662f7461c220 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -32,6 +32,7 @@ #include "nsWindowMemoryReporter.h" #include "nsDOMClassInfo.h" #include "ShimInterfaceInfo.h" +#include "nsIAddonInterposition.h" using namespace mozilla; using namespace JS; @@ -3490,8 +3491,9 @@ nsXPCComponents_Utils::SetAddonInterposition(const nsACString& addonIdStr, JSAddonId* addonId = xpc::NewAddonId(cx, addonIdStr); if (!addonId) return NS_ERROR_FAILURE; - if (!XPCWrappedNativeScope::SetAddonInterposition(addonId, interposition)) + if (!XPCWrappedNativeScope::SetAddonInterposition(cx, addonId, interposition)) return NS_ERROR_FAILURE; + return NS_OK; } diff --git a/js/xpconnect/src/XPCWrappedNativeScope.cpp b/js/xpconnect/src/XPCWrappedNativeScope.cpp index c675809db8fe..4dd06db0cddd 100644 --- a/js/xpconnect/src/XPCWrappedNativeScope.cpp +++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp @@ -27,6 +27,7 @@ using namespace JS; XPCWrappedNativeScope* XPCWrappedNativeScope::gScopes = nullptr; XPCWrappedNativeScope* XPCWrappedNativeScope::gDyingScopes = nullptr; XPCWrappedNativeScope::InterpositionMap* XPCWrappedNativeScope::gInterpositionMap = nullptr; +InterpositionWhitelistArray* XPCWrappedNativeScope::gInterpositionWhitelists = nullptr; NS_IMPL_ISUPPORTS(XPCWrappedNativeScope::ClearInterpositionsObserver, nsIObserver) @@ -46,6 +47,11 @@ XPCWrappedNativeScope::ClearInterpositionsObserver::Observe(nsISupports* subject gInterpositionMap = nullptr; } + if (gInterpositionWhitelists) { + delete gInterpositionWhitelists; + gInterpositionWhitelists = nullptr; + } + nsContentUtils::UnregisterShutdownObserver(this); return NS_OK; } @@ -143,6 +149,8 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext* cx, "extensions.interposition.enabled", false); if (interpositionEnabled) { mInterposition = do_GetService("@mozilla.org/addons/default-addon-shims;1"); + MOZ_ASSERT(mInterposition); + UpdateInterpositionWhitelist(cx, mInterposition); } } } @@ -756,7 +764,8 @@ XPCWrappedNativeScope::SetExpandoChain(JSContext* cx, HandleObject target, } /* static */ bool -XPCWrappedNativeScope::SetAddonInterposition(JSAddonId* addonId, +XPCWrappedNativeScope::SetAddonInterposition(JSContext* cx, + JSAddonId* addonId, nsIAddonInterposition* interp) { if (!gInterpositionMap) { @@ -764,14 +773,17 @@ XPCWrappedNativeScope::SetAddonInterposition(JSAddonId* addonId, gInterpositionMap->init(); // Make sure to clear the map at shutdown. + // Note: this will take care of gInterpositionWhitelists too. nsContentUtils::RegisterShutdownObserver(new ClearInterpositionsObserver()); } if (interp) { - return gInterpositionMap->put(addonId, interp); + bool ok = gInterpositionMap->put(addonId, interp); + NS_ENSURE_TRUE(ok, false); + UpdateInterpositionWhitelist(cx, interp); } else { gInterpositionMap->remove(addonId); - return true; } + return true; } nsCOMPtr @@ -780,6 +792,103 @@ XPCWrappedNativeScope::GetInterposition() return mInterposition; } +/* static */ InterpositionWhitelist* +XPCWrappedNativeScope::GetInterpositionWhitelist(nsIAddonInterposition* interposition) +{ + if (!gInterpositionWhitelists) + return nullptr; + + InterpositionWhitelistArray& wls = *gInterpositionWhitelists; + for (size_t i = 0; i < wls.Length(); i++) { + if (wls[i].interposition == interposition) + return &wls[i].whitelist; + } + + return nullptr; +} + +/* static */ bool +XPCWrappedNativeScope::UpdateInterpositionWhitelist(JSContext* cx, + nsIAddonInterposition* interposition) +{ + // We want to set the interpostion whitelist only once. + InterpositionWhitelist* whitelist = GetInterpositionWhitelist(interposition); + if (whitelist) + return true; + + // The hashsets in gInterpositionWhitelists do not have a copy constructor so + // a reallocation for the array will lead to a memory corruption. If you + // need more interpositions, change the capacity of the array please. + static const size_t MAX_INTERPOSITION = 8; + if (!gInterpositionWhitelists) + gInterpositionWhitelists = new InterpositionWhitelistArray(MAX_INTERPOSITION); + + MOZ_RELEASE_ASSERT(MAX_INTERPOSITION > gInterpositionWhitelists->Length() + 1); + InterpositionWhitelistPair* newPair = gInterpositionWhitelists->AppendElement(); + newPair->interposition = interposition; + newPair->whitelist.init(); + whitelist = &newPair->whitelist; + + RootedValue whitelistVal(cx); + nsresult rv = interposition->GetWhitelist(&whitelistVal); + if (NS_FAILED(rv)) { + JS_ReportError(cx, "Could not get the whitelist from the interposition."); + return false; + } + + if (!whitelistVal.isObject()) { + JS_ReportError(cx, "Whitelist must be an array."); + return false; + } + + // We want to enter the whitelist's compartment to avoid any wrappers. + // To be on the safe side let's make sure that it's a system compartment + // and we don't accidentally trigger some content function here by parsing + // the whitelist object. + RootedObject whitelistObj(cx, &whitelistVal.toObject()); + whitelistObj = js::UncheckedUnwrap(whitelistObj); + if (!AccessCheck::isChrome(whitelistObj)) { + JS_ReportError(cx, "Whitelist must be from system scope."); + return false; + } + + { + JSAutoCompartment ac(cx, whitelistObj); + + uint32_t length; + if (!JS_IsArrayObject(cx, whitelistObj) || + !JS_GetArrayLength(cx, whitelistObj, &length)) { + JS_ReportError(cx, "Whitelist must be an array."); + return false; + } + + for (uint32_t i = 0; i < length; i++) { + RootedValue idval(cx); + if (!JS_GetElement(cx, whitelistObj, i, &idval)) + return false; + + if (!idval.isString()) { + JS_ReportError(cx, "Whitelist must contain strings only."); + return false; + } + + RootedString str(cx, idval.toString()); + str = JS_InternJSString(cx, str); + if (!str) { + JS_ReportError(cx, "String internization failed."); + return false; + } + + // By internizing the id's we ensure that they won't get + // GCed so we can use them as hash keys. + jsid id = INTERNED_STRING_TO_JSID(cx, str); + whitelist->put(JSID_BITS(id)); + } + } + + return true; +} + /***************************************************************************/ // static diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 144fb13c360c..d5cf7d1445ef 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -1360,17 +1360,14 @@ bool SetAddonInterposition(const nsACString& addonIdStr, nsIAddonInterposition* interposition) { JSAddonId* addonId; - { - // We enter the junk scope just to allocate a string, which actually will go - // in the system zone. - AutoJSAPI jsapi; - jsapi.Init(xpc::PrivilegedJunkScope()); - addonId = NewAddonId(jsapi.cx(), addonIdStr); - if (!addonId) - return false; - } - - return XPCWrappedNativeScope::SetAddonInterposition(addonId, interposition); + // We enter the junk scope just to allocate a string, which actually will go + // in the system zone. + AutoJSAPI jsapi; + jsapi.Init(xpc::PrivilegedJunkScope()); + addonId = NewAddonId(jsapi.cx(), addonIdStr); + if (!addonId) + return false; + return XPCWrappedNativeScope::SetAddonInterposition(jsapi.cx(), addonId, interposition); } } // namespace xpc diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 9c7f11244003..8dc0ceec9d3d 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -1018,6 +1018,17 @@ static inline bool IS_PROTO_CLASS(const js::Class* clazz) clazz == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass; } +typedef js::HashSet, + js::SystemAllocPolicy> InterpositionWhitelist; + +struct InterpositionWhitelistPair { + nsIAddonInterposition* interposition; + InterpositionWhitelist whitelist; +}; + +typedef nsTArray InterpositionWhitelistArray; + /***************************************************************************/ // XPCWrappedNativeScope is one-to-one with a JS global object. @@ -1187,9 +1198,14 @@ public: bool HasInterposition() { return mInterposition; } nsCOMPtr GetInterposition(); - static bool SetAddonInterposition(JSAddonId* addonId, + static bool SetAddonInterposition(JSContext* cx, + JSAddonId* addonId, nsIAddonInterposition* interp); + static InterpositionWhitelist* GetInterpositionWhitelist(nsIAddonInterposition* interposition); + static bool UpdateInterpositionWhitelist(JSContext* cx, + nsIAddonInterposition* interposition); + void SetAddonCallInterposition() { mHasCallInterpositions = true; } bool HasCallInterposition() { return mHasCallInterpositions; }; @@ -1212,6 +1228,8 @@ private: static InterpositionMap* gInterpositionMap; + static InterpositionWhitelistArray* gInterpositionWhitelists; + XPCJSRuntime* mRuntime; Native2WrappedNativeMap* mWrappedNativeMap; ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap; diff --git a/js/xpconnect/tests/unit/test_interposition.js b/js/xpconnect/tests/unit/test_interposition.js index 2590114b2472..f755bbd7d443 100644 --- a/js/xpconnect/tests/unit/test_interposition.js +++ b/js/xpconnect/tests/unit/test_interposition.js @@ -34,6 +34,11 @@ let TestInterposition = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition, Ci.nsISupportsWeakReference]), + getWhitelist: function() { + return ["abcxyz", "utils", "dataprop", "getterprop", "setterprop", + "objprop", "defineprop", "configurableprop"]; + }, + interposeProperty: function(addonId, target, iid, prop) { do_check_eq(addonId, ADDONID); do_check_eq(gExpectedProp, prop); diff --git a/js/xpconnect/wrappers/AddonWrapper.cpp b/js/xpconnect/wrappers/AddonWrapper.cpp index b73d365c1d96..e0fdd960568c 100644 --- a/js/xpconnect/wrappers/AddonWrapper.cpp +++ b/js/xpconnect/wrappers/AddonWrapper.cpp @@ -29,11 +29,12 @@ InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId // wrapped natives. RootedObject unwrapped(cx, UncheckedUnwrap(target)); const js::Class* clasp = js::GetObjectClass(unwrapped); + bool isCPOW = jsipc::IsWrappedCPOW(unwrapped); if (!mozilla::dom::IsDOMClass(clasp) && !IS_WN_CLASS(clasp) && !IS_PROTO_CLASS(clasp) && clasp != &OuterWindowProxyClass && - !jsipc::IsWrappedCPOW(unwrapped)) { + !isCPOW) { return true; } @@ -41,6 +42,12 @@ InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId MOZ_ASSERT(scope->HasInterposition()); nsCOMPtr interp = scope->GetInterposition(); + InterpositionWhitelist* wl = XPCWrappedNativeScope::GetInterpositionWhitelist(interp); + // We do InterposeProperty only if the id is on the whitelist of the interpostion + // or if the target is a CPOW. + if ((!wl || !wl->has(JSID_BITS(id.get()))) && !isCPOW) + return true; + JSAddonId* addonId = AddonIdOfObject(target); RootedValue addonIdValue(cx, StringValue(StringOfAddonId(addonId))); RootedValue prop(cx, IdToValue(id)); diff --git a/toolkit/components/addoncompat/defaultShims.js b/toolkit/components/addoncompat/defaultShims.js index 107d6ee8fd48..a786efed7d39 100644 --- a/toolkit/components/addoncompat/defaultShims.js +++ b/toolkit/components/addoncompat/defaultShims.js @@ -22,6 +22,10 @@ DefaultInterpositionService.prototype = { classID: Components.ID("{50bc93ce-602a-4bef-bf3a-61fc749c4caf}"), QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition, Ci.nsISupportsWeakReference]), + getWhitelist: function() { + return []; + }, + interposeProperty: function(addon, target, iid, prop) { return null; }, diff --git a/toolkit/components/addoncompat/multiprocessShims.js b/toolkit/components/addoncompat/multiprocessShims.js index 0da79015ccc8..6c8d559b3c46 100644 --- a/toolkit/components/addoncompat/multiprocessShims.js +++ b/toolkit/components/addoncompat/multiprocessShims.js @@ -70,12 +70,42 @@ function AddonInterpositionService() // kinds of objects. this._interfaceInterpositions = RemoteAddonsParent.getInterfaceInterpositions(); this._taggedInterpositions = RemoteAddonsParent.getTaggedInterpositions(); + + let wl = []; + for (let v in this._interfaceInterpositions) { + let interp = this._interfaceInterpositions[v]; + wl.push(...Object.getOwnPropertyNames(interp.methods)); + wl.push(...Object.getOwnPropertyNames(interp.getters)); + wl.push(...Object.getOwnPropertyNames(interp.setters)); + } + + for (let v in this._taggedInterpositions) { + let interp = this._taggedInterpositions[v]; + wl.push(...Object.getOwnPropertyNames(interp.methods)); + wl.push(...Object.getOwnPropertyNames(interp.getters)); + wl.push(...Object.getOwnPropertyNames(interp.setters)); + } + + let nameSet = new Set(); + wl = wl.filter(function(item) { + if (nameSet.has(item)) + return true; + + nameSet.add(item); + return true; + }); + + this._whitelist = wl; } AddonInterpositionService.prototype = { classID: Components.ID("{1363d5f0-d95e-11e3-9c1a-0800200c9a66}"), QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition, Ci.nsISupportsWeakReference]), + getWhitelist: function() { + return this._whitelist; + }, + // When the interface is not known for a method call, this code // determines the type of the target object. getObjectTag: function(target) { From 53918bdd59a9d59f93de8161be2c10d07a608107 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sun, 31 May 2015 14:44:40 -0500 Subject: [PATCH 41/85] Bug 1168630. Part 1. Add layers id to hit test node. r=botond When the ancestors of a hit testing node do not have an APZC we will need the layers id of the layer that was hit in order to find the root APZC for that layers id. --- gfx/layers/LayersLogging.cpp | 2 +- gfx/layers/apz/src/APZCTreeManager.cpp | 13 +++++++------ gfx/layers/apz/src/APZCTreeManager.h | 3 ++- gfx/layers/apz/src/AsyncPanZoomController.h | 5 +++++ gfx/layers/apz/src/HitTestingTreeNode.cpp | 15 ++++++++++++--- gfx/layers/apz/src/HitTestingTreeNode.h | 7 +++++-- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/gfx/layers/LayersLogging.cpp b/gfx/layers/LayersLogging.cpp index d7049de072b1..f8461e44f6bb 100644 --- a/gfx/layers/LayersLogging.cpp +++ b/gfx/layers/LayersLogging.cpp @@ -213,7 +213,7 @@ AppendToString(std::stringstream& aStream, const ScrollableLayerGuid& s, const char* pfx, const char* sfx) { aStream << pfx - << nsPrintfCString("{ l=%llu, p=%u, v=%llu }", s.mLayersId, s.mPresShellId, s.mScrollId).get() + << nsPrintfCString("{ l=%" PRIu64 ", p=%u, v=%" PRIu64 " }", s.mLayersId, s.mPresShellId, s.mScrollId).get() << sfx; } diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 20cf3bd9c2bb..1bebc580cb47 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -280,7 +280,8 @@ GetEventRegions(const LayerMetricsWrapper& aLayer) already_AddRefed APZCTreeManager::RecycleOrCreateNode(TreeBuildingState& aState, - AsyncPanZoomController* aApzc) + AsyncPanZoomController* aApzc, + uint64_t aLayersId) { // Find a node without an APZC and return it. Note that unless the layer tree // actually changes, this loop should generally do an early-return on the @@ -289,11 +290,11 @@ APZCTreeManager::RecycleOrCreateNode(TreeBuildingState& aState, nsRefPtr node = aState.mNodesToDestroy[i]; if (!node->IsPrimaryHolder()) { aState.mNodesToDestroy.RemoveElement(node); - node->RecycleWith(aApzc); + node->RecycleWith(aApzc, aLayersId); return node.forget(); } } - nsRefPtr node = new HitTestingTreeNode(aApzc, false); + nsRefPtr node = new HitTestingTreeNode(aApzc, false, aLayersId); return node.forget(); } @@ -333,7 +334,7 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, nsRefPtr node = nullptr; if (!needsApzc) { - node = RecycleOrCreateNode(aState, nullptr); + node = RecycleOrCreateNode(aState, nullptr, aLayersId); AttachNodeToTree(node, aParent, aNextSibling); node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(), aLayer.GetClipRect() ? Some(ParentLayerIntRegion(*aLayer.GetClipRect())) : Nothing(), @@ -413,7 +414,7 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, apzc->ShareFrameMetricsAcrossProcesses(); } MOZ_ASSERT(node == nullptr); - node = new HitTestingTreeNode(apzc, true); + node = new HitTestingTreeNode(apzc, true, aLayersId); } else { // If we are re-using a node for this layer clear the tree pointers // so that it doesn't continue pointing to nodes that might no longer @@ -487,7 +488,7 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, // now that will also be using that APZC. The hit-test region on the APZC needs // to be updated to deal with the new layer's hit region. - node = RecycleOrCreateNode(aState, apzc); + node = RecycleOrCreateNode(aState, apzc, aLayersId); AttachNodeToTree(node, aParent, aNextSibling); // Even though different layers associated with a given APZC may be at diff --git a/gfx/layers/apz/src/APZCTreeManager.h b/gfx/layers/apz/src/APZCTreeManager.h index 61801b1d49cf..6dc2f1b71f83 100644 --- a/gfx/layers/apz/src/APZCTreeManager.h +++ b/gfx/layers/apz/src/APZCTreeManager.h @@ -433,7 +433,8 @@ private: void FlushRepaintsRecursively(HitTestingTreeNode* aNode); already_AddRefed RecycleOrCreateNode(TreeBuildingState& aState, - AsyncPanZoomController* aApzc); + AsyncPanZoomController* aApzc, + uint64_t aLayersId); HitTestingTreeNode* PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, const FrameMetrics& aMetrics, uint64_t aLayersId, diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index 19679b43b8ee..0f3f17c474e9 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -1087,6 +1087,11 @@ public: return mAsyncTransformAppliedToContent; } + uint64_t GetLayersId() const + { + return mLayersId; + } + private: // Extra offset to add in SampleContentTransformForFrame for testing CSSPoint mTestAsyncScrollOffset; diff --git a/gfx/layers/apz/src/HitTestingTreeNode.cpp b/gfx/layers/apz/src/HitTestingTreeNode.cpp index 47ad0c3ab44f..25d5cee56fb0 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.cpp +++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp @@ -18,22 +18,28 @@ namespace mozilla { namespace layers { HitTestingTreeNode::HitTestingTreeNode(AsyncPanZoomController* aApzc, - bool aIsPrimaryHolder) + bool aIsPrimaryHolder, + uint64_t aLayersId) : mApzc(aApzc) , mIsPrimaryApzcHolder(aIsPrimaryHolder) + , mLayersId(aLayersId) , mOverride(EventRegionsOverride::NoOverride) { if (mIsPrimaryApzcHolder) { MOZ_ASSERT(mApzc); } + MOZ_ASSERT(!mApzc || mApzc->GetLayersId() == mLayersId); } void -HitTestingTreeNode::RecycleWith(AsyncPanZoomController* aApzc) +HitTestingTreeNode::RecycleWith(AsyncPanZoomController* aApzc, + uint64_t aLayersId) { MOZ_ASSERT(!mIsPrimaryApzcHolder); Destroy(); // clear out tree pointers mApzc = aApzc; + mLayersId = aLayersId; + MOZ_ASSERT(!mApzc || mApzc->GetLayersId() == mLayersId); // The caller is expected to call SetHitTestData to repopulate the hit-test // fields. } @@ -57,6 +63,8 @@ HitTestingTreeNode::Destroy() } mApzc = nullptr; } + + mLayersId = 0; } void @@ -229,7 +237,8 @@ HitTestingTreeNode::Dump(const char* aPrefix) const mPrevSibling->Dump(aPrefix); } printf_stderr("%sHitTestingTreeNode (%p) APZC (%p) g=(%s) %s%sr=(%s) t=(%s) c=(%s)\n", - aPrefix, this, mApzc.get(), mApzc ? Stringify(mApzc->GetGuid()).c_str() : "", + aPrefix, this, mApzc.get(), + mApzc ? Stringify(mApzc->GetGuid()).c_str() : nsPrintfCString("l=%" PRIu64, mLayersId).get(), (mOverride & EventRegionsOverride::ForceDispatchToContent) ? "fdtc " : "", (mOverride & EventRegionsOverride::ForceEmptyHitRegion) ? "fehr " : "", Stringify(mEventRegions).c_str(), Stringify(mTransform).c_str(), diff --git a/gfx/layers/apz/src/HitTestingTreeNode.h b/gfx/layers/apz/src/HitTestingTreeNode.h index d5a157c9de61..d27578fd2998 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.h +++ b/gfx/layers/apz/src/HitTestingTreeNode.h @@ -53,8 +53,9 @@ class HitTestingTreeNode { private: ~HitTestingTreeNode(); public: - HitTestingTreeNode(AsyncPanZoomController* aApzc, bool aIsPrimaryHolder); - void RecycleWith(AsyncPanZoomController* aApzc); + HitTestingTreeNode(AsyncPanZoomController* aApzc, bool aIsPrimaryHolder, + uint64_t aLayersId); + void RecycleWith(AsyncPanZoomController* aApzc, uint64_t aLayersId); void Destroy(); /* Tree construction methods */ @@ -106,6 +107,8 @@ private: nsRefPtr mApzc; bool mIsPrimaryApzcHolder; + uint64_t mLayersId; + /* Let {L,M} be the {layer, scrollable metrics} pair that this node * corresponds to in the layer tree. mEventRegions contains the event regions * from L, in the case where event-regions are enabled. If event-regions are From 316e76fb96c7cdcc5e66a7063c1f85405eb93de7 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sun, 31 May 2015 14:44:40 -0500 Subject: [PATCH 42/85] Bug 1168630. Part 2. Only return an APZC from GetAPZCAtPoint that has the same layers id as the layer that was hit. r=botond In a future patch we will look for the root APZC for the same layers id so that this doesn't make us return null. --- gfx/layers/apz/src/APZCTreeManager.cpp | 2 +- gfx/layers/apz/src/HitTestingTreeNode.cpp | 13 +++++++++++++ gfx/layers/apz/src/HitTestingTreeNode.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 1bebc580cb47..786ec5ec494a 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -1462,7 +1462,7 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode, node); HitTestResult hitResult = node->HitTest(aHitTestPoint); if (hitResult != HitTestResult::HitNothing) { - result = node->GetNearestContainingApzc(); + result = node->GetNearestContainingApzcWithSameLayersId(); APZCTM_LOG("Successfully matched APZC %p via node %p (hit result %d)\n", result, node, hitResult); MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion); diff --git a/gfx/layers/apz/src/HitTestingTreeNode.cpp b/gfx/layers/apz/src/HitTestingTreeNode.cpp index 25d5cee56fb0..31d1380bb334 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.cpp +++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp @@ -155,6 +155,19 @@ HitTestingTreeNode::GetNearestContainingApzc() const return nullptr; } +AsyncPanZoomController* +HitTestingTreeNode::GetNearestContainingApzcWithSameLayersId() const +{ + for (const HitTestingTreeNode* n = this; + n && n->mLayersId == mLayersId; + n = n->GetParent()) { + if (n->GetApzc()) { + return n->GetApzc(); + } + } + return nullptr; +} + bool HitTestingTreeNode::IsPrimaryHolder() const { diff --git a/gfx/layers/apz/src/HitTestingTreeNode.h b/gfx/layers/apz/src/HitTestingTreeNode.h index d27578fd2998..33b3db74af1d 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.h +++ b/gfx/layers/apz/src/HitTestingTreeNode.h @@ -76,6 +76,7 @@ public: AsyncPanZoomController* GetApzc() const; AsyncPanZoomController* GetNearestContainingApzc() const; + AsyncPanZoomController* GetNearestContainingApzcWithSameLayersId() const; bool IsPrimaryHolder() const; /* Hit test related methods */ From 17048184a50f2684ecc52039fc1b2fe822131149 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sun, 31 May 2015 14:44:41 -0500 Subject: [PATCH 43/85] Bug 1168630. Part 3. Add IsLayersIdRoot to frame metrics. r=botond This field tells us if this frame metrics should be considered the root APZC for its layers id. Without this there doesn't seem to be a way to compute this from just the layers tree. --- gfx/ipc/GfxMessageUtils.h | 2 ++ gfx/layers/FrameMetrics.h | 15 ++++++++++++++- gfx/layers/apz/src/AsyncPanZoomController.cpp | 1 + layout/base/nsLayoutUtils.cpp | 7 +++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index e8df05d23755..d46c76495981 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -733,6 +733,7 @@ struct ParamTraits WriteParam(aMsg, aParam.GetPageScrollAmount()); WriteParam(aMsg, aParam.AllowVerticalScrollWithWheel()); WriteParam(aMsg, aParam.mClipRect); + WriteParam(aMsg, aParam.mIsLayersIdRoot); WriteParam(aMsg, aParam.GetContentDescription()); } @@ -776,6 +777,7 @@ struct ParamTraits ReadParam(aMsg, aIter, &aResult->mPageScrollAmount) && ReadParam(aMsg, aIter, &aResult->mAllowVerticalScrollWithWheel) && ReadParam(aMsg, aIter, &aResult->mClipRect) && + ReadParam(aMsg, aIter, &aResult->mIsLayersIdRoot) && ReadContentDescription(aMsg, aIter, aResult)); } }; diff --git a/gfx/layers/FrameMetrics.h b/gfx/layers/FrameMetrics.h index 319d0dfaac80..68696b84ddcc 100644 --- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -67,6 +67,7 @@ public: , mLineScrollAmount(0, 0) , mPageScrollAmount(0, 0) , mAllowVerticalScrollWithWheel(false) + , mIsLayersIdRoot(false) { } @@ -100,7 +101,8 @@ public: mLineScrollAmount == aOther.mLineScrollAmount && mPageScrollAmount == aOther.mPageScrollAmount && mAllowVerticalScrollWithWheel == aOther.mAllowVerticalScrollWithWheel && - mClipRect == aOther.mClipRect; + mClipRect == aOther.mClipRect && + mIsLayersIdRoot == aOther.mIsLayersIdRoot; } bool operator!=(const FrameMetrics& aOther) const { @@ -525,6 +527,13 @@ public: return mClipRect.ref(); } + void SetIsLayersIdRoot(bool aValue) { + mIsLayersIdRoot = aValue; + } + bool IsLayersIdRoot() const { + return mIsLayersIdRoot; + } + private: // The pres-shell resolution that has been induced on the document containing @@ -699,6 +708,10 @@ private: // The clip rect to use when compositing a layer with this FrameMetrics. Maybe mClipRect; + // Whether these framemetrics are for the root scroll frame (root element if + // we don't have a root scroll frame) for its layers id. + bool mIsLayersIdRoot; + // WARNING!!!! // // When adding new fields to FrameMetrics, the following places should be diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index df9ffbf0d869..d7d9d5852caa 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -2900,6 +2900,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri mFrameMetrics.SetLineScrollAmount(aLayerMetrics.GetLineScrollAmount()); mFrameMetrics.SetPageScrollAmount(aLayerMetrics.GetPageScrollAmount()); mFrameMetrics.SetClipRect(aLayerMetrics.GetClipRect()); + mFrameMetrics.SetIsLayersIdRoot(aLayerMetrics.IsLayersIdRoot()); if (scrollOffsetUpdated) { APZC_LOG("%p updating scroll offset from %s to %s\n", this, diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index fd5dd6936674..db0519b6e67e 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -8229,6 +8229,13 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame, metrics.SetIsRoot(aIsRoot); metrics.SetScrollParentId(aScrollParentId); + if (scrollId != FrameMetrics::NULL_SCROLL_ID && !presContext->GetParentPresContext()) { + if ((aScrollFrame && (aScrollFrame == presShell->GetRootScrollFrame())) || + aContent == presShell->GetDocument()->GetDocumentElement()) { + metrics.SetIsLayersIdRoot(true); + } + } + // Only the root scrollable frame for a given presShell should pick up // the presShell's resolution. All the other frames are 1.0. if (aScrollFrame == presShell->GetRootScrollFrame()) { From 367081293739c73f350c41c14343c1548feb413d Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sun, 31 May 2015 14:44:41 -0500 Subject: [PATCH 44/85] Bug 1168630. Part 4. Rename AsyncPanZoomController::IsRootForLayersId to HasNoParentWithSameLayersId. r=botond The function did not tell you if the APZC was the root for the layers id. It just told you if it had no parent. Which are different things. Since IsRootForLayersId didn't do what it was expected to, the users of HasNoParentWithSameLayersId will be audited and then removed or changed to be correct by bug 1158424. --- gfx/layers/apz/src/APZCTreeManager.cpp | 16 ++++++++-------- gfx/layers/apz/src/AsyncPanZoomController.h | 5 +++-- gfx/layers/apz/test/apz_test_utils.js | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 786ec5ec494a..d193d851468b 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -453,9 +453,9 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, // we are logging about APZCs is the scroll id, and otherwise we could // confuse APZCs from different layer trees with the same scroll id. if (aLayersId == aState.mOriginatingLayersId) { - if (apzc->IsRootForLayersId()) { + if (apzc->HasNoParentWithSameLayersId()) { aState.mPaintLogger.LogTestData(aMetrics.GetScrollId(), - "isRootForLayersId", true); + "hasNoParentWithSameLayersId", true); } else { MOZ_ASSERT(apzc->GetParent()); aState.mPaintLogger.LogTestData(aMetrics.GetScrollId(), @@ -464,7 +464,7 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, } if (newApzc) { - if (apzc->IsRootForLayersId()) { + if (apzc->HasNoParentWithSameLayersId()) { // If we just created a new apzc that is the root for its layers ID, then // we need to update its zoom constraints which might have arrived before this // was created @@ -1040,7 +1040,7 @@ APZCTreeManager::UpdateZoomConstraints(const ScrollableLayerGuid& aGuid, // For a given layers id, non-root APZCs inherit the zoom constraints // of their root. - if (node && node->GetApzc()->IsRootForLayersId()) { + if (node && node->GetApzc()->HasNoParentWithSameLayersId()) { UpdateZoomConstraintsRecursively(node.get(), aConstraints); } } @@ -1057,7 +1057,7 @@ APZCTreeManager::UpdateZoomConstraintsRecursively(HitTestingTreeNode* aNode, } for (HitTestingTreeNode* child = aNode->GetLastChild(); child; child = child->GetPrevSibling()) { // We can have subtrees with their own layers id - leave those alone. - if (child->GetApzc() && child->GetApzc()->IsRootForLayersId()) { + if (child->GetApzc() && child->GetApzc()->HasNoParentWithSameLayersId()) { continue; } UpdateZoomConstraintsRecursively(child, aConstraints); @@ -1344,7 +1344,7 @@ APZCTreeManager::BuildOverscrollHandoffChain(const nsRefPtrAdd(apzc); if (apzc->GetScrollHandoffParentId() == FrameMetrics::NULL_SCROLL_ID) { - if (!apzc->IsRootForLayersId()) { + if (!apzc->HasNoParentWithSameLayersId()) { // This probably indicates a bug or missed case in layout code NS_WARNING("Found a non-root APZ with no handoff parent"); } @@ -1362,7 +1362,7 @@ APZCTreeManager::BuildOverscrollHandoffChain(const nsRefPtrIsRootForLayersId()) { + while (!parent->HasNoParentWithSameLayersId()) { parent = parent->GetParent(); // While walking up to find the root of the subtree, if we encounter the // handoff parent, we don't actually need to do the search so we can @@ -1705,7 +1705,7 @@ APZCTreeManager::RootAPZCForLayersId(AsyncPanZoomController* aApzc) const { MonitorAutoLock lock(mTreeLock); nsRefPtr apzc = aApzc; - while (apzc && !apzc->IsRootForLayersId()) { + while (apzc && !apzc->HasNoParentWithSameLayersId()) { apzc = apzc->GetParent(); } return apzc.forget(); diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index 0f3f17c474e9..691f297cec46 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -899,9 +899,10 @@ public: } /* Returns true if there is no APZC higher in the tree with the same - * layers id. + * layers id. Deprecated. New code shouldn't use this. Old code should be + * updated to not use this. */ - bool IsRootForLayersId() const { + bool HasNoParentWithSameLayersId() const { return !mParent || (mParent->mLayersId != mLayersId); } diff --git a/gfx/layers/apz/test/apz_test_utils.js b/gfx/layers/apz/test/apz_test_utils.js index a4ae85ce5a8e..834afd8970e5 100644 --- a/gfx/layers/apz/test/apz_test_utils.js +++ b/gfx/layers/apz/test/apz_test_utils.js @@ -91,7 +91,7 @@ function buildApzcTree(paint) { // This 'root' does not correspond to an APZC. var root = makeNode(-1); for (var scrollId in paint) { - if ("isRootForLayersId" in paint[scrollId]) { + if ("hasNoParentWithSameLayersId" in paint[scrollId]) { addRoot(root, scrollId); } else if ("parentScrollId" in paint[scrollId]) { addLink(root, scrollId, paint[scrollId]["parentScrollId"]); From a86398c9d585594bda29c7195ff5b604c58ce723 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sun, 31 May 2015 14:44:41 -0500 Subject: [PATCH 45/85] Bug 1168630. Part 5. If GetAPZCAtPoint hit a layer but did not find an APZC on the ancestor chain with the same layers id then return the root APZC of the same layers id. r=botond This requires use to search the hit testing tree to find the root APZC (which we require to be there). --- gfx/layers/apz/src/APZCTreeManager.cpp | 33 +++++++++++++++++++++ gfx/layers/apz/src/APZCTreeManager.h | 1 + gfx/layers/apz/src/AsyncPanZoomController.h | 5 ++++ gfx/layers/apz/src/HitTestingTreeNode.cpp | 6 ++++ gfx/layers/apz/src/HitTestingTreeNode.h | 1 + 5 files changed, 46 insertions(+) diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index d193d851468b..054648e285ef 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -1463,6 +1463,10 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode, HitTestResult hitResult = node->HitTest(aHitTestPoint); if (hitResult != HitTestResult::HitNothing) { result = node->GetNearestContainingApzcWithSameLayersId(); + if (!result) { + result = FindRootApzcForLayersId(node->GetLayersId()); + MOZ_ASSERT(result); + } APZCTM_LOG("Successfully matched APZC %p via node %p (hit result %d)\n", result, node, hitResult); MOZ_ASSERT(hitResult == HitLayer || hitResult == HitDispatchToContentRegion); @@ -1479,6 +1483,35 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode, return nullptr; } +AsyncPanZoomController* +APZCTreeManager::FindRootApzcForLayersId(uint64_t aLayersId) const +{ + mTreeLock.AssertCurrentThreadOwns(); + + if (!mRootNode) { + return nullptr; + } + std::deque queue; + queue.push_back(mRootNode); + while (!queue.empty()) { + const HitTestingTreeNode* node = queue.front(); + queue.pop_front(); + + AsyncPanZoomController* apzc = node->GetApzc(); + if (apzc && apzc->GetLayersId() == aLayersId && apzc->IsRootForLayersId()) { + return apzc; + } + + for (HitTestingTreeNode* child = node->GetLastChild(); + child; + child = child->GetPrevSibling()) { + queue.push_back(child); + } + } + + return nullptr; +} + /* The methods GetScreenToApzcTransform() and GetApzcToGeckoTransform() return some useful transformations that input events may need applied. This is best illustrated with an example. Consider a chain of layers, L, M, N, O, P, Q, R. Layer L diff --git a/gfx/layers/apz/src/APZCTreeManager.h b/gfx/layers/apz/src/APZCTreeManager.h index 6dc2f1b71f83..cd4707a23d93 100644 --- a/gfx/layers/apz/src/APZCTreeManager.h +++ b/gfx/layers/apz/src/APZCTreeManager.h @@ -412,6 +412,7 @@ private: AsyncPanZoomController* GetAPZCAtPoint(HitTestingTreeNode* aNode, const ParentLayerPoint& aHitTestPoint, HitTestResult* aOutHitResult); + AsyncPanZoomController* FindRootApzcForLayersId(uint64_t aLayersId) const; already_AddRefed GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const; already_AddRefed CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const; already_AddRefed RootAPZCForLayersId(AsyncPanZoomController* aApzc) const; diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index 691f297cec46..01ebb1a168f9 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -906,6 +906,11 @@ public: return !mParent || (mParent->mLayersId != mLayersId); } + bool IsRootForLayersId() const { + ReentrantMonitorAutoEnter lock(mMonitor); + return mFrameMetrics.IsLayersIdRoot(); + } + private: // This is a raw pointer to avoid introducing a reference cycle between // AsyncPanZoomController and APZCTreeManager. Since these objects don't diff --git a/gfx/layers/apz/src/HitTestingTreeNode.cpp b/gfx/layers/apz/src/HitTestingTreeNode.cpp index 31d1380bb334..9a8693d49fd8 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.cpp +++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp @@ -174,6 +174,12 @@ HitTestingTreeNode::IsPrimaryHolder() const return mIsPrimaryApzcHolder; } +uint64_t +HitTestingTreeNode::GetLayersId() const +{ + return mLayersId; +} + void HitTestingTreeNode::SetHitTestData(const EventRegions& aRegions, const gfx::Matrix4x4& aTransform, diff --git a/gfx/layers/apz/src/HitTestingTreeNode.h b/gfx/layers/apz/src/HitTestingTreeNode.h index 33b3db74af1d..08f1195681b5 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.h +++ b/gfx/layers/apz/src/HitTestingTreeNode.h @@ -78,6 +78,7 @@ public: AsyncPanZoomController* GetNearestContainingApzc() const; AsyncPanZoomController* GetNearestContainingApzcWithSameLayersId() const; bool IsPrimaryHolder() const; + uint64_t GetLayersId() const; /* Hit test related methods */ From ae72b1ab27fe773b328467ccad75d9d446e6ca75 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sun, 31 May 2015 14:44:41 -0500 Subject: [PATCH 46/85] Bug 1168630. Part 6. Modify the test for bug 1119497 based on the new assumption of always having a root APZC. r=botond Part 5 adds an assert that we always return an APZC from GetAPZCAtPoint. The test for bug 1119497 fails this assumption because it does not give it's layer tree a root AZPC. In all non-test code we ensure that there is always a root APZC and many things would break without such. So we modify the test to always have a root APZC more like actual code. The test is testing that we don't return the layer below (with an APZC) the topmost child layer (without an APZC). So checking if we hit the root APZC still makes the test test the same thing. --- gfx/tests/gtest/TestAsyncPanZoomController.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index 7746fb22abf6..d53764a78dd8 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -1894,6 +1894,10 @@ protected: CSSRect aScrollableRect = CSSRect(-1, -1, -1, -1)) { FrameMetrics metrics; metrics.SetScrollId(aScrollId); + // By convention in this test file, START_SCROLL_ID is the root, so mark it as such. + if (aScrollId == FrameMetrics::START_SCROLL_ID) { + metrics.SetIsLayersIdRoot(true); + } IntRect layerBound = aLayer->GetVisibleRegion().GetBounds(); metrics.SetCompositionBounds(ParentLayerRect(layerBound.x, layerBound.y, layerBound.width, layerBound.height)); @@ -2864,9 +2868,10 @@ protected: void CreateBug1119497LayerTree() { const char* layerTreeSyntax = "c(tt)"; // LayerID 0 12 - // 0 is the root and doesn't have an APZC - // 1 is behind 2 and does have an APZC - // 2 entirely covers 1 and should take all the input events + // 0 is the root and has an APZC + // 1 is behind 2 and has an APZC + // 2 entirely covers 1 and should take all the input events, but has no APZC + // so hits to 2 should go to to the root APZC nsIntRegion layerVisibleRegions[] = { nsIntRegion(IntRect(0, 0, 100, 100)), nsIntRegion(IntRect(0, 0, 100, 100)), @@ -2874,6 +2879,7 @@ protected: }; root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers); + SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID); SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1); registration = MakeUnique(0, root, mcc); @@ -3006,8 +3012,8 @@ TEST_F(APZEventRegionsTester, Bug1119497) { HitTestResult result; nsRefPtr hit = manager->GetTargetAPZC(ScreenPoint(50, 50), &result); // We should hit layers[2], so |result| will be HitLayer but there's no - // actual APZC in that parent chain, so |hit| should be nullptr. - EXPECT_EQ(nullptr, hit.get()); + // actual APZC on layers[2], so it will be the APZC of the root layer. + EXPECT_EQ(ApzcOf(layers[0]), hit.get()); EXPECT_EQ(HitTestResult::HitLayer, result); } From cdd4b3ca80b1b2d8852a8a726e2f076d69ee3ead Mon Sep 17 00:00:00 2001 From: Morgan Phillips Date: Fri, 29 May 2015 19:54:39 +0200 Subject: [PATCH 47/85] Bug 1155749 - Enable Linux64 Opt builds from Try; r=dustin --- .../tasks/branches/base_job_flags.yml | 1 + .../tasks/branches/try/job_flags.yml | 6 +++ .../taskcluster/tasks/builds/opt_linux64.yml | 53 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 testing/taskcluster/tasks/builds/opt_linux64.yml diff --git a/testing/taskcluster/tasks/branches/base_job_flags.yml b/testing/taskcluster/tasks/branches/base_job_flags.yml index f08738d64a4f..e1abe7c62f10 100644 --- a/testing/taskcluster/tasks/branches/base_job_flags.yml +++ b/testing/taskcluster/tasks/branches/base_job_flags.yml @@ -27,6 +27,7 @@ flags: - aries-ota - aries-eng - android-api-11 + - linux64 tests: - cppunit diff --git a/testing/taskcluster/tasks/branches/try/job_flags.yml b/testing/taskcluster/tasks/branches/try/job_flags.yml index 686431667569..bdbe6498dbdd 100644 --- a/testing/taskcluster/tasks/branches/try/job_flags.yml +++ b/testing/taskcluster/tasks/branches/try/job_flags.yml @@ -122,6 +122,12 @@ builds: types: opt: task: tasks/builds/android_api_11.yml + linux64: + platforms: + - Opt Linux64 + types: + opt: + task: tasks/builds/opt_linux64.yml tests: cppunit: diff --git a/testing/taskcluster/tasks/builds/opt_linux64.yml b/testing/taskcluster/tasks/builds/opt_linux64.yml new file mode 100644 index 000000000000..fed5177c029e --- /dev/null +++ b/testing/taskcluster/tasks/builds/opt_linux64.yml @@ -0,0 +1,53 @@ +$inherits: + from: 'tasks/build.yml' + variables: + build_name: 'linux64' + build_type: 'opt' +task: + metadata: + name: '[TC] Linux64 Opt' + description: 'Linux64 Opt' + + workerType: b2g-desktop-opt + + routes: + - 'index.buildbot.branches.{{project}}.linux64' + - 'index.buildbot.revisions.{{head_rev}}.{{project}}.linux64' + + scopes: + - 'docker-worker:cache:build-linux64-workspace' + - 'docker-worker:cache:tooltool-cache' + + payload: + image: '{{#docker_image}}desktop-build{{/docker_image}}' + cache: + build-linux64-workspace: '/home/worker/workspace' + tooltool-cache: '/home/worker/tooltool-cache' + + env: + MOZHARNESS_SCRIPT: 'mozharness/scripts/fx_desktop_build.py' + MOZHARNESS_CONFIG: 'builds/releng_base_linux_64_builds.py balrog/production.py disable_sendchange.py' + MH_BRANCH: {{project}} + MH_BUILD_POOL: taskcluster + # image paths + TOOLTOOL_CACHE: '/home/worker/tooltool-cache' + RELENGAPI_TOKEN: 'TODO' # 1164612: encrypt this secret + + maxRunTime: 36000 + + command: ["/bin/bash", "bin/build.sh"] + + extra: + treeherderEnv: + - production + - staging + treeherder: + machine: + # see https://github.com/mozilla/treeherder/blob/master/ui/js/values.js + platform: linux64 + # Rather then enforcing particular conventions we require that all build + # tasks provide the "build" extra field to specify where the build and tests + # files are located. + locations: + build: 'public/build/target.linux-x86_64.tar.bz2' + tests: 'public/build/target.tests.zip' From 9cbd0f19204acca3fa650f053427ea6154a60f05 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Sun, 31 May 2015 17:28:44 -0500 Subject: [PATCH 48/85] Bug 1148582. Part 3 follow up. Properly test if a scroll frame uses async scrolling when determining if it needs its clip put on its layer. r=mstange Android (without APZ) only uses async scrolling on the root scroll frame of the root content doc. --- layout/generic/nsGfxScrollFrame.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 7e2ef310fdc7..db7c1cadfff8 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -3092,7 +3092,15 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer, parentLayerClip = Some(clip); } - if (!gfxPrefs::AsyncPanZoomEnabled()) { + bool thisScrollFrameUsesAsyncScrolling = nsLayoutUtils::UsesAsyncScrolling(); +#if defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_ANDROID_APZ) + // Android without apzc (aka the java pan zoom code) only uses async scrolling + // for the root scroll frame of the root content document. + if (!isRoot) { + thisScrollFrameUsesAsyncScrolling = false; + } +#endif + if (!thisScrollFrameUsesAsyncScrolling) { if (parentLayerClip) { // If APZ is not enabled, we still need the displayport to be clipped // in the compositor. From b81b9d9003d40615f3a6ad8fc8cd00d52c8d38bb Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 18 May 2015 20:48:21 -0700 Subject: [PATCH 49/85] Bug 1168007 (part 5) - Use PLDHashTable2 in nsTemplateMap. r=froydnj. --HG-- extra : rebase_source : 567f4b62fb905660318158df59dd345e58ae0976 --- dom/xul/templates/nsTemplateMap.h | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/dom/xul/templates/nsTemplateMap.h b/dom/xul/templates/nsTemplateMap.h index 71203f559746..25cc01481deb 100644 --- a/dom/xul/templates/nsTemplateMap.h +++ b/dom/xul/templates/nsTemplateMap.h @@ -16,21 +16,12 @@ protected: nsIContent* mTemplate; }; - PLDHashTable mTable; - - void - Init() - { - PL_DHashTableInit(&mTable, PL_DHashGetStubOps(), sizeof(Entry)); - } - - void - Finish() { PL_DHashTableFinish(&mTable); } + PLDHashTable2 mTable; public: - nsTemplateMap() { Init(); } + nsTemplateMap() : mTable(PL_DHashGetStubOps(), sizeof(Entry)) { } - ~nsTemplateMap() { Finish(); } + ~nsTemplateMap() { } void Put(nsIContent* aContent, nsIContent* aTemplate) { @@ -70,7 +61,7 @@ public: } void - Clear() { Finish(); Init(); } + Clear() { mTable.Clear(); } }; #endif // nsTemplateMap_h__ From 58ee0c69e5f50b7aa88c7343272da581cb7f663e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 18 May 2015 21:02:48 -0700 Subject: [PATCH 50/85] Bug 1168007 (part 6) - Use PLDHashTable2 in nsSecureBrowserUIImpl. r=froydnj. --HG-- extra : rebase_source : fe8f14d5caf24931bace563518b7541beb838074 --- security/manager/ssl/nsSecureBrowserUIImpl.cpp | 15 +++------------ security/manager/ssl/nsSecureBrowserUIImpl.h | 4 ++-- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/security/manager/ssl/nsSecureBrowserUIImpl.cpp b/security/manager/ssl/nsSecureBrowserUIImpl.cpp index 0f542990fd05..441d98e5bbca 100644 --- a/security/manager/ssl/nsSecureBrowserUIImpl.cpp +++ b/security/manager/ssl/nsSecureBrowserUIImpl.cpp @@ -111,20 +111,14 @@ nsSecureBrowserUIImpl::nsSecureBrowserUIImpl() #ifdef DEBUG , mOnStateLocationChangeReentranceDetection(0) #endif + , mTransferringRequests(&gMapOps, sizeof(RequestHashEntry)) { ResetStateTracking(); - + if (!gSecureDocLog) gSecureDocLog = PR_NewLogModule("nsSecureBrowserUI"); } -nsSecureBrowserUIImpl::~nsSecureBrowserUIImpl() -{ - if (mTransferringRequests.IsInitialized()) { - PL_DHashTableFinish(&mTransferringRequests); - } -} - NS_IMPL_ISUPPORTS(nsSecureBrowserUIImpl, nsISecureBrowserUI, nsIWebProgressListener, @@ -379,10 +373,7 @@ void nsSecureBrowserUIImpl::ResetStateTracking() ReentrantMonitorAutoEnter lock(mReentrantMonitor); mDocumentRequestsInProgress = 0; - if (mTransferringRequests.IsInitialized()) { - PL_DHashTableFinish(&mTransferringRequests); - } - PL_DHashTableInit(&mTransferringRequests, &gMapOps, sizeof(RequestHashEntry)); + mTransferringRequests.Clear(); } void diff --git a/security/manager/ssl/nsSecureBrowserUIImpl.h b/security/manager/ssl/nsSecureBrowserUIImpl.h index 4dd0792b6ed2..8432270901b1 100644 --- a/security/manager/ssl/nsSecureBrowserUIImpl.h +++ b/security/manager/ssl/nsSecureBrowserUIImpl.h @@ -48,7 +48,7 @@ public: NS_DECL_NSISSLSTATUSPROVIDER protected: - virtual ~nsSecureBrowserUIImpl(); + virtual ~nsSecureBrowserUIImpl() {}; mozilla::ReentrantMonitor mReentrantMonitor; @@ -100,7 +100,7 @@ protected: nsCOMPtr mSSLStatus; nsCOMPtr mCurrentToplevelSecurityInfo; - PLDHashTable mTransferringRequests; + PLDHashTable2 mTransferringRequests; }; From df91e412ac6b008b3399cde9da78b9f5186dbedb Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 18 May 2015 21:14:51 -0700 Subject: [PATCH 51/85] Bug 1168007 (part 7) - Use PLDHashTable2 in nsCertTree. r=froydnj. It's possible that Clear() will be called on a table that hasn't had anything inserted in it, but that's ok. --HG-- extra : rebase_source : 454a79d9ec0fbf8d82706c12535c5862fe687cba --- security/manager/ssl/nsCertTree.cpp | 33 +++++++++++------------------ security/manager/ssl/nsCertTree.h | 5 +++-- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/security/manager/ssl/nsCertTree.cpp b/security/manager/ssl/nsCertTree.cpp index 7610ce399411..0085c492213a 100644 --- a/security/manager/ssl/nsCertTree.cpp +++ b/security/manager/ssl/nsCertTree.cpp @@ -149,7 +149,10 @@ nsCertTreeDispInfo::GetHostPort(nsAString &aHostPort) NS_IMPL_ISUPPORTS(nsCertTree, nsICertTree, nsITreeView) -nsCertTree::nsCertTree() : mTreeArray(nullptr) +nsCertTree::nsCertTree() + : mTreeArray(nullptr) + , mCompareCache(&gMapOps, sizeof(CompareCacheHashEntryPtr), + kInitialCacheLength) { static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); @@ -165,22 +168,11 @@ nsCertTree::nsCertTree() : mTreeArray(nullptr) void nsCertTree::ClearCompareHash() { - if (mCompareCache.IsInitialized()) { - PL_DHashTableFinish(&mCompareCache); - } -} - -nsresult nsCertTree::InitCompareHash() -{ - ClearCompareHash(); - PL_DHashTableInit(&mCompareCache, &gMapOps, - sizeof(CompareCacheHashEntryPtr), 64); - return NS_OK; + mCompareCache.ClearAndPrepareForLength(kInitialCacheLength); } nsCertTree::~nsCertTree() { - ClearCompareHash(); delete [] mTreeArray; } @@ -661,11 +653,11 @@ nsCertTree::LoadCertsFromCache(nsIX509CertList *aCache, uint32_t aType) mTreeArray = nullptr; mNumRows = 0; } - nsresult rv = InitCompareHash(); - if (NS_FAILED(rv)) return rv; + ClearCompareHash(); - rv = GetCertsByTypeFromCache(aCache, aType, - GetCompareFuncFromCertType(aType), &mCompareCache); + nsresult rv = GetCertsByTypeFromCache(aCache, aType, + GetCompareFuncFromCertType(aType), + &mCompareCache); if (NS_FAILED(rv)) return rv; return UpdateUIContents(); } @@ -679,11 +671,10 @@ nsCertTree::LoadCerts(uint32_t aType) mTreeArray = nullptr; mNumRows = 0; } - nsresult rv = InitCompareHash(); - if (NS_FAILED(rv)) return rv; + ClearCompareHash(); - rv = GetCertsByType(aType, - GetCompareFuncFromCertType(aType), &mCompareCache); + nsresult rv = GetCertsByType(aType, GetCompareFuncFromCertType(aType), + &mCompareCache); if (NS_FAILED(rv)) return rv; return UpdateUIContents(); } diff --git a/security/manager/ssl/nsCertTree.h b/security/manager/ssl/nsCertTree.h index e9518e3682cc..419e7b020fe9 100644 --- a/security/manager/ssl/nsCertTree.h +++ b/security/manager/ssl/nsCertTree.h @@ -90,7 +90,6 @@ public: protected: virtual ~nsCertTree(); - nsresult InitCompareHash(); void ClearCompareHash(); void RemoveCacheEntry(void *key); @@ -117,13 +116,15 @@ protected: nsresult GetCertsByTypeFromCache(nsIX509CertList *aCache, uint32_t aType, nsCertCompareFunc aCertCmpFn, void *aCertCmpFnArg); private: + static const uint32_t kInitialCacheLength = 64; + nsTArray< mozilla::RefPtr > mDispInfo; nsCOMPtr mTree; nsCOMPtr mSelection; treeArrayEl *mTreeArray; int32_t mNumOrgs; int32_t mNumRows; - PLDHashTable mCompareCache; + PLDHashTable2 mCompareCache; nsCOMPtr mNSSComponent; nsCOMPtr mOverrideService; mozilla::RefPtr mOriginalOverrideService; From 1a3aaea52dbb81953b3ea797d530a7db4f00d03e Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 6 May 2015 15:35:35 -0400 Subject: [PATCH 52/85] Bug 1091112 - Serialize nsIPrintSettings options bitfield. r=jimm --HG-- extra : commitid : Dms9DmIQc6x extra : rebase_source : 28597e8eb3c7c9e11bf26f611dae21ff96fad968 --- embedding/components/printingui/ipc/PPrintingTypes.ipdlh | 1 + widget/nsIPrintSettings.idl | 9 +++++++-- widget/nsPrintOptionsImpl.cpp | 4 ++++ widget/nsPrintSettingsImpl.cpp | 9 ++++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/embedding/components/printingui/ipc/PPrintingTypes.ipdlh b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh index 4540ef2fbf3a..1ac9c7f4cbff 100644 --- a/embedding/components/printingui/ipc/PPrintingTypes.ipdlh +++ b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh @@ -72,6 +72,7 @@ struct PrintData { bool isInitializedFromPrinter; bool isInitializedFromPrefs; bool persistMarginBoxSettings; + int32_t optionFlags; /* Windows-specific things */ nsString driverName; diff --git a/widget/nsIPrintSettings.idl b/widget/nsIPrintSettings.idl index b57100959617..723dada0f5f7 100644 --- a/widget/nsIPrintSettings.idl +++ b/widget/nsIPrintSettings.idl @@ -22,7 +22,7 @@ interface nsIPrintSession; /** * Simplified graphics interface for JS rendering. */ -[scriptable, uuid(1bcfc611-8941-4c39-9e06-7116e564a1ce)] +[scriptable, uuid(11b86b46-12c9-4e63-8023-129dd239ace7)] interface nsIPrintSettings : nsISupports { @@ -137,10 +137,15 @@ interface nsIPrintSettings : nsISupports boolean GetPrintOptions(in int32_t aType); /** - * Set PrintOptions Bit field + * Get PrintOptions Bit field */ int32_t GetPrintOptionsBits(); + /** + * Set PrintOptions Bit field + */ + void SetPrintOptionsBits(in int32_t bits); + /** * Get the page size in twips, considering the * orientation (portrait or landscape). diff --git a/widget/nsPrintOptionsImpl.cpp b/widget/nsPrintOptionsImpl.cpp index f70d93595f5f..371adf94b0dc 100644 --- a/widget/nsPrintOptionsImpl.cpp +++ b/widget/nsPrintOptionsImpl.cpp @@ -223,6 +223,8 @@ nsPrintOptions::SerializeToPrintData(nsIPrintSettings* aSettings, aSettings->GetIsInitializedFromPrefs(&data->isInitializedFromPrefs()); aSettings->GetPersistMarginBoxSettings(&data->persistMarginBoxSettings()); + aSettings->GetPrintOptionsBits(&data->optionFlags()); + // Initialize the platform-specific values that don't // default-initialize, so that we don't send uninitialized data over // IPC (which leads to valgrind warnings, and, for bools, fatal @@ -324,6 +326,8 @@ nsPrintOptions::DeserializeToPrintSettings(const PrintData& data, settings->SetIsInitializedFromPrefs(data.isInitializedFromPrefs()); settings->SetPersistMarginBoxSettings(data.persistMarginBoxSettings()); + settings->SetPrintOptionsBits(data.optionFlags()); + return NS_OK; } diff --git a/widget/nsPrintSettingsImpl.cpp b/widget/nsPrintSettingsImpl.cpp index 9a24706fca8a..c4ab73f3251c 100644 --- a/widget/nsPrintSettingsImpl.cpp +++ b/widget/nsPrintSettingsImpl.cpp @@ -693,7 +693,7 @@ nsPrintSettings::SetPrintOptions(int32_t aType, bool aTurnOnOff) * See documentation in nsPrintSettingsImpl.h * @update 1/12/01 rods */ -NS_IMETHODIMP +NS_IMETHODIMP nsPrintSettings::GetPrintOptionsBits(int32_t *aBits) { NS_ENSURE_ARG_POINTER(aBits); @@ -701,6 +701,13 @@ nsPrintSettings::GetPrintOptionsBits(int32_t *aBits) return NS_OK; } +NS_IMETHODIMP +nsPrintSettings::SetPrintOptionsBits(int32_t aBits) +{ + mPrintOptions = aBits; + return NS_OK; +} + /* attribute wstring docTitle; */ nsresult nsPrintSettings::GetMarginStrs(char16_t * *aTitle, From 1a81ee823931e796809e399c735119f688d2c7df Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 6 May 2015 14:09:08 -0400 Subject: [PATCH 53/85] Bug 1091112 - Add OS X-specific members to PrintData IPDL struct. r=jimm --HG-- extra : commitid : Dr2MlrmVcdg extra : rebase_source : 886e4fcae950fd46b51aad1b8f5e5fa47bdbeaa6 --- .../printingui/ipc/PPrintingTypes.ipdlh | 15 +++++++++++++-- widget/nsPrintOptionsImpl.cpp | 11 +++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/embedding/components/printingui/ipc/PPrintingTypes.ipdlh b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh index 1ac9c7f4cbff..f178906375d2 100644 --- a/embedding/components/printingui/ipc/PPrintingTypes.ipdlh +++ b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh @@ -92,9 +92,20 @@ struct PrintData { CStringKeyValue[] GTKPrintSettings; /** - * TODO: OS X specific things - specifically, an array of names for the - * document to be supplied by nsIWebBrowserPrint::enumerateDocumentNames + * OS X specific things. */ + nsString printJobName; + bool printAllPages; + bool mustCollate; + nsString disposition; + /** TODO: Is there an "unsigned short" primitive? **/ + short pagesAcross; + short pagesDown; + nsString printTime; + bool detailedErrorReporting; + nsString faxNumber; + bool addHeaderAndFooter; + bool fileNameExtensionHidden; }; } // namespace embedding diff --git a/widget/nsPrintOptionsImpl.cpp b/widget/nsPrintOptionsImpl.cpp index 371adf94b0dc..334af5b965fe 100644 --- a/widget/nsPrintOptionsImpl.cpp +++ b/widget/nsPrintOptionsImpl.cpp @@ -236,6 +236,17 @@ nsPrintOptions::SerializeToPrintData(nsIPrintSettings* aSettings, data->isIFrameSelected() = false; data->isRangeSelection() = false; // data->GTKPrintSettings() default-initializes + // data->printJobName() default-initializes + data->printAllPages() = true; + data->mustCollate() = false; + // data->disposition() default-initializes + data->pagesAcross() = 1; + data->pagesDown() = 1; + // data->printTime() default-initializes + data->detailedErrorReporting() = true; + // data->faxNumber() default-initializes + data->addHeaderAndFooter() = false; + data->fileNameExtensionHidden() = false; return NS_OK; } From a1d6a9cf9c9209bc5e1942fb90d4bf1e9ac21569 Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 6 May 2015 14:10:21 -0400 Subject: [PATCH 54/85] Bug 1091112 - Proxy opening the print dialog on OS X to the parent. r=mstange --HG-- extra : commitid : JRKXD6lod1d extra : rebase_source : b2bfa7c4f750852c0654367708cc4f0a6c607a24 extra : histedit_source : f0da46869101dc23b8d6b654416298951b078ccb --- embedding/components/build/moz.build | 1 + .../printingui/ipc/PPrintingTypes.ipdlh | 2 +- .../printingui/ipc/PrintDataUtils.cpp | 18 +- widget/cocoa/nsPrintDialogX.mm | 9 +- widget/cocoa/nsPrintOptionsX.h | 15 ++ widget/cocoa/nsPrintOptionsX.mm | 206 ++++++++++++++++++ widget/cocoa/nsPrintSettingsX.mm | 5 +- widget/nsPrintOptionsImpl.cpp | 2 +- 8 files changed, 252 insertions(+), 6 deletions(-) diff --git a/embedding/components/build/moz.build b/embedding/components/build/moz.build index 1108b5ceb57c..2412e7d1dd31 100644 --- a/embedding/components/build/moz.build +++ b/embedding/components/build/moz.build @@ -26,6 +26,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': '../printingui/win', ] elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': + DEFINES['PROXY_PRINTING'] = 1 LOCAL_INCLUDES += [ '../printingui/mac', ] diff --git a/embedding/components/printingui/ipc/PPrintingTypes.ipdlh b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh index f178906375d2..a382bf9abbfc 100644 --- a/embedding/components/printingui/ipc/PPrintingTypes.ipdlh +++ b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh @@ -101,7 +101,7 @@ struct PrintData { /** TODO: Is there an "unsigned short" primitive? **/ short pagesAcross; short pagesDown; - nsString printTime; + double printTime; bool detailedErrorReporting; nsString faxNumber; bool addHeaderAndFooter; diff --git a/embedding/components/printingui/ipc/PrintDataUtils.cpp b/embedding/components/printingui/ipc/PrintDataUtils.cpp index 8afd4d739567..3c121895d376 100644 --- a/embedding/components/printingui/ipc/PrintDataUtils.cpp +++ b/embedding/components/printingui/ipc/PrintDataUtils.cpp @@ -129,7 +129,23 @@ NS_IMETHODIMP MockWebBrowserPrint::EnumerateDocumentNames(uint32_t* aCount, char16_t*** aResult) { - return NS_ERROR_NOT_IMPLEMENTED; + *aCount = 0; + *aResult = nullptr; + + if (mData.printJobName().IsEmpty()) { + return NS_OK; + } + + // The only consumer that cares about this is the OS X printing + // dialog, and even then, it only cares about the first document + // name. That's why we only send a single document name through + // PrintData. + char16_t** array = (char16_t**) moz_xmalloc(sizeof(char16_t*)); + array[0] = ToNewUnicode(mData.printJobName()); + + *aCount = 1; + *aResult = array; + return NS_OK; } NS_IMETHODIMP diff --git a/widget/cocoa/nsPrintDialogX.mm b/widget/cocoa/nsPrintDialogX.mm index a3724b1c9153..61935e9e9b70 100644 --- a/widget/cocoa/nsPrintDialogX.mm +++ b/widget/cocoa/nsPrintDialogX.mm @@ -88,9 +88,14 @@ nsPrintDialogServiceX::Show(nsIDOMWindow *aParent, nsIPrintSettings *aSettings, int button = [panel runModal]; nsCocoaUtils::CleanUpAfterNativeAppModalDialog(); - settingsX->SetCocoaPrintInfo([[[NSPrintOperation currentOperation] printInfo] copy]); + NSPrintInfo* copy = [[[NSPrintOperation currentOperation] printInfo] copy]; + if (!copy) { + return NS_ERROR_OUT_OF_MEMORY; + } + settingsX->SetCocoaPrintInfo(copy); + [copy release]; + [NSPrintOperation setCurrentOperation:nil]; - [printInfo release]; [tmpView release]; if (button != NSOKButton) diff --git a/widget/cocoa/nsPrintOptionsX.h b/widget/cocoa/nsPrintOptionsX.h index a87e763ba532..ad8313764440 100644 --- a/widget/cocoa/nsPrintOptionsX.h +++ b/widget/cocoa/nsPrintOptionsX.h @@ -8,11 +8,26 @@ #include "nsPrintOptionsImpl.h" +namespace mozilla +{ +namespace embedding +{ + class PrintData; +} // namespace embedding +} // namespace mozilla + class nsPrintOptionsX : public nsPrintOptions { public: nsPrintOptionsX(); virtual ~nsPrintOptionsX(); + + NS_IMETHODIMP SerializeToPrintData(nsIPrintSettings* aSettings, + nsIWebBrowserPrint* aWBP, + mozilla::embedding::PrintData* data); + NS_IMETHODIMP DeserializeToPrintSettings(const mozilla::embedding::PrintData& data, + nsIPrintSettings* settings); + protected: nsresult _CreatePrintSettings(nsIPrintSettings **_retval); nsresult ReadPrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName, uint32_t aFlags); diff --git a/widget/cocoa/nsPrintOptionsX.mm b/widget/cocoa/nsPrintOptionsX.mm index db72392dc3b3..48cd3db16924 100644 --- a/widget/cocoa/nsPrintOptionsX.mm +++ b/widget/cocoa/nsPrintOptionsX.mm @@ -9,6 +9,8 @@ #include "nsPrintOptionsX.h" #include "nsPrintSettingsX.h" +using namespace mozilla::embedding; + nsPrintOptionsX::nsPrintOptionsX() { } @@ -17,6 +19,210 @@ nsPrintOptionsX::~nsPrintOptionsX() { } +NS_IMETHODIMP +nsPrintOptionsX::SerializeToPrintData(nsIPrintSettings* aSettings, + nsIWebBrowserPrint* aWBP, + PrintData* data) +{ + nsresult rv = nsPrintOptions::SerializeToPrintData(aSettings, aWBP, data); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + if (aWBP) { + // When serializing an nsIWebBrowserPrint, we need to pass up the first + // document name. We could pass up the entire collection of document + // names, but the OS X printing prompt code only really cares about + // the first one, so we just send the first to save IPC traffic. + char16_t** docTitles; + uint32_t titleCount; + nsresult rv = aWBP->EnumerateDocumentNames(&titleCount, &docTitles); + if (NS_SUCCEEDED(rv) && titleCount > 0) { + data->printJobName().Assign(docTitles[0]); + } + + for (int32_t i = titleCount - 1; i >= 0; i--) { + free(docTitles[i]); + } + free(docTitles); + docTitles = nullptr; + } + + nsRefPtr settingsX(do_QueryObject(aSettings)); + if (NS_WARN_IF(!settingsX)) { + return NS_ERROR_FAILURE; + } + + NSPrintInfo* printInfo = settingsX->GetCocoaPrintInfo(); + if (NS_WARN_IF(!printInfo)) { + return NS_ERROR_FAILURE; + } + + NSDictionary* dict = [printInfo dictionary]; + if (NS_WARN_IF(!dict)) { + return NS_ERROR_FAILURE; + } + + NSString* printerName = [dict objectForKey: NSPrintPrinterName]; + if (printerName) { + nsCocoaUtils::GetStringForNSString(printerName, data->printerName()); + } + + NSString* faxNumber = [dict objectForKey: NSPrintFaxNumber]; + if (faxNumber) { + nsCocoaUtils::GetStringForNSString(faxNumber, data->faxNumber()); + } + + NSURL* printToFileURL = [dict objectForKey: NSPrintJobSavingURL]; + if (printToFileURL) { + nsCocoaUtils::GetStringForNSString([printToFileURL absoluteString], + data->toFileName()); + } + + NSDate* printTime = [dict objectForKey: NSPrintTime]; + if (printTime) { + NSTimeInterval timestamp = [printTime timeIntervalSinceReferenceDate]; + data->printTime() = timestamp; + } + + NSString* disposition = [dict objectForKey: NSPrintJobDisposition]; + if (disposition) { + nsCocoaUtils::GetStringForNSString(disposition, data->disposition()); + } + + data->numCopies() = [[dict objectForKey: NSPrintCopies] intValue]; + data->printAllPages() = [[dict objectForKey: NSPrintAllPages] boolValue]; + data->startPageRange() = [[dict objectForKey: NSPrintFirstPage] intValue]; + data->endPageRange() = [[dict objectForKey: NSPrintLastPage] intValue]; + data->mustCollate() = [[dict objectForKey: NSPrintMustCollate] boolValue]; + data->printReversed() = [[dict objectForKey: NSPrintReversePageOrder] boolValue]; + data->pagesAcross() = [[dict objectForKey: NSPrintPagesAcross] unsignedShortValue]; + data->pagesDown() = [[dict objectForKey: NSPrintPagesDown] unsignedShortValue]; + data->detailedErrorReporting() = [[dict objectForKey: NSPrintDetailedErrorReporting] boolValue]; + data->addHeaderAndFooter() = [[dict objectForKey: NSPrintHeaderAndFooter] boolValue]; + data->fileNameExtensionHidden() = + [[dict objectForKey: NSPrintJobSavingFileNameExtensionHidden] boolValue]; + + bool printSelectionOnly = [[dict objectForKey: NSPrintSelectionOnly] boolValue]; + aSettings->SetPrintOptions(nsIPrintSettings::kEnableSelectionRB, + printSelectionOnly); + aSettings->GetPrintOptionsBits(&data->optionFlags()); + + return NS_OK; +} + +NS_IMETHODIMP +nsPrintOptionsX::DeserializeToPrintSettings(const PrintData& data, + nsIPrintSettings* settings) +{ + nsresult rv = nsPrintOptions::DeserializeToPrintSettings(data, settings); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + nsRefPtr settingsX(do_QueryObject(settings)); + if (NS_WARN_IF(!settingsX)) { + return NS_ERROR_FAILURE; + } + + NSPrintInfo* sharedPrintInfo = [NSPrintInfo sharedPrintInfo]; + if (NS_WARN_IF(!sharedPrintInfo)) { + return NS_ERROR_FAILURE; + } + + NSDictionary* sharedDict = [sharedPrintInfo dictionary]; + if (NS_WARN_IF(!sharedDict)) { + return NS_ERROR_FAILURE; + } + + // We need to create a new NSMutableDictionary to pass to NSPrintInfo with + // the values that we got from the other process. + NSMutableDictionary* newPrintInfoDict = + [NSMutableDictionary dictionaryWithDictionary:sharedDict]; + if (NS_WARN_IF(!newPrintInfoDict)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + NSString* printerName = nsCocoaUtils::ToNSString(data.printerName()); + if (printerName) { + NSPrinter* printer = [NSPrinter printerWithName: printerName]; + if (NS_WARN_IF(!printer)) { + return NS_ERROR_FAILURE; + } + [newPrintInfoDict setObject: printer forKey: NSPrintPrinter]; + [newPrintInfoDict setObject: printerName forKey: NSPrintPrinterName]; + } + + [newPrintInfoDict setObject: [NSNumber numberWithInt: data.numCopies()] + forKey: NSPrintCopies]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.printAllPages()] + forKey: NSPrintAllPages]; + [newPrintInfoDict setObject: [NSNumber numberWithInt: data.startPageRange()] + forKey: NSPrintFirstPage]; + [newPrintInfoDict setObject: [NSNumber numberWithInt: data.endPageRange()] + forKey: NSPrintLastPage]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.mustCollate()] + forKey: NSPrintMustCollate]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.printReversed()] + forKey: NSPrintReversePageOrder]; + + [newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.disposition()) + forKey: NSPrintJobDisposition]; + + [newPrintInfoDict setObject: [NSNumber numberWithShort: data.pagesAcross()] + forKey: NSPrintPagesAcross]; + [newPrintInfoDict setObject: [NSNumber numberWithShort: data.pagesDown()] + forKey: NSPrintPagesDown]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.detailedErrorReporting()] + forKey: NSPrintDetailedErrorReporting]; + [newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.faxNumber()) + forKey: NSPrintFaxNumber]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.addHeaderAndFooter()] + forKey: NSPrintHeaderAndFooter]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.fileNameExtensionHidden()] + forKey: NSPrintJobSavingFileNameExtensionHidden]; + + // At this point, the base class should have properly deserialized the print + // options bitfield for nsIPrintSettings, so that it holds the correct value + // for kEnableSelectionRB, which we use to set NSPrintSelectionOnly. + + bool printSelectionOnly = false; + rv = settings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &printSelectionOnly); + if (NS_SUCCEEDED(rv)) { + [newPrintInfoDict setObject: [NSNumber numberWithBool: printSelectionOnly] + forKey: NSPrintSelectionOnly]; + } else { + [newPrintInfoDict setObject: [NSNumber numberWithBool: NO] + forKey: NSPrintSelectionOnly]; + } + + NSURL* jobSavingURL = + [NSURL URLWithString:[nsCocoaUtils::ToNSString(data.toFileName()) + stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; + if (jobSavingURL) { + [newPrintInfoDict setObject: jobSavingURL forKey: NSPrintJobSavingURL]; + } + + NSTimeInterval timestamp = data.printTime(); + NSDate* printTime = [NSDate dateWithTimeIntervalSinceReferenceDate: timestamp]; + if (printTime) { + [newPrintInfoDict setObject: printTime forKey: NSPrintTime]; + } + + // Next, we create a new NSPrintInfo with the values in our dictionary. + NSPrintInfo* newPrintInfo = + [[NSPrintInfo alloc] initWithDictionary: newPrintInfoDict]; + if (NS_WARN_IF(!newPrintInfo)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // And now swap in the new NSPrintInfo we've just populated. + settingsX->SetCocoaPrintInfo(newPrintInfo); + [newPrintInfo release]; + + return NS_OK; +} + nsresult nsPrintOptionsX::ReadPrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName, uint32_t aFlags) { diff --git a/widget/cocoa/nsPrintSettingsX.mm b/widget/cocoa/nsPrintSettingsX.mm index d2306c87fd22..b3d381c40f6f 100644 --- a/widget/cocoa/nsPrintSettingsX.mm +++ b/widget/cocoa/nsPrintSettingsX.mm @@ -94,7 +94,10 @@ NS_IMETHODIMP nsPrintSettingsX::InitUnwriteableMargin() void nsPrintSettingsX::SetCocoaPrintInfo(NSPrintInfo* aPrintInfo) { - mPrintInfo = aPrintInfo; + if (mPrintInfo != aPrintInfo) { + [mPrintInfo release]; + mPrintInfo = [aPrintInfo retain]; + } } NS_IMETHODIMP nsPrintSettingsX::ReadPageFormatFromPrefs() diff --git a/widget/nsPrintOptionsImpl.cpp b/widget/nsPrintOptionsImpl.cpp index 334af5b965fe..4689c04189ab 100644 --- a/widget/nsPrintOptionsImpl.cpp +++ b/widget/nsPrintOptionsImpl.cpp @@ -242,7 +242,7 @@ nsPrintOptions::SerializeToPrintData(nsIPrintSettings* aSettings, // data->disposition() default-initializes data->pagesAcross() = 1; data->pagesDown() = 1; - // data->printTime() default-initializes + data->printTime() = 0; data->detailedErrorReporting() = true; // data->faxNumber() default-initializes data->addHeaderAndFooter() = false; From f810a81b622c07c434773dce3a2000c0adfe2cb1 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 12:10:35 -0700 Subject: [PATCH 55/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/b9db874e5b5b Author: tamarahills Desc: Merge pull request #30292 from tamarahills/bugfix/1160483-imei-dogfood Bug 1160483 - Change the deviceID to IMEI for dogfood=1. ======== https://hg.mozilla.org/integration/gaia-central/rev/b32019db9eca Author: Tamara Hills Desc: Bug 1160483 - Change the deviceID to IMEI for build flag IMEI_TRACKING=1. r=marshall. --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 7ca50b400f1f..35035b3c382c 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "e6dc0f4c583407a4a52a66ce7cb11f058302a762", + "git_revision": "1428c18b748addc56abaa559dec914a41550df07", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "51be40eaad6a141d3741dbae10948968ebfc07a6", + "revision": "b9db874e5b5b8d9377cf5e30cd71f85d7ad9fe57", "repo_path": "integration/gaia-central" } From d4897d04eda73a40558c7b18c5d17b8953ab45a8 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 12:12:57 -0700 Subject: [PATCH 56/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 255da5522a97..dacc085339fc 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index f2c651436573..1f9b9ece17e5 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 2d6bf98016ef..2f29f72247b7 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 8da6199e529b..5a5631ef91f6 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index b49a7f1cd5ea..0ed53dadc6bb 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 8c1c2237813b..baef60878b94 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 2d6bf98016ef..2f29f72247b7 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 2fe19b3083f6..93bcaa867867 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 8c1e33003172..981602ecf8a1 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 1dccdd577e30..7256bde019b7 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 5857609162bcfbfe4517861ec9a631a64ac456da Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 13:15:18 -0700 Subject: [PATCH 57/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/2151aecbbc37 Author: Eli Perelman Desc: Merge pull request #30313 from eliperelman/bug-1169636 Bug 1169636 - [mozdevice] Swapping out log stream parser ======== https://hg.mozilla.org/integration/gaia-central/rev/f68e0fc64a7c Author: Eli Perelman Desc: Bug 1169636 - [mozdevice] Swapping out log stream parser --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 35035b3c382c..4e82ff441113 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "1428c18b748addc56abaa559dec914a41550df07", + "git_revision": "448614871aa79653494fada91be98c341ffa0926", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "b9db874e5b5b8d9377cf5e30cd71f85d7ad9fe57", + "revision": "2151aecbbc376d12134f46295e5a5aa104da3533", "repo_path": "integration/gaia-central" } From e5e75798e104612cfd84c136fed4b3b69ea89ccb Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 13:17:14 -0700 Subject: [PATCH 58/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index dacc085339fc..a18ae7203c3b 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 1f9b9ece17e5..432eb418ff02 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 2f29f72247b7..756ae570f5cf 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 5a5631ef91f6..e0a540f8f0df 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 0ed53dadc6bb..d4424e9710b1 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index baef60878b94..f22522a853dd 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 2f29f72247b7..756ae570f5cf 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 93bcaa867867..d531d82e594c 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 981602ecf8a1..22c5f609fc2f 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 7256bde019b7..ac068f9e8af7 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 2be83976cc47e9d7be9e81b77a849afcfc1f6fa5 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 14:25:27 -0700 Subject: [PATCH 59/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/df576dc6524e Author: tamarahills Desc: Merge pull request #30176 from tamarahills/bugfix/1160491-Spark-Dogfood-Flag Bug 1160491 - Add a Build Flag to create a setting for Spark Dogfooders. ======== https://hg.mozilla.org/integration/gaia-central/rev/6477a0b5c4b1 Author: Tamara Hills Desc: Bug 1160491 - Add a Build Flag to create a setting for Spark Dogfooders. --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 4e82ff441113..a9df8170423c 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "448614871aa79653494fada91be98c341ffa0926", + "git_revision": "88cda9017426595696a47294a76bc6df688db666", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "2151aecbbc376d12134f46295e5a5aa104da3533", + "revision": "df576dc6524e44c848ed60b1178b1351cc50612d", "repo_path": "integration/gaia-central" } From 94ecaa4380a07600a09e23c6179b83a00820d37d Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 14:27:23 -0700 Subject: [PATCH 60/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index a18ae7203c3b..80fa751685ca 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 432eb418ff02..064a0dd73b3a 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 756ae570f5cf..2f4273e30658 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index e0a540f8f0df..8ff5840adadf 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index d4424e9710b1..8e5a9d457d44 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index f22522a853dd..c9b661d295f9 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 756ae570f5cf..2f4273e30658 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index d531d82e594c..920eb3daca7f 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 22c5f609fc2f..2606fc88e8fb 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index ac068f9e8af7..3972c4a42b47 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From c07ab7d2e91b3496e46340647a2a8c9b5ae822ba Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 14:45:17 -0700 Subject: [PATCH 61/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/c168d1ff758f Author: Kevin Grandon Desc: Merge pull request #30310 from KevinGrandon/bug_1169615_gaia_switch_change_events Bug 1169615 - Add change event bubbling when a gaia-switch is changed ======== https://hg.mozilla.org/integration/gaia-central/rev/98fd682faa4b Author: Kevin Grandon Desc: Bug 1169615 - Add change event bubbling when a gaia-switch is changed --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index a9df8170423c..202d08547316 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "88cda9017426595696a47294a76bc6df688db666", + "git_revision": "d9ba689e3b6db6a85e41079146726470541275bd", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "df576dc6524e44c848ed60b1178b1351cc50612d", + "revision": "c168d1ff758f1af3d178be8358a403352ac14ee8", "repo_path": "integration/gaia-central" } From 4f4872eeddf1237f4b754b0d42fab0c6a4caf938 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 14:47:15 -0700 Subject: [PATCH 62/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 80fa751685ca..d49cb02cc7d3 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 064a0dd73b3a..4914ca9360f6 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 2f4273e30658..ea98bf4fbcbd 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 8ff5840adadf..cd47c130c562 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 8e5a9d457d44..c37bea0bc033 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index c9b661d295f9..368064955613 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 2f4273e30658..ea98bf4fbcbd 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 920eb3daca7f..c7f222b829de 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 2606fc88e8fb..787e1f670929 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 3972c4a42b47..a23f73c40e7d 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 2be67e1c236c7d2e886ba2f086bf02899122628c Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 15:46:48 -0700 Subject: [PATCH 63/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ======== https://hg.mozilla.org/integration/gaia-central/rev/42e983fc5dda Author: Ghislain 'Aus' Lacroix Desc: Merge pull request #30324 from nullaus/bug1169397 Bug 1169397 - Use hub.docker.com as our default for gaia-taskenv, npm… ======== https://hg.mozilla.org/integration/gaia-central/rev/237e17c434a7 Author: Ghislain 'Aus' Lacroix Desc: Bug 1169397 - Use hub.docker.com as our default for gaia-taskenv, npm-cache worker images. r=jonasfj --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 202d08547316..e33b1b24004e 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "d9ba689e3b6db6a85e41079146726470541275bd", + "git_revision": "e3a717a21b0287e1992d152f75c9fcec2f7da8fc", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "c168d1ff758f1af3d178be8358a403352ac14ee8", + "revision": "42e983fc5dda6014f5266b7c5fb12005d75d14b1", "repo_path": "integration/gaia-central" } From da420e5ab045d587b5e5e1cdc3d30542e1d8c9bf Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 15:48:46 -0700 Subject: [PATCH 64/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index d49cb02cc7d3..0cbe1683b06a 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 4914ca9360f6..ad5d828b5908 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index ea98bf4fbcbd..a4ffcb5f417b 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index cd47c130c562..4c0b04bfdf9b 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index c37bea0bc033..2661af38078c 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 368064955613..f72a2098346c 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index ea98bf4fbcbd..a4ffcb5f417b 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index c7f222b829de..dc8f02bd78df 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 787e1f670929..b5f9eaa174c8 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index a23f73c40e7d..36f8cd0ef341 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From b584c64e0bea5292bf50d4e61402f8668ab1fee3 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Fri, 29 May 2015 16:03:15 -0700 Subject: [PATCH 65/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 0cbe1683b06a..2f3318b8cf0b 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index ad5d828b5908..203a8239320f 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 4c0b04bfdf9b..06a3466a6036 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -20,7 +20,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 2661af38078c..4bcf33f39d65 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index f72a2098346c..188ccec8b072 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index dc8f02bd78df..39153e896c66 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index b5f9eaa174c8..6a419fa0f5df 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -20,7 +20,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 36f8cd0ef341..e59ac8952412 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -23,7 +23,7 @@ - + From 612ec0f6aecc8f22f85291e80d49dda0a117c512 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Sat, 30 May 2015 06:05:26 -0700 Subject: [PATCH 66/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/b9f3e9d5bdc2 Author: Martijn Desc: Merge pull request #30312 from mwargers/1169327_2 Bug 1169327 - Part 2, Remove the fake update checker code ======== https://hg.mozilla.org/integration/gaia-central/rev/aa9d9446e353 Author: Martijn Wargers Desc: Bug 1169327 - Part 2, Remove the fake update checker code --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index e33b1b24004e..e715b3e99bc2 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "e3a717a21b0287e1992d152f75c9fcec2f7da8fc", + "git_revision": "4ac2e0e4f7ef9c863143a4d6da21afdeb8ab8940", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "42e983fc5dda6014f5266b7c5fb12005d75d14b1", + "revision": "b9f3e9d5bdc253558e3887f81fbe3ff8c208f836", "repo_path": "integration/gaia-central" } From 6ae7d88befdcdb92581b27591e77791180643f5b Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Sat, 30 May 2015 06:07:22 -0700 Subject: [PATCH 67/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 2f3318b8cf0b..760b712d3189 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 203a8239320f..1d4b6986e1d3 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index a4ffcb5f417b..222b092f3aa2 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 06a3466a6036..fc5c47a129e2 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 4bcf33f39d65..8b5ca9601ad4 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 188ccec8b072..db546ad29213 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index a4ffcb5f417b..222b092f3aa2 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 39153e896c66..fca1a851d45d 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 6a419fa0f5df..f0ff0667ee1d 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index e59ac8952412..8dd1f4dfbb26 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 6b4b7c956744241f8a5006aa16256a3ad438c987 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Tsai Date: Thu, 28 May 2015 17:05:10 +0800 Subject: [PATCH 68/85] Bug 1168515 - do not block incall MMI requests on alerting state. r=aknow --- dom/telephony/Telephony.cpp | 20 -------------------- dom/telephony/Telephony.h | 3 --- 2 files changed, 23 deletions(-) diff --git a/dom/telephony/Telephony.cpp b/dom/telephony/Telephony.cpp index 88f5fd4d7c7d..6f23e52a098e 100644 --- a/dom/telephony/Telephony.cpp +++ b/dom/telephony/Telephony.cpp @@ -193,20 +193,6 @@ Telephony::GetServiceId(const Optional& aServiceId, return serviceId; } -bool -Telephony::HasDialingCall() -{ - for (uint32_t i = 0; i < mCalls.Length(); i++) { - const nsRefPtr& call = mCalls[i]; - if (call->CallState() > nsITelephonyService::CALL_STATE_UNKNOWN && - call->CallState() < nsITelephonyService::CALL_STATE_CONNECTED) { - return true; - } - } - - return false; -} - already_AddRefed Telephony::DialInternal(uint32_t aServiceId, const nsAString& aNumber, bool aEmergency, ErrorResult& aRv) @@ -226,12 +212,6 @@ Telephony::DialInternal(uint32_t aServiceId, const nsAString& aNumber, return promise.forget(); } - // We only support one outgoing call at a time. - if (HasDialingCall()) { - promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); - return promise.forget(); - } - nsCOMPtr callback = new TelephonyDialCallback(GetOwner(), this, promise); diff --git a/dom/telephony/Telephony.h b/dom/telephony/Telephony.h index e71bf2e8bd54..0ef8ce27704d 100644 --- a/dom/telephony/Telephony.h +++ b/dom/telephony/Telephony.h @@ -177,9 +177,6 @@ private: GetServiceId(const Optional& aServiceId, bool aGetIfActiveCall = false); - bool - HasDialingCall(); - already_AddRefed DialInternal(uint32_t aServiceId, const nsAString& aNumber, bool aEmergency, ErrorResult& aRv); From e6879816ca84f6434fe41a577ac7d7c5ab55b157 Mon Sep 17 00:00:00 2001 From: ffxbld Date: Sat, 30 May 2015 03:26:57 -0700 Subject: [PATCH 69/85] No bug, Automated HSTS preload list update from host bld-linux64-spot-534 - a=hsts-update --- security/manager/ssl/nsSTSPreloadList.errors | 39 ++++++++++---------- security/manager/ssl/nsSTSPreloadList.inc | 27 +++++++------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/security/manager/ssl/nsSTSPreloadList.errors b/security/manager/ssl/nsSTSPreloadList.errors index 774ea11f5709..18cbc9b54f89 100644 --- a/security/manager/ssl/nsSTSPreloadList.errors +++ b/security/manager/ssl/nsSTSPreloadList.errors @@ -25,7 +25,6 @@ atavio.at: could not connect to host atavio.ch: could not connect to host atavio.de: did not receive HSTS header au.search.yahoo.com: did not receive HSTS header -aurainfosec.com.au: could not connect to host auth.mail.ru: did not receive HSTS header auto4trade.nl: did not receive HSTS header az.search.yahoo.com: did not receive HSTS header @@ -38,6 +37,7 @@ bccx.com: could not connect to host bcm.com.au: max-age too low: 0 be.search.yahoo.com: did not receive HSTS header bedeta.de: could not connect to host +bentertain.de: could not connect to host betnet.fr: could not connect to host bi.search.yahoo.com: did not receive HSTS header bidon.ca: did not receive HSTS header @@ -101,11 +101,10 @@ ct.search.yahoo.com: did not receive HSTS header cujanovic.com: did not receive HSTS header cyanogenmod.xxx: could not connect to host cybershambles.com: could not connect to host -darknode.in: did not receive HSTS header -darkserver.fedoraproject.org: could not connect to host datasnitch.co.uk: could not connect to host daylightcompany.com: did not receive HSTS header de.search.yahoo.com: did not receive HSTS header +deadbeef.ninja: could not connect to host decibelios.li: did not receive HSTS header destinationbijoux.fr: max-age too low: 2678400 devh.de: did not receive HSTS header @@ -145,14 +144,16 @@ fi.search.yahoo.com: did not receive HSTS header firebaseio.com: could not connect to host fixingdns.com: did not receive HSTS header fj.search.yahoo.com: did not receive HSTS header +fleximus.org: max-age too low: 1 fm83.nl: did not receive HSTS header fonetiq.io: could not connect to host fr.search.yahoo.com: did not receive HSTS header -freeshell.de: did not receive HSTS header fsma.pl: did not receive HSTS header gamesdepartment.co.uk: did not receive HSTS header geekandi.com: max-age too low: 7776000 +getcolor.com: could not connect to host getlantern.org: did not receive HSTS header +getssl.uz: could not connect to host gl.search.yahoo.com: did not receive HSTS header glass.google.com: did not receive HSTS header (error ignored - included regardless) gm.search.yahoo.com: did not receive HSTS header @@ -203,12 +204,13 @@ j0s.at: did not receive HSTS header jamesdoylephoto.com: did not receive HSTS header janus-engineering.de: did not receive HSTS header jelmer.co.uk: could not connect to host +jkb.pics: could not connect to host +jkbuster.com: could not connect to host johners.me: could not connect to host jottit.com: could not connect to host julian-kipka.de: did not receive HSTS header k-dev.de: could not connect to host kamikano.com: did not receive HSTS header -karaoketonight.com: could not connect to host keeley.gq: could not connect to host keeley.ml: could not connect to host keepclean.me: could not connect to host @@ -219,7 +221,6 @@ kitsta.com: could not connect to host kiwiirc.com: max-age too low: 5256000 klaxn.com: could not connect to host klaxn.org: could not connect to host -koenvdheuvel.me: did not receive HSTS header komandakovalchuk.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] koop-bremen.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] kr.search.yahoo.com: did not receive HSTS header @@ -235,10 +236,8 @@ library.linode.com: did not receive HSTS header libraryfreedomproject.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] lifeguard.aecom.com: max-age too low: 86400 lists.fedoraproject.org: did not receive HSTS header -lockify.com: could not connect to host login.corp.google.com: max-age too low: 7776000 (error ignored - included regardless) logotype.se: did not receive HSTS header -lookzook.com: did not receive HSTS header lovelycorral.com: did not receive HSTS header lt.search.yahoo.com: did not receive HSTS header lu.search.yahoo.com: did not receive HSTS header @@ -247,15 +246,15 @@ lumi.do: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FA luxus-russen.de: could not connect to host lv.search.yahoo.com: did not receive HSTS header m.gparent.org: could not connect to host +maff.scot: did not receive HSTS header mail.google.com: did not receive HSTS header (error ignored - included regardless) maktoob.search.yahoo.com: did not receive HSTS header malaysia.search.yahoo.com: did not receive HSTS header manage.zenpayroll.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] market.android.com: did not receive HSTS header (error ignored - included regardless) +markusueberallassetmanagement.de: could not connect to host marshut.net: could not connect to host -matatall.com: could not connect to host mccrypto.de: could not connect to host -mdfnet.se: could not connect to host mediacru.sh: could not connect to host megashur.se: did not receive HSTS header megaxchange.com: did not receive HSTS header @@ -283,6 +282,7 @@ myni.io: could not connect to host neftaly.com: did not receive HSTS header neonisi.com: could not connect to host netrelay.email: did not receive HSTS header +netzbit.de: did not receive HSTS header netzpolitik.org: did not receive HSTS header netztest.at: did not receive HSTS header newkaliningrad.ru: did not receive HSTS header @@ -319,10 +319,10 @@ platform.lookout.com: could not connect to host play.google.com: did not receive HSTS header (error ignored - included regardless) polymathematician.com: could not connect to host popcorntime.ws: max-age too low: 2592000 -powerplannerapp.com: did not receive HSTS header pr.search.yahoo.com: did not receive HSTS header pressfreedomfoundation.org: did not receive HSTS header prodpad.com: did not receive HSTS header +projektzentrisch.de: could not connect to host promecon-gmbh.de: did not receive HSTS header proximato.com: could not connect to host pult.co: could not connect to host @@ -333,15 +333,16 @@ rasing.me: could not connect to host redlatam.org: did not receive HSTS header redports.org: did not receive HSTS header regar42.fr: could not connect to host +reishunger.de: did not receive HSTS header reserve-online.net: did not receive HSTS header -rid-wan.com: could not connect to host +rid-wan.com: max-age too low: 0 riseup.net: did not receive HSTS header rme.li: did not receive HSTS header ro.search.yahoo.com: did not receive HSTS header roan24.pl: did not receive HSTS header roddis.net: did not receive HSTS header -rpavlik.cz: did not receive HSTS header ru.search.yahoo.com: did not receive HSTS header +rubyshop.nl: did not receive HSTS header rw.search.yahoo.com: did not receive HSTS header sah3.net: could not connect to host saturngames.co.uk: could not connect to host @@ -351,11 +352,13 @@ sdsl-speedtest.de: could not connect to host se.search.yahoo.com: did not receive HSTS header search.yahoo.com: did not receive HSTS header security.google.com: did not receive HSTS header (error ignored - included regardless) +sellocdn.com: could not connect to host semenkovich.com: did not receive HSTS header seomobo.com: did not receive HSTS header seowarp.net: max-age too low: 1576800 serverdensity.io: did not receive HSTS header sg.search.yahoo.com: did not receive HSTS header +sh-network.de: could not connect to host shops.neonisi.com: could not connect to host siammedia.co: did not receive HSTS header silentcircle.org: could not connect to host @@ -364,7 +367,6 @@ simplyfixit.co.uk: [Exception... "Component returned failure code: 0x80004005 (N sistemy48.ru: did not receive HSTS header sites.google.com: did not receive HSTS header (error ignored - included regardless) smartlend.se: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] -sockeye.cc: could not connect to host sol.io: could not connect to host souyar.de: could not connect to host souyar.net: could not connect to host @@ -374,7 +376,6 @@ spreadsheets.google.com: did not receive HSTS header (error ignored - included r square.com: did not receive HSTS header ssl.google-analytics.com: did not receive HSTS header (error ignored - included regardless) ssl.panoramio.com: did not receive HSTS header -stevegrav.es: did not receive HSTS header stillyarts.com: did not receive HSTS header stocktrade.de: could not connect to host suite73.org: could not connect to host @@ -382,6 +383,7 @@ sunshinepress.org: could not connect to host surfeasy.com: did not receive HSTS header suzukikenichi.com: did not receive HSTS header sv.search.yahoo.com: did not receive HSTS header +sychov.pro: could not connect to host sylaps.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] t.facebook.com: did not receive HSTS header tablet.facebook.com: did not receive HSTS header @@ -390,7 +392,7 @@ talk.google.com: could not connect to host (error ignored - included regardless) talkgadget.google.com: did not receive HSTS header (error ignored - included regardless) tandarts-haarlem.nl: did not receive HSTS header tapka.cz: did not receive HSTS header -taxsquirrel.com: did not receive HSTS header +taxsquirrel.com: could not connect to host tc-bonito.de: did not receive HSTS header tektoria.de: did not receive HSTS header temehu.com: did not receive HSTS header @@ -406,6 +408,7 @@ tradingcentre.com.au: did not receive HSTS header translate.googleapis.com: did not receive HSTS header (error ignored - included regardless) translatoruk.co.uk: did not receive HSTS header triop.se: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] +tuturulianda.com: did not receive HSTS header tv.search.yahoo.com: could not connect to host tw.search.yahoo.com: did not receive HSTS header ua.search.yahoo.com: did not receive HSTS header @@ -422,10 +425,8 @@ viennan.net: did not receive HSTS header vn.search.yahoo.com: did not receive HSTS header vyncke.org: did not receive HSTS header webmail.mayfirst.org: did not receive HSTS header -wf-training-master.appspot.com: could not connect to host -wf-training-master.appspot.com: could not connect to host (error ignored - included regardless) -wideup.net: did not receive HSTS header wikidsystems.com: did not receive HSTS header +willnorris.com: could not connect to host withustrading.com: did not receive HSTS header wiz.biz: could not connect to host wohnungsbau-ludwigsburg.de: did not receive HSTS header diff --git a/security/manager/ssl/nsSTSPreloadList.inc b/security/manager/ssl/nsSTSPreloadList.inc index 7c530c2f5d86..aee1b2c709f5 100644 --- a/security/manager/ssl/nsSTSPreloadList.inc +++ b/security/manager/ssl/nsSTSPreloadList.inc @@ -8,7 +8,7 @@ /*****************************************************************************/ #include -const PRTime gPreloadListExpirationTime = INT64_C(1443262889968000); +const PRTime gPreloadListExpirationTime = INT64_C(1443867487249000); class nsSTSPreload { @@ -383,6 +383,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "danw.io", true }, { "daphne.informatik.uni-freiburg.de", true }, { "darchoods.net", false }, + { "darknode.in", true }, { "darkpony.ru", true }, { "darkserver.fedoraproject.org", true }, { "darkserver.stg.fedoraproject.org", true }, @@ -406,7 +407,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "dee.pe", true }, { "defcon.org", true }, { "dekasan.ru", true }, - { "deliverance.co.uk", true }, + { "deliverance.co.uk", false }, { "denh.am", true }, { "depechemode-live.com", true }, { "derevtsov.com", false }, @@ -557,7 +558,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "fj.simple.com", false }, { "flagspot.net", true }, { "flamer-scene.com", true }, - { "fleximus.org", false }, { "floobits.com", true }, { "florian-lillpopp.de", true }, { "florianlillpopp.de", true }, @@ -576,6 +576,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "fralef.me", false }, { "frederik-braun.com", true }, { "freenetproject.org", true }, + { "freeshell.de", true }, { "freesounding.com", true }, { "freesounding.ru", true }, { "freethought.org.au", true }, @@ -766,7 +767,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "irmag.ru", true }, { "ironfistdesign.com", true }, { "isitchristmas.com", true }, - { "isogram.nl", false }, + { "isogram.nl", true }, { "it-schwerin.de", true }, { "itdashboard.gov", true }, { "itriskltd.com", true }, @@ -860,6 +861,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "knowledgehook.com", true }, { "koen.io", true }, { "koenrouwhorst.nl", true }, + { "koenvdheuvel.me", true }, { "kojipkgs.fedoraproject.org", true }, { "kollawat.me", true }, { "komandakovalchuk.com", false }, @@ -934,6 +936,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "lolicore.ch", true }, { "lookout.com", false }, { "lookyman.net", true }, + { "lookzook.com", true }, { "lore.azurewebsites.net", true }, { "ludwig.im", true }, { "luelistan.net", true }, @@ -947,7 +950,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "madars.org", true }, { "madeitwor.se", true }, { "mafamane.com", true }, - { "maff.scot", false }, { "magneticanvil.com", true }, { "mahamed91.pw", true }, { "mail.de", true }, @@ -976,7 +978,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "marshut.net", true }, { "massivum.de", false }, { "masters.black", true }, - { "matatall.com", true }, + { "matatall.com", false }, { "mathiasbynens.be", true }, { "matteomarescotti.it", true }, { "mattfin.ch", true }, @@ -989,7 +991,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "mccrypto.de", true }, { "mcnext.net", true }, { "md5file.com", true }, - { "mdfnet.se", true }, + { "mdfnet.se", false }, { "meamod.com", true }, { "medallia.io", true }, { "mediacru.sh", true }, @@ -1102,7 +1104,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "netbox.cc", true }, { "netera.se", true }, { "netrider.net.au", true }, - { "netzbit.de", true }, { "newstarnootropics.com", true }, { "ng-security.com", true }, { "nginxnudes.com", true }, @@ -1244,6 +1245,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "portal.tirol.gv.at", true }, { "posteo.de", false }, { "postfinance.ch", true }, + { "powerplannerapp.com", true }, { "prakharprasad.com", true }, { "prefontaine.name", true }, { "preissler.co.uk", true }, @@ -1297,7 +1299,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "refundo.cz", true }, { "refundo.sk", true }, { "reg.ru", false }, - { "reishunger.de", true }, { "release-monitoring.org", true }, { "reliable-mail.de", true }, { "renem.net", true }, @@ -1309,7 +1310,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "riccy.org", true }, { "richiemail.net", true }, { "ricochet.im", true }, - { "rid-wan.com", true }, { "riesenmagnete.de", true }, { "rika.me", true }, { "rippleunion.com", true }, @@ -1337,7 +1337,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "ru-sprachstudio.ch", true }, { "rubecodeberg.com", true }, { "rubendv.be", true }, - { "rubyshop.nl", true }, { "rudloff.pro", true }, { "rusadmin.biz", true }, { "ruudkoot.nl", true }, @@ -1440,7 +1439,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "smith.is", true }, { "snakehosting.dk", true }, { "sneezry.com", true }, - { "sockeye.cc", true }, + { "sockeye.cc", false }, { "soia.ca", true }, { "sorz.org", true }, { "souki.cz", true }, @@ -1474,6 +1473,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "stationary-traveller.eu", true }, { "stereo.lu", true }, { "stesti.cz", true }, + { "stevegrav.es", true }, { "steventress.com", true }, { "sticklerjs.org", true }, { "stirling.co", true }, @@ -1615,7 +1615,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "tor2web.org", true }, { "tormentedradio.com", true }, { "torproject.org", false }, - { "torquato.de", true }, + { "torquato.de", false }, { "toshnix.com", true }, { "touch.facebook.com", false }, { "touch.mail.ru", true }, @@ -1635,7 +1635,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "tucuxi.org", true }, { "tuitle.com", true }, { "tunebitfm.de", true }, - { "tuturulianda.com", true }, { "tuxplace.nl", true }, { "twentymilliseconds.com", true }, { "twisto.cz", true }, From b6ea902b969546b6ae6c2d43e68b193bfb48716e Mon Sep 17 00:00:00 2001 From: ffxbld Date: Sat, 30 May 2015 03:26:59 -0700 Subject: [PATCH 70/85] No bug, Automated HPKP preload list update from host bld-linux64-spot-534 - a=hpkp-update --- security/manager/ssl/StaticHPKPins.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/manager/ssl/StaticHPKPins.h b/security/manager/ssl/StaticHPKPins.h index 95d3a4ef049e..b083deab5033 100644 --- a/security/manager/ssl/StaticHPKPins.h +++ b/security/manager/ssl/StaticHPKPins.h @@ -1093,4 +1093,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = { static const int32_t kUnknownId = -1; -static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1440843695456000); +static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1441448291452000); From dd609468e4b5cde11bb7586137388d994f0854ea Mon Sep 17 00:00:00 2001 From: Bob Owen Date: Mon, 1 Jun 2015 07:39:25 +0100 Subject: [PATCH 71/85] Backed out 2 changesets (bug 1164014) for WinXP debug crashtest failures on a CLOSED TREE Backed out changeset 4f4454ece5ac (bug 1164014) Backed out changeset 81d78a498313 (bug 1164014) --- browser/installer/package-manifest.in | 1 - js/xpconnect/idl/nsIAddonInterposition.idl | 12 +- js/xpconnect/src/XPCComponents.cpp | 4 +- js/xpconnect/src/XPCWrappedNativeScope.cpp | 115 +----------------- js/xpconnect/src/nsXPConnect.cpp | 19 +-- js/xpconnect/src/xpcprivate.h | 20 +-- js/xpconnect/tests/unit/test_interposition.js | 5 - js/xpconnect/wrappers/AddonWrapper.cpp | 9 +- .../components/addoncompat/defaultShims.js | 4 - toolkit/components/addoncompat/moz.build | 1 - .../addoncompat/multiprocessShims.js | 30 ----- 11 files changed, 18 insertions(+), 202 deletions(-) diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 9206a5255086..4a57e538473e 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -436,7 +436,6 @@ @RESPATH@/components/nsUpdateTimerManager.js @RESPATH@/components/addoncompat.manifest @RESPATH@/components/multiprocessShims.js -@RESPATH@/components/defaultShims.js @RESPATH@/components/remoteTagService.js @RESPATH@/components/pluginGlue.manifest @RESPATH@/components/ProcessSingleton.manifest diff --git a/js/xpconnect/idl/nsIAddonInterposition.idl b/js/xpconnect/idl/nsIAddonInterposition.idl index 1d1166ef239b..9ed0f9b7a370 100644 --- a/js/xpconnect/idl/nsIAddonInterposition.idl +++ b/js/xpconnect/idl/nsIAddonInterposition.idl @@ -20,7 +20,7 @@ * property, it should return a replacement property descriptor for it. If not, * it should return null. */ -[scriptable,uuid(d05cc5fd-ad88-41a6-854c-36fd94d69ddb)] +[scriptable,uuid(215353cb-6e77-462f-a791-6891f42e593f)] interface nsIAddonInterposition : nsISupports { /** @@ -54,14 +54,4 @@ interface nsIAddonInterposition : nsISupports in jsval originalFunc, in jsval originalThis, in jsval args); - - /** - * For the first time when the interposition is registered the engine - * calls getWhitelist and expects an array of strings. The strings are - * the name of properties the interposition wants interposeProperty - * to be called. It can be an empty array. - * Note: for CPOWs interposeProperty is always called regardless if - * the name of the property is on the whitelist or not. - */ - jsval getWhitelist(); }; diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index 662f7461c220..4c3290dc07d5 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -32,7 +32,6 @@ #include "nsWindowMemoryReporter.h" #include "nsDOMClassInfo.h" #include "ShimInterfaceInfo.h" -#include "nsIAddonInterposition.h" using namespace mozilla; using namespace JS; @@ -3491,9 +3490,8 @@ nsXPCComponents_Utils::SetAddonInterposition(const nsACString& addonIdStr, JSAddonId* addonId = xpc::NewAddonId(cx, addonIdStr); if (!addonId) return NS_ERROR_FAILURE; - if (!XPCWrappedNativeScope::SetAddonInterposition(cx, addonId, interposition)) + if (!XPCWrappedNativeScope::SetAddonInterposition(addonId, interposition)) return NS_ERROR_FAILURE; - return NS_OK; } diff --git a/js/xpconnect/src/XPCWrappedNativeScope.cpp b/js/xpconnect/src/XPCWrappedNativeScope.cpp index 4dd06db0cddd..c675809db8fe 100644 --- a/js/xpconnect/src/XPCWrappedNativeScope.cpp +++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp @@ -27,7 +27,6 @@ using namespace JS; XPCWrappedNativeScope* XPCWrappedNativeScope::gScopes = nullptr; XPCWrappedNativeScope* XPCWrappedNativeScope::gDyingScopes = nullptr; XPCWrappedNativeScope::InterpositionMap* XPCWrappedNativeScope::gInterpositionMap = nullptr; -InterpositionWhitelistArray* XPCWrappedNativeScope::gInterpositionWhitelists = nullptr; NS_IMPL_ISUPPORTS(XPCWrappedNativeScope::ClearInterpositionsObserver, nsIObserver) @@ -47,11 +46,6 @@ XPCWrappedNativeScope::ClearInterpositionsObserver::Observe(nsISupports* subject gInterpositionMap = nullptr; } - if (gInterpositionWhitelists) { - delete gInterpositionWhitelists; - gInterpositionWhitelists = nullptr; - } - nsContentUtils::UnregisterShutdownObserver(this); return NS_OK; } @@ -149,8 +143,6 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext* cx, "extensions.interposition.enabled", false); if (interpositionEnabled) { mInterposition = do_GetService("@mozilla.org/addons/default-addon-shims;1"); - MOZ_ASSERT(mInterposition); - UpdateInterpositionWhitelist(cx, mInterposition); } } } @@ -764,8 +756,7 @@ XPCWrappedNativeScope::SetExpandoChain(JSContext* cx, HandleObject target, } /* static */ bool -XPCWrappedNativeScope::SetAddonInterposition(JSContext* cx, - JSAddonId* addonId, +XPCWrappedNativeScope::SetAddonInterposition(JSAddonId* addonId, nsIAddonInterposition* interp) { if (!gInterpositionMap) { @@ -773,17 +764,14 @@ XPCWrappedNativeScope::SetAddonInterposition(JSContext* cx, gInterpositionMap->init(); // Make sure to clear the map at shutdown. - // Note: this will take care of gInterpositionWhitelists too. nsContentUtils::RegisterShutdownObserver(new ClearInterpositionsObserver()); } if (interp) { - bool ok = gInterpositionMap->put(addonId, interp); - NS_ENSURE_TRUE(ok, false); - UpdateInterpositionWhitelist(cx, interp); + return gInterpositionMap->put(addonId, interp); } else { gInterpositionMap->remove(addonId); + return true; } - return true; } nsCOMPtr @@ -792,103 +780,6 @@ XPCWrappedNativeScope::GetInterposition() return mInterposition; } -/* static */ InterpositionWhitelist* -XPCWrappedNativeScope::GetInterpositionWhitelist(nsIAddonInterposition* interposition) -{ - if (!gInterpositionWhitelists) - return nullptr; - - InterpositionWhitelistArray& wls = *gInterpositionWhitelists; - for (size_t i = 0; i < wls.Length(); i++) { - if (wls[i].interposition == interposition) - return &wls[i].whitelist; - } - - return nullptr; -} - -/* static */ bool -XPCWrappedNativeScope::UpdateInterpositionWhitelist(JSContext* cx, - nsIAddonInterposition* interposition) -{ - // We want to set the interpostion whitelist only once. - InterpositionWhitelist* whitelist = GetInterpositionWhitelist(interposition); - if (whitelist) - return true; - - // The hashsets in gInterpositionWhitelists do not have a copy constructor so - // a reallocation for the array will lead to a memory corruption. If you - // need more interpositions, change the capacity of the array please. - static const size_t MAX_INTERPOSITION = 8; - if (!gInterpositionWhitelists) - gInterpositionWhitelists = new InterpositionWhitelistArray(MAX_INTERPOSITION); - - MOZ_RELEASE_ASSERT(MAX_INTERPOSITION > gInterpositionWhitelists->Length() + 1); - InterpositionWhitelistPair* newPair = gInterpositionWhitelists->AppendElement(); - newPair->interposition = interposition; - newPair->whitelist.init(); - whitelist = &newPair->whitelist; - - RootedValue whitelistVal(cx); - nsresult rv = interposition->GetWhitelist(&whitelistVal); - if (NS_FAILED(rv)) { - JS_ReportError(cx, "Could not get the whitelist from the interposition."); - return false; - } - - if (!whitelistVal.isObject()) { - JS_ReportError(cx, "Whitelist must be an array."); - return false; - } - - // We want to enter the whitelist's compartment to avoid any wrappers. - // To be on the safe side let's make sure that it's a system compartment - // and we don't accidentally trigger some content function here by parsing - // the whitelist object. - RootedObject whitelistObj(cx, &whitelistVal.toObject()); - whitelistObj = js::UncheckedUnwrap(whitelistObj); - if (!AccessCheck::isChrome(whitelistObj)) { - JS_ReportError(cx, "Whitelist must be from system scope."); - return false; - } - - { - JSAutoCompartment ac(cx, whitelistObj); - - uint32_t length; - if (!JS_IsArrayObject(cx, whitelistObj) || - !JS_GetArrayLength(cx, whitelistObj, &length)) { - JS_ReportError(cx, "Whitelist must be an array."); - return false; - } - - for (uint32_t i = 0; i < length; i++) { - RootedValue idval(cx); - if (!JS_GetElement(cx, whitelistObj, i, &idval)) - return false; - - if (!idval.isString()) { - JS_ReportError(cx, "Whitelist must contain strings only."); - return false; - } - - RootedString str(cx, idval.toString()); - str = JS_InternJSString(cx, str); - if (!str) { - JS_ReportError(cx, "String internization failed."); - return false; - } - - // By internizing the id's we ensure that they won't get - // GCed so we can use them as hash keys. - jsid id = INTERNED_STRING_TO_JSID(cx, str); - whitelist->put(JSID_BITS(id)); - } - } - - return true; -} - /***************************************************************************/ // static diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index d5cf7d1445ef..144fb13c360c 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -1360,14 +1360,17 @@ bool SetAddonInterposition(const nsACString& addonIdStr, nsIAddonInterposition* interposition) { JSAddonId* addonId; - // We enter the junk scope just to allocate a string, which actually will go - // in the system zone. - AutoJSAPI jsapi; - jsapi.Init(xpc::PrivilegedJunkScope()); - addonId = NewAddonId(jsapi.cx(), addonIdStr); - if (!addonId) - return false; - return XPCWrappedNativeScope::SetAddonInterposition(jsapi.cx(), addonId, interposition); + { + // We enter the junk scope just to allocate a string, which actually will go + // in the system zone. + AutoJSAPI jsapi; + jsapi.Init(xpc::PrivilegedJunkScope()); + addonId = NewAddonId(jsapi.cx(), addonIdStr); + if (!addonId) + return false; + } + + return XPCWrappedNativeScope::SetAddonInterposition(addonId, interposition); } } // namespace xpc diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 8dc0ceec9d3d..9c7f11244003 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -1018,17 +1018,6 @@ static inline bool IS_PROTO_CLASS(const js::Class* clazz) clazz == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass; } -typedef js::HashSet, - js::SystemAllocPolicy> InterpositionWhitelist; - -struct InterpositionWhitelistPair { - nsIAddonInterposition* interposition; - InterpositionWhitelist whitelist; -}; - -typedef nsTArray InterpositionWhitelistArray; - /***************************************************************************/ // XPCWrappedNativeScope is one-to-one with a JS global object. @@ -1198,14 +1187,9 @@ public: bool HasInterposition() { return mInterposition; } nsCOMPtr GetInterposition(); - static bool SetAddonInterposition(JSContext* cx, - JSAddonId* addonId, + static bool SetAddonInterposition(JSAddonId* addonId, nsIAddonInterposition* interp); - static InterpositionWhitelist* GetInterpositionWhitelist(nsIAddonInterposition* interposition); - static bool UpdateInterpositionWhitelist(JSContext* cx, - nsIAddonInterposition* interposition); - void SetAddonCallInterposition() { mHasCallInterpositions = true; } bool HasCallInterposition() { return mHasCallInterpositions; }; @@ -1228,8 +1212,6 @@ private: static InterpositionMap* gInterpositionMap; - static InterpositionWhitelistArray* gInterpositionWhitelists; - XPCJSRuntime* mRuntime; Native2WrappedNativeMap* mWrappedNativeMap; ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap; diff --git a/js/xpconnect/tests/unit/test_interposition.js b/js/xpconnect/tests/unit/test_interposition.js index f755bbd7d443..2590114b2472 100644 --- a/js/xpconnect/tests/unit/test_interposition.js +++ b/js/xpconnect/tests/unit/test_interposition.js @@ -34,11 +34,6 @@ let TestInterposition = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition, Ci.nsISupportsWeakReference]), - getWhitelist: function() { - return ["abcxyz", "utils", "dataprop", "getterprop", "setterprop", - "objprop", "defineprop", "configurableprop"]; - }, - interposeProperty: function(addonId, target, iid, prop) { do_check_eq(addonId, ADDONID); do_check_eq(gExpectedProp, prop); diff --git a/js/xpconnect/wrappers/AddonWrapper.cpp b/js/xpconnect/wrappers/AddonWrapper.cpp index e0fdd960568c..b73d365c1d96 100644 --- a/js/xpconnect/wrappers/AddonWrapper.cpp +++ b/js/xpconnect/wrappers/AddonWrapper.cpp @@ -29,12 +29,11 @@ InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId // wrapped natives. RootedObject unwrapped(cx, UncheckedUnwrap(target)); const js::Class* clasp = js::GetObjectClass(unwrapped); - bool isCPOW = jsipc::IsWrappedCPOW(unwrapped); if (!mozilla::dom::IsDOMClass(clasp) && !IS_WN_CLASS(clasp) && !IS_PROTO_CLASS(clasp) && clasp != &OuterWindowProxyClass && - !isCPOW) { + !jsipc::IsWrappedCPOW(unwrapped)) { return true; } @@ -42,12 +41,6 @@ InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId MOZ_ASSERT(scope->HasInterposition()); nsCOMPtr interp = scope->GetInterposition(); - InterpositionWhitelist* wl = XPCWrappedNativeScope::GetInterpositionWhitelist(interp); - // We do InterposeProperty only if the id is on the whitelist of the interpostion - // or if the target is a CPOW. - if ((!wl || !wl->has(JSID_BITS(id.get()))) && !isCPOW) - return true; - JSAddonId* addonId = AddonIdOfObject(target); RootedValue addonIdValue(cx, StringValue(StringOfAddonId(addonId))); RootedValue prop(cx, IdToValue(id)); diff --git a/toolkit/components/addoncompat/defaultShims.js b/toolkit/components/addoncompat/defaultShims.js index a786efed7d39..107d6ee8fd48 100644 --- a/toolkit/components/addoncompat/defaultShims.js +++ b/toolkit/components/addoncompat/defaultShims.js @@ -22,10 +22,6 @@ DefaultInterpositionService.prototype = { classID: Components.ID("{50bc93ce-602a-4bef-bf3a-61fc749c4caf}"), QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition, Ci.nsISupportsWeakReference]), - getWhitelist: function() { - return []; - }, - interposeProperty: function(addon, target, iid, prop) { return null; }, diff --git a/toolkit/components/addoncompat/moz.build b/toolkit/components/addoncompat/moz.build index a7ad54b3ed71..411c28399e84 100644 --- a/toolkit/components/addoncompat/moz.build +++ b/toolkit/components/addoncompat/moz.build @@ -8,7 +8,6 @@ TEST_DIRS += ['tests'] EXTRA_COMPONENTS += [ 'addoncompat.manifest', - 'defaultShims.js', 'multiprocessShims.js', 'remoteTagService.js', ] diff --git a/toolkit/components/addoncompat/multiprocessShims.js b/toolkit/components/addoncompat/multiprocessShims.js index 6c8d559b3c46..0da79015ccc8 100644 --- a/toolkit/components/addoncompat/multiprocessShims.js +++ b/toolkit/components/addoncompat/multiprocessShims.js @@ -70,42 +70,12 @@ function AddonInterpositionService() // kinds of objects. this._interfaceInterpositions = RemoteAddonsParent.getInterfaceInterpositions(); this._taggedInterpositions = RemoteAddonsParent.getTaggedInterpositions(); - - let wl = []; - for (let v in this._interfaceInterpositions) { - let interp = this._interfaceInterpositions[v]; - wl.push(...Object.getOwnPropertyNames(interp.methods)); - wl.push(...Object.getOwnPropertyNames(interp.getters)); - wl.push(...Object.getOwnPropertyNames(interp.setters)); - } - - for (let v in this._taggedInterpositions) { - let interp = this._taggedInterpositions[v]; - wl.push(...Object.getOwnPropertyNames(interp.methods)); - wl.push(...Object.getOwnPropertyNames(interp.getters)); - wl.push(...Object.getOwnPropertyNames(interp.setters)); - } - - let nameSet = new Set(); - wl = wl.filter(function(item) { - if (nameSet.has(item)) - return true; - - nameSet.add(item); - return true; - }); - - this._whitelist = wl; } AddonInterpositionService.prototype = { classID: Components.ID("{1363d5f0-d95e-11e3-9c1a-0800200c9a66}"), QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition, Ci.nsISupportsWeakReference]), - getWhitelist: function() { - return this._whitelist; - }, - // When the interface is not known for a method call, this code // determines the type of the target object. getObjectTag: function(target) { From 50799137e0fd3a154f7c120c9a0e0c09552a5ee5 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Mon, 1 Jun 2015 09:02:35 +0200 Subject: [PATCH 72/85] Bug 1169611 part 2 - Unbox getprop/getelem inputs based on Baseline feedback. r=bhackett --- js/src/jit/BaselineIC.cpp | 44 +++++++++++++------ js/src/jit/BaselineIC.h | 15 ++++++- js/src/jit/BaselineInspector.cpp | 74 ++++++++++++++++++++++++++++++++ js/src/jit/BaselineInspector.h | 1 + js/src/jit/IonBuilder.cpp | 59 +++++++++++++------------ js/src/jit/IonBuilder.h | 5 ++- 6 files changed, 151 insertions(+), 47 deletions(-) diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 4b3b3cbc4226..78cb94106cf0 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -3808,7 +3808,7 @@ IsOptimizableElementPropertyName(JSContext* cx, HandleValue key, MutableHandleId static bool TryAttachNativeGetValueElemStub(JSContext* cx, HandleScript script, jsbytecode* pc, ICGetElem_Fallback* stub, HandleNativeObject obj, - HandleValue key) + HandleValue key, bool* attached) { RootedId id(cx); if (!IsOptimizableElementPropertyName(cx, key, &id)) @@ -3858,6 +3858,7 @@ TryAttachNativeGetValueElemStub(JSContext* cx, HandleScript script, jsbytecode* return false; stub->addNewStub(newStub); + *attached = true; } return true; } @@ -3865,7 +3866,7 @@ TryAttachNativeGetValueElemStub(JSContext* cx, HandleScript script, jsbytecode* static bool TryAttachNativeGetAccessorElemStub(JSContext* cx, HandleScript script, jsbytecode* pc, ICGetElem_Fallback* stub, HandleNativeObject obj, - HandleValue key, bool* attached) + HandleValue key, bool* attached, bool* isTemporarilyUnoptimizable) { MOZ_ASSERT(!*attached); @@ -3881,15 +3882,15 @@ TryAttachNativeGetAccessorElemStub(JSContext* cx, HandleScript script, jsbytecod RootedObject baseHolder(cx); if (!EffectlesslyLookupProperty(cx, obj, propName, &baseHolder, &shape)) return false; - if(!baseHolder || baseHolder->isNative()) + if (!baseHolder || baseHolder->isNative()) return true; HandleNativeObject holder = baseHolder.as(); bool getterIsScripted = false; - bool isTemporarilyUnoptimizable = false; if (IsCacheableGetPropCall(cx, obj, baseHolder, shape, &getterIsScripted, - &isTemporarilyUnoptimizable, /*isDOMProxy=*/false)) { + isTemporarilyUnoptimizable, /*isDOMProxy=*/false)) + { RootedFunction getter(cx, &shape->getterObject()->as()); #if JS_HAS_NO_SUCH_METHOD @@ -4003,7 +4004,7 @@ IsNativeOrUnboxedDenseElementAccess(HandleObject obj, HandleValue key) static bool TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_Fallback* stub, - HandleValue lhs, HandleValue rhs, HandleValue res) + HandleValue lhs, HandleValue rhs, HandleValue res, bool* attached) { bool isCallElem = (JSOp(*pc) == JSOP_CALLELEM); @@ -4020,6 +4021,7 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_ return false; stub->addNewStub(stringStub); + *attached = true; return true; } @@ -4038,6 +4040,7 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_ return false; stub->addNewStub(argsStub); + *attached = true; return true; } @@ -4060,6 +4063,7 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_ return false; stub->addNewStub(argsStub); + *attached = true; return true; } } @@ -4074,6 +4078,7 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_ return false; stub->addNewStub(denseStub); + *attached = true; return true; } @@ -4081,10 +4086,12 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_ if (obj->isNative() && rhs.isString()) { RootedScript rootedScript(cx, script); if (!TryAttachNativeGetValueElemStub(cx, rootedScript, pc, stub, - obj.as(), rhs)) + obj.as(), rhs, attached)) { return false; } + if (*attached) + return true; script = rootedScript; } @@ -4098,6 +4105,7 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_ return false; stub->addNewStub(unboxedStub); + *attached = true; return true; } @@ -4131,6 +4139,7 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_ return false; stub->addNewStub(typedArrayStub); + *attached = true; return true; } @@ -4179,15 +4188,20 @@ DoGetElemFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback* stub_ if (stub->numOptimizedStubs() >= ICGetElem_Fallback::MAX_OPTIMIZED_STUBS) { // TODO: Discard all stubs in this IC and replace with inert megamorphic stub. // But for now we just bail. + stub->noteUnoptimizableAccess(); attached = true; } // Try to attach an optimized getter stub. + bool isTemporarilyUnoptimizable = false; if (!attached && lhs.isObject() && lhs.toObject().isNative() && rhs.isString()){ RootedScript rootedScript(cx, frame->script()); RootedNativeObject obj(cx, &lhs.toObject().as()); - if (!TryAttachNativeGetAccessorElemStub(cx, rootedScript, pc, stub, obj, rhs, &attached)) + if (!TryAttachNativeGetAccessorElemStub(cx, rootedScript, pc, stub, obj, rhs, &attached, + &isTemporarilyUnoptimizable)) + { return false; + } script = rootedScript; } @@ -4209,11 +4223,11 @@ DoGetElemFallback(JSContext* cx, BaselineFrame* frame, ICGetElem_Fallback* stub_ return true; // Try to attach an optimized stub. - if (!TryAttachGetElemStub(cx, frame->script(), pc, stub, lhs, rhs, res)) + if (!TryAttachGetElemStub(cx, frame->script(), pc, stub, lhs, rhs, res, &attached)) return false; - // If we ever add a way to note unoptimizable accesses here, propagate the - // isTemporarilyUnoptimizable state from TryAttachNativeGetElemStub to here. + if (!attached && !isTemporarilyUnoptimizable) + stub->noteUnoptimizableAccess(); return true; } @@ -12682,11 +12696,15 @@ ICGetIntrinsic_Constant::~ICGetIntrinsic_Constant() { } ICGetProp_Primitive::ICGetProp_Primitive(JitCode* stubCode, ICStub* firstMonitorStub, - Shape* protoShape, uint32_t offset) + JSValueType primitiveType, Shape* protoShape, + uint32_t offset) : ICMonitoredStub(GetProp_Primitive, stubCode, firstMonitorStub), protoShape_(protoShape), offset_(offset) -{ } +{ + extra_ = uint16_t(primitiveType); + MOZ_ASSERT(JSValueType(extra_) == primitiveType); +} ICGetPropNativeStub::ICGetPropNativeStub(ICStub::Kind kind, JitCode* stubCode, ICStub* firstMonitorStub, diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index b570c07de6bd..7894a44b5b82 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -2638,6 +2638,7 @@ class ICGetElem_Fallback : public ICMonitoredFallbackStub static const uint16_t EXTRA_NON_NATIVE = 0x1; static const uint16_t EXTRA_NEGATIVE_INDEX = 0x2; + static const uint16_t EXTRA_UNOPTIMIZABLE_ACCESS = 0x4; public: static const uint32_t MAX_OPTIMIZED_STUBS = 16; @@ -2655,6 +2656,12 @@ class ICGetElem_Fallback : public ICMonitoredFallbackStub bool hasNegativeIndex() const { return extra_ & EXTRA_NEGATIVE_INDEX; } + void noteUnoptimizableAccess() { + extra_ |= EXTRA_UNOPTIMIZABLE_ACCESS; + } + bool hadUnoptimizableAccess() const { + return extra_ & EXTRA_UNOPTIMIZABLE_ACCESS; + } // Compiler for this stub kind. class Compiler : public ICStubCompiler { @@ -4109,13 +4116,17 @@ class ICGetProp_Primitive : public ICMonitoredStub // Fixed or dynamic slot offset. uint32_t offset_; - ICGetProp_Primitive(JitCode* stubCode, ICStub* firstMonitorStub, + ICGetProp_Primitive(JitCode* stubCode, ICStub* firstMonitorStub, JSValueType primitiveType, Shape* protoShape, uint32_t offset); public: HeapPtrShape& protoShape() { return protoShape_; } + JSValueType primitiveType() const { + return JSValueType(extra_); + } + static size_t offsetOfProtoShape() { return offsetof(ICGetProp_Primitive, protoShape_); } @@ -4155,7 +4166,7 @@ class ICGetProp_Primitive : public ICMonitoredStub ICStub* getStub(ICStubSpace* space) { RootedShape protoShape(cx, prototype_->as().lastProperty()); return newStub(space, getStubCode(), firstMonitorStub_, - protoShape, offset_); + primitiveType_, protoShape, offset_); } }; }; diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index d743beac0e32..95b93faa165e 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -702,6 +702,80 @@ BaselineInspector::commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shap return true; } +MIRType +BaselineInspector::expectedPropertyAccessInputType(jsbytecode* pc) +{ + if (!hasBaselineScript()) + return MIRType_Value; + + const ICEntry& entry = icEntryFromPC(pc); + MIRType type = MIRType_None; + + for (ICStub* stub = entry.firstStub(); stub; stub = stub->next()) { + MIRType stubType; + switch (stub->kind()) { + case ICStub::GetProp_Fallback: + if (stub->toGetProp_Fallback()->hadUnoptimizableAccess()) + return MIRType_Value; + continue; + + case ICStub::GetElem_Fallback: + if (stub->toGetElem_Fallback()->hadUnoptimizableAccess()) + return MIRType_Value; + continue; + + case ICStub::GetProp_Generic: + return MIRType_Value; + + case ICStub::GetProp_ArgumentsLength: + case ICStub::GetElem_Arguments: + // Either an object or magic arguments. + return MIRType_Value; + + case ICStub::GetProp_ArrayLength: + case ICStub::GetProp_Native: + case ICStub::GetProp_NativeDoesNotExist: + case ICStub::GetProp_NativePrototype: + case ICStub::GetProp_Unboxed: + case ICStub::GetProp_TypedObject: + case ICStub::GetProp_CallScripted: + case ICStub::GetProp_CallNative: + case ICStub::GetProp_CallDOMProxyNative: + case ICStub::GetProp_CallDOMProxyWithGenerationNative: + case ICStub::GetProp_DOMProxyShadowed: + case ICStub::GetElem_NativeSlot: + case ICStub::GetElem_NativePrototypeSlot: + case ICStub::GetElem_NativePrototypeCallNative: + case ICStub::GetElem_NativePrototypeCallScripted: + case ICStub::GetElem_String: + case ICStub::GetElem_Dense: + case ICStub::GetElem_TypedArray: + stubType = MIRType_Object; + break; + + case ICStub::GetProp_Primitive: + stubType = MIRTypeFromValueType(stub->toGetProp_Primitive()->primitiveType()); + break; + + case ICStub::GetProp_StringLength: + stubType = MIRType_String; + break; + + default: + MOZ_CRASH("Unexpected stub"); + } + + if (type != MIRType_None) { + if (type != stubType) + return MIRType_Value; + } else { + type = stubType; + } + } + + return (type == MIRType_None) ? MIRType_Value : type; +} + bool BaselineInspector::instanceOfData(jsbytecode* pc, Shape** shape, uint32_t* slot, JSObject** prototypeObject) diff --git a/js/src/jit/BaselineInspector.h b/js/src/jit/BaselineInspector.h index d0e0965201a0..10d61d849eac 100644 --- a/js/src/jit/BaselineInspector.h +++ b/js/src/jit/BaselineInspector.h @@ -104,6 +104,7 @@ class BaselineInspector MIRType expectedResultType(jsbytecode* pc); MCompare::CompareType expectedCompareType(jsbytecode* pc); MIRType expectedBinaryArithSpecialization(jsbytecode* pc); + MIRType expectedPropertyAccessInputType(jsbytecode* pc); bool hasSeenNonNativeGetElement(jsbytecode* pc); bool hasSeenNegativeIndexGetElement(jsbytecode* pc); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index e7b0bd05b31c..845165b7372e 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -7195,15 +7195,10 @@ IonBuilder::testSingletonProperty(JSObject* obj, PropertyName* name) } JSObject* -IonBuilder::testSingletonPropertyTypes(MDefinition* obj, PropertyName* name, - bool* testObject, bool* testString) +IonBuilder::testSingletonPropertyTypes(MDefinition* obj, PropertyName* name) { // As for TestSingletonProperty, but the input is any value in a type set - // rather than a specific object. If testObject is set then the constant - // result can only be used after ensuring the input is an object. - - *testObject = false; - *testString = false; + // rather than a specific object. TemporaryTypeSet* types = obj->resultTypeSet(); if (types && types->unknownObject()) @@ -7213,8 +7208,12 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, PropertyName* name, if (objectSingleton) return testSingletonProperty(objectSingleton, name); + MIRType objType = obj->type(); + if (objType == MIRType_Value && types) + objType = types->getKnownMIRType(); + JSProtoKey key; - switch (obj->type()) { + switch (objType) { case MIRType_String: key = JSProto_String; break; @@ -7232,20 +7231,10 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, PropertyName* name, key = JSProto_Boolean; break; - case MIRType_Object: - case MIRType_Value: { + case MIRType_Object: { if (!types) return nullptr; - if (types->hasType(TypeSet::StringType())) { - key = JSProto_String; - *testString = true; - break; - } - - if (!types->maybeObject()) - return nullptr; - // For property accesses which may be on many objects, we just need to // find a prototype common to all the objects; if that prototype // has the singleton property, the access will not be on a missing property. @@ -7282,8 +7271,6 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, PropertyName* name, return nullptr; } } - // If this is not a known object, a test will be needed. - *testObject = (obj->type() != MIRType_Object); return singleton; } default: @@ -7739,6 +7726,8 @@ IonBuilder::jsop_getelem() return pushTypeBarrier(ins, types, BarrierKind::TypeSet); } + obj = maybeUnboxForPropertyAccess(obj); + bool emitted = false; trackOptimizationAttempt(TrackedStrategy::GetElem_TypedObject); @@ -10017,6 +10006,21 @@ IonBuilder::shouldAbortOnPreliminaryGroups(MDefinition *obj) return preliminary; } +MDefinition* +IonBuilder::maybeUnboxForPropertyAccess(MDefinition* def) +{ + if (def->type() != MIRType_Value) + return def; + + MIRType type = inspector->expectedPropertyAccessInputType(pc); + if (type == MIRType_Value || !def->mightBeType(type)) + return def; + + MUnbox* unbox = MUnbox::New(alloc(), def, type, MUnbox::Fallible); + current->add(unbox); + return unbox; +} + bool IonBuilder::jsop_getprop(PropertyName* name) { @@ -10042,6 +10046,8 @@ IonBuilder::jsop_getprop(PropertyName* name) return emitted; } + obj = maybeUnboxForPropertyAccess(obj); + BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), obj, name, types); @@ -10316,19 +10322,12 @@ IonBuilder::getPropTryConstant(bool* emitted, MDefinition* obj, PropertyName* na return true; } - bool testObject, testString; - JSObject* singleton = testSingletonPropertyTypes(obj, name, &testObject, &testString); + JSObject* singleton = testSingletonPropertyTypes(obj, name); if (!singleton) return true; // Property access is a known constant -- safe to emit. - MOZ_ASSERT(!testString || !testObject); - if (testObject) - current->add(MGuardObject::New(alloc(), obj)); - else if (testString) - current->add(MGuardString::New(alloc(), obj)); - else - obj->setImplicitlyUsedUnchecked(); + obj->setImplicitlyUsedUnchecked(); pushConstant(ObjectValue(*singleton)); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index aeeed8f01380..ace8c2d8707e 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -422,6 +422,7 @@ class IonBuilder bool shouldAbortOnPreliminaryGroups(MDefinition *obj); MDefinition* tryInnerizeWindow(MDefinition* obj); + MDefinition* maybeUnboxForPropertyAccess(MDefinition* def); // jsop_getprop() helpers. bool checkIsDefinitelyOptimizedArguments(MDefinition* obj, bool* isOptimizedArgs); @@ -941,8 +942,8 @@ class IonBuilder MGetPropertyCache* getInlineableGetPropertyCache(CallInfo& callInfo); JSObject* testSingletonProperty(JSObject* obj, PropertyName* name); - JSObject* testSingletonPropertyTypes(MDefinition* obj, PropertyName* name, - bool* testObject, bool* testString); + JSObject* testSingletonPropertyTypes(MDefinition* obj, PropertyName* name); + uint32_t getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_t* pnfixed, BaselineInspector::ObjectGroupVector& convertUnboxedGroups); MDefinition* convertUnboxedObjects(MDefinition* obj, From db365593685ff5715122ab38fc257509b446d4f2 Mon Sep 17 00:00:00 2001 From: Chris Peterson Date: Sun, 31 May 2015 19:38:34 -0700 Subject: [PATCH 73/85] Bug 1170059 - Fix -Wunreachable-code clang warnings in webrtc/signaling. r=jesup --- media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp | 3 +-- media/webrtc/signaling/src/sdp/sipcc/sdp_attr.c | 4 ---- media/webrtc/signaling/src/sdp/sipcc/sdp_attr_access.c | 6 ------ 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp index 0374184a510a..839c0bc48555 100644 --- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp +++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp @@ -991,9 +991,8 @@ void MediaPipelineTransmit::PipelineListener::ProcessAudioChunk( memset(samples, 0, chunk.mDuration * sizeof(samples[0])); break; default: - MOZ_ASSERT(PR_FALSE); + MOZ_ASSERT_UNREACHABLE("Unexpected AudioSampleFormat"); return; - break; } } else { // This means silence. diff --git a/media/webrtc/signaling/src/sdp/sipcc/sdp_attr.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_attr.c index 860e3d4f3341..577cb63772a2 100644 --- a/media/webrtc/signaling/src/sdp/sipcc/sdp_attr.c +++ b/media/webrtc/signaling/src/sdp/sipcc/sdp_attr.c @@ -5163,13 +5163,11 @@ sdp_result_e sdp_parse_attr_setup(sdp_t *sdp_p, "%s Warning: Unknown setup attribute", sdp_p->debug_str); return SDP_INVALID_PARAMETER; - break; default: /* This is an internal error, not a parsing error */ CSFLogError(logTag, "%s Error: Invalid setup enum (%d)", sdp_p->debug_str, attr_p->attr.setup); return SDP_FAILURE; - break; } return SDP_SUCCESS; @@ -5223,13 +5221,11 @@ sdp_result_e sdp_parse_attr_connection(sdp_t *sdp_p, "%s Warning: Unknown connection attribute", sdp_p->debug_str); return SDP_INVALID_PARAMETER; - break; default: /* This is an internal error, not a parsing error */ CSFLogError(logTag, "%s Error: Invalid connection enum (%d)", sdp_p->debug_str, attr_p->attr.connection); return SDP_FAILURE; - break; } return SDP_SUCCESS; } diff --git a/media/webrtc/signaling/src/sdp/sipcc/sdp_attr_access.c b/media/webrtc/signaling/src/sdp/sipcc/sdp_attr_access.c index dd6fb7273acc..0f0b889286a4 100644 --- a/media/webrtc/signaling/src/sdp/sipcc/sdp_attr_access.c +++ b/media/webrtc/signaling/src/sdp/sipcc/sdp_attr_access.c @@ -1625,8 +1625,6 @@ sdp_result_e sdp_attr_get_ice_attribute (sdp_t *sdp_p, uint16_t level, sdp_p->conf_p->num_invalid_param++; return (SDP_INVALID_PARAMETER); } - - return (SDP_FAILURE); } /* Function: sdp_attr_is_present @@ -1693,8 +1691,6 @@ sdp_result_e sdp_attr_get_rtcp_mux_attribute (sdp_t *sdp_p, uint16_t level, sdp_p->conf_p->num_invalid_param++; return (SDP_INVALID_PARAMETER); } - - return (SDP_FAILURE); } /* Function: sdp_attr_get_setup_attribute @@ -1798,8 +1794,6 @@ sdp_result_e sdp_attr_get_dtls_fingerprint_attribute (sdp_t *sdp_p, uint16_t lev sdp_p->conf_p->num_invalid_param++; return (SDP_INVALID_PARAMETER); } - - return (SDP_FAILURE); } /* Function: sdp_attr_sprtmap_payload_valid From f5612c6c051308ae799d87e9b9d70a0d920d299a Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Sun, 31 May 2015 20:05:28 -0700 Subject: [PATCH 74/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/102f45e23dea Author: George Desc: Merge pull request #30282 from cctuan/1169206 Bug 1169206 - Error when 2nd make and remove clean-stage-app step ======== https://hg.mozilla.org/integration/gaia-central/rev/2727758efd28 Author: cctuan Desc: Bug 1169206 - Error when 2nd make and remove clean-stage-app step --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index e715b3e99bc2..53c54e98bb9d 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "4ac2e0e4f7ef9c863143a4d6da21afdeb8ab8940", + "git_revision": "27d847fd7a1eed6a0a66c30398cd165ec87f873c", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "b9f3e9d5bdc253558e3887f81fbe3ff8c208f836", + "revision": "102f45e23deaf045b360c4a7cdfb8d4dc1c283bb", "repo_path": "integration/gaia-central" } From 17b2cea4ef36af0d96653e09252250df90fd6c9b Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Sun, 31 May 2015 20:07:24 -0700 Subject: [PATCH 75/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 760b712d3189..1201380e8f64 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 1d4b6986e1d3..19294e308249 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 222b092f3aa2..c5b8a7768151 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index fc5c47a129e2..b4c9a77ea4aa 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 8b5ca9601ad4..701766d9ce9a 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index db546ad29213..ce871e028722 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 222b092f3aa2..c5b8a7768151 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index fca1a851d45d..fb703856fb8d 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index f0ff0667ee1d..8a719d30a6d1 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 8dd1f4dfbb26..d332123b6c0e 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 238699784764a698880f09d35ccaa1610bb3b6e0 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Sun, 31 May 2015 20:40:31 -0700 Subject: [PATCH 76/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ======== https://hg.mozilla.org/integration/gaia-central/rev/698b98717410 Author: Sung Chiu Desc: Merge pull request #30281 from sean2449/Bug-1168722-display-css Bug 1168722 - [Stingray][EPG] Update program info section and refacto…, r=johnhu ======== https://hg.mozilla.org/integration/gaia-central/rev/12e37100b2c2 Author: Sung Chiu Desc: Bug 1168722 - [Stingray][EPG] Update program info section and refactor layout --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 53c54e98bb9d..2bbae137df66 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "27d847fd7a1eed6a0a66c30398cd165ec87f873c", + "git_revision": "694656c9935a5421f80bd25562cb927f87ea9b65", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "102f45e23deaf045b360c4a7cdfb8d4dc1c283bb", + "revision": "698b987174109d0c8c036b816a2cb1c918d7ed7a", "repo_path": "integration/gaia-central" } From 4b1f4aa578c52638b218e9f338e77c708970b551 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Sun, 31 May 2015 20:42:55 -0700 Subject: [PATCH 77/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 1201380e8f64..d009de79b1a2 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 19294e308249..2077a3186d65 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index c5b8a7768151..bfbeb17a34ee 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index b4c9a77ea4aa..4e8ac86a062a 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 701766d9ce9a..7c2b2bd81d05 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index ce871e028722..34d84061c326 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index c5b8a7768151..bfbeb17a34ee 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index fb703856fb8d..9616b3c8bc23 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 8a719d30a6d1..b7941da9a1b8 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index d332123b6c0e..ce1273fe7f43 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 5fed4ccb1986f346c8f9f984ed6668eb1ee6ec0b Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Sun, 31 May 2015 21:26:30 -0700 Subject: [PATCH 78/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ======== https://hg.mozilla.org/integration/gaia-central/rev/5e79edb42ebf Author: Sung Chiu Desc: Merge pull request #30303 from sean2449/Bug-1169540 Bug 1169540 - [Stingray][Shared] Clock should refresh again before se…, r=johnhu ======== https://hg.mozilla.org/integration/gaia-central/rev/e5ea504d5d18 Author: Sung Chiu Desc: Bug 1169540 - [Stingray][Shared] Clock should refresh again before setInterval --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 2bbae137df66..e6ab02365b21 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "694656c9935a5421f80bd25562cb927f87ea9b65", + "git_revision": "7b31544768c6e32348e4b032cf6fceefb98d90b3", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "698b987174109d0c8c036b816a2cb1c918d7ed7a", + "revision": "5e79edb42ebfede069f8f38105aadd12a7dd7909", "repo_path": "integration/gaia-central" } From 4548fc1e3a7b8bc9b5e2fff3994dd4aba1b8adec Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Sun, 31 May 2015 21:28:27 -0700 Subject: [PATCH 79/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index d009de79b1a2..4a0625bfe848 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 2077a3186d65..4b3882cec8a0 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index bfbeb17a34ee..aadfa22f81d0 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 4e8ac86a062a..872ac26656b1 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 7c2b2bd81d05..87e27879b983 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 34d84061c326..b44a77b799c6 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index bfbeb17a34ee..aadfa22f81d0 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 9616b3c8bc23..3452b088eaee 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index b7941da9a1b8..16730d5d4fcf 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index ce1273fe7f43..56fd42430d4b 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 2e464cd4bdfb8e5b33c3b32e45c815b7de3a4d7e Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 1 Jun 2015 00:00:26 -0700 Subject: [PATCH 80/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/a4d81914887c Author: John Hu Desc: Merge pull request #30304 from john-hu/bug-1169507-focus-while-opening-closed Bug 1169507 - Set focus while modal-dialog-will-open event fired, r=chens ======== https://hg.mozilla.org/integration/gaia-central/rev/6123fddfd5a9 Author: John Hu Desc: Bug 1169507 - Set focus while modal-dialog-will-open event fired --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index e6ab02365b21..7ddce8f8586b 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "7b31544768c6e32348e4b032cf6fceefb98d90b3", + "git_revision": "85e6fcef45c0cb2c017739df42b68b96cf5bb9c3", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "5e79edb42ebfede069f8f38105aadd12a7dd7909", + "revision": "a4d81914887c6dac8e96e149a573d22fa313444f", "repo_path": "integration/gaia-central" } From a4ee2b766e754f28addb6ee3d594490b7ab4f64b Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 1 Jun 2015 00:02:22 -0700 Subject: [PATCH 81/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 4a0625bfe848..e52b48b6426f 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 4b3882cec8a0..aa9c0cdfb411 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index aadfa22f81d0..a5d74d80957a 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 872ac26656b1..f8c514c163db 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 87e27879b983..92d4fdbc6fcd 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index b44a77b799c6..a7babf68e13f 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index aadfa22f81d0..a5d74d80957a 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 3452b088eaee..8093909f28af 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 16730d5d4fcf..3d907cddcae5 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 56fd42430d4b..75b03f6d4a4e 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 810f7a1dfefdd0fe142aa1427cdbb516e0483d7a Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Mon, 1 Jun 2015 09:12:46 +0100 Subject: [PATCH 82/85] Bug 1148660 - Correct the handling of glyph positioning offsets in vertical-upright mode. r=jdaggett --- gfx/thebes/gfxFont.cpp | 2 +- gfx/thebes/gfxHarfBuzzShaper.cpp | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 64e44ec528de..d714266ea9ec 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -2249,7 +2249,7 @@ gfxFont::Measure(gfxTextRun *aTextRun, const gfxTextRun::DetailedGlyph *details = aTextRun->GetDetailedGlyphs(i); NS_ASSERTION(details != nullptr, - "detaiedGlyph record should not be missing!"); + "detailedGlyph record should not be missing!"); uint32_t j; for (j = 0; j < glyphCount; ++j, ++details) { uint32_t glyphIndex = details->mGlyphID; diff --git a/gfx/thebes/gfxHarfBuzzShaper.cpp b/gfx/thebes/gfxHarfBuzzShaper.cpp index 1790a405af83..453860041e8a 100644 --- a/gfx/thebes/gfxHarfBuzzShaper.cpp +++ b/gfx/thebes/gfxHarfBuzzShaper.cpp @@ -1791,10 +1791,18 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxContext *aContext, charGlyphs[baseCharIndex].SetSimpleGlyph(advance, ginfo[glyphStart].codepoint); } else { - // collect all glyphs in a list to be assigned to the first char; + // Collect all glyphs in a list to be assigned to the first char; // there must be at least one in the clump, and we already measured // its advance, hence the placement of the loop-exit test and the - // measurement of the next glyph + // measurement of the next glyph. + // For vertical orientation, we add a "base offset" to compensate + // for the positioning within the cluster being based on horizontal + // glyph origin/offset. + hb_position_t baseIOffset, baseBOffset; + if (aVertical) { + baseIOffset = 2 * (i_offset - i_advance); + baseBOffset = GetGlyphHAdvance(ginfo[glyphStart].codepoint); + } while (1) { gfxTextRun::DetailedGlyph* details = detailedGlyphs.AppendElement(); @@ -1817,9 +1825,9 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxContext *aContext, } if (aVertical) { - i_offset = posInfo[glyphStart].y_offset; + i_offset = baseIOffset - posInfo[glyphStart].y_offset; i_advance = posInfo[glyphStart].y_advance; - b_offset = posInfo[glyphStart].x_offset; + b_offset = baseBOffset - posInfo[glyphStart].x_offset; b_advance = posInfo[glyphStart].x_advance; } else { i_offset = posInfo[glyphStart].x_offset; From 0d2e591a3da985628330982225471bc2104505a9 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Mon, 1 Jun 2015 09:13:29 +0100 Subject: [PATCH 83/85] Bug 964512 - Check for existence of character before trying to get its metrics in gfxGDIFont::Initialize. r=jdaggett --- gfx/thebes/gfxGDIFont.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/gfx/thebes/gfxGDIFont.cpp b/gfx/thebes/gfxGDIFont.cpp index 6ba3b592f6ba..2c33860469c9 100644 --- a/gfx/thebes/gfxGDIFont.cpp +++ b/gfx/thebes/gfxGDIFont.cpp @@ -337,26 +337,27 @@ gfxGDIFont::Initialize() } } - // Cache the width of a single space. - SIZE size; - GetTextExtentPoint32W(dc.GetDC(), L" ", 1, &size); - mMetrics->spaceWidth = ROUND(size.cx); - - // Cache the width of digit zero. - // XXX MSDN (http://msdn.microsoft.com/en-us/library/ms534223.aspx) - // does not say what the failure modes for GetTextExtentPoint32 are - - // is it safe to assume it will fail iff the font has no '0'? - if (GetTextExtentPoint32W(dc.GetDC(), L"0", 1, &size)) { - mMetrics->zeroOrAveCharWidth = ROUND(size.cx); - } else { - mMetrics->zeroOrAveCharWidth = mMetrics->aveCharWidth; - } - WORD glyph; + SIZE size; DWORD ret = GetGlyphIndicesW(dc.GetDC(), L" ", 1, &glyph, GGI_MARK_NONEXISTING_GLYPHS); if (ret != GDI_ERROR && glyph != 0xFFFF) { mSpaceGlyph = glyph; + // Cache the width of a single space. + GetTextExtentPoint32W(dc.GetDC(), L" ", 1, &size); + mMetrics->spaceWidth = ROUND(size.cx); + } else { + mMetrics->spaceWidth = mMetrics->aveCharWidth; + } + + // Cache the width of digit zero, if available. + ret = GetGlyphIndicesW(dc.GetDC(), L"0", 1, &glyph, + GGI_MARK_NONEXISTING_GLYPHS); + if (ret != GDI_ERROR && glyph != 0xFFFF) { + GetTextExtentPoint32W(dc.GetDC(), L"0", 1, &size); + mMetrics->zeroOrAveCharWidth = ROUND(size.cx); + } else { + mMetrics->zeroOrAveCharWidth = mMetrics->aveCharWidth; } SanitizeMetrics(mMetrics, GetFontEntry()->mIsBadUnderlineFont); From 9f296aab7373713ab5614185d67970b882e9ebee Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 1 Jun 2015 01:35:28 -0700 Subject: [PATCH 84/85] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/aa653cc24c71 Author: Alive.Kuo Desc: Merge pull request #29932 from alivedise/new-bootstrap-0507 Bug 1094759 - new bootstrap, r=etienne, timdream, mhenrenty ======== https://hg.mozilla.org/integration/gaia-central/rev/df20fe075e73 Author: Alive Kuo Desc: Bug 1094759 - new Bootstrap --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 7ddce8f8586b..9533b4cea823 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "85e6fcef45c0cb2c017739df42b68b96cf5bb9c3", + "git_revision": "97c41d6839e2c5fa6962aaf9b1720adf79f219ba", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "a4d81914887c6dac8e96e149a573d22fa313444f", + "revision": "aa653cc24c710327fa734718ea1af94e470f77bc", "repo_path": "integration/gaia-central" } From c67b1940c9f359a96307b3ec0853bba4d03a4afb Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 1 Jun 2015 01:37:24 -0700 Subject: [PATCH 85/85] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index e52b48b6426f..bd2c2b1a9480 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index aa9c0cdfb411..c0192986750f 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index a5d74d80957a..2af2129a4dc2 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index f8c514c163db..acb77b809042 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 92d4fdbc6fcd..81e22c8994fb 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index a7babf68e13f..2b17d1c8c146 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index a5d74d80957a..2af2129a4dc2 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 8093909f28af..cd532135824e 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 3d907cddcae5..19f8a454f99d 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 75b03f6d4a4e..7e70628a720b 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - +