Merge m-c to b2g-inbound.

This commit is contained in:
Ryan VanderMeulen 2013-08-17 12:39:44 -04:00
commit 64bd7ad5a3
125 changed files with 1828 additions and 951 deletions

View File

@ -116,6 +116,7 @@ this.AccessFu = {
Services.obs.addObserver(this, 'Accessibility:PreviousObject', false); Services.obs.addObserver(this, 'Accessibility:PreviousObject', false);
Services.obs.addObserver(this, 'Accessibility:Focus', false); Services.obs.addObserver(this, 'Accessibility:Focus', false);
Services.obs.addObserver(this, 'Accessibility:ActivateObject', false); Services.obs.addObserver(this, 'Accessibility:ActivateObject', false);
Services.obs.addObserver(this, 'Accessibility:LongPress', false);
Services.obs.addObserver(this, 'Accessibility:MoveByGranularity', false); Services.obs.addObserver(this, 'Accessibility:MoveByGranularity', false);
Utils.win.addEventListener('TabOpen', this); Utils.win.addEventListener('TabOpen', this);
Utils.win.addEventListener('TabClose', this); Utils.win.addEventListener('TabClose', this);
@ -159,6 +160,7 @@ this.AccessFu = {
Services.obs.removeObserver(this, 'Accessibility:PreviousObject'); Services.obs.removeObserver(this, 'Accessibility:PreviousObject');
Services.obs.removeObserver(this, 'Accessibility:Focus'); Services.obs.removeObserver(this, 'Accessibility:Focus');
Services.obs.removeObserver(this, 'Accessibility:ActivateObject'); Services.obs.removeObserver(this, 'Accessibility:ActivateObject');
Services.obs.removeObserver(this, 'Accessibility:LongPress');
Services.obs.removeObserver(this, 'Accessibility:MoveByGranularity'); Services.obs.removeObserver(this, 'Accessibility:MoveByGranularity');
if (this.doneCallback) { if (this.doneCallback) {
@ -276,6 +278,9 @@ this.AccessFu = {
case 'Accessibility:ActivateObject': case 'Accessibility:ActivateObject':
this.Input.activateCurrent(JSON.parse(aData)); this.Input.activateCurrent(JSON.parse(aData));
break; break;
case 'Accessibility:LongPress':
this.Input.sendContextMenuMessage();
break;
case 'Accessibility:Focus': case 'Accessibility:Focus':
this._focused = JSON.parse(aData); this._focused = JSON.parse(aData);
if (this._focused) { if (this._focused) {

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1376092730000"> <blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1376427851000">
<emItems> <emItems>
<emItem blockID="i350" id="sqlmoz@facebook.com"> <emItem blockID="i350" id="sqlmoz@facebook.com">
<versionRange minVersion="0" maxVersion="*" severity="3"> <versionRange minVersion="0" maxVersion="*" severity="3">
@ -147,8 +147,10 @@
<versionRange minVersion="0" maxVersion="*" severity="1"> <versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange> </versionRange>
</emItem> </emItem>
<emItem blockID="i429" id="{B40794A0-7477-4335-95C5-8CB9BBC5C4A5}"> <emItem blockID="i443" id="{B40794A0-7477-4335-95C5-8CB9BBC5C4A5}">
<versionRange minVersion="0" maxVersion="*" severity="3"> <versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange> </versionRange>
</emItem> </emItem>
<emItem blockID="i11" id="yslow@yahoo-inc.com"> <emItem blockID="i11" id="yslow@yahoo-inc.com">
@ -198,6 +200,10 @@
<versionRange minVersion="0" maxVersion="*"> <versionRange minVersion="0" maxVersion="*">
</versionRange> </versionRange>
</emItem> </emItem>
<emItem blockID="i442" id="pennerdu@faceobooks.ws">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i168" id="flashX@adobe.com"> <emItem blockID="i168" id="flashX@adobe.com">
<versionRange minVersion="0" maxVersion="*" severity="3"> <versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange> </versionRange>

View File

@ -2275,7 +2275,7 @@
Components.utils.reportError("gBrowser.addProgressListener was " + Components.utils.reportError("gBrowser.addProgressListener was " +
"called with a second argument, " + "called with a second argument, " +
"which is not supported. See bug " + "which is not supported. See bug " +
"608628."); "608628. Call stack: " + new Error().stack);
} }
this.mProgressListeners.push(aListener); this.mProgressListeners.push(aListener);

View File

@ -81,15 +81,15 @@ fi
dnl A high level macro for selecting compiler options. dnl A high level macro for selecting compiler options.
AC_DEFUN([MOZ_COMPILER_OPTS], AC_DEFUN([MOZ_COMPILER_OPTS],
[ [
DEVELOPER_OPTIONS=1 if test -z "$MOZILLA_OFFICIAL"; then
DEVELOPER_OPTIONS=1
fi
MOZ_ARG_ENABLE_BOOL(release, MOZ_ARG_ENABLE_BOOL(release,
[ --enable-release Build with more conservative, release engineering-oriented options. [ --enable-release Build with more conservative, release engineering-oriented options.
This may slow down builds.], This may slow down builds.],
DEVELOPER_OPTIONS=) DEVELOPER_OPTIONS=,
DEVELOPER_OPTIONS=1)
if test -n "$MOZILLA_OFFICIAL" -a -n "$DEVELOPER_OPTIONS"; then
AC_MSG_ERROR([You cannot set MOZILLA_OFFICIAL without --enable-release])
fi
AC_SUBST(DEVELOPER_OPTIONS) AC_SUBST(DEVELOPER_OPTIONS)
MOZ_DEBUGGING_OPTS MOZ_DEBUGGING_OPTS

View File

@ -25,7 +25,7 @@ $(call BUILDSTATUS,SUBTIER_FINISH precompile $(1))
endef endef
export:: export::
$(call BUILDSTATUS,SUBTIERS IPDL WebIDL XPIDL) $(call BUILDSTATUS,SUBTIERS IPDL WebIDL XPIDL XPIDLParser)
export:: ipdl webidl xpidl-parser xpidl export:: ipdl webidl xpidl-parser xpidl

View File

@ -4324,7 +4324,7 @@ nsContentUtils::DropJSObjects(void* aScriptObjectHolder)
bool bool
nsContentUtils::AreJSObjectsHeld(void* aScriptObjectHolder) nsContentUtils::AreJSObjectsHeld(void* aScriptObjectHolder)
{ {
return cyclecollector::TestJSHolder(aScriptObjectHolder); return cyclecollector::IsJSHolder(aScriptObjectHolder);
} }
#endif #endif

View File

@ -21,6 +21,9 @@
#include "nsIURIFixup.h" #include "nsIURIFixup.h"
#include "nsDefaultURIFixup.h" #include "nsDefaultURIFixup.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/ipc/URIUtils.h"
#include "nsIObserverService.h" #include "nsIObserverService.h"
using namespace mozilla; using namespace mozilla;
@ -335,6 +338,28 @@ NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
} }
keyword.Trim(" "); keyword.Trim(" ");
if (XRE_GetProcessType() == GeckoProcessType_Content) {
dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
if (!contentChild) {
return NS_ERROR_NOT_AVAILABLE;
}
ipc::OptionalInputStreamParams postData;
ipc::OptionalURIParams uri;
if (!contentChild->SendKeywordToURI(keyword, &postData, &uri)) {
return NS_ERROR_FAILURE;
}
if (aPostData) {
nsCOMPtr<nsIInputStream> temp = DeserializeInputStream(postData);
temp.forget(aPostData);
}
nsCOMPtr<nsIURI> temp = DeserializeURI(uri);
temp.forget(aURI);
return NS_OK;
}
#ifdef MOZ_TOOLKIT_SEARCH #ifdef MOZ_TOOLKIT_SEARCH
// Try falling back to the search service's default search engine // Try falling back to the search service's default search engine
nsCOMPtr<nsIBrowserSearchService> searchSvc = do_GetService("@mozilla.org/browser/search-service;1"); nsCOMPtr<nsIBrowserSearchService> searchSvc = do_GetService("@mozilla.org/browser/search-service;1");

View File

@ -4536,10 +4536,6 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL,
} }
else if (aURL) else if (aURL)
{ {
// We need a URI object to store a session history entry, so make up a URI
nsresult rv = NS_NewURI(getter_AddRefs(mFailedURI), "about:blank");
NS_ENSURE_SUCCESS(rv, rv);
CopyUTF16toUTF8(aURL, url); CopyUTF16toUTF8(aURL, url);
} }
else else
@ -8002,6 +7998,10 @@ nsDocShell::CreateContentViewer(const char *aContentType,
if (!failedURI) { if (!failedURI) {
failedURI = mFailedURI; failedURI = mFailedURI;
} }
if (!failedURI) {
// We need a URI object to store a session history entry, so make up a URI
NS_NewURI(getter_AddRefs(failedURI), "about:blank");
}
// When we don't have failedURI, something wrong will happen. See // When we don't have failedURI, something wrong will happen. See
// bug 291876. // bug 291876.

View File

@ -20,9 +20,6 @@ NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
NS_IMPL_ADDREF_INHERITED(DOMCursor, DOMRequest) NS_IMPL_ADDREF_INHERITED(DOMCursor, DOMRequest)
NS_IMPL_RELEASE_INHERITED(DOMCursor, DOMRequest) NS_IMPL_RELEASE_INHERITED(DOMCursor, DOMRequest)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(DOMCursor, DOMRequest)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
DOMCursor::DOMCursor(nsIDOMWindow* aWindow, nsICursorContinueCallback* aCallback) DOMCursor::DOMCursor(nsIDOMWindow* aWindow, nsICursorContinueCallback* aCallback)
: DOMRequest(aWindow) : DOMRequest(aWindow)
, mCallback(aCallback) , mCallback(aCallback)
@ -36,9 +33,7 @@ DOMCursor::Reset()
MOZ_ASSERT(!mFinished); MOZ_ASSERT(!mFinished);
// Reset the request state so we can FireSuccess() again. // Reset the request state so we can FireSuccess() again.
if (mRooted) { mResult = JSVAL_VOID;
UnrootResultVal();
}
mDone = false; mDone = false;
} }

View File

@ -22,8 +22,8 @@ class DOMCursor : public DOMRequest
public: public:
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMDOMCURSOR NS_DECL_NSIDOMDOMCURSOR
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(DOMCursor, NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMCursor,
DOMRequest) DOMRequest)
DOMCursor(nsIDOMWindow* aWindow, nsICursorContinueCallback *aCallback); DOMCursor(nsIDOMWindow* aWindow, nsICursorContinueCallback *aCallback);

View File

@ -20,7 +20,6 @@ using mozilla::AutoPushJSContext;
DOMRequest::DOMRequest(nsIDOMWindow* aWindow) DOMRequest::DOMRequest(nsIDOMWindow* aWindow)
: mResult(JSVAL_VOID) : mResult(JSVAL_VOID)
, mDone(false) , mDone(false)
, mRooted(false)
{ {
SetIsDOMBinding(); SetIsDOMBinding();
Init(aWindow); Init(aWindow);
@ -31,7 +30,6 @@ DOMRequest::DOMRequest(nsIDOMWindow* aWindow)
DOMRequest::DOMRequest() DOMRequest::DOMRequest()
: mResult(JSVAL_VOID) : mResult(JSVAL_VOID)
, mDone(false) , mDone(false)
, mRooted(false)
{ {
SetIsDOMBinding(); SetIsDOMBinding();
} }
@ -53,10 +51,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMRequest, NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMRequest,
nsDOMEventTargetHelper) nsDOMEventTargetHelper)
if (tmp->mRooted) {
tmp->UnrootResultVal();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mError) NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
tmp->mResult = JSVAL_VOID;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(DOMRequest, NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(DOMRequest,
@ -193,21 +189,10 @@ DOMRequest::FireEvent(const nsAString& aType, bool aBubble, bool aCancelable)
void void
DOMRequest::RootResultVal() DOMRequest::RootResultVal()
{ {
NS_ASSERTION(!mRooted, "Don't call me if already rooted!");
nsXPCOMCycleCollectionParticipant *participant; nsXPCOMCycleCollectionParticipant *participant;
CallQueryInterface(this, &participant); CallQueryInterface(this, &participant);
nsContentUtils::HoldJSObjects(NS_CYCLE_COLLECTION_UPCAST(this, DOMRequest), nsContentUtils::HoldJSObjects(NS_CYCLE_COLLECTION_UPCAST(this, DOMRequest),
participant); participant);
mRooted = true;
}
void
DOMRequest::UnrootResultVal()
{
NS_ASSERTION(mRooted, "Don't call me if not rooted!");
mResult = JSVAL_VOID;
NS_DROP_JS_OBJECTS(this, DOMRequest);
mRooted = false;
} }
NS_IMPL_ISUPPORTS1(DOMRequestService, nsIDOMRequestService) NS_IMPL_ISUPPORTS1(DOMRequestService, nsIDOMRequestService)

View File

@ -24,7 +24,6 @@ protected:
JS::Heap<JS::Value> mResult; JS::Heap<JS::Value> mResult;
nsCOMPtr<nsISupports> mError; nsCOMPtr<nsISupports> mError;
bool mDone; bool mDone;
bool mRooted;
public: public:
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
@ -78,16 +77,14 @@ public:
virtual ~DOMRequest() virtual ~DOMRequest()
{ {
if (mRooted) { mResult = JSVAL_VOID;
UnrootResultVal(); NS_DROP_JS_OBJECTS(this, DOMRequest);
}
} }
protected: protected:
void FireEvent(const nsAString& aType, bool aBubble, bool aCancelable); void FireEvent(const nsAString& aType, bool aBubble, bool aCancelable);
void RootResultVal(); void RootResultVal();
void UnrootResultVal();
void Init(nsIDOMWindow* aWindow); void Init(nsIDOMWindow* aWindow);
}; };

View File

@ -1593,14 +1593,16 @@ TraceMallocOpenLogFile(JSContext *cx, unsigned argc, JS::Value *vp)
static bool static bool
TraceMallocChangeLogFD(JSContext *cx, unsigned argc, JS::Value *vp) TraceMallocChangeLogFD(JSContext *cx, unsigned argc, JS::Value *vp)
{ {
JS::CallArgs args = CallArgsFromVp(argc, vp);
if (!CheckUniversalXPConnectForTraceMalloc(cx)) if (!CheckUniversalXPConnectForTraceMalloc(cx))
return false; return false;
int32_t fd, oldfd; int32_t fd, oldfd;
if (argc == 0) { if (args.length() == 0) {
oldfd = -1; oldfd = -1;
} else { } else {
if (!JS_ValueToECMAInt32(cx, JS_ARGV(cx, vp)[0], &fd)) if (!JS::ToInt32(cx, args[0], &fd))
return false; return false;
oldfd = NS_TraceMallocChangeLogFD(fd); oldfd = NS_TraceMallocChangeLogFD(fd);
if (oldfd == -2) { if (oldfd == -2) {
@ -1608,23 +1610,27 @@ TraceMallocChangeLogFD(JSContext *cx, unsigned argc, JS::Value *vp)
return false; return false;
} }
} }
JS_SET_RVAL(cx, vp, INT_TO_JSVAL(oldfd)); args.rval().setInt32(oldfd);
return true; return true;
} }
static bool static bool
TraceMallocCloseLogFD(JSContext *cx, unsigned argc, JS::Value *vp) TraceMallocCloseLogFD(JSContext *cx, unsigned argc, JS::Value *vp)
{ {
JS::CallArgs args = CallArgsFromVp(argc, vp);
if (!CheckUniversalXPConnectForTraceMalloc(cx)) if (!CheckUniversalXPConnectForTraceMalloc(cx))
return false; return false;
int32_t fd; int32_t fd;
JS_SET_RVAL(cx, vp, JSVAL_VOID); if (args.length() == 0) {
if (argc == 0) args.rval().setUndefined();
return true; return true;
if (!JS_ValueToECMAInt32(cx, JS_ARGV(cx, vp)[0], &fd)) }
if (!JS::ToInt32(cx, args[0], &fd))
return false; return false;
NS_TraceMallocCloseLogFD((int) fd); NS_TraceMallocCloseLogFD((int) fd);
args.rval().setInt32(fd);
return true; return true;
} }

View File

@ -191,11 +191,15 @@ nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, bool *aIsInterval,
} }
int32_t interval = 0; int32_t interval = 0;
if (argc > 1 && !::JS_ValueToECMAInt32(cx, argv[1], &interval)) { if (argc > 1) {
::JS_ReportError(cx, JS::Rooted<JS::Value> arg(cx, argv[1]);
"Second argument to %s must be a millisecond interval",
aIsInterval ? kSetIntervalStr : kSetTimeoutStr); if (!JS::ToInt32(cx, arg, &interval)) {
return NS_ERROR_DOM_TYPE_ERR; ::JS_ReportError(cx,
"Second argument to %s must be a millisecond interval",
aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
return NS_ERROR_DOM_TYPE_ERR;
}
} }
if (argc == 1) { if (argc == 1) {

View File

@ -240,7 +240,8 @@ function removeAndroidDefaultCategory(category) {
} }
for (var i = 0; i < category.length; i++) { for (var i = 0; i < category.length; i++) {
if (category[i] == "My Contacts") { // Some devices may return the full group name (prefixed with "System Group: ")
if (category[i] == "My Contacts" || category[i] == "System Group: My Contacts") {
category.splice(i, 1); category.splice(i, 1);
} }
} }
@ -1393,6 +1394,12 @@ var steps = [
req.onerror = onFailure; req.onerror = onFailure;
}, },
function () { function () {
// Android does not support published/updated fields. Skip this.
if (isAndroid) {
next();
return;
}
ok(true, "Test sorting with published"); ok(true, "Test sorting with published");
var options = {sortBy: "familyName", var options = {sortBy: "familyName",
sortOrder: "descending"}; sortOrder: "descending"};

View File

@ -1726,13 +1726,11 @@ nsDOMDeviceStorageCursor::Continue(ErrorResult& aRv)
return; return;
} }
if (mRooted) { if (mResult != JSVAL_VOID) {
// We call onsuccess multiple times. clear the last // We call onsuccess multiple times. Clear the last
// rooted result. // result.
mResult = JSVAL_VOID; mResult = JSVAL_VOID;
NS_DROP_JS_OBJECTS(this, nsDOMDeviceStorageCursor);
mDone = false; mDone = false;
mRooted = false;
} }
nsCOMPtr<ContinueCursorEvent> event = new ContinueCursorEvent(this); nsCOMPtr<ContinueCursorEvent> event = new ContinueCursorEvent(this);

View File

@ -345,8 +345,11 @@ ContentChild::SetProcessName(const nsAString& aName)
printf_stderr("\n\nCHILDCHILDCHILDCHILD\n [%s] debug me @%d\n\n", name, getpid()); printf_stderr("\n\nCHILDCHILDCHILDCHILD\n [%s] debug me @%d\n\n", name, getpid());
sleep(30); sleep(30);
#elif defined(OS_WIN) #elif defined(OS_WIN)
printf_stderr("\n\nCHILDCHILDCHILDCHILD\n [%s] debug me @%d\n\n", name, _getpid()); // Windows has a decent JIT debugging story, so NS_DebugBreak does the
Sleep(30000); // right thing.
NS_DebugBreak(NS_DEBUG_BREAK,
"Invoking NS_DebugBreak() to debug child process",
nullptr, __FILE__, __LINE__);
#endif #endif
} }

View File

@ -37,6 +37,7 @@
#include "mozilla/Hal.h" #include "mozilla/Hal.h"
#include "mozilla/hal_sandbox/PHalParent.h" #include "mozilla/hal_sandbox/PHalParent.h"
#include "mozilla/ipc/TestShellParent.h" #include "mozilla/ipc/TestShellParent.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/layers/CompositorParent.h" #include "mozilla/layers/CompositorParent.h"
#include "mozilla/layers/ImageBridgeParent.h" #include "mozilla/layers/ImageBridgeParent.h"
#include "mozilla/net/NeckoParent.h" #include "mozilla/net/NeckoParent.h"
@ -48,6 +49,7 @@
#include "nsAppDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h"
#include "nsAppRunner.h" #include "nsAppRunner.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsCDefaultURIFixup.h"
#include "nsCExternalHandlerService.h" #include "nsCExternalHandlerService.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsChromeRegistryChrome.h" #include "nsChromeRegistryChrome.h"
@ -76,6 +78,7 @@
#include "nsIScriptError.h" #include "nsIScriptError.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsISupportsPrimitives.h" #include "nsISupportsPrimitives.h"
#include "nsIURIFixup.h"
#include "nsIWindowWatcher.h" #include "nsIWindowWatcher.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "nsSystemInfo.h" #include "nsSystemInfo.h"
@ -1181,6 +1184,7 @@ ContentParent::ContentParent(mozIApplication* aApp,
, mIsForBrowser(aIsForBrowser) , mIsForBrowser(aIsForBrowser)
, mCalledClose(false) , mCalledClose(false)
, mCalledCloseWithError(false) , mCalledCloseWithError(false)
, mCalledKillHard(false)
{ {
// No more than one of !!aApp, aIsForBrowser, and aIsForPreallocated should // No more than one of !!aApp, aIsForBrowser, and aIsForPreallocated should
// be true. // be true.
@ -1918,6 +1922,13 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
void void
ContentParent::KillHard() ContentParent::KillHard()
{ {
// On Windows, calling KillHard multiple times causes problems - the
// process handle becomes invalid on the first call, causing a second call
// to crash our process - more details in bug 890840.
if (mCalledKillHard) {
return;
}
mCalledKillHard = true;
mForceKillTask = nullptr; mForceKillTask = nullptr;
// This ensures the process is eventually killed, but doesn't // This ensures the process is eventually killed, but doesn't
// immediately KILLITWITHFIRE because we want to get a minidump if // immediately KILLITWITHFIRE because we want to get a minidump if
@ -2760,5 +2771,26 @@ ContentParent::RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsS
#endif #endif
} }
bool
ContentParent::RecvKeywordToURI(const nsCString& aKeyword, OptionalInputStreamParams* aPostData,
OptionalURIParams* aURI)
{
nsCOMPtr<nsIURIFixup> fixup = do_GetService(NS_URIFIXUP_CONTRACTID);
if (!fixup) {
return true;
}
nsCOMPtr<nsIInputStream> postData;
nsCOMPtr<nsIURI> uri;
if (NS_FAILED(fixup->KeywordToURI(aKeyword, getter_AddRefs(postData),
getter_AddRefs(uri)))) {
return true;
}
SerializeInputStream(postData, *aPostData);
SerializeURI(uri, *aURI);
return true;
}
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

View File

@ -425,6 +425,9 @@ private:
virtual bool RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState) MOZ_OVERRIDE; virtual bool RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState) MOZ_OVERRIDE;
virtual bool RecvKeywordToURI(const nsCString& aKeyword, OptionalInputStreamParams* aPostData,
OptionalURIParams* aURI);
virtual void ProcessingError(Result what) MOZ_OVERRIDE; virtual void ProcessingError(Result what) MOZ_OVERRIDE;
// If you add strong pointers to cycle collected objects here, be sure to // If you add strong pointers to cycle collected objects here, be sure to
@ -472,10 +475,11 @@ private:
bool mSendPermissionUpdates; bool mSendPermissionUpdates;
bool mIsForBrowser; bool mIsForBrowser;
// These variables track whether we've called Close() and CloseWithError() // These variables track whether we've called Close(), CloseWithError()
// on our channel. // and KillHard() on our channel.
bool mCalledClose; bool mCalledClose;
bool mCalledCloseWithError; bool mCalledCloseWithError;
bool mCalledKillHard;
friend class CrashReporterParent; friend class CrashReporterParent;

View File

@ -411,6 +411,9 @@ parent:
async CreateFakeVolume(nsString fsName, nsString mountPoint); async CreateFakeVolume(nsString fsName, nsString mountPoint);
async SetFakeVolumeState(nsString fsName, int32_t fsState); async SetFakeVolumeState(nsString fsName, int32_t fsState);
sync KeywordToURI(nsCString keyword)
returns (OptionalInputStreamParams postData, OptionalURIParams uri);
both: both:
AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows); AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows);
}; };

View File

@ -12,6 +12,7 @@ relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk include $(DEPTH)/config/autoconf.mk
MOCHITEST_FILES = \ MOCHITEST_FILES = \
test__content.html \
file_MozEnteredDomFullscreen.html \ file_MozEnteredDomFullscreen.html \
test_outerHTML.html \ test_outerHTML.html \
test_outerHTML.xhtml \ test_outerHTML.xhtml \

View File

@ -0,0 +1,28 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=863390
-->
<head>
<title>Test for Bug 863390</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=863390">Mozilla Bug 863390</a>
<p id="display"></p>
<div id="content">
<iframe id="frame" style="height:100px; width:100px; border:0"></iframe>
<div id="status" style="display: none"></div>
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
/** Test for Bug 863390 **/
is(window._content, window.content, "_content and content should be the same");
</script>
</body>
</html>

View File

@ -9,7 +9,7 @@
interface imgIRequest; interface imgIRequest;
[ChromeOnly] [ChromeOnly, OverrideBuiltins]
interface ImageDocument : HTMLDocument { interface ImageDocument : HTMLDocument {
/* Whether the pref for image resizing has been set. */ /* Whether the pref for image resizing has been set. */
readonly attribute boolean imageResizingEnabled; readonly attribute boolean imageResizingEnabled;

View File

@ -2880,7 +2880,7 @@ WifiWorker.prototype = {
self._stateRequests[0].callback.call(self, self._stateRequests[0].enabled); self._stateRequests[0].callback.call(self, self._stateRequests[0].enabled);
} else { } else {
WifiManager.setWifiEnabled(self._stateRequests[0].enabled, WifiManager.setWifiEnabled(self._stateRequests[0].enabled,
self._setWifiEnabledCallback.bind(this)); self._setWifiEnabledCallback.bind(self));
} }
timer = null; timer = null;
}; };

View File

@ -292,7 +292,7 @@ public:
* aFilter Resampling filter used for resampling the image. * aFilter Resampling filter used for resampling the image.
*/ */
SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode, SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode,
const Matrix &aMatrix = Matrix(), Filter aFilter = FILTER_LINEAR) const Matrix &aMatrix = Matrix(), Filter aFilter = FILTER_GOOD)
: mSurface(aSourceSurface) : mSurface(aSourceSurface)
, mExtendMode(aExtendMode) , mExtendMode(aExtendMode)
, mFilter(aFilter) , mFilter(aFilter)

View File

@ -123,6 +123,19 @@ CGBlendMode ToBlendMode(CompositionOp op)
return mode; return mode;
} }
static CGInterpolationQuality
InterpolationQualityFromFilter(Filter aFilter)
{
switch (aFilter) {
default:
case FILTER_LINEAR:
return kCGInterpolationLow;
case FILTER_POINT:
return kCGInterpolationNone;
case FILTER_GOOD:
return kCGInterpolationDefault;
}
}
DrawTargetCG::DrawTargetCG() : mCg(nullptr), mSnapshot(nullptr) DrawTargetCG::DrawTargetCG() : mCg(nullptr), mSnapshot(nullptr)
@ -291,10 +304,7 @@ DrawTargetCG::DrawSurface(SourceSurface *aSurface,
CGRect flippedRect = CGRectMake(aDest.x, -(aDest.y + aDest.height), CGRect flippedRect = CGRectMake(aDest.x, -(aDest.y + aDest.height),
aDest.width, aDest.height); aDest.width, aDest.height);
if (aSurfOptions.mFilter == FILTER_POINT) CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(aSurfOptions.mFilter));
CGContextSetInterpolationQuality(cg, kCGInterpolationNone);
else
CGContextSetInterpolationQuality(cg, kCGInterpolationLow);
CGContextDrawImage(cg, flippedRect, image); CGContextDrawImage(cg, flippedRect, image);
@ -653,10 +663,7 @@ SetFillFromPattern(CGContextRef cg, CGColorSpaceRef aColorSpace, const Pattern &
CGPatternRef pattern = CreateCGPattern(aPattern, CGContextGetCTM(cg)); CGPatternRef pattern = CreateCGPattern(aPattern, CGContextGetCTM(cg));
const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern); const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
if (pat.mFilter == FILTER_POINT) CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(pat.mFilter));
CGContextSetInterpolationQuality(cg, kCGInterpolationNone);
else
CGContextSetInterpolationQuality(cg, kCGInterpolationLow);
CGFloat alpha = 1.; CGFloat alpha = 1.;
CGContextSetFillPattern(cg, pattern, &alpha); CGContextSetFillPattern(cg, pattern, &alpha);
CGPatternRelease(pattern); CGPatternRelease(pattern);
@ -681,10 +688,7 @@ SetStrokeFromPattern(CGContextRef cg, CGColorSpaceRef aColorSpace, const Pattern
CGPatternRef pattern = CreateCGPattern(aPattern, CGContextGetCTM(cg)); CGPatternRef pattern = CreateCGPattern(aPattern, CGContextGetCTM(cg));
const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern); const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
if (pat.mFilter == FILTER_POINT) CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(pat.mFilter));
CGContextSetInterpolationQuality(cg, kCGInterpolationNone);
else
CGContextSetInterpolationQuality(cg, kCGInterpolationLow);
CGFloat alpha = 1.; CGFloat alpha = 1.;
CGContextSetStrokePattern(cg, pattern, &alpha); CGContextSetStrokePattern(cg, pattern, &alpha);
CGPatternRelease(pattern); CGPatternRelease(pattern);
@ -770,10 +774,7 @@ DrawTargetCG::FillRect(const Rect &aRect,
CGRect imageRect = CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)); CGRect imageRect = CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image));
if (pat.mFilter == FILTER_POINT) CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(pat.mFilter));
CGContextSetInterpolationQuality(cg, kCGInterpolationNone);
else
CGContextSetInterpolationQuality(cg, kCGInterpolationLow);
CGContextDrawImage(cg, imageRect, image); CGContextDrawImage(cg, imageRect, image);
} else { } else {

View File

@ -285,7 +285,7 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(aSurface)->GetBitmap(); const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(aSurface)->GetBitmap();
AutoPaintSetup paint(mCanvas.get(), aOptions); AutoPaintSetup paint(mCanvas.get(), aOptions);
if (aSurfOptions.mFilter != FILTER_LINEAR) { if (aSurfOptions.mFilter == FILTER_POINT) {
paint.mPaint.setFilterBitmap(false); paint.mPaint.setFilterBitmap(false);
} }

View File

@ -82,6 +82,8 @@ GfxFilterToCairoFilter(Filter filter)
{ {
switch (filter) switch (filter)
{ {
case FILTER_GOOD:
return CAIRO_FILTER_GOOD;
case FILTER_LINEAR: case FILTER_LINEAR:
return CAIRO_FILTER_BILINEAR; return CAIRO_FILTER_BILINEAR;
case FILTER_POINT: case FILTER_POINT:

View File

@ -104,7 +104,7 @@ enum ExtendMode { EXTEND_CLAMP, EXTEND_REPEAT, EXTEND_REFLECT };
enum FillRule { FILL_WINDING, FILL_EVEN_ODD }; enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL, AA_DEFAULT }; enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL, AA_DEFAULT };
enum Snapping { SNAP_NONE, SNAP_ALIGNED }; enum Snapping { SNAP_NONE, SNAP_ALIGNED };
enum Filter { FILTER_LINEAR, FILTER_POINT }; enum Filter { FILTER_GOOD, FILTER_LINEAR, FILTER_POINT };
enum PatternType { PATTERN_COLOR, PATTERN_SURFACE, PATTERN_LINEAR_GRADIENT, PATTERN_RADIAL_GRADIENT }; enum PatternType { PATTERN_COLOR, PATTERN_SURFACE, PATTERN_LINEAR_GRADIENT, PATTERN_RADIAL_GRADIENT };
enum JoinStyle { JOIN_BEVEL, JOIN_ROUND, JOIN_MITER, JOIN_MITER_OR_BEVEL }; enum JoinStyle { JOIN_BEVEL, JOIN_ROUND, JOIN_MITER, JOIN_MITER_OR_BEVEL };
enum CapStyle { CAP_BUTT, CAP_ROUND, CAP_SQUARE }; enum CapStyle { CAP_BUTT, CAP_ROUND, CAP_SQUARE };

View File

@ -2,13 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(GLCONSTS_H_) #ifndef GLCONSTS_H_
#define GLCONSTS_H_ #define GLCONSTS_H_
/** /**
* GENERATED FILE, DO NOT MODIFY DIRECTLY. * GENERATED FILE, DO NOT MODIFY DIRECTLY.
* THIS IS A GENERATED FILE DIRECTLY FROM THE OFFCIAL OPENGL REGISTRY * This is a file generated directly from the official OpenGL registry
* XML AVAILABLE AT http://www.opengl.org/registry/#specfiles. * xml available http://www.opengl.org/registry/#specfiles.
* *
* To generate this file, see tutorial in GLParseRegistry.py * To generate this file, see tutorial in GLParseRegistry.py
*/ */
@ -176,17 +176,17 @@
#define LOCAL_GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 #define LOCAL_GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
#define LOCAL_GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 #define LOCAL_GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER 0x92C0 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER 0x92C0
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
#define LOCAL_GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 #define LOCAL_GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
#define LOCAL_GL_ATTACHED_SHADERS 0x8B85 #define LOCAL_GL_ATTACHED_SHADERS 0x8B85
@ -581,7 +581,7 @@
#define LOCAL_GL_COMPRESSED_RGB8_ETC2 0x9274 #define LOCAL_GL_COMPRESSED_RGB8_ETC2 0x9274
#define LOCAL_GL_COMPRESSED_RGB8_ETC2_OES 0x9274 #define LOCAL_GL_COMPRESSED_RGB8_ETC2_OES 0x9274
#define LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 #define LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
#define LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9276 #define LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9276
#define LOCAL_GL_COMPRESSED_RGBA 0x84EE #define LOCAL_GL_COMPRESSED_RGBA 0x84EE
#define LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 #define LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
#define LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC_OES 0x9278 #define LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC_OES 0x9278
@ -653,7 +653,7 @@
#define LOCAL_GL_COMPRESSED_SRGB8_ETC2 0x9275 #define LOCAL_GL_COMPRESSED_SRGB8_ETC2 0x9275
#define LOCAL_GL_COMPRESSED_SRGB8_ETC2_OES 0x9275 #define LOCAL_GL_COMPRESSED_SRGB8_ETC2_OES 0x9275
#define LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 #define LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
#define LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9277 #define LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES 0x9277
#define LOCAL_GL_COMPRESSED_SRGB_ALPHA 0x8C49 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA 0x8C49
#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
#define LOCAL_GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 #define LOCAL_GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
@ -1437,7 +1437,7 @@
#define LOCAL_GL_FRAGMENT_LIGHTING_SGIX 0x8400 #define LOCAL_GL_FRAGMENT_LIGHTING_SGIX 0x8400
#define LOCAL_GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A #define LOCAL_GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A
#define LOCAL_GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 #define LOCAL_GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408
#define LOCAL_GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B #define LOCAL_GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B
#define LOCAL_GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 #define LOCAL_GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409
#define LOCAL_GL_FRAGMENT_MATERIAL_EXT 0x8349 #define LOCAL_GL_FRAGMENT_MATERIAL_EXT 0x8349
#define LOCAL_GL_FRAGMENT_NORMAL_EXT 0x834A #define LOCAL_GL_FRAGMENT_NORMAL_EXT 0x834A
@ -1446,7 +1446,7 @@
#define LOCAL_GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8BB3 #define LOCAL_GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8BB3
#define LOCAL_GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8BB2 #define LOCAL_GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8BB2
#define LOCAL_GL_FRAGMENT_PROGRAM_CALLBACK_MESA 0x8BB1 #define LOCAL_GL_FRAGMENT_PROGRAM_CALLBACK_MESA 0x8BB1
#define LOCAL_GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D #define LOCAL_GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D
#define LOCAL_GL_FRAGMENT_PROGRAM_NV 0x8870 #define LOCAL_GL_FRAGMENT_PROGRAM_NV 0x8870
#define LOCAL_GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 #define LOCAL_GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4
#define LOCAL_GL_FRAGMENT_PROGRAM_POSITION_MESA 0x8BB0 #define LOCAL_GL_FRAGMENT_PROGRAM_POSITION_MESA 0x8BB0
@ -1483,11 +1483,11 @@
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES 0x8CD0 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES 0x8CD0
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES 0x8CD3 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES 0x8CD3
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
#define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 #define LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
@ -1528,8 +1528,8 @@
#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8
#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7
#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
#define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 #define LOCAL_GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56
@ -2253,12 +2253,12 @@
#define LOCAL_GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 #define LOCAL_GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
#define LOCAL_GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 #define LOCAL_GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
#define LOCAL_GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF #define LOCAL_GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
#define LOCAL_GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 #define LOCAL_GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
#define LOCAL_GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 #define LOCAL_GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39
#define LOCAL_GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 #define LOCAL_GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
#define LOCAL_GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC #define LOCAL_GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
#define LOCAL_GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E #define LOCAL_GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
#define LOCAL_GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F #define LOCAL_GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
#define LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D #define LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
#define LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D #define LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D
#define LOCAL_GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E #define LOCAL_GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
@ -2379,10 +2379,10 @@
#define LOCAL_GL_MAX_NAME_STACK_DEPTH 0x0D37 #define LOCAL_GL_MAX_NAME_STACK_DEPTH 0x0D37
#define LOCAL_GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 #define LOCAL_GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
#define LOCAL_GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 #define LOCAL_GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
#define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA #define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA
#define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD #define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD
#define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE #define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE
#define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC #define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC
#define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB #define LOCAL_GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB
#define LOCAL_GL_MAX_PALETTE_MATRICES_ARB 0x8842 #define LOCAL_GL_MAX_PALETTE_MATRICES_ARB 0x8842
#define LOCAL_GL_MAX_PALETTE_MATRICES_OES 0x8842 #define LOCAL_GL_MAX_PALETTE_MATRICES_OES 0x8842
@ -2504,15 +2504,15 @@
#define LOCAL_GL_MAX_TRACK_MATRICES_NV 0x862F #define LOCAL_GL_MAX_TRACK_MATRICES_NV 0x862F
#define LOCAL_GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E #define LOCAL_GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E
#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A
#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A
#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B
#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B
#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80
#define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 #define LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80
#define LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 #define LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
#define LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F #define LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
#define LOCAL_GL_MAX_UNIFORM_LOCATIONS 0x826E #define LOCAL_GL_MAX_UNIFORM_LOCATIONS 0x826E
@ -2779,7 +2779,7 @@
#define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 #define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850
#define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 #define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851
#define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 #define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852
#define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 #define LOCAL_GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853
#define LOCAL_GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3 #define LOCAL_GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3
#define LOCAL_GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1 #define LOCAL_GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1
#define LOCAL_GL_OFFSET_TEXTURE_2D_NV 0x86E8 #define LOCAL_GL_OFFSET_TEXTURE_2D_NV 0x86E8
@ -3276,7 +3276,7 @@
#define LOCAL_GL_QUADRATIC_CURVE_TO_NV 0x0A #define LOCAL_GL_QUADRATIC_CURVE_TO_NV 0x0A
#define LOCAL_GL_QUADS 0x0007 #define LOCAL_GL_QUADS 0x0007
#define LOCAL_GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C #define LOCAL_GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
#define LOCAL_GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C #define LOCAL_GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
#define LOCAL_GL_QUAD_ALPHA4_SGIS 0x811E #define LOCAL_GL_QUAD_ALPHA4_SGIS 0x811E
#define LOCAL_GL_QUAD_ALPHA8_SGIS 0x811F #define LOCAL_GL_QUAD_ALPHA8_SGIS 0x811F
#define LOCAL_GL_QUAD_INTENSITY4_SGIS 0x8122 #define LOCAL_GL_QUAD_INTENSITY4_SGIS 0x8122
@ -4584,8 +4584,8 @@
#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
#define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 #define LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
#define LOCAL_GL_UNIFORM_BUFFER 0x8A11 #define LOCAL_GL_UNIFORM_BUFFER 0x8A11
#define LOCAL_GL_UNIFORM_BUFFER_BINDING 0x8A28 #define LOCAL_GL_UNIFORM_BUFFER_BINDING 0x8A28
@ -5089,13 +5089,13 @@
#define LOCAL_EGL_CONTEXT_LOST 0x300E #define LOCAL_EGL_CONTEXT_LOST 0x300E
#define LOCAL_EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 #define LOCAL_EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
#define LOCAL_EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB #define LOCAL_EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
#define LOCAL_EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 #define LOCAL_EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
#define LOCAL_EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 #define LOCAL_EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
#define LOCAL_EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 #define LOCAL_EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
#define LOCAL_EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 #define LOCAL_EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define LOCAL_EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD #define LOCAL_EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
#define LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138 #define LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
#define LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD #define LOCAL_EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
#define LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 #define LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
#define LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF #define LOCAL_EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
#define LOCAL_EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 #define LOCAL_EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
@ -5377,7 +5377,7 @@
#define LOCAL_GLX_COLOR_INDEX_TYPE_SGIX 0x8015 #define LOCAL_GLX_COLOR_INDEX_TYPE_SGIX 0x8015
#define LOCAL_GLX_COLOR_SAMPLES_NV 0x20B3 #define LOCAL_GLX_COLOR_SAMPLES_NV 0x20B3
#define LOCAL_GLX_CONFIG_CAVEAT 0x20 #define LOCAL_GLX_CONFIG_CAVEAT 0x20
#define LOCAL_GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095 #define LOCAL_GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095
#define LOCAL_GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 #define LOCAL_GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define LOCAL_GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define LOCAL_GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define LOCAL_GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 #define LOCAL_GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001

View File

@ -50,13 +50,13 @@ class GLConstHeader:
' * License, v. 2.0. If a copy of the MPL was not distributed with this', ' * 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/. */', ' * file, You can obtain one at http://mozilla.org/MPL/2.0/. */',
'', '',
'#if !defined(GLCONSTS_H_)', '#ifndef GLCONSTS_H_',
'#define GLCONSTS_H_', '#define GLCONSTS_H_',
'', '',
'/**', '/**',
' * GENERATED FILE, DO NOT MODIFY DIRECTLY.', ' * GENERATED FILE, DO NOT MODIFY DIRECTLY.',
' * THIS IS A GENERATED FILE DIRECTLY FROM THE OFFCIAL OPENGL REGISTRY', ' * This is a file generated directly from the official OpenGL registry',
' * XML AVAILABLE AT http://www.opengl.org/registry/#specfiles.', ' * xml available http://www.opengl.org/registry/#specfiles.',
' *', ' *',
' * To generate this file, see tutorial in GLParseRegistry.py', ' * To generate this file, see tutorial in GLParseRegistry.py',
' */', ' */',
@ -75,7 +75,11 @@ class GLConstHeader:
# value is the value of the const (example: 0xABCD) # value is the value of the const (example: 0xABCD)
define = '#define LOCAL_' + lib + '_' + name define = '#define LOCAL_' + lib + '_' + name
whitespace = max(60 - len(define), 0) whitespace = 60 - len(define)
if whitespace < 0:
whitespace = whitespace % 8
self.write(define + ' ' * whitespace + ' ' + value) self.write(define + ' ' * whitespace + ' ' + value)

View File

@ -847,6 +847,7 @@ CompositorD3D11::SetSamplerForFilter(Filter aFilter)
{ {
ID3D11SamplerState *sampler; ID3D11SamplerState *sampler;
switch (aFilter) { switch (aFilter) {
default:
case FILTER_LINEAR: case FILTER_LINEAR:
sampler = mAttachments->mLinearSamplerState; sampler = mAttachments->mLinearSamplerState;
break; break;

View File

@ -69,6 +69,8 @@ inline Filter ToFilter(gfxPattern::GraphicsFilter aFilter)
switch (aFilter) { switch (aFilter) {
case gfxPattern::FILTER_NEAREST: case gfxPattern::FILTER_NEAREST:
return FILTER_POINT; return FILTER_POINT;
case gfxPattern::FILTER_GOOD:
return FILTER_GOOD;
default: default:
return FILTER_LINEAR; return FILTER_LINEAR;
} }

View File

@ -98,6 +98,8 @@ struct ObjectsExtraSizes
size_t elementsNonAsmJS; size_t elementsNonAsmJS;
size_t elementsAsmJSHeap; size_t elementsAsmJSHeap;
size_t elementsAsmJSNonHeap; size_t elementsAsmJSNonHeap;
size_t asmJSModuleCode;
size_t asmJSModuleData;
size_t argumentsData; size_t argumentsData;
size_t regExpStatics; size_t regExpStatics;
size_t propertyIteratorData; size_t propertyIteratorData;
@ -112,6 +114,8 @@ struct ObjectsExtraSizes
this->elementsNonAsmJS += sizes.elementsNonAsmJS; this->elementsNonAsmJS += sizes.elementsNonAsmJS;
this->elementsAsmJSHeap += sizes.elementsAsmJSHeap; this->elementsAsmJSHeap += sizes.elementsAsmJSHeap;
this->elementsAsmJSNonHeap += sizes.elementsAsmJSNonHeap; this->elementsAsmJSNonHeap += sizes.elementsAsmJSNonHeap;
this->asmJSModuleCode += sizes.asmJSModuleCode;
this->asmJSModuleData += sizes.asmJSModuleData;
this->argumentsData += sizes.argumentsData; this->argumentsData += sizes.argumentsData;
this->regExpStatics += sizes.regExpStatics; this->regExpStatics += sizes.regExpStatics;
this->propertyIteratorData += sizes.propertyIteratorData; this->propertyIteratorData += sizes.propertyIteratorData;
@ -148,7 +152,6 @@ struct TypeInferenceSizes
struct CodeSizes struct CodeSizes
{ {
size_t ion; size_t ion;
size_t asmJS;
size_t baseline; size_t baseline;
size_t regexp; size_t regexp;
size_t other; size_t other;

View File

@ -49,12 +49,10 @@ ExecutableAllocator::sizeOfCode(JS::CodeSizes *sizes) const
ExecutablePool* pool = r.front(); ExecutablePool* pool = r.front();
sizes->ion += pool->m_ionCodeBytes; sizes->ion += pool->m_ionCodeBytes;
sizes->baseline += pool->m_baselineCodeBytes; sizes->baseline += pool->m_baselineCodeBytes;
sizes->asmJS += pool->m_asmJSCodeBytes;
sizes->regexp += pool->m_regexpCodeBytes; sizes->regexp += pool->m_regexpCodeBytes;
sizes->other += pool->m_otherCodeBytes; sizes->other += pool->m_otherCodeBytes;
sizes->unused += pool->m_allocation.size - pool->m_ionCodeBytes sizes->unused += pool->m_allocation.size - pool->m_ionCodeBytes
- pool->m_baselineCodeBytes - pool->m_baselineCodeBytes
- pool->m_asmJSCodeBytes
- pool->m_regexpCodeBytes - pool->m_regexpCodeBytes
- pool->m_otherCodeBytes; - pool->m_otherCodeBytes;
} }

View File

@ -84,7 +84,7 @@ namespace JSC {
class ExecutableAllocator; class ExecutableAllocator;
enum CodeKind { ION_CODE, BASELINE_CODE, REGEXP_CODE, ASMJS_CODE, OTHER_CODE }; enum CodeKind { ION_CODE, BASELINE_CODE, REGEXP_CODE, OTHER_CODE };
// These are reference-counted. A new one starts with a count of 1. // These are reference-counted. A new one starts with a count of 1.
class ExecutablePool { class ExecutablePool {
@ -110,7 +110,6 @@ private:
// Number of bytes currently used for Method and Regexp JIT code. // Number of bytes currently used for Method and Regexp JIT code.
size_t m_ionCodeBytes; size_t m_ionCodeBytes;
size_t m_baselineCodeBytes; size_t m_baselineCodeBytes;
size_t m_asmJSCodeBytes;
size_t m_regexpCodeBytes; size_t m_regexpCodeBytes;
size_t m_otherCodeBytes; size_t m_otherCodeBytes;
@ -133,9 +132,8 @@ public:
ExecutablePool(ExecutableAllocator* allocator, Allocation a) ExecutablePool(ExecutableAllocator* allocator, Allocation a)
: m_allocator(allocator), m_freePtr(a.pages), m_end(m_freePtr + a.size), m_allocation(a), : m_allocator(allocator), m_freePtr(a.pages), m_end(m_freePtr + a.size), m_allocation(a),
m_refCount(1), m_ionCodeBytes(0), m_baselineCodeBytes(0), m_refCount(1), m_ionCodeBytes(0), m_baselineCodeBytes(0), m_regexpCodeBytes(0),
m_asmJSCodeBytes(0), m_regexpCodeBytes(0), m_otherCodeBytes(0), m_otherCodeBytes(0), m_destroy(false), m_gcNumber(0)
m_destroy(false), m_gcNumber(0)
{ } { }
~ExecutablePool(); ~ExecutablePool();
@ -159,7 +157,6 @@ private:
switch (kind) { switch (kind) {
case ION_CODE: m_ionCodeBytes += n; break; case ION_CODE: m_ionCodeBytes += n; break;
case BASELINE_CODE: m_baselineCodeBytes += n; break; case BASELINE_CODE: m_baselineCodeBytes += n; break;
case ASMJS_CODE: m_asmJSCodeBytes += n; break;
case REGEXP_CODE: m_regexpCodeBytes += n; break; case REGEXP_CODE: m_regexpCodeBytes += n; break;
case OTHER_CODE: m_otherCodeBytes += n; break; case OTHER_CODE: m_otherCodeBytes += n; break;
default: MOZ_ASSUME_UNREACHABLE("bad code kind"); default: MOZ_ASSUME_UNREACHABLE("bad code kind");

View File

@ -81,15 +81,15 @@ fi
dnl A high level macro for selecting compiler options. dnl A high level macro for selecting compiler options.
AC_DEFUN([MOZ_COMPILER_OPTS], AC_DEFUN([MOZ_COMPILER_OPTS],
[ [
DEVELOPER_OPTIONS=1 if test -z "$MOZILLA_OFFICIAL"; then
DEVELOPER_OPTIONS=1
fi
MOZ_ARG_ENABLE_BOOL(release, MOZ_ARG_ENABLE_BOOL(release,
[ --enable-release Build with more conservative, release engineering-oriented options. [ --enable-release Build with more conservative, release engineering-oriented options.
This may slow down builds.], This may slow down builds.],
DEVELOPER_OPTIONS=) DEVELOPER_OPTIONS=,
DEVELOPER_OPTIONS=1)
if test -n "$MOZILLA_OFFICIAL" -a -n "$DEVELOPER_OPTIONS"; then
AC_MSG_ERROR([You cannot set MOZILLA_OFFICIAL without --enable-release])
fi
AC_SUBST(DEVELOPER_OPTIONS) AC_SUBST(DEVELOPER_OPTIONS)
MOZ_DEBUGGING_OPTS MOZ_DEBUGGING_OPTS

View File

@ -24,6 +24,9 @@ function indirectCallCannotGC(caller, name)
if (name == "params" && caller == "PR_ExplodeTime") if (name == "params" && caller == "PR_ExplodeTime")
return true; return true;
if (name == "op" && /GetWeakmapKeyDelegate/.test(caller))
return true;
var CheckCallArgs = "AsmJS.cpp:uint8 CheckCallArgs(FunctionCompiler*, js::frontend::ParseNode*, (uint8)(FunctionCompiler*,js::frontend::ParseNode*,Type)*, FunctionCompiler::Call*)"; var CheckCallArgs = "AsmJS.cpp:uint8 CheckCallArgs(FunctionCompiler*, js::frontend::ParseNode*, (uint8)(FunctionCompiler*,js::frontend::ParseNode*,Type)*, FunctionCompiler::Call*)";
if (name == "checkArg" && caller == CheckCallArgs) if (name == "checkArg" && caller == CheckCallArgs)
return true; return true;
@ -68,6 +71,8 @@ var ignoreCallees = {
"js::ion::LInstruction.getDef" : true, // virtual but no implementation can GC "js::ion::LInstruction.getDef" : true, // virtual but no implementation can GC
"js::ion::IonCache.kind" : true, // macro generated virtuals just return a constant "js::ion::IonCache.kind" : true, // macro generated virtuals just return a constant
"icu_50::UObject.__deleting_dtor" : true, // destructors in ICU code can't cause GC "icu_50::UObject.__deleting_dtor" : true, // destructors in ICU code can't cause GC
"mozilla::CycleCollectedJSRuntime.DescribeCustomObjects" : true, // During tracing, cannot GC.
"mozilla::CycleCollectedJSRuntime.NoteCustomGCThingXPCOMChildren" : true, // During tracing, cannot GC.
}; };
function fieldCallCannotGC(csu, fullfield) function fieldCallCannotGC(csu, fullfield)

View File

@ -434,7 +434,7 @@ class LifoAlloc
// Move the read position forward by |size| bytes. // Move the read position forward by |size| bytes.
void popFront(size_t size) { void popFront(size_t size) {
ensureSpaceAndAlignment(size); ensureSpaceAndAlignment(size);
position_ = detail::AlignPtr(position_ + size); position_ = position_ + size;
} }
// Update the bytes at the current position with a new value. // Update the bytes at the current position with a new value.

View File

@ -353,6 +353,17 @@ Parser<ParseHandler>::report(ParseReportKind kind, bool strict, Node pn, unsigne
return result; return result;
} }
template <typename ParseHandler>
bool
Parser<ParseHandler>::reportNoOffset(ParseReportKind kind, bool strict, unsigned errorNumber, ...)
{
va_list args;
va_start(args, errorNumber);
bool result = reportHelper(kind, strict, TokenStream::NoOffset, errorNumber, args);
va_end(args);
return result;
}
template <typename ParseHandler> template <typename ParseHandler>
bool bool
Parser<ParseHandler>::reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset, Parser<ParseHandler>::reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset,
@ -2438,7 +2449,7 @@ Parser<FullParseHandler>::asmJS(Node list)
// function from the beginning. Reparsing is triggered by marking that a // function from the beginning. Reparsing is triggered by marking that a
// new directive has been encountered and returning 'false'. // new directive has been encountered and returning 'false'.
bool validated; bool validated;
if (!CompileAsmJS(context->asJSContext(), *this, list, &validated)) if (!CompileAsmJS(context, *this, list, &validated))
return false; return false;
if (!validated) { if (!validated) {
pc->newDirectives->setAsmJS(); pc->newDirectives->setAsmJS();

View File

@ -353,6 +353,7 @@ class Parser : private AutoGCRooter, public StrictModeGetter
unsigned errorNumber, va_list args); unsigned errorNumber, va_list args);
public: public:
bool report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...); bool report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...);
bool reportNoOffset(ParseReportKind kind, bool strict, unsigned errorNumber, ...);
bool reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset, unsigned errorNumber, bool reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset, unsigned errorNumber,
...); ...);

View File

@ -633,8 +633,13 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
err.report.errorNumber = errorNumber; err.report.errorNumber = errorNumber;
err.report.filename = filename; err.report.filename = filename;
err.report.originPrincipals = originPrincipals; err.report.originPrincipals = originPrincipals;
err.report.lineno = srcCoords.lineNum(offset); if (offset == NoOffset) {
err.report.column = srcCoords.columnIndex(offset); err.report.lineno = 0;
err.report.column = 0;
} else {
err.report.lineno = srcCoords.lineNum(offset);
err.report.column = srcCoords.columnIndex(offset);
}
err.argumentsType = (flags & JSREPORT_UC) ? ArgumentsAreUnicode : ArgumentsAreASCII; err.argumentsType = (flags & JSREPORT_UC) ? ArgumentsAreUnicode : ArgumentsAreASCII;
@ -652,7 +657,7 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
// So we don't even try, leaving report.linebuf and friends zeroed. This // So we don't even try, leaving report.linebuf and friends zeroed. This
// means that any error involving a multi-line token (e.g. an unterminated // means that any error involving a multi-line token (e.g. an unterminated
// multi-line string literal) won't have a context printed. // multi-line string literal) won't have a context printed.
if (err.report.lineno == lineno) { if (offset != NoOffset && err.report.lineno == lineno) {
const jschar *tokenStart = userbuf.base() + offset; const jschar *tokenStart = userbuf.base() + offset;
// We show only a portion (a "window") of the line around the erroneous // We show only a portion (a "window") of the line around the erroneous

View File

@ -420,6 +420,8 @@ class MOZ_STACK_CLASS TokenStream
bool reportError(unsigned errorNumber, ...); bool reportError(unsigned errorNumber, ...);
bool reportWarning(unsigned errorNumber, ...); bool reportWarning(unsigned errorNumber, ...);
static const uint32_t NoOffset = UINT32_MAX;
// General-purpose error reporters. You should avoid calling these // General-purpose error reporters. You should avoid calling these
// directly, and instead use the more succinct alternatives (e.g. // directly, and instead use the more succinct alternatives (e.g.
// reportError()) in TokenStream, Parser, and BytecodeEmitter. // reportError()) in TokenStream, Parser, and BytecodeEmitter.

View File

@ -193,11 +193,16 @@ struct Zone : private JS::shadow::Zone,
} }
void scheduleGC() { void scheduleGC() {
JS_ASSERT(!runtimeFromMainThread()->isHeapBusy()); JSRuntime *rt = runtimeFromMainThread();
JS_ASSERT(!rt->isHeapBusy());
/* Note: zones cannot be collected while in use by other threads. */ /* Note: zones cannot be collected while in use by other threads. */
if (!usedByExclusiveThread) if (usedByExclusiveThread)
gcScheduled = true; return;
if (rt->isAtomsZone(this) && rt->exclusiveThreadsPresent())
return;
gcScheduled = true;
} }
void unscheduleGC() { void unscheduleGC() {

View File

@ -299,7 +299,7 @@ FunctionLastReturnStatementOrNull(ParseNode *fn)
} }
static inline bool static inline bool
IsNormalObjectField(JSContext *cx, ParseNode *pn) IsNormalObjectField(ExclusiveContext *cx, ParseNode *pn)
{ {
JS_ASSERT(pn->isKind(PNK_COLON)); JS_ASSERT(pn->isKind(PNK_COLON));
return pn->getOp() == JSOP_INITPROP && return pn->getOp() == JSOP_INITPROP &&
@ -308,7 +308,7 @@ IsNormalObjectField(JSContext *cx, ParseNode *pn)
} }
static inline PropertyName * static inline PropertyName *
ObjectNormalFieldName(JSContext *cx, ParseNode *pn) ObjectNormalFieldName(ExclusiveContext *cx, ParseNode *pn)
{ {
JS_ASSERT(IsNormalObjectField(cx, pn)); JS_ASSERT(IsNormalObjectField(cx, pn));
return BinaryLeft(pn)->name(); return BinaryLeft(pn)->name();
@ -657,9 +657,9 @@ class Signature
RetType retType_; RetType retType_;
public: public:
Signature(JSContext *cx) Signature(ExclusiveContext *cx)
: argTypes_(cx) {} : argTypes_(cx) {}
Signature(JSContext *cx, RetType retType) Signature(ExclusiveContext *cx, RetType retType)
: argTypes_(cx), retType_(retType) {} : argTypes_(cx), retType_(retType) {}
Signature(MoveRef<VarTypeVector> argTypes, RetType retType) Signature(MoveRef<VarTypeVector> argTypes, RetType retType)
: argTypes_(argTypes), retType_(retType) {} : argTypes_(argTypes), retType_(retType) {}
@ -1072,8 +1072,9 @@ class MOZ_STACK_CLASS ModuleCompiler
FuncPtrVector elems_; FuncPtrVector elems_;
public: public:
FuncPtrTable(JSContext *cx, MoveRef<Signature> sig, uint32_t mask, uint32_t globalDataOffset) FuncPtrTable(ExclusiveContext *cx, MoveRef<Signature> sig, uint32_t mask, uint32_t gdo)
: sig_(sig), mask_(mask), globalDataOffset_(globalDataOffset), elems_(cx) {} : sig_(sig), mask_(mask), globalDataOffset_(gdo), elems_(cx)
{}
FuncPtrTable(MoveRef<FuncPtrTable> rhs) FuncPtrTable(MoveRef<FuncPtrTable> rhs)
: sig_(Move(rhs->sig_)), mask_(rhs->mask_), globalDataOffset_(rhs->globalDataOffset_), : sig_(Move(rhs->sig_)), mask_(rhs->mask_), globalDataOffset_(rhs->globalDataOffset_),
@ -1121,7 +1122,7 @@ class MOZ_STACK_CLASS ModuleCompiler
} }
}; };
typedef HashMap<ExitDescriptor, unsigned, ExitDescriptor, ContextAllocPolicy> ExitMap; typedef HashMap<ExitDescriptor, unsigned, ExitDescriptor> ExitMap;
private: private:
struct SlowFunction struct SlowFunction
@ -1138,7 +1139,7 @@ class MOZ_STACK_CLASS ModuleCompiler
typedef Vector<AsmJSGlobalAccess> GlobalAccessVector; typedef Vector<AsmJSGlobalAccess> GlobalAccessVector;
typedef Vector<SlowFunction> SlowFunctionVector; typedef Vector<SlowFunction> SlowFunctionVector;
JSContext * cx_; ExclusiveContext * cx_;
AsmJSParser & parser_; AsmJSParser & parser_;
MacroAssembler masm_; MacroAssembler masm_;
@ -1174,7 +1175,7 @@ class MOZ_STACK_CLASS ModuleCompiler
} }
public: public:
ModuleCompiler(JSContext *cx, AsmJSParser &parser) ModuleCompiler(ExclusiveContext *cx, AsmJSParser &parser)
: cx_(cx), : cx_(cx),
parser_(parser), parser_(parser),
masm_(MacroAssembler::AsmJSToken()), masm_(MacroAssembler::AsmJSToken()),
@ -1214,9 +1215,6 @@ class MOZ_STACK_CLASS ModuleCompiler
} }
bool init() { bool init() {
if (!cx_->compartment()->ensureIonCompartmentExists(cx_))
return false;
if (!globals_.init() || !exits_.init()) if (!globals_.init() || !exits_.init())
return false; return false;
@ -1278,8 +1276,8 @@ class MOZ_STACK_CLASS ModuleCompiler
} }
bool failName(ParseNode *pn, const char *fmt, PropertyName *name) { bool failName(ParseNode *pn, const char *fmt, PropertyName *name) {
JSAutoByteString bytes(cx_, name); JSAutoByteString bytes;
if (bytes.ptr()) if (AtomToPrintableString(cx_, name, &bytes))
failf(pn, fmt, bytes.ptr()); failf(pn, fmt, bytes.ptr());
return false; return false;
} }
@ -1298,7 +1296,7 @@ class MOZ_STACK_CLASS ModuleCompiler
/*************************************************** Read-only interface */ /*************************************************** Read-only interface */
JSContext *cx() const { return cx_; } ExclusiveContext *cx() const { return cx_; }
AsmJSParser &parser() const { return parser_; } AsmJSParser &parser() const { return parser_; }
MacroAssembler &masm() { return masm_; } MacroAssembler &masm() { return masm_; }
Label &stackOverflowLabel() { return stackOverflowLabel_; } Label &stackOverflowLabel() { return stackOverflowLabel_; }
@ -1566,26 +1564,10 @@ class MOZ_STACK_CLASS ModuleCompiler
if (masm_.oom()) if (masm_.oom())
return false; return false;
// The global data section sits immediately after the executable (and // The returned memory is owned by module_.
// other) data allocated by the MacroAssembler. Round up bytesNeeded so uint8_t *code = module_->allocateCodeAndGlobalSegment(cx_, masm_.bytesNeeded());
// that doubles/pointers stay aligned. if (!code)
size_t codeBytes = AlignBytes(masm_.bytesNeeded(), sizeof(double));
size_t totalBytes = codeBytes + module_->globalDataBytes();
// The code must be page aligned, so include extra space so that we can
// AlignBytes the allocation result below.
size_t allocedBytes = totalBytes + AsmJSPageSize;
// Allocate the slab of memory.
JSC::ExecutableAllocator *execAlloc = cx_->compartment()->ionCompartment()->execAlloc();
JSC::ExecutablePool *pool;
uint8_t *unalignedBytes = (uint8_t*)execAlloc->alloc(allocedBytes, &pool, JSC::ASMJS_CODE);
if (!unalignedBytes)
return false; return false;
uint8_t *code = (uint8_t*)AlignBytes((uintptr_t)unalignedBytes, AsmJSPageSize);
// The ExecutablePool owns the memory and must be released by the AsmJSModule.
module_->takeOwnership(pool, code, codeBytes, totalBytes);
// Copy the buffer into executable memory (c.f. IonCode::copyFrom). // Copy the buffer into executable memory (c.f. IonCode::copyFrom).
masm_.executableCopy(code); masm_.executableCopy(code);
@ -1622,14 +1604,14 @@ class MOZ_STACK_CLASS ModuleCompiler
// The AsmJSHeapAccess offsets need to be updated to reflect the // The AsmJSHeapAccess offsets need to be updated to reflect the
// "actualOffset" (an ARM distinction). // "actualOffset" (an ARM distinction).
for (unsigned i = 0; i < module_->numHeapAccesses(); i++) { for (unsigned i = 0; i < module_->numHeapAccesses(); i++) {
AsmJSHeapAccess &access = module_->heapAccess(i); AsmJSHeapAccess &a = module_->heapAccess(i);
access.setOffset(masm_.actualOffset(access.offset())); a.setOffset(masm_.actualOffset(a.offset()));
} }
JS_ASSERT(globalAccesses_.length() == 0); JS_ASSERT(globalAccesses_.length() == 0);
#else #else
for (unsigned i = 0; i < globalAccesses_.length(); i++) { for (unsigned i = 0; i < globalAccesses_.length(); i++) {
AsmJSGlobalAccess access = globalAccesses_[i]; AsmJSGlobalAccess a = globalAccesses_[i];
masm_.patchAsmJSGlobalAccess(access.offset, code, codeBytes, access.globalDataOffset); masm_.patchAsmJSGlobalAccess(a.offset, code, module_->globalData(), a.globalDataOffset);
} }
#endif #endif
@ -1689,8 +1671,6 @@ class FunctionCompiler
LabeledBlockMap labeledBreaks_; LabeledBlockMap labeledBreaks_;
LabeledBlockMap labeledContinues_; LabeledBlockMap labeledContinues_;
AutoFlushCache autoFlushCache_;
public: public:
FunctionCompiler(ModuleCompiler &m, ParseNode *fn, LifoAlloc &lifo) FunctionCompiler(ModuleCompiler &m, ParseNode *fn, LifoAlloc &lifo)
: m_(m), : m_(m),
@ -1708,14 +1688,13 @@ class FunctionCompiler
unlabeledBreaks_(m.cx()), unlabeledBreaks_(m.cx()),
unlabeledContinues_(m.cx()), unlabeledContinues_(m.cx()),
labeledBreaks_(m.cx()), labeledBreaks_(m.cx()),
labeledContinues_(m.cx()), labeledContinues_(m.cx())
autoFlushCache_("asm.js")
{} {}
ModuleCompiler & m() const { return m_; } ModuleCompiler & m() const { return m_; }
LifoAlloc & lifo() const { return lifo_; } LifoAlloc & lifo() const { return lifo_; }
ParseNode * fn() const { return fn_; } ParseNode * fn() const { return fn_; }
JSContext * cx() const { return m_.cx(); } ExclusiveContext * cx() const { return m_.cx(); }
const AsmJSModule & module() const { return m_.module(); } const AsmJSModule & module() const { return m_.module(); }
bool init() bool init()
@ -1748,7 +1727,8 @@ class FunctionCompiler
~FunctionCompiler() ~FunctionCompiler()
{ {
if (!m().hasError() && !cx()->isExceptionPending()) { #ifdef DEBUG
if (!m().hasError() && cx()->isJSContext() && !cx()->asJSContext()->isExceptionPending()) {
JS_ASSERT(loopStack_.empty()); JS_ASSERT(loopStack_.empty());
JS_ASSERT(unlabeledBreaks_.empty()); JS_ASSERT(unlabeledBreaks_.empty());
JS_ASSERT(unlabeledContinues_.empty()); JS_ASSERT(unlabeledContinues_.empty());
@ -1756,6 +1736,7 @@ class FunctionCompiler
JS_ASSERT(labeledContinues_.empty()); JS_ASSERT(labeledContinues_.empty());
JS_ASSERT(curBlock_ == NULL); JS_ASSERT(curBlock_ == NULL);
} }
#endif
} }
/***************************************************** Local scope setup */ /***************************************************** Local scope setup */
@ -1783,7 +1764,7 @@ class FunctionCompiler
JS_ASSERT(locals_.count() == argTypes.length() + varInitializers_.length()); JS_ASSERT(locals_.count() == argTypes.length() + varInitializers_.length());
alloc_ = lifo_.new_<TempAllocator>(&lifo_); alloc_ = lifo_.new_<TempAllocator>(&lifo_);
ionContext_.construct(m_.cx()->runtime(), m_.cx()->compartment(), alloc_); ionContext_.construct(m_.cx(), alloc_);
graph_ = lifo_.new_<MIRGraph>(alloc_); graph_ = lifo_.new_<MIRGraph>(alloc_);
info_ = lifo_.new_<CompileInfo>(locals_.count(), SequentialExecution); info_ = lifo_.new_<CompileInfo>(locals_.count(), SequentialExecution);
@ -4822,6 +4803,22 @@ CheckFunctionsSequential(ModuleCompiler &m)
} }
#ifdef JS_WORKER_THREADS #ifdef JS_WORKER_THREADS
static bool
ParallelCompilationEnabled(ExclusiveContext *cx)
{
// If 'cx' isn't a JSContext, then we are already off the main thread so
// off-thread compilation must be enabled. However, since there are a fixed
// number of worker threads and one is already being consumed by this
// parsing task, ensure that there another free thread to avoid deadlock.
// (Note: there is at most one thread used for parsing so we don't have to
// worry about general dining philosophers.)
if (!cx->isJSContext())
return cx->workerThreadState()->numThreads > 1;
return OffThreadCompilationEnabled(cx->asJSContext());
}
// State of compilation as tracked and updated by the main thread. // State of compilation as tracked and updated by the main thread.
struct ParallelGroupState struct ParallelGroupState
{ {
@ -4839,7 +4836,7 @@ struct ParallelGroupState
static AsmJSParallelTask * static AsmJSParallelTask *
GetFinishedCompilation(ModuleCompiler &m, ParallelGroupState &group) GetFinishedCompilation(ModuleCompiler &m, ParallelGroupState &group)
{ {
AutoLockWorkerThreadState lock(m.cx()->runtime()); AutoLockWorkerThreadState lock(*m.cx()->workerThreadState());
while (!group.state.asmJSWorkerFailed()) { while (!group.state.asmJSWorkerFailed()) {
if (!group.state.asmJSFinishedList.empty()) { if (!group.state.asmJSFinishedList.empty()) {
@ -4865,7 +4862,7 @@ GenerateCodeForFinishedJob(ModuleCompiler &m, ParallelGroupState &group, AsmJSPa
{ {
// Perform code generation on the main thread. // Perform code generation on the main thread.
IonContext ionContext(m.cx()->runtime(), m.cx()->compartment(), &task->mir->temp()); IonContext ionContext(m.cx(), &task->mir->temp());
if (!GenerateCode(m, func, *task->mir, *task->lir)) if (!GenerateCode(m, func, *task->mir, *task->lir))
return false; return false;
} }
@ -4951,7 +4948,7 @@ CancelOutstandingJobs(ModuleCompiler &m, ParallelGroupState &group)
if (!group.outstandingJobs) if (!group.outstandingJobs)
return; return;
AutoLockWorkerThreadState lock(m.cx()->runtime()); AutoLockWorkerThreadState lock(*m.cx()->workerThreadState());
// From the compiling tasks, eliminate those waiting for worker assignation. // From the compiling tasks, eliminate those waiting for worker assignation.
group.outstandingJobs -= group.state.asmJSWorklist.length(); group.outstandingJobs -= group.state.asmJSWorklist.length();
@ -4985,7 +4982,7 @@ static bool
CheckFunctionsParallel(ModuleCompiler &m) CheckFunctionsParallel(ModuleCompiler &m)
{ {
// Saturate all worker threads plus the main thread. // Saturate all worker threads plus the main thread.
WorkerThreadState &state = *m.cx()->runtime()->workerThreadState; WorkerThreadState &state = *m.cx()->workerThreadState();
size_t numParallelJobs = state.numThreads + 1; size_t numParallelJobs = state.numThreads + 1;
// Allocate scoped AsmJSParallelTask objects. Each contains a unique // Allocate scoped AsmJSParallelTask objects. Each contains a unique
@ -6225,8 +6222,9 @@ FinishModule(ModuleCompiler &m,
ScopedJSDeletePtr<AsmJSModule> *module, ScopedJSDeletePtr<AsmJSModule> *module,
ScopedJSFreePtr<char> *compilationTimeReport) ScopedJSFreePtr<char> *compilationTimeReport)
{ {
TempAllocator alloc(&m.cx()->tempLifoAlloc()); LifoAlloc lifo(LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
IonContext ionContext(m.cx()->runtime(), m.cx()->compartment(), &alloc); TempAllocator alloc(&lifo);
IonContext ionContext(m.cx(), &alloc);
if (!GenerateStubs(m)) if (!GenerateStubs(m))
return false; return false;
@ -6235,7 +6233,7 @@ FinishModule(ModuleCompiler &m,
} }
static bool static bool
CheckModule(JSContext *cx, AsmJSParser &parser, ParseNode *stmtList, CheckModule(ExclusiveContext *cx, AsmJSParser &parser, ParseNode *stmtList,
ScopedJSDeletePtr<AsmJSModule> *module, ScopedJSDeletePtr<AsmJSModule> *module,
ScopedJSFreePtr<char> *compilationTimeReport) ScopedJSFreePtr<char> *compilationTimeReport)
{ {
@ -6262,7 +6260,7 @@ CheckModule(JSContext *cx, AsmJSParser &parser, ParseNode *stmtList,
return false; return false;
#ifdef JS_WORKER_THREADS #ifdef JS_WORKER_THREADS
if (OffThreadCompilationEnabled(cx)) { if (ParallelCompilationEnabled(cx)) {
if (!CheckFunctionsParallel(m)) if (!CheckFunctionsParallel(m))
return false; return false;
} else { } else {
@ -6290,48 +6288,63 @@ CheckModule(JSContext *cx, AsmJSParser &parser, ParseNode *stmtList,
} }
static bool static bool
Warn(JSContext *cx, int code, const char *str) Warn(AsmJSParser &parser, int errorNumber, const char *str)
{ {
return JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING, js_GetErrorMessage, parser.reportNoOffset(ParseWarning, /* strict = */ false, errorNumber, str ? str : "");
NULL, code, str ? str : ""); return false;
}
static bool
EstablishPreconditions(ExclusiveContext *cx, AsmJSParser &parser)
{
if (!cx->jitSupportsFloatingPoint())
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by lack of floating point support");
if (!cx->signalHandlersInstalled())
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Platform missing signal handler support");
if (cx->gcSystemPageSize() != AsmJSPageSize)
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by non 4KiB system page size");
if (!parser.options().asmJSOption)
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by javascript.options.asmjs in about:config");
if (!parser.options().compileAndGo)
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Temporarily disabled for event-handler and other cloneable scripts");
if (cx->compartment()->debugMode())
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by debugger");
# ifdef JS_WORKER_THREADS
if (ParallelCompilationEnabled(cx)) {
if (!EnsureWorkerThreadsInitialized(cx))
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Failed compilation thread initialization");
}
# endif
return true;
}
static bool
NoExceptionPending(ExclusiveContext *cx)
{
return !cx->isJSContext() || !cx->asJSContext()->isExceptionPending();
} }
bool bool
js::CompileAsmJS(JSContext *cx, AsmJSParser &parser, ParseNode *stmtList, bool *validated) js::CompileAsmJS(ExclusiveContext *cx, AsmJSParser &parser, ParseNode *stmtList, bool *validated)
{ {
*validated = false; *validated = false;
if (!JSC::MacroAssembler::supportsFloatingPoint()) if (!EstablishPreconditions(cx, parser))
return Warn(cx, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by lack of floating point support"); return NoExceptionPending(cx);
if (cx->runtime()->gcSystemPageSize != AsmJSPageSize)
return Warn(cx, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by non 4KiB system page size");
if (!cx->hasOption(JSOPTION_ASMJS))
return Warn(cx, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by javascript.options.asmjs in about:config");
if (!parser.options().compileAndGo)
return Warn(cx, JSMSG_USE_ASM_TYPE_FAIL, "Temporarily disabled for event-handler and other cloneable scripts");
if (cx->compartment()->debugMode())
return Warn(cx, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by debugger");
if (!EnsureAsmJSSignalHandlersInstalled(cx->runtime()))
return Warn(cx, JSMSG_USE_ASM_TYPE_FAIL, "Platform missing signal handler support");
# ifdef JS_WORKER_THREADS
if (OffThreadCompilationEnabled(cx)) {
if (!EnsureWorkerThreadsInitialized(cx->runtime()))
return Warn(cx, JSMSG_USE_ASM_TYPE_FAIL, "Failed compilation thread initialization");
}
# endif
ScopedJSFreePtr<char> compilationTimeReport; ScopedJSFreePtr<char> compilationTimeReport;
ScopedJSDeletePtr<AsmJSModule> module; ScopedJSDeletePtr<AsmJSModule> module;
if (!CheckModule(cx, parser, stmtList, &module, &compilationTimeReport)) if (!CheckModule(cx, parser, stmtList, &module, &compilationTimeReport))
return !cx->isExceptionPending(); return NoExceptionPending(cx);
RootedObject moduleObj(cx, NewAsmJSModuleObject(cx, &module)); RootedObject moduleObj(cx, AsmJSModuleObject::create(cx, &module));
if (!moduleObj) if (!moduleObj)
return false; return false;
@ -6344,7 +6357,8 @@ js::CompileAsmJS(JSContext *cx, AsmJSParser &parser, ParseNode *stmtList, bool *
funbox->object = moduleFun; funbox->object = moduleFun;
*validated = true; *validated = true;
return Warn(cx, JSMSG_USE_ASM_TYPE_OK, compilationTimeReport); Warn(parser, JSMSG_USE_ASM_TYPE_OK, compilationTimeReport.get());
return NoExceptionPending(cx);
} }
bool bool
@ -6352,7 +6366,9 @@ js::IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, Value *vp)
{ {
CallArgs args = CallArgsFromVp(argc, vp); CallArgs args = CallArgsFromVp(argc, vp);
// See EstablishPreconditions.
bool available = JSC::MacroAssembler::supportsFloatingPoint() && bool available = JSC::MacroAssembler::supportsFloatingPoint() &&
cx->gcSystemPageSize() == AsmJSPageSize &&
!cx->compartment()->debugMode() && !cx->compartment()->debugMode() &&
cx->hasOption(JSOPTION_ASMJS); cx->hasOption(JSOPTION_ASMJS);

View File

@ -11,6 +11,7 @@
namespace js { namespace js {
class ExclusiveContext;
class AsmJSModule; class AsmJSModule;
class SPSProfiler; class SPSProfiler;
namespace frontend { namespace frontend {
@ -29,7 +30,8 @@ typedef frontend::ParseContext<frontend::FullParseHandler> AsmJSParseContext;
// In this case, the parser.tokenStream has been advanced an indeterminate // In this case, the parser.tokenStream has been advanced an indeterminate
// amount and the entire function should be reparsed from the beginning. // amount and the entire function should be reparsed from the beginning.
extern bool extern bool
CompileAsmJS(JSContext *cx, AsmJSParser &parser, frontend::ParseNode *stmtList, bool *validated); CompileAsmJS(ExclusiveContext *cx, AsmJSParser &parser, frontend::ParseNode *stmtList,
bool *validated);
// The JSRuntime maintains a stack of AsmJSModule activations. An "activation" // The JSRuntime maintains a stack of AsmJSModule activations. An "activation"
// of module A is an initial call from outside A into a function inside A, // of module A is an initial call from outside A into a function inside A,

View File

@ -313,7 +313,7 @@ CallAsmJS(JSContext *cx, unsigned argc, Value *vp)
// - a pointer to the module from which it was returned // - a pointer to the module from which it was returned
// - its index in the ordered list of exported functions // - its index in the ordered list of exported functions
RootedObject moduleObj(cx, &callee->getExtendedSlot(ASM_MODULE_SLOT).toObject()); RootedObject moduleObj(cx, &callee->getExtendedSlot(ASM_MODULE_SLOT).toObject());
AsmJSModule &module = AsmJSModuleObjectToModule(moduleObj); AsmJSModule &module = moduleObj->as<AsmJSModuleObject>().module();
// An exported function points to the code as well as the exported // An exported function points to the code as well as the exported
// function's signature, which implies the dynamic coercions performed on // function's signature, which implies the dynamic coercions performed on
@ -576,7 +576,7 @@ SendModuleToAttachedProfiler(JSContext *cx, AsmJSModule &module)
static JSObject * static JSObject *
CreateExportObject(JSContext *cx, HandleObject moduleObj) CreateExportObject(JSContext *cx, HandleObject moduleObj)
{ {
AsmJSModule &module = AsmJSModuleObjectToModule(moduleObj); AsmJSModule &module = moduleObj->as<AsmJSModuleObject>().module();
if (module.numExportedFunctions() == 1) { if (module.numExportedFunctions() == 1) {
const AsmJSModule::ExportedFunction &func = module.exportedFunction(0); const AsmJSModule::ExportedFunction &func = module.exportedFunction(0);
@ -616,7 +616,7 @@ LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
// function and stores its module in an extended slot. // function and stores its module in an extended slot.
RootedFunction fun(cx, &args.callee().as<JSFunction>()); RootedFunction fun(cx, &args.callee().as<JSFunction>());
RootedObject moduleObj(cx, &fun->getExtendedSlot(MODULE_FUN_SLOT).toObject()); RootedObject moduleObj(cx, &fun->getExtendedSlot(MODULE_FUN_SLOT).toObject());
AsmJSModule &module = AsmJSModuleObjectToModule(moduleObj); AsmJSModule &module = moduleObj->as<AsmJSModuleObject>().module();
// Link the module by performing the link-time validation checks in the // Link the module by performing the link-time validation checks in the
// asm.js spec and then patching the generated module to associate it with // asm.js spec and then patching the generated module to associate it with
@ -645,7 +645,7 @@ LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
} }
JSFunction * JSFunction *
js::NewAsmJSModuleFunction(JSContext *cx, JSFunction *origFun, HandleObject moduleObj) js::NewAsmJSModuleFunction(ExclusiveContext *cx, JSFunction *origFun, HandleObject moduleObj)
{ {
RootedPropertyName name(cx, origFun->name()); RootedPropertyName name(cx, origFun->name());
JSFunction *moduleFun = NewFunction(cx, NullPtr(), LinkAsmJS, origFun->nargs, JSFunction *moduleFun = NewFunction(cx, NullPtr(), LinkAsmJS, origFun->nargs,

View File

@ -16,7 +16,7 @@ namespace js {
// Create a new JSFunction to replace originalFun as the representation of the // Create a new JSFunction to replace originalFun as the representation of the
// function defining the succesfully-validated module 'moduleObj'. // function defining the succesfully-validated module 'moduleObj'.
extern JSFunction * extern JSFunction *
NewAsmJSModuleFunction(JSContext *cx, JSFunction *originalFun, HandleObject moduleObj); NewAsmJSModuleFunction(ExclusiveContext *cx, JSFunction *originalFun, HandleObject moduleObj);
// Return whether this is the js::Native returned by NewAsmJSModuleFunction. // Return whether this is the js::Native returned by NewAsmJSModuleFunction.
extern bool extern bool

View File

@ -7,71 +7,20 @@
#include "jit/AsmJSModule.h" #include "jit/AsmJSModule.h"
#include "jit/IonCode.h" #include "jit/IonCode.h"
#ifndef XP_WIN
# include <sys/mman.h>
#endif
#ifdef XP_WIN
# include "jswin.h"
#endif
#include "js/MemoryMetrics.h"
#include "jsobjinlines.h" #include "jsobjinlines.h"
using namespace js; using namespace js;
static void AsmJSModuleObject_finalize(FreeOp *fop, JSObject *obj);
static void AsmJSModuleObject_trace(JSTracer *trc, JSObject *obj);
static const unsigned ASM_CODE_RESERVED_SLOT = 0;
static const unsigned ASM_CODE_NUM_RESERVED_SLOTS = 1;
static Class AsmJSModuleClass = {
"AsmJSModuleObject",
JSCLASS_IS_ANONYMOUS | JSCLASS_IMPLEMENTS_BARRIERS |
JSCLASS_HAS_RESERVED_SLOTS(ASM_CODE_NUM_RESERVED_SLOTS),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
NULL, /* convert */
AsmJSModuleObject_finalize,
NULL, /* checkAccess */
NULL, /* call */
NULL, /* hasInstance */
NULL, /* construct */
AsmJSModuleObject_trace
};
bool
js::IsAsmJSModuleObject(JSObject *obj)
{
return obj->getClass() == &AsmJSModuleClass;
}
AsmJSModule &
js::AsmJSModuleObjectToModule(JSObject *obj)
{
JS_ASSERT(IsAsmJSModuleObject(obj));
return *(AsmJSModule *)obj->getReservedSlot(ASM_CODE_RESERVED_SLOT).toPrivate();
}
static void
AsmJSModuleObject_finalize(FreeOp *fop, JSObject *obj)
{
fop->delete_(&AsmJSModuleObjectToModule(obj));
}
static void
AsmJSModuleObject_trace(JSTracer *trc, JSObject *obj)
{
AsmJSModuleObjectToModule(obj).trace(trc);
}
JSObject *
js::NewAsmJSModuleObject(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *module)
{
JSObject *obj = NewObjectWithGivenProto(cx, &AsmJSModuleClass, NULL, NULL);
if (!obj)
return NULL;
obj->setReservedSlot(ASM_CODE_RESERVED_SLOT, PrivateValue(module->forget()));
return obj;
}
void void
AsmJSModule::patchHeapAccesses(ArrayBufferObject *heap, JSContext *cx) AsmJSModule::patchHeapAccesses(ArrayBufferObject *heap, JSContext *cx)
{ {
@ -92,6 +41,60 @@ AsmJSModule::patchHeapAccesses(ArrayBufferObject *heap, JSContext *cx)
#endif #endif
} }
static uint8_t *
AllocateExecutableMemory(ExclusiveContext *cx, size_t totalBytes)
{
JS_ASSERT(totalBytes % AsmJSPageSize == 0);
#ifdef XP_WIN
void *p = VirtualAlloc(NULL, totalBytes, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!p) {
js_ReportOutOfMemory(cx);
return NULL;
}
#else // assume Unix
void *p = mmap(NULL, totalBytes, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
if (p == MAP_FAILED) {
js_ReportOutOfMemory(cx);
return NULL;
}
#endif
return (uint8_t *)p;
}
static void
DeallocateExecutableMemory(uint8_t *code, size_t totalBytes)
{
#ifdef XP_WIN
JS_ALWAYS_TRUE(VirtualFree(code, 0, MEM_RELEASE));
#else
JS_ALWAYS_TRUE(munmap(code, totalBytes) == 0);
#endif
}
uint8_t *
AsmJSModule::allocateCodeAndGlobalSegment(ExclusiveContext *cx, size_t bytesNeeded)
{
JS_ASSERT(!code_);
// The global data section sits immediately after the executable (and
// other) data allocated by the MacroAssembler, so ensure it is
// double-aligned.
codeBytes_ = AlignBytes(bytesNeeded, sizeof(double));
// The entire region is allocated via mmap/VirtualAlloc which requires
// units of pages.
totalBytes_ = AlignBytes(codeBytes_ + globalDataBytes(), AsmJSPageSize);
code_ = AllocateExecutableMemory(cx, totalBytes_);
if (!code_)
return NULL;
JS_ASSERT(uintptr_t(code_) % AsmJSPageSize == 0);
return code_;
}
AsmJSModule::~AsmJSModule() AsmJSModule::~AsmJSModule()
{ {
if (code_) { if (code_) {
@ -110,8 +113,79 @@ AsmJSModule::~AsmJSModule()
ion::DependentAsmJSModuleExit exit(this, i); ion::DependentAsmJSModuleExit exit(this, i);
script->ionScript()->removeDependentAsmJSModule(exit); script->ionScript()->removeDependentAsmJSModule(exit);
} }
DeallocateExecutableMemory(code_, totalBytes_);
} }
for (size_t i = 0; i < numFunctionCounts(); i++) for (size_t i = 0; i < numFunctionCounts(); i++)
js_delete(functionCounts(i)); js_delete(functionCounts(i));
} }
void
AsmJSModule::sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, size_t *asmJSModuleCode,
size_t *asmJSModuleData)
{
*asmJSModuleCode = totalBytes_;
*asmJSModuleData = mallocSizeOf(this) +
globals_.sizeOfExcludingThis(mallocSizeOf) +
exits_.sizeOfExcludingThis(mallocSizeOf) +
exports_.sizeOfExcludingThis(mallocSizeOf) +
heapAccesses_.sizeOfExcludingThis(mallocSizeOf) +
#if defined(MOZ_VTUNE)
profiledFunctions_.sizeOfExcludingThis(mallocSizeOf) +
#endif
#if defined(JS_ION_PERF)
perfProfiledFunctions_.sizeOfExcludingThis(mallocSizeOf) +
perfProfiledBlocksFunctions_.sizeOfExcludingThis(mallocSizeOf) +
#endif
functionCounts_.sizeOfExcludingThis(mallocSizeOf);
}
static void
AsmJSModuleObject_finalize(FreeOp *fop, JSObject *obj)
{
fop->delete_(&obj->as<AsmJSModuleObject>().module());
}
static void
AsmJSModuleObject_trace(JSTracer *trc, JSObject *obj)
{
obj->as<AsmJSModuleObject>().module().trace(trc);
}
Class AsmJSModuleObject::class_ = {
"AsmJSModuleObject",
JSCLASS_IS_ANONYMOUS | JSCLASS_IMPLEMENTS_BARRIERS |
JSCLASS_HAS_RESERVED_SLOTS(AsmJSModuleObject::RESERVED_SLOTS),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
NULL, /* convert */
AsmJSModuleObject_finalize,
NULL, /* checkAccess */
NULL, /* call */
NULL, /* hasInstance */
NULL, /* construct */
AsmJSModuleObject_trace
};
AsmJSModuleObject *
AsmJSModuleObject::create(ExclusiveContext *cx, ScopedJSDeletePtr<AsmJSModule> *module)
{
JSObject *obj = NewObjectWithGivenProto(cx, &AsmJSModuleObject::class_, NULL, NULL);
if (!obj)
return NULL;
obj->setReservedSlot(MODULE_SLOT, PrivateValue(module->forget()));
return &obj->as<AsmJSModuleObject>();
}
AsmJSModule &
AsmJSModuleObject::module() const
{
JS_ASSERT(is<AsmJSModuleObject>());
return *(AsmJSModule *)getReservedSlot(MODULE_SLOT).toPrivate();
}

View File

@ -353,7 +353,6 @@ class AsmJSModule
size_t funcPtrTableAndExitBytes_; size_t funcPtrTableAndExitBytes_;
bool hasArrayView_; bool hasArrayView_;
ScopedReleasePtr<JSC::ExecutablePool> codePool_;
uint8_t * code_; uint8_t * code_;
uint8_t * operationCallbackExit_; uint8_t * operationCallbackExit_;
size_t functionBytes_; size_t functionBytes_;
@ -648,13 +647,8 @@ class AsmJSModule
} }
void patchHeapAccesses(ArrayBufferObject *heap, JSContext *cx); void patchHeapAccesses(ArrayBufferObject *heap, JSContext *cx);
void takeOwnership(JSC::ExecutablePool *pool, uint8_t *code, size_t codeBytes, size_t totalBytes) { uint8_t *allocateCodeAndGlobalSegment(ExclusiveContext *cx, size_t bytesNeeded);
JS_ASSERT(uintptr_t(code) % AsmJSPageSize == 0);
codePool_ = pool;
code_ = code;
codeBytes_ = codeBytes;
totalBytes_ = totalBytes;
}
uint8_t *functionCode() const { uint8_t *functionCode() const {
JS_ASSERT(code_); JS_ASSERT(code_);
JS_ASSERT(uintptr_t(code_) % AsmJSPageSize == 0); JS_ASSERT(uintptr_t(code_) % AsmJSPageSize == 0);
@ -704,21 +698,36 @@ class AsmJSModule
void detachIonCompilation(size_t exitIndex) const { void detachIonCompilation(size_t exitIndex) const {
exitIndexToGlobalDatum(exitIndex).exit = exit(exitIndex).interpCode(); exitIndexToGlobalDatum(exitIndex).exit = exit(exitIndex).interpCode();
} }
// Part of about:memory reporting:
void sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, size_t *asmJSModuleCode,
size_t *asmJSModuleData);
}; };
// On success, return an AsmJSModuleClass JSObject that has taken ownership // An AsmJSModuleObject is an internal implementation object (i.e., not exposed
// (and release()ed) the given module. // directly to user script) which manages the lifetime of an AsmJSModule. A
extern JSObject * // JSObject is necessary since we want LinkAsmJS/CallAsmJS JSFunctions to be
NewAsmJSModuleObject(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *module); // able to point to their module via their extended slots.
class AsmJSModuleObject : public JSObject
{
static const unsigned MODULE_SLOT = 0;
// Return whether the given object was created by NewAsmJSModuleObject. public:
extern bool static const unsigned RESERVED_SLOTS = 1;
IsAsmJSModuleObject(JSObject *obj);
// The AsmJSModule C++ object is held by a JSObject that takes care of calling // On success, return an AsmJSModuleClass JSObject that has taken ownership
// 'trace' and the destructor on finalization. // (and release()ed) the given module.
extern AsmJSModule & static AsmJSModuleObject *create(ExclusiveContext *cx, ScopedJSDeletePtr<AsmJSModule> *module);
AsmJSModuleObjectToModule(JSObject *obj);
AsmJSModule &module() const;
void sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, size_t *asmJSModuleCode,
size_t *asmJSModuleData) {
module().sizeOfMisc(mallocSizeOf, asmJSModuleCode, asmJSModuleData);
}
static Class class_;
};
} // namespace js } // namespace js

View File

@ -969,18 +969,6 @@ CodeGenerator::visitCallee(LCallee *lir)
return true; return true;
} }
bool
CodeGenerator::visitForceUseV(LForceUseV *lir)
{
return true;
}
bool
CodeGenerator::visitForceUseT(LForceUseT *lir)
{
return true;
}
bool bool
CodeGenerator::visitStart(LStart *lir) CodeGenerator::visitStart(LStart *lir)
{ {
@ -7316,5 +7304,85 @@ CodeGenerator::visitAsmJSCheckOverRecursed(LAsmJSCheckOverRecursed *lir)
return true; return true;
} }
bool
CodeGenerator::visitRangeAssert(LRangeAssert *ins)
{
Register input = ToRegister(ins->input());
Range *r = ins->range();
// Check the lower bound.
if (r->lower() != INT32_MIN) {
Label success;
masm.branch32(Assembler::GreaterThanOrEqual, input, Imm32(r->lower()), &success);
masm.breakpoint();
masm.bind(&success);
}
// Check the upper bound.
if (r->upper() != INT32_MAX) {
Label success;
masm.branch32(Assembler::LessThanOrEqual, input, Imm32(r->upper()), &success);
masm.breakpoint();
masm.bind(&success);
}
// For r->isDecimal() and r->exponent(), there's nothing to check, because
// if we ended up in the integer range checking code, the value is already
// in an integer register in the integer range.
return true;
}
bool
CodeGenerator::visitDoubleRangeAssert(LDoubleRangeAssert *ins)
{
FloatRegister input = ToFloatRegister(ins->input());
FloatRegister temp = ToFloatRegister(ins->temp());
Range *r = ins->range();
// Check the lower bound.
if (!r->isLowerInfinite()) {
Label success;
masm.loadConstantDouble(r->lower(), temp);
if (r->isUpperInfinite())
masm.branchDouble(Assembler::DoubleUnordered, input, input, &success);
masm.branchDouble(Assembler::DoubleGreaterThanOrEqual, input, temp, &success);
masm.breakpoint();
masm.bind(&success);
}
// Check the upper bound.
if (!r->isUpperInfinite()) {
Label success;
masm.loadConstantDouble(r->upper(), temp);
if (r->isLowerInfinite())
masm.branchDouble(Assembler::DoubleUnordered, input, input, &success);
masm.branchDouble(Assembler::DoubleLessThanOrEqual, input, temp, &success);
masm.breakpoint();
masm.bind(&success);
}
// This code does not yet check r->isDecimal(). This would require new
// assembler interfaces to make rounding instructions available.
if (!r->isInfinite()) {
// Check the bounds implied by the maximum exponent.
Label exponentLoOk;
masm.loadConstantDouble(pow(2.0, r->exponent() + 1), temp);
masm.branchDouble(Assembler::DoubleUnordered, input, input, &exponentLoOk);
masm.branchDouble(Assembler::DoubleLessThanOrEqual, input, temp, &exponentLoOk);
masm.breakpoint();
masm.bind(&exponentLoOk);
Label exponentHiOk;
masm.loadConstantDouble(-pow(2.0, r->exponent() + 1), temp);
masm.branchDouble(Assembler::DoubleUnordered, input, input, &exponentHiOk);
masm.branchDouble(Assembler::DoubleGreaterThanOrEqual, input, temp, &exponentHiOk);
masm.breakpoint();
masm.bind(&exponentHiOk);
}
return true;
}
} // namespace ion } // namespace ion
} // namespace js } // namespace js

View File

@ -60,8 +60,6 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitTableSwitchV(LTableSwitchV *ins); bool visitTableSwitchV(LTableSwitchV *ins);
bool visitParameter(LParameter *lir); bool visitParameter(LParameter *lir);
bool visitCallee(LCallee *lir); bool visitCallee(LCallee *lir);
bool visitForceUseV(LForceUseV *lir);
bool visitForceUseT(LForceUseT *lir);
bool visitStart(LStart *lir); bool visitStart(LStart *lir);
bool visitReturn(LReturn *ret); bool visitReturn(LReturn *ret);
bool visitDefVar(LDefVar *lir); bool visitDefVar(LDefVar *lir);
@ -304,6 +302,9 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitNameIC(OutOfLineUpdateCache *ool, NameIC *ic); bool visitNameIC(OutOfLineUpdateCache *ool, NameIC *ic);
bool visitCallsiteCloneIC(OutOfLineUpdateCache *ool, CallsiteCloneIC *ic); bool visitCallsiteCloneIC(OutOfLineUpdateCache *ool, CallsiteCloneIC *ic);
bool visitRangeAssert(LRangeAssert *ins);
bool visitDoubleRangeAssert(LDoubleRangeAssert *ins);
IonScriptCounts *extractUnassociatedScriptCounts() { IonScriptCounts *extractUnassociatedScriptCounts() {
IonScriptCounts *counts = unassociatedScriptCounts_; IonScriptCounts *counts = unassociatedScriptCounts_;
unassociatedScriptCounts_ = NULL; // prevent delete in dtor unassociatedScriptCounts_ = NULL; // prevent delete in dtor

View File

@ -124,6 +124,17 @@ IonContext::IonContext(JSContext *cx, TempAllocator *temp)
SetIonContext(this); SetIonContext(this);
} }
IonContext::IonContext(ExclusiveContext *cx, TempAllocator *temp)
: runtime(cx->runtime_),
cx(NULL),
compartment(NULL),
temp(temp),
prev_(CurrentIonContext()),
assemblerCount_(0)
{
SetIonContext(this);
}
IonContext::IonContext(JSRuntime *rt, JSCompartment *comp, TempAllocator *temp) IonContext::IonContext(JSRuntime *rt, JSCompartment *comp, TempAllocator *temp)
: runtime(rt), : runtime(rt),
cx(NULL), cx(NULL),
@ -183,7 +194,6 @@ IonRuntime::IonRuntime()
functionWrappers_(NULL), functionWrappers_(NULL),
osrTempData_(NULL), osrTempData_(NULL),
flusher_(NULL), flusher_(NULL),
signalHandlersInstalled_(false),
ionCodeProtected_(false) ionCodeProtected_(false)
{ {
} }
@ -283,8 +293,6 @@ IonRuntime::initialize(JSContext *cx)
return false; return false;
} }
signalHandlersInstalled_ = EnsureAsmJSSignalHandlersInstalled(cx->runtime());
return true; return true;
} }
@ -333,7 +341,7 @@ IonRuntime::ensureIonCodeProtected(JSRuntime *rt)
{ {
JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock()); JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
if (!signalHandlersInstalled_ || ionCodeProtected_ || !ionAlloc_) if (!rt->signalHandlersInstalled() || ionCodeProtected_ || !ionAlloc_)
return; return;
// Protect all Ion code in the runtime to trigger an access violation the // Protect all Ion code in the runtime to trigger an access violation the
@ -345,7 +353,7 @@ IonRuntime::ensureIonCodeProtected(JSRuntime *rt)
bool bool
IonRuntime::handleAccessViolation(JSRuntime *rt, void *faultingAddress) IonRuntime::handleAccessViolation(JSRuntime *rt, void *faultingAddress)
{ {
if (!signalHandlersInstalled_ || !ionAlloc_ || !ionAlloc_->codeContains((char *) faultingAddress)) if (!rt->signalHandlersInstalled() || !ionAlloc_ || !ionAlloc_->codeContains((char *) faultingAddress))
return false; return false;
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
@ -1521,7 +1529,7 @@ AttachFinishedCompilations(JSContext *cx)
if (!ion || !cx->runtime()->workerThreadState) if (!ion || !cx->runtime()->workerThreadState)
return; return;
AutoLockWorkerThreadState lock(cx->runtime()); AutoLockWorkerThreadState lock(*cx->runtime()->workerThreadState);
OffThreadCompilationVector &compilations = ion->finishedOffThreadCompilations(); OffThreadCompilationVector &compilations = ion->finishedOffThreadCompilations();
@ -2591,8 +2599,10 @@ AutoFlushCache::updateTop(uintptr_t p, size_t len)
{ {
IonContext *ictx = GetIonContext(); IonContext *ictx = GetIonContext();
IonRuntime *irt = ictx->runtime->ionRuntime(); IonRuntime *irt = ictx->runtime->ionRuntime();
AutoFlushCache *afc = irt->flusher(); if (!irt || !irt->flusher())
afc->update(p, len); JSC::ExecutableAllocator::cacheFlush((void*)p, len);
else
irt->flusher()->update(p, len);
} }
AutoFlushCache::AutoFlushCache(const char *nonce, IonRuntime *rt) AutoFlushCache::AutoFlushCache(const char *nonce, IonRuntime *rt)

View File

@ -77,6 +77,12 @@ struct IonOptions
// Default: true // Default: true
bool rangeAnalysis; bool rangeAnalysis;
// Whether to enable extra code to perform dynamic validation of
// RangeAnalysis results.
//
// Default: false
bool checkRangeAnalysis;
// Toggles whether Unreachable Code Elimination is performed. // Toggles whether Unreachable Code Elimination is performed.
// //
// Default: true // Default: true
@ -212,6 +218,7 @@ struct IonOptions
inlining(true), inlining(true),
edgeCaseAnalysis(true), edgeCaseAnalysis(true),
rangeAnalysis(true), rangeAnalysis(true),
checkRangeAnalysis(false),
uce(true), uce(true),
eaa(true), eaa(true),
parallelCompilation(false), parallelCompilation(false),
@ -266,6 +273,7 @@ class IonContext
{ {
public: public:
IonContext(JSContext *cx, TempAllocator *temp); IonContext(JSContext *cx, TempAllocator *temp);
IonContext(ExclusiveContext *cx, TempAllocator *temp);
IonContext(JSRuntime *rt, JSCompartment *comp, TempAllocator *temp); IonContext(JSRuntime *rt, JSCompartment *comp, TempAllocator *temp);
IonContext(JSRuntime *rt); IonContext(JSRuntime *rt);
~IonContext(); ~IonContext();

View File

@ -3716,11 +3716,6 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
returnBlock->inheritSlots(current); returnBlock->inheritSlots(current);
returnBlock->pop(); returnBlock->pop();
// If callee is not a constant, add an MForceUse with the callee to make sure that
// it gets kept alive across the inlined body.
if (!callInfo.fun()->isConstant())
returnBlock->add(MForceUse::New(callInfo.fun()));
// Accumulate return values. // Accumulate return values.
MIRGraphExits &exits = *inlineBuilder.graph().exitAccumulator(); MIRGraphExits &exits = *inlineBuilder.graph().exitAccumulator();
if (exits.length() == 0) { if (exits.length() == 0) {

View File

@ -203,10 +203,6 @@ class IonRuntime
// Keep track of memoryregions that are going to be flushed. // Keep track of memoryregions that are going to be flushed.
AutoFlushCache *flusher_; AutoFlushCache *flusher_;
// Whether asm.js signal handlers have been installed and can be used for
// performing interrupt checks in loops.
bool signalHandlersInstalled_;
// Whether all Ion code in the runtime is protected, and will fault if it // Whether all Ion code in the runtime is protected, and will fault if it
// is accessed. // is accessed.
bool ionCodeProtected_; bool ionCodeProtected_;
@ -257,9 +253,6 @@ class IonRuntime
return ionAlloc_; return ionAlloc_;
} }
bool signalHandlersInstalled() {
return signalHandlersInstalled_;
}
bool ionCodeProtected() { bool ionCodeProtected() {
return ionCodeProtected_; return ionCodeProtected_;
} }

View File

@ -7,6 +7,7 @@
#ifndef jit_LIR_Common_h #ifndef jit_LIR_Common_h
#define jit_LIR_Common_h #define jit_LIR_Common_h
#include "jit/RangeAnalysis.h"
#include "jit/shared/Assembler-shared.h" #include "jit/shared/Assembler-shared.h"
// This file declares LIR instructions that are common to every platform. // This file declares LIR instructions that are common to every platform.
@ -219,23 +220,6 @@ class LCallee : public LInstructionHelper<1, 0, 0>
LIR_HEADER(Callee) LIR_HEADER(Callee)
}; };
class LForceUseV : public LInstructionHelper<0, BOX_PIECES, 0>
{
public:
LIR_HEADER(ForceUseV)
};
class LForceUseT : public LInstructionHelper<0, 1, 0>
{
public:
LIR_HEADER(ForceUseT)
LForceUseT(const LAllocation &value)
{
setOperand(0, value);
}
};
// Base class for control instructions (goto, branch, etc.) // Base class for control instructions (goto, branch, etc.)
template <size_t Succs, size_t Operands, size_t Temps> template <size_t Succs, size_t Operands, size_t Temps>
class LControlInstructionHelper : public LInstructionHelper<0, Operands, Temps> { class LControlInstructionHelper : public LInstructionHelper<0, Operands, Temps> {
@ -4959,6 +4943,55 @@ class LAsmJSCheckOverRecursed : public LInstructionHelper<0, 0, 0>
} }
}; };
class LRangeAssert : public LInstructionHelper<0, 1, 0>
{
Range range_;
public:
LIR_HEADER(RangeAssert)
LRangeAssert(const LAllocation &input, Range r)
: range_(r)
{
setOperand(0, input);
}
const LAllocation *input() {
return getOperand(0);
}
Range *range() {
return &range_;
}
};
class LDoubleRangeAssert : public LInstructionHelper<0, 1, 1>
{
Range range_;
public:
LIR_HEADER(DoubleRangeAssert)
LDoubleRangeAssert(const LAllocation &input, const LDefinition &temp, Range r)
: range_(r)
{
setOperand(0, input);
setTemp(0, temp);
}
const LAllocation *input() {
return getOperand(0);
}
const LDefinition *temp() {
return getTemp(0);
}
Range *range() {
return &range_;
}
};
} // namespace ion } // namespace ion
} // namespace js } // namespace js

View File

@ -18,8 +18,6 @@
_(Value) \ _(Value) \
_(Parameter) \ _(Parameter) \
_(Callee) \ _(Callee) \
_(ForceUseV) \
_(ForceUseT) \
_(TableSwitch) \ _(TableSwitch) \
_(TableSwitchV) \ _(TableSwitchV) \
_(Goto) \ _(Goto) \
@ -247,7 +245,9 @@
_(AsmJSPassStackArg) \ _(AsmJSPassStackArg) \
_(AsmJSCall) \ _(AsmJSCall) \
_(AsmJSCheckOverRecursed) \ _(AsmJSCheckOverRecursed) \
_(CheckInterruptPar) _(CheckInterruptPar) \
_(RangeAssert) \
_(DoubleRangeAssert)
#if defined(JS_CPU_X86) #if defined(JS_CPU_X86)
# include "jit/x86/LOpcodes-x86.h" # include "jit/x86/LOpcodes-x86.h"

View File

@ -58,20 +58,6 @@ LIRGenerator::visitCallee(MCallee *ins)
return define(new LCallee(), ins); return define(new LCallee(), ins);
} }
bool
LIRGenerator::visitForceUse(MForceUse *ins)
{
if (ins->input()->type() == MIRType_Value) {
LForceUseV *lir = new LForceUseV();
if (!useBox(lir, 0, ins->input()))
return false;
return add(lir);
}
LForceUseT *lir = new LForceUseT(useAnyOrConstant(ins->input()));
return add(lir);
}
bool bool
LIRGenerator::visitGoto(MGoto *ins) LIRGenerator::visitGoto(MGoto *ins)
{ {
@ -1785,7 +1771,7 @@ LIRGenerator::visitInterruptCheck(MInterruptCheck *ins)
// installed. ARM does not yet use implicit interrupt checks, see // installed. ARM does not yet use implicit interrupt checks, see
// bug 864220. // bug 864220.
#ifndef JS_CPU_ARM #ifndef JS_CPU_ARM
if (GetIonContext()->runtime->ionRuntime()->signalHandlersInstalled()) { if (GetIonContext()->runtime->signalHandlersInstalled()) {
LInterruptCheckImplicit *lir = new LInterruptCheckImplicit(); LInterruptCheckImplicit *lir = new LInterruptCheckImplicit();
return add(lir) && assignSafepoint(lir, ins); return add(lir) && assignSafepoint(lir, ins);
} }
@ -2957,6 +2943,25 @@ LIRGenerator::visitInstruction(MInstruction *ins)
return false; return false;
} }
// Check the computed range for this instruction, if the option is set. Note
// that this code is quite invasive; it adds numerous additional
// instructions for each MInstruction with a computed range, and it uses
// registers, so it also affects register allocation.
if (js_IonOptions.checkRangeAnalysis) {
if (Range *r = ins->range()) {
switch (ins->type()) {
case MIRType_Int32:
add(new LRangeAssert(useRegisterAtStart(ins), *r));
break;
case MIRType_Double:
add(new LDoubleRangeAssert(useRegister(ins), tempFloat(), *r));
break;
default:
break;
}
}
}
return true; return true;
} }

View File

@ -80,7 +80,6 @@ class LIRGenerator : public LIRGeneratorSpecific
// intercept without a bunch of explicit gunk in the .cpp. // intercept without a bunch of explicit gunk in the .cpp.
bool visitParameter(MParameter *param); bool visitParameter(MParameter *param);
bool visitCallee(MCallee *callee); bool visitCallee(MCallee *callee);
bool visitForceUse(MForceUse *forceUse);
bool visitGoto(MGoto *ins); bool visitGoto(MGoto *ins);
bool visitTableSwitch(MTableSwitch *tableswitch); bool visitTableSwitch(MTableSwitch *tableswitch);
bool visitNewSlots(MNewSlots *ins); bool visitNewSlots(MNewSlots *ins);

View File

@ -994,34 +994,6 @@ class MCallee : public MNullaryInstruction
} }
}; };
// MForceUse exists to force the use of a resumePoint-recorded
// instruction at a later point in time, so that the contents don't get
// discarded when inlining.
class MForceUse : public MUnaryInstruction
{
public:
MForceUse(MDefinition *input)
: MUnaryInstruction(input)
{
setGuard();
setResultType(MIRType_None);
}
public:
INSTRUCTION_HEADER(ForceUse)
bool congruentTo(MDefinition *ins) const {
return false;
}
static MForceUse *New(MDefinition *input) {
return new MForceUse(input);
}
AliasSet getAliasSet() const {
return AliasSet::None();
}
};
class MControlInstruction : public MInstruction class MControlInstruction : public MInstruction
{ {
public: public:

View File

@ -14,7 +14,6 @@ namespace ion {
_(Constant) \ _(Constant) \
_(Parameter) \ _(Parameter) \
_(Callee) \ _(Callee) \
_(ForceUse) \
_(TableSwitch) \ _(TableSwitch) \
_(Goto) \ _(Goto) \
_(Test) \ _(Test) \

View File

@ -108,7 +108,6 @@ class ParallelSafetyVisitor : public MInstructionVisitor
SAFE_OP(Constant) SAFE_OP(Constant)
SAFE_OP(Parameter) SAFE_OP(Parameter)
SAFE_OP(Callee) SAFE_OP(Callee)
SAFE_OP(ForceUse)
SAFE_OP(TableSwitch) SAFE_OP(TableSwitch)
SAFE_OP(Goto) SAFE_OP(Goto)
SAFE_OP(Test) SAFE_OP(Test)

View File

@ -161,7 +161,7 @@ RangeAnalysis::addBetaNobes()
} else if (right->isConstant() && right->toConstant()->value().isInt32()) { } else if (right->isConstant() && right->toConstant()->value().isInt32()) {
bound = right->toConstant()->value().toInt32(); bound = right->toConstant()->value().toInt32();
val = left; val = left;
} else { } else if (left->type() == MIRType_Int32 && right->type() == MIRType_Int32) {
MDefinition *smaller = NULL; MDefinition *smaller = NULL;
MDefinition *greater = NULL; MDefinition *greater = NULL;
if (jsop == JSOP_LT) { if (jsop == JSOP_LT) {
@ -173,22 +173,22 @@ RangeAnalysis::addBetaNobes()
} }
if (smaller && greater) { if (smaller && greater) {
MBeta *beta; MBeta *beta;
beta = MBeta::New(smaller, new Range(JSVAL_INT_MIN, JSVAL_INT_MAX-1, beta = MBeta::New(smaller, new Range(JSVAL_INT_MIN, JSVAL_INT_MAX-1));
smaller->type() != MIRType_Int32,
Range::MaxDoubleExponent));
block->insertBefore(*block->begin(), beta); block->insertBefore(*block->begin(), beta);
replaceDominatedUsesWith(smaller, beta, block); replaceDominatedUsesWith(smaller, beta, block);
IonSpew(IonSpew_Range, "Adding beta node for smaller %d", smaller->id()); IonSpew(IonSpew_Range, "Adding beta node for smaller %d", smaller->id());
beta = MBeta::New(greater, new Range(JSVAL_INT_MIN+1, JSVAL_INT_MAX, beta = MBeta::New(greater, new Range(JSVAL_INT_MIN+1, JSVAL_INT_MAX));
greater->type() != MIRType_Int32,
Range::MaxDoubleExponent));
block->insertBefore(*block->begin(), beta); block->insertBefore(*block->begin(), beta);
replaceDominatedUsesWith(greater, beta, block); replaceDominatedUsesWith(greater, beta, block);
IonSpew(IonSpew_Range, "Adding beta node for greater %d", greater->id()); IonSpew(IonSpew_Range, "Adding beta node for greater %d", greater->id());
} }
continue; continue;
} else {
continue;
} }
// At this point, one of the operands if the compare is a constant, and
// val is the other operand.
JS_ASSERT(val); JS_ASSERT(val);
@ -853,6 +853,12 @@ MConstant::computeRange()
// Safe double comparisons, because there is no precision loss. // Safe double comparisons, because there is no precision loss.
int64_t l = integral - ((rest < 0) ? 1 : 0); int64_t l = integral - ((rest < 0) ? 1 : 0);
int64_t h = integral + ((rest > 0) ? 1 : 0); int64_t h = integral + ((rest > 0) ? 1 : 0);
// If we adjusted into a new exponent range, adjust exp accordingly.
if ((rest < 0 && (l == INT64_MIN || IsPowerOfTwo(Abs(l)))) ||
(rest > 0 && (h == INT64_MIN || IsPowerOfTwo(Abs(h)))))
{
++exp;
}
setRange(new Range(l, h, (rest != 0), exp)); setRange(new Range(l, h, (rest != 0), exp));
} else { } else {
// This double has a precision loss. This also mean that it cannot // This double has a precision loss. This also mean that it cannot
@ -984,8 +990,8 @@ MAbs::computeRange()
Range other(getOperand(0)); Range other(getOperand(0));
setRange(Range::abs(&other)); setRange(Range::abs(&other));
if (implicitTruncate_ && !range()->isInt32()) if (implicitTruncate_)
setRange(new Range(INT32_MIN, INT32_MAX)); range()->wrapAroundToInt32();
} }
void void
@ -1009,8 +1015,8 @@ MAdd::computeRange()
Range *next = Range::add(&left, &right); Range *next = Range::add(&left, &right);
setRange(next); setRange(next);
if (isTruncated() && !range()->isInt32()) if (isTruncated())
setRange(new Range(INT32_MIN, INT32_MAX)); range()->wrapAroundToInt32();
} }
void void
@ -1023,8 +1029,8 @@ MSub::computeRange()
Range *next = Range::sub(&left, &right); Range *next = Range::sub(&left, &right);
setRange(next); setRange(next);
if (isTruncated() && !range()->isInt32()) if (isTruncated())
setRange(new Range(INT32_MIN, INT32_MAX)); range()->wrapAroundToInt32();
} }
void void
@ -1039,8 +1045,8 @@ MMul::computeRange()
setRange(Range::mul(&left, &right)); setRange(Range::mul(&left, &right));
// Truncated multiplications could overflow in both directions // Truncated multiplications could overflow in both directions
if (isTruncated() && !range()->isInt32()) if (isTruncated())
setRange(new Range(INT32_MIN, INT32_MAX)); range()->wrapAroundToInt32();
} }
void void
@ -1056,6 +1062,10 @@ MMod::computeRange()
if (lhs.isInfinite() || rhs.isInfinite()) if (lhs.isInfinite() || rhs.isInfinite())
return; return;
// If RHS can be zero, the result can be NaN.
if (rhs.lower() <= 0 && rhs.upper() >= 0)
return;
// Math.abs(lhs % rhs) == Math.abs(lhs) % Math.abs(rhs). // Math.abs(lhs % rhs) == Math.abs(lhs) % Math.abs(rhs).
// First, the absolute value of the result will always be less than the // First, the absolute value of the result will always be less than the
// absolute value of rhs. (And if rhs is zero, the result is NaN). // absolute value of rhs. (And if rhs is zero, the result is NaN).
@ -1663,15 +1673,15 @@ MAdd::truncate()
// Remember analysis, needed for fallible checks. // Remember analysis, needed for fallible checks.
setTruncated(true); setTruncated(true);
// Modify the instruction if needed. if (type() == MIRType_Double || type() == MIRType_Int32) {
if (type() != MIRType_Double) specialization_ = MIRType_Int32;
return false; setResultType(MIRType_Int32);
if (range())
range()->wrapAroundToInt32();
return true;
}
specialization_ = MIRType_Int32; return false;
setResultType(MIRType_Int32);
if (range())
range()->wrapAroundToInt32();
return true;
} }
bool bool
@ -1680,15 +1690,15 @@ MSub::truncate()
// Remember analysis, needed for fallible checks. // Remember analysis, needed for fallible checks.
setTruncated(true); setTruncated(true);
// Modify the instruction if needed. if (type() == MIRType_Double || type() == MIRType_Int32) {
if (type() != MIRType_Double) specialization_ = MIRType_Int32;
return false; setResultType(MIRType_Int32);
if (range())
range()->wrapAroundToInt32();
return true;
}
specialization_ = MIRType_Int32; return false;
setResultType(MIRType_Int32);
if (range())
range()->wrapAroundToInt32();
return true;
} }
bool bool
@ -1697,22 +1707,16 @@ MMul::truncate()
// Remember analysis, needed to remove negative zero checks. // Remember analysis, needed to remove negative zero checks.
setTruncated(true); setTruncated(true);
// Modify the instruction. if (type() == MIRType_Double || type() == MIRType_Int32) {
bool truncated = type() == MIRType_Int32;
if (type() == MIRType_Double) {
specialization_ = MIRType_Int32; specialization_ = MIRType_Int32;
setResultType(MIRType_Int32); setResultType(MIRType_Int32);
truncated = true;
JS_ASSERT(range());
}
if (truncated && range()) {
range()->wrapAroundToInt32();
setTruncated(true);
setCanBeNegativeZero(false); setCanBeNegativeZero(false);
if (range())
range()->wrapAroundToInt32();
return true;
} }
return truncated; return false;
} }
bool bool

View File

@ -2748,11 +2748,6 @@ void
AutoFlushCache::update(uintptr_t newStart, size_t len) AutoFlushCache::update(uintptr_t newStart, size_t len)
{ {
uintptr_t newStop = newStart + len; uintptr_t newStop = newStart + len;
if (this == NULL) {
// just flush right here and now.
JSC::ExecutableAllocator::cacheFlush((void*)newStart, len);
return;
}
used_ = true; used_ = true;
if (!start_) { if (!start_) {
IonSpewCont(IonSpew_CacheFlush, "."); IonSpewCont(IonSpew_CacheFlush, ".");

View File

@ -1117,12 +1117,12 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
} }
// See CodeGeneratorX64 calls to noteAsmJSGlobalAccess. // See CodeGeneratorX64 calls to noteAsmJSGlobalAccess.
void patchAsmJSGlobalAccess(unsigned offset, uint8_t *code, unsigned codeBytes, void patchAsmJSGlobalAccess(unsigned offset, uint8_t *code, uint8_t *globalData,
unsigned globalDataOffset) unsigned globalDataOffset)
{ {
uint8_t *nextInsn = code + offset; uint8_t *nextInsn = code + offset;
JS_ASSERT(nextInsn <= code + codeBytes); JS_ASSERT(nextInsn <= globalData);
uint8_t *target = code + codeBytes + globalDataOffset; uint8_t *target = globalData + globalDataOffset;
((int32_t *)nextInsn)[-1] = target - nextInsn; ((int32_t *)nextInsn)[-1] = target - nextInsn;
} }
void memIntToValue(Address Source, Address Dest) { void memIntToValue(Address Source, Address Dest) {

View File

@ -981,12 +981,12 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
} }
// See CodeGeneratorX86 calls to noteAsmJSGlobalAccess. // See CodeGeneratorX86 calls to noteAsmJSGlobalAccess.
void patchAsmJSGlobalAccess(unsigned offset, uint8_t *code, unsigned codeBytes, void patchAsmJSGlobalAccess(unsigned offset, uint8_t *code, uint8_t *globalData,
unsigned globalDataOffset) unsigned globalDataOffset)
{ {
uint8_t *nextInsn = code + offset; uint8_t *nextInsn = code + offset;
JS_ASSERT(nextInsn <= code + codeBytes); JS_ASSERT(nextInsn <= globalData);
uint8_t *target = code + codeBytes + globalDataOffset; uint8_t *target = globalData + globalDataOffset;
((int32_t *)nextInsn)[-1] = uintptr_t(target); ((int32_t *)nextInsn)[-1] = uintptr_t(target);
} }
}; };

View File

@ -1,4 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -75,9 +77,13 @@ BEGIN_TEST(testChromeBuffer)
const char *paramName = "trusted"; const char *paramName = "trusted";
const char *bytes = "try { " const char *bytes = "try { "
" return untrusted(trusted); " " return untrusted(trusted); "
"} catch (e) { " "} catch (e) { "
" return trusted(100); " " try { "
" return trusted(100); "
" } catch(e) { "
" return -1; "
" } "
"} "; "} ";
CHECK(fun = JS_CompileFunction(cx, global, "untrusted", 1, &paramName, CHECK(fun = JS_CompileFunction(cx, global, "untrusted", 1, &paramName,
bytes, strlen(bytes), "", 0)); bytes, strlen(bytes), "", 0));

View File

@ -271,6 +271,7 @@ JS_ConvertArgumentsVA(JSContext *cx, unsigned argc, jsval *argv, const char *for
} }
break; break;
} }
RootedValue arg(cx, *sp);
switch (c) { switch (c) {
case 'b': case 'b':
*va_arg(ap, bool *) = ToBoolean(*sp); *va_arg(ap, bool *) = ToBoolean(*sp);
@ -280,7 +281,7 @@ JS_ConvertArgumentsVA(JSContext *cx, unsigned argc, jsval *argv, const char *for
return false; return false;
break; break;
case 'i': case 'i':
if (!JS_ValueToECMAInt32(cx, *sp, va_arg(ap, int32_t *))) if (!ToInt32(cx, arg, va_arg(ap, int32_t *)))
return false; return false;
break; break;
case 'u': case 'u':
@ -474,12 +475,6 @@ JS_DoubleToUint32(double d)
return ToUint32(d); return ToUint32(d);
} }
JS_PUBLIC_API(bool)
JS_ValueToECMAInt32(JSContext *cx, jsval valueArg, int32_t *ip)
{
RootedValue value(cx, valueArg);
return JS::ToInt32(cx, value, ip);
}
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)
JS_ValueToECMAUint32(JSContext *cx, jsval valueArg, uint32_t *ip) JS_ValueToECMAUint32(JSContext *cx, jsval valueArg, uint32_t *ip)

View File

@ -34,6 +34,8 @@ js_ReportOverRecursed(js::ThreadSafeContext *cx);
namespace js { namespace js {
namespace ion { class IonContext; }
struct CallsiteCloneKey { struct CallsiteCloneKey {
/* The original function that we are cloning. */ /* The original function that we are cloning. */
JSFunction *original; JSFunction *original;
@ -264,7 +266,10 @@ struct ThreadSafeContext : ContextFriendFields,
// GCs cannot happen while non-main threads are running. // GCs cannot happen while non-main threads are running.
uint64_t gcNumber() { return runtime_->gcNumber; } uint64_t gcNumber() { return runtime_->gcNumber; }
size_t gcSystemPageSize() { return runtime_->gcSystemPageSize; }
bool isHeapBusy() { return runtime_->isHeapBusy(); } bool isHeapBusy() { return runtime_->isHeapBusy(); }
bool signalHandlersInstalled() const { return runtime_->signalHandlersInstalled(); }
bool jitSupportsFloatingPoint() const { return runtime_->jitSupportsFloatingPoint; }
// Thread local data that may be accessed freely. // Thread local data that may be accessed freely.
DtoaState *dtoaState() { DtoaState *dtoaState() {
@ -281,6 +286,7 @@ class ExclusiveContext : public ThreadSafeContext
friend class AutoLockForExclusiveAccess; friend class AutoLockForExclusiveAccess;
friend struct StackBaseShape; friend struct StackBaseShape;
friend void JSScript::initCompartment(ExclusiveContext *cx); friend void JSScript::initCompartment(ExclusiveContext *cx);
friend class ion::IonContext;
// The worker on which this context is running, if this is not a JSContext. // The worker on which this context is running, if this is not a JSContext.
WorkerThread *workerThread; WorkerThread *workerThread;
@ -363,6 +369,15 @@ class ExclusiveContext : public ThreadSafeContext
ScriptDataTable &scriptDataTable() { ScriptDataTable &scriptDataTable() {
return runtime_->scriptDataTable(); return runtime_->scriptDataTable();
} }
#if defined(JS_ION) && defined(JS_THREADSAFE)
// Since JSRuntime::workerThreadState is necessarily initialized from the
// main thread before the first worker thread can access it, there is no
// possibility for a race read/writing it.
WorkerThreadState *workerThreadState() {
return runtime_->workerThreadState;
}
#endif
}; };
inline void inline void

View File

@ -343,7 +343,7 @@ ExclusiveContext::maybePause() const
{ {
#ifdef JS_WORKER_THREADS #ifdef JS_WORKER_THREADS
if (workerThread && runtime_->workerThreadState->shouldPause) { if (workerThread && runtime_->workerThreadState->shouldPause) {
AutoLockWorkerThreadState lock(runtime_); AutoLockWorkerThreadState lock(*runtime_->workerThreadState);
workerThread->pause(); workerThread->pause();
} }
#endif #endif

View File

@ -912,8 +912,8 @@ JS_DumpCompartmentPCCounts(JSContext *cx)
if (obj->compartment() != cx->compartment()) if (obj->compartment() != cx->compartment())
continue; continue;
if (IsAsmJSModuleObject(obj)) { if (obj->is<AsmJSModuleObject>()) {
AsmJSModule &module = AsmJSModuleObjectToModule(obj); AsmJSModule &module = obj->as<AsmJSModuleObject>().module();
Sprinter sprinter(cx); Sprinter sprinter(cx);
if (!sprinter.init()) if (!sprinter.init())

View File

@ -38,6 +38,7 @@
#include "frontend/BytecodeCompiler.h" #include "frontend/BytecodeCompiler.h"
#include "gc/Marking.h" #include "gc/Marking.h"
#include "jit/AsmJSModule.h"
#include "jit/BaselineJIT.h" #include "jit/BaselineJIT.h"
#include "js/MemoryMetrics.h" #include "js/MemoryMetrics.h"
#include "vm/ArgumentsObject.h" #include "vm/ArgumentsObject.h"
@ -5662,6 +5663,11 @@ JSObject::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ObjectsExt
sizes->regExpStatics = as<RegExpStaticsObject>().sizeOfData(mallocSizeOf); sizes->regExpStatics = as<RegExpStaticsObject>().sizeOfData(mallocSizeOf);
} else if (is<PropertyIteratorObject>()) { } else if (is<PropertyIteratorObject>()) {
sizes->propertyIteratorData = as<PropertyIteratorObject>().sizeOfMisc(mallocSizeOf); sizes->propertyIteratorData = as<PropertyIteratorObject>().sizeOfMisc(mallocSizeOf);
#ifdef JS_ION
} else if (is<AsmJSModuleObject>()) {
as<AsmJSModuleObject>().sizeOfMisc(mallocSizeOf, &sizes->asmJSModuleCode,
&sizes->asmJSModuleData);
#endif
#ifdef JS_HAS_CTYPES #ifdef JS_HAS_CTYPES
} else { } else {
// This must be the last case. // This must be the last case.

View File

@ -24,8 +24,16 @@ using namespace js;
using mozilla::DebugOnly; using mozilla::DebugOnly;
bool bool
js::EnsureWorkerThreadsInitialized(JSRuntime *rt) js::EnsureWorkerThreadsInitialized(ExclusiveContext *cx)
{ {
// If 'cx' is not a JSContext, we are already off the main thread and the
// worker threads would have already been initialized.
if (!cx->isJSContext()) {
JS_ASSERT(cx->workerThreadState() != NULL);
return true;
}
JSRuntime *rt = cx->asJSContext()->runtime();
if (rt->workerThreadState) if (rt->workerThreadState)
return true; return true;
@ -43,17 +51,17 @@ js::EnsureWorkerThreadsInitialized(JSRuntime *rt)
} }
bool bool
js::StartOffThreadAsmJSCompile(JSContext *cx, AsmJSParallelTask *asmData) js::StartOffThreadAsmJSCompile(ExclusiveContext *cx, AsmJSParallelTask *asmData)
{ {
// Threads already initialized by the AsmJS compiler. // Threads already initialized by the AsmJS compiler.
JS_ASSERT(cx->runtime()->workerThreadState); JS_ASSERT(cx->workerThreadState() != NULL);
JS_ASSERT(asmData->mir); JS_ASSERT(asmData->mir);
JS_ASSERT(asmData->lir == NULL); JS_ASSERT(asmData->lir == NULL);
WorkerThreadState &state = *cx->runtime()->workerThreadState; WorkerThreadState &state = *cx->workerThreadState();
JS_ASSERT(state.numThreads); JS_ASSERT(state.numThreads);
AutoLockWorkerThreadState lock(cx->runtime()); AutoLockWorkerThreadState lock(state);
// Don't append this task if another failed. // Don't append this task if another failed.
if (state.asmJSWorkerFailed()) if (state.asmJSWorkerFailed())
@ -69,14 +77,13 @@ js::StartOffThreadAsmJSCompile(JSContext *cx, AsmJSParallelTask *asmData)
bool bool
js::StartOffThreadIonCompile(JSContext *cx, ion::IonBuilder *builder) js::StartOffThreadIonCompile(JSContext *cx, ion::IonBuilder *builder)
{ {
JSRuntime *rt = cx->runtime(); if (!EnsureWorkerThreadsInitialized(cx))
if (!EnsureWorkerThreadsInitialized(rt))
return false; return false;
WorkerThreadState &state = *cx->runtime()->workerThreadState; WorkerThreadState &state = *cx->runtime()->workerThreadState;
JS_ASSERT(state.numThreads); JS_ASSERT(state.numThreads);
AutoLockWorkerThreadState lock(rt); AutoLockWorkerThreadState lock(state);
if (!state.ionWorklist.append(builder)) if (!state.ionWorklist.append(builder))
return false; return false;
@ -122,7 +129,7 @@ js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
if (!ion) if (!ion)
return; return;
AutoLockWorkerThreadState lock(rt); AutoLockWorkerThreadState lock(state);
/* Cancel any pending entries for which processing hasn't started. */ /* Cancel any pending entries for which processing hasn't started. */
for (size_t i = 0; i < state.ionWorklist.length(); i++) { for (size_t i = 0; i < state.ionWorklist.length(); i++) {
@ -208,8 +215,7 @@ js::StartOffThreadParseScript(JSContext *cx, const CompileOptions &options,
frontend::MaybeCallSourceHandler(cx, options, chars, length); frontend::MaybeCallSourceHandler(cx, options, chars, length);
JSRuntime *rt = cx->runtime(); if (!EnsureWorkerThreadsInitialized(cx))
if (!EnsureWorkerThreadsInitialized(rt))
return false; return false;
JS::CompartmentOptions compartmentOptions(cx->compartment()->options()); JS::CompartmentOptions compartmentOptions(cx->compartment()->options());
@ -270,7 +276,7 @@ js::StartOffThreadParseScript(JSContext *cx, const CompileOptions &options,
WorkerThreadState &state = *cx->runtime()->workerThreadState; WorkerThreadState &state = *cx->runtime()->workerThreadState;
JS_ASSERT(state.numThreads); JS_ASSERT(state.numThreads);
AutoLockWorkerThreadState lock(rt); AutoLockWorkerThreadState lock(state);
if (!state.parseWorklist.append(task.get())) if (!state.parseWorklist.append(task.get()))
return false; return false;
@ -289,7 +295,7 @@ js::WaitForOffThreadParsingToFinish(JSRuntime *rt)
WorkerThreadState &state = *rt->workerThreadState; WorkerThreadState &state = *rt->workerThreadState;
AutoLockWorkerThreadState lock(rt); AutoLockWorkerThreadState lock(state);
while (true) { while (true) {
if (state.parseWorklist.empty()) { if (state.parseWorklist.empty()) {
@ -481,7 +487,7 @@ WorkerThreadState::finishParseTaskForScript(JSScript *script)
ParseTask *parseTask = NULL; ParseTask *parseTask = NULL;
{ {
AutoLockWorkerThreadState lock(rt); AutoLockWorkerThreadState lock(*rt->workerThreadState);
for (size_t i = 0; i < parseFinishedList.length(); i++) { for (size_t i = 0; i < parseFinishedList.length(); i++) {
if (parseFinishedList[i]->script == script) { if (parseFinishedList[i]->script == script) {
parseTask = parseFinishedList[i]; parseTask = parseFinishedList[i];
@ -540,7 +546,7 @@ WorkerThread::destroy()
if (thread) { if (thread) {
{ {
AutoLockWorkerThreadState lock(runtime); AutoLockWorkerThreadState lock(state);
terminate = true; terminate = true;
/* Notify all workers, to ensure that this thread wakes up. */ /* Notify all workers, to ensure that this thread wakes up. */
@ -682,7 +688,7 @@ void
WorkerThread::threadLoop() WorkerThread::threadLoop()
{ {
WorkerThreadState &state = *runtime->workerThreadState; WorkerThreadState &state = *runtime->workerThreadState;
AutoLockWorkerThreadState lock(runtime); AutoLockWorkerThreadState lock(state);
js::TlsPerThreadData.set(threadData.addr()); js::TlsPerThreadData.set(threadData.addr());
@ -727,7 +733,7 @@ AutoPauseWorkersForGC::AutoPauseWorkersForGC(JSRuntime *rt MOZ_GUARD_OBJECT_NOTI
if (!state.numThreads) if (!state.numThreads)
return; return;
AutoLockWorkerThreadState lock(runtime); AutoLockWorkerThreadState lock(state);
// Tolerate reentrant use of AutoPauseWorkersForGC. // Tolerate reentrant use of AutoPauseWorkersForGC.
if (state.shouldPause) { if (state.shouldPause) {
@ -753,7 +759,7 @@ AutoPauseWorkersForGC::~AutoPauseWorkersForGC()
return; return;
WorkerThreadState &state = *runtime->workerThreadState; WorkerThreadState &state = *runtime->workerThreadState;
AutoLockWorkerThreadState lock(runtime); AutoLockWorkerThreadState lock(state);
state.shouldPause = 0; state.shouldPause = 0;
@ -786,7 +792,7 @@ WorkerThread::pause()
using namespace js; using namespace js;
bool bool
js::StartOffThreadAsmJSCompile(JSContext *cx, AsmJSParallelTask *asmData) js::StartOffThreadAsmJSCompile(ExclusiveContext *cx, AsmJSParallelTask *asmData)
{ {
MOZ_ASSUME_UNREACHABLE("Off thread compilation not available in non-THREADSAFE builds"); MOZ_ASSUME_UNREACHABLE("Off thread compilation not available in non-THREADSAFE builds");
} }

View File

@ -201,11 +201,11 @@ OffThreadCompilationEnabled(JSContext *cx)
/* Initialize worker threads unless already initialized. */ /* Initialize worker threads unless already initialized. */
bool bool
EnsureWorkerThreadsInitialized(JSRuntime *rt); EnsureWorkerThreadsInitialized(ExclusiveContext *cx);
/* Perform MIR optimization and LIR generation on a single function. */ /* Perform MIR optimization and LIR generation on a single function. */
bool bool
StartOffThreadAsmJSCompile(JSContext *cx, AsmJSParallelTask *asmData); StartOffThreadAsmJSCompile(ExclusiveContext *cx, AsmJSParallelTask *asmData);
/* /*
* Schedule an Ion compilation for a script, given a builder which has been * Schedule an Ion compilation for a script, given a builder which has been
@ -236,28 +236,25 @@ WaitForOffThreadParsingToFinish(JSRuntime *rt);
class AutoLockWorkerThreadState class AutoLockWorkerThreadState
{ {
JSRuntime *rt; WorkerThreadState &state;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
public: public:
AutoLockWorkerThreadState(WorkerThreadState &state
AutoLockWorkerThreadState(JSRuntime *rt
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: rt(rt) : state(state)
{ {
MOZ_GUARD_OBJECT_NOTIFIER_INIT; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
#ifdef JS_WORKER_THREADS #ifdef JS_WORKER_THREADS
JS_ASSERT(rt->workerThreadState); state.lock();
rt->workerThreadState->lock();
#else #else
(void)this->rt; (void)state;
#endif #endif
} }
~AutoLockWorkerThreadState() ~AutoLockWorkerThreadState() {
{
#ifdef JS_WORKER_THREADS #ifdef JS_WORKER_THREADS
rt->workerThreadState->unlock(); state.unlock();
#endif #endif
} }
}; };

View File

@ -5092,6 +5092,9 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op)
return OptionFailure("ion-range-analysis", str); return OptionFailure("ion-range-analysis", str);
} }
if (op->getBoolOption("ion-check-range-analysis"))
ion::js_IonOptions.checkRangeAnalysis = true;
if (const char *str = op->getStringOption("ion-inlining")) { if (const char *str = op->getStringOption("ion-inlining")) {
if (strcmp(str, "on") == 0) if (strcmp(str, "on") == 0)
ion::js_IonOptions.inlining = true; ion::js_IonOptions.inlining = true;
@ -5377,6 +5380,8 @@ main(int argc, char **argv, char **envp)
"Find edge cases where Ion can avoid bailouts (default: on, off to disable)") "Find edge cases where Ion can avoid bailouts (default: on, off to disable)")
|| !op.addStringOption('\0', "ion-range-analysis", "on/off", || !op.addStringOption('\0', "ion-range-analysis", "on/off",
"Range analysis (default: off, on to enable)") "Range analysis (default: off, on to enable)")
|| !op.addBoolOption('\0', "ion-check-range-analysis",
"Range analysis checking")
|| !op.addStringOption('\0', "ion-inlining", "on/off", || !op.addStringOption('\0', "ion-inlining", "on/off",
"Inline methods where possible (default: on, off to disable)") "Inline methods where possible (default: on, off to disable)")
|| !op.addStringOption('\0', "ion-osr", "on/off", || !op.addStringOption('\0', "ion-osr", "on/off",

View File

@ -231,6 +231,7 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
data(NULL), data(NULL),
gcLock(NULL), gcLock(NULL),
gcHelperThread(thisFromCtor()), gcHelperThread(thisFromCtor()),
signalHandlersInstalled_(false),
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
#ifdef JS_ION #ifdef JS_ION
workerThreadState(NULL), workerThreadState(NULL),
@ -379,6 +380,10 @@ JSRuntime::init(uint32_t maxbytes)
nativeStackBase = GetNativeStackBase(); nativeStackBase = GetNativeStackBase();
jitSupportsFloatingPoint = JitSupportsFloatingPoint(); jitSupportsFloatingPoint = JitSupportsFloatingPoint();
#ifdef JS_ION
signalHandlersInstalled_ = EnsureAsmJSSignalHandlersInstalled(this);
#endif
return true; return true;
} }

View File

@ -1305,6 +1305,15 @@ struct JSRuntime : public JS::shadow::Runtime,
js::AsmJSMachExceptionHandler asmJSMachExceptionHandler; js::AsmJSMachExceptionHandler asmJSMachExceptionHandler;
#endif #endif
// Whether asm.js signal handlers have been installed and can be used for
// performing interrupt checks in loops.
private:
bool signalHandlersInstalled_;
public:
bool signalHandlersInstalled() const {
return signalHandlersInstalled_;
}
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
# ifdef JS_ION # ifdef JS_ION
js::WorkerThreadState *workerThreadState; js::WorkerThreadState *workerThreadState;

View File

@ -228,7 +228,10 @@ InterpreterStack::purge(JSRuntime *rt)
uint8_t * uint8_t *
InterpreterStack::allocateFrame(JSContext *cx, size_t size) InterpreterStack::allocateFrame(JSContext *cx, size_t size)
{ {
if (JS_UNLIKELY(frameCount_ >= MAX_FRAMES)) { size_t maxFrames = cx->compartment()->principals == cx->runtime()->trustedPrincipals()
? MAX_FRAMES_TRUSTED
: MAX_FRAMES;
if (JS_UNLIKELY(frameCount_ >= maxFrames)) {
js_ReportOverRecursed(cx); js_ReportOverRecursed(cx);
return NULL; return NULL;
} }

View File

@ -1040,6 +1040,7 @@ class InterpreterStack
// Number of interpreter frames on the stack, for over-recursion checks. // Number of interpreter frames on the stack, for over-recursion checks.
static const size_t MAX_FRAMES = 50 * 1000; static const size_t MAX_FRAMES = 50 * 1000;
static const size_t MAX_FRAMES_TRUSTED = MAX_FRAMES + 1000;
size_t frameCount_; size_t frameCount_;
inline uint8_t *allocateFrame(JSContext *cx, size_t size); inline uint8_t *allocateFrame(JSContext *cx, size_t size);

View File

@ -2039,6 +2039,14 @@ ReportCompartmentStats(const JS::CompartmentStats &cStats,
"This memory lives outside both the malloc heap and the JS heap."); "This memory lives outside both the malloc heap and the JS heap.");
} }
REPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/non-heap/code/asm.js"),
KIND_NONHEAP, cStats.objectsExtra.asmJSModuleCode,
"Memory allocated for AOT-compiled asm.js code.");
ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/asm.js-module-data"),
cStats.objectsExtra.asmJSModuleData,
"Memory allocated for asm.js module data.");
ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/arguments-data"), ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/arguments-data"),
cStats.objectsExtra.argumentsData, cStats.objectsExtra.argumentsData,
"Memory allocated on the malloc heap for data belonging to arguments objects."); "Memory allocated on the malloc heap for data belonging to arguments objects.");
@ -2239,10 +2247,6 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
KIND_NONHEAP, rtStats.runtime.code.baseline, KIND_NONHEAP, rtStats.runtime.code.baseline,
"Memory used by the Baseline JIT to hold generated code."); "Memory used by the Baseline JIT to hold generated code.");
RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/asm.js"),
KIND_NONHEAP, rtStats.runtime.code.asmJS,
"Memory used by AOT-compiled asm.js code.");
RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/regexp"), RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/regexp"),
KIND_NONHEAP, rtStats.runtime.code.regexp, KIND_NONHEAP, rtStats.runtime.code.regexp,
"Memory used by the regexp JIT to hold generated code."); "Memory used by the regexp JIT to hold generated code.");

View File

@ -293,12 +293,12 @@ def write_getter(a, iface, fd):
fd.write(" aDict.%s = u;\n" % a.name) fd.write(" aDict.%s = u;\n" % a.name)
elif realtype.count("int16_t"): elif realtype.count("int16_t"):
fd.write(" int32_t i;\n") fd.write(" int32_t i;\n")
fd.write(" NS_ENSURE_STATE(JS_ValueToECMAInt32(aCx, v, &i));\n") fd.write(" NS_ENSURE_STATE(JS::ToInt32(aCx, v, &i));\n")
fd.write(" aDict.%s = i;\n" % a.name) fd.write(" aDict.%s = i;\n" % a.name)
elif realtype.count("uint32_t"): elif realtype.count("uint32_t"):
fd.write(" NS_ENSURE_STATE(JS_ValueToECMAUint32(aCx, v, &aDict.%s));\n" % a.name) fd.write(" NS_ENSURE_STATE(JS_ValueToECMAUint32(aCx, v, &aDict.%s));\n" % a.name)
elif realtype.count("int32_t"): elif realtype.count("int32_t"):
fd.write(" NS_ENSURE_STATE(JS_ValueToECMAInt32(aCx, v, &aDict.%s));\n" % a.name) fd.write(" NS_ENSURE_STATE(JS::ToInt32(aCx, v, &aDict.%s));\n" % a.name)
elif realtype.count("uint64_t"): elif realtype.count("uint64_t"):
fd.write(" NS_ENSURE_STATE(JS::ToUint64(aCx, v, &aDict.%s));\n" % a.name) fd.write(" NS_ENSURE_STATE(JS::ToUint64(aCx, v, &aDict.%s));\n" % a.name)
elif realtype.count("int64_t"): elif realtype.count("int64_t"):

View File

@ -139,8 +139,8 @@ nsXPConnect::~nsXPConnect()
// static // static
void void
nsXPConnect::InitStatics() nsXPConnect::InitStatics()
{ {
gSelf = new nsXPConnect(); gSelf = new nsXPConnect();
gOnceAliveNowDead = false; gOnceAliveNowDead = false;
if (!gSelf->mRuntime) { if (!gSelf->mRuntime) {
@ -1348,12 +1348,6 @@ PopJSContextNoScriptContext()
XPCJSRuntime::Get()->GetJSContextStack()->Pop(); XPCJSRuntime::Get()->GetJSContextStack()->Pop();
} }
bool
IsJSContextOnStack(JSContext *aCx)
{
return XPCJSRuntime::Get()->GetJSContextStack()->HasJSContext(aCx);
}
} // namespace xpc } // namespace xpc
nsIPrincipal* nsIPrincipal*
@ -1399,13 +1393,6 @@ nsXPConnect::HoldObject(JSContext *aJSContext, JSObject *aObjectArg,
namespace xpc { namespace xpc {
bool
DeferredRelease(nsISupports *obj)
{
nsContentUtils::DeferredFinalize(obj);
return true;
}
NS_EXPORT_(bool) NS_EXPORT_(bool)
Base64Encode(JSContext *cx, JS::Value val, JS::Value *out) Base64Encode(JSContext *cx, JS::Value val, JS::Value *out)
{ {
@ -1730,9 +1717,10 @@ namespace dom {
bool bool
IsChromeOrXBL(JSContext* cx, JSObject* /* unused */) IsChromeOrXBL(JSContext* cx, JSObject* /* unused */)
{ {
JSCompartment* compartment = js::GetContextCompartment(cx); MOZ_ASSERT(NS_IsMainThread());
return AccessCheck::isChrome(compartment) || JSCompartment* compartment = js::GetContextCompartment(cx);
IsXBLScope(compartment); return AccessCheck::isChrome(compartment) ||
IsXBLScope(compartment);
} }
} // namespace dom } // namespace dom

View File

@ -391,7 +391,7 @@ argumentUnboxingTemplates = {
'short': 'short':
" int32_t ${name}_i32;\n" " int32_t ${name}_i32;\n"
" if (!JS_ValueToECMAInt32(cx, ${argVal}, &${name}_i32))\n" " if (!JS::ToInt32(cx, ${argVal}, &${name}_i32))\n"
" return false;\n" " return false;\n"
" int16_t ${name} = (int16_t) ${name}_i32;\n", " int16_t ${name} = (int16_t) ${name}_i32;\n",
@ -403,7 +403,7 @@ argumentUnboxingTemplates = {
'long': 'long':
" int32_t ${name};\n" " int32_t ${name};\n"
" if (!JS_ValueToECMAInt32(cx, ${argVal}, &${name}))\n" " if (!JS::ToInt32(cx, ${argVal}, &${name}))\n"
" return false;\n", " return false;\n",
'unsigned long': 'unsigned long':

View File

@ -2230,9 +2230,8 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
childReflowState.SetComputedHeight(curItem.GetMainSize()); childReflowState.SetComputedHeight(curItem.GetMainSize());
} }
nsresult rv = nsresult rv = SizeItemInCrossAxis(aPresContext, axisTracker,
SizeItemInCrossAxis(aPresContext, axisTracker, childReflowState, curItem);
childReflowState, curItem);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }

View File

@ -787,7 +787,12 @@ nsFrameSelection::MoveCaret(uint32_t aKeycode,
} }
int32_t caretStyle = Preferences::GetInt("layout.selection.caret_style", 0); int32_t caretStyle = Preferences::GetInt("layout.selection.caret_style", 0);
if (caretStyle == 0) { if (caretStyle == 0
#ifdef XP_WIN
&& aKeycode != nsIDOMKeyEvent::DOM_VK_UP
&& aKeycode != nsIDOMKeyEvent::DOM_VK_DOWN
#endif
) {
// Put caret at the selection edge in the |aKeycode| direction. // Put caret at the selection edge in the |aKeycode| direction.
caretStyle = 2; caretStyle = 2;
} }

View File

@ -61,6 +61,7 @@ MOCHITEST_FILES = \
test_bug579767.html \ test_bug579767.html \
test_bug597333.html \ test_bug597333.html \
test_bug666225.html \ test_bug666225.html \
test_bug904810.html \
test_image_selection.html \ test_image_selection.html \
test_image_selection_2.html \ test_image_selection_2.html \
test_invalidate_during_plugin_paint.html \ test_invalidate_during_plugin_paint.html \

View File

@ -0,0 +1,110 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=904810
-->
<head>
<title>Test for Bug 904810</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=904810">Mozilla Bug 904810</a>
<p id="display">
<textarea dir="ltr" id="textarea904810">
first line
second line
third line
</textarea></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 904810 **/
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function test() {
function shiftLeft(i) {
for ( ; i > 0; --i)
synthesizeKey("VK_LEFT", {shiftKey:true});
}
function shiftRight(i) {
for ( ; i > 0; --i)
synthesizeKey("VK_RIGHT", {shiftKey:true});
}
const isWindows = /WINNT/.test(SpecialPowers.OS);
var textarea = document.getElementById('textarea904810');
textarea.focus();
// Testing VK_DOWN with forward selection
textarea.selectionStart = 1;
textarea.selectionEnd = 1;
shiftRight(7);
synthesizeKey("VK_DOWN", {});
if (isWindows) {
is(textarea.selectionStart, 19, "caret moved to next line below selection end");
is(textarea.selectionEnd, 19, "caret moved to next line below selection end");
} else {
is(textarea.selectionStart, 8, "caret moved to visual end of selection");
is(textarea.selectionEnd, 8, "caret moved to visual end of selection");
}
// Testing VK_DOWN with backward selection
textarea.selectionStart = 8;
textarea.selectionEnd = 8;
shiftLeft(7);
synthesizeKey("VK_DOWN", {});
if (isWindows) {
is(textarea.selectionStart, 12, "caret moved to next line below selection start");
is(textarea.selectionEnd, 12, "caret moved to next line below selection start");
} else {
is(textarea.selectionStart, 8, "caret moved to visual end of selection");
is(textarea.selectionEnd, 8, "caret moved to visual end of selection");
}
// Testing VK_UP with forward selection
textarea.selectionStart = 12;
textarea.selectionEnd = 12;
shiftRight(7);
synthesizeKey("VK_UP", {});
var result = textarea.selectionEnd
if (isWindows) {
is(textarea.selectionStart, 8, "caret moved to previous line above selection end");
is(textarea.selectionEnd, 8, "caret moved to previous line above selection end");
} else {
is(textarea.selectionStart, 12, "caret moved to visual start of selection");
is(textarea.selectionEnd, 12, "caret moved to visual start of selection");
}
// Testing VK_UP with backward selection
textarea.selectionStart = 19;
textarea.selectionEnd = 19;
shiftLeft(7);
synthesizeKey("VK_UP", {});
var result = textarea.selectionEnd
if (isWindows) {
is(textarea.selectionStart, 1, "caret moved to previous line above selection start");
is(textarea.selectionEnd, 1, "caret moved to previous line above selection start");
} else {
is(textarea.selectionStart, 12, "caret moved to visual start of selection");
is(textarea.selectionEnd, 12, "caret moved to visual start of selection");
}
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -993,8 +993,8 @@ AddCSSValueCanonicalCalc(double aCoeff1, const nsCSSValue &aValue1,
} }
static void static void
AddCSSValueAngle(const nsCSSValue &aValue1, double aCoeff1, AddCSSValueAngle(double aCoeff1, const nsCSSValue &aValue1,
const nsCSSValue &aValue2, double aCoeff2, double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult) nsCSSValue &aResult)
{ {
aResult.SetFloatValue(aCoeff1 * aValue1.GetAngleValueInRadians() + aResult.SetFloatValue(aCoeff1 * aValue1.GetAngleValueInRadians() +
@ -1093,8 +1093,8 @@ AddShadowItems(double aCoeff1, const nsCSSValue &aValue1,
} }
static void static void
AddTransformTranslate(const nsCSSValue &aValue1, double aCoeff1, AddTransformTranslate(double aCoeff1, const nsCSSValue &aValue1,
const nsCSSValue &aValue2, double aCoeff2, double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult) nsCSSValue &aResult)
{ {
NS_ABORT_IF_FALSE(aValue1.GetUnit() == eCSSUnit_Percent || NS_ABORT_IF_FALSE(aValue1.GetUnit() == eCSSUnit_Percent ||
@ -1119,8 +1119,8 @@ AddTransformTranslate(const nsCSSValue &aValue1, double aCoeff1,
} }
static void static void
AddTransformScale(const nsCSSValue &aValue1, double aCoeff1, AddTransformScale(double aCoeff1, const nsCSSValue &aValue1,
const nsCSSValue &aValue2, double aCoeff2, double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult) nsCSSValue &aResult)
{ {
// Handle scale, and the two matrix components where identity is 1, by // Handle scale, and the two matrix components where identity is 1, by
@ -1517,8 +1517,8 @@ nsStyleAnimation::InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1,
} }
static nsCSSValueList* static nsCSSValueList*
AddDifferentTransformLists(const nsCSSValueList* aList1, double aCoeff1, AddDifferentTransformLists(double aCoeff1, const nsCSSValueList* aList1,
const nsCSSValueList* aList2, double aCoeff2) double aCoeff2, const nsCSSValueList* aList2)
{ {
nsAutoPtr<nsCSSValueList> result; nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result); nsCSSValueList **resultTail = getter_Transfers(result);
@ -1548,8 +1548,8 @@ TransformFunctionsMatch(nsCSSKeyword func1, nsCSSKeyword func2)
} }
static nsCSSValueList* static nsCSSValueList*
AddTransformLists(const nsCSSValueList* aList1, double aCoeff1, AddTransformLists(double aCoeff1, const nsCSSValueList* aList1,
const nsCSSValueList* aList2, double aCoeff2) double aCoeff2, const nsCSSValueList* aList2)
{ {
nsAutoPtr<nsCSSValueList> result; nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result); nsCSSValueList **resultTail = getter_Transfers(result);
@ -1577,11 +1577,11 @@ AddTransformLists(const nsCSSValueList* aList1, double aCoeff1,
case eCSSKeyword_translate3d: { case eCSSKeyword_translate3d: {
NS_ABORT_IF_FALSE(a1->Count() == 4, "unexpected count"); NS_ABORT_IF_FALSE(a1->Count() == 4, "unexpected count");
NS_ABORT_IF_FALSE(a2->Count() == 4, "unexpected count"); NS_ABORT_IF_FALSE(a2->Count() == 4, "unexpected count");
AddTransformTranslate(a1->Item(1), aCoeff1, a2->Item(1), aCoeff2, AddTransformTranslate(aCoeff1, a1->Item(1), aCoeff2, a2->Item(1),
arr->Item(1)); arr->Item(1));
AddTransformTranslate(a1->Item(2), aCoeff1, a2->Item(2), aCoeff2, AddTransformTranslate(aCoeff1, a1->Item(2), aCoeff2, a2->Item(2),
arr->Item(2)); arr->Item(2));
AddTransformTranslate(a1->Item(3), aCoeff1, a2->Item(3), aCoeff2, AddTransformTranslate(aCoeff1, a1->Item(3), aCoeff2, a2->Item(3),
arr->Item(3)); arr->Item(3));
break; break;
} }
@ -1589,11 +1589,11 @@ AddTransformLists(const nsCSSValueList* aList1, double aCoeff1,
NS_ABORT_IF_FALSE(a1->Count() == 4, "unexpected count"); NS_ABORT_IF_FALSE(a1->Count() == 4, "unexpected count");
NS_ABORT_IF_FALSE(a2->Count() == 4, "unexpected count"); NS_ABORT_IF_FALSE(a2->Count() == 4, "unexpected count");
AddTransformScale(a1->Item(1), aCoeff1, a2->Item(1), aCoeff2, AddTransformScale(aCoeff1, a1->Item(1), aCoeff2, a2->Item(1),
arr->Item(1)); arr->Item(1));
AddTransformScale(a1->Item(2), aCoeff1, a2->Item(2), aCoeff2, AddTransformScale(aCoeff1, a1->Item(2), aCoeff2, a2->Item(2),
arr->Item(2)); arr->Item(2));
AddTransformScale(a1->Item(3), aCoeff1, a2->Item(3), aCoeff2, AddTransformScale(aCoeff1, a1->Item(3), aCoeff2, a2->Item(3),
arr->Item(3)); arr->Item(3));
break; break;
@ -1611,15 +1611,15 @@ AddTransformLists(const nsCSSValueList* aList1, double aCoeff1,
nsCSSValue zero(0.0f, eCSSUnit_Radian); nsCSSValue zero(0.0f, eCSSUnit_Radian);
// Add Y component of skew. // Add Y component of skew.
AddCSSValueAngle(a1->Count() == 3 ? a1->Item(2) : zero, AddCSSValueAngle(aCoeff1,
aCoeff1, a1->Count() == 3 ? a1->Item(2) : zero,
a2->Count() == 3 ? a2->Item(2) : zero,
aCoeff2, aCoeff2,
a2->Count() == 3 ? a2->Item(2) : zero,
arr->Item(2)); arr->Item(2));
// Add X component of skew (which can be merged with case below // Add X component of skew (which can be merged with case below
// in non-DEBUG). // in non-DEBUG).
AddCSSValueAngle(a1->Item(1), aCoeff1, a2->Item(1), aCoeff2, AddCSSValueAngle(aCoeff1, a1->Item(1), aCoeff2, a2->Item(1),
arr->Item(1)); arr->Item(1));
break; break;
@ -1633,7 +1633,7 @@ AddTransformLists(const nsCSSValueList* aList1, double aCoeff1,
NS_ABORT_IF_FALSE(a1->Count() == 2, "unexpected count"); NS_ABORT_IF_FALSE(a1->Count() == 2, "unexpected count");
NS_ABORT_IF_FALSE(a2->Count() == 2, "unexpected count"); NS_ABORT_IF_FALSE(a2->Count() == 2, "unexpected count");
AddCSSValueAngle(a1->Item(1), aCoeff1, a2->Item(1), aCoeff2, AddCSSValueAngle(aCoeff1, a1->Item(1), aCoeff2, a2->Item(1),
arr->Item(1)); arr->Item(1));
break; break;
@ -1653,10 +1653,10 @@ AddTransformLists(const nsCSSValueList* aList1, double aCoeff1,
if (aList1 == aList2) { if (aList1 == aList2) {
*resultTail = *resultTail =
AddDifferentTransformLists(&tempList1, aCoeff1, &tempList1, aCoeff2); AddDifferentTransformLists(aCoeff1, &tempList1, aCoeff2, &tempList1);
} else { } else {
*resultTail = *resultTail =
AddDifferentTransformLists(&tempList1, aCoeff1, &tempList2, aCoeff2); AddDifferentTransformLists(aCoeff1, &tempList1, aCoeff2, &tempList2);
} }
// Now advance resultTail to point to the new tail slot. // Now advance resultTail to point to the new tail slot.
@ -2079,11 +2079,11 @@ nsStyleAnimation::AddWeighted(nsCSSProperty aProperty,
result->mValue.SetNoneValue(); result->mValue.SetNoneValue();
} }
} else { } else {
result = AddTransformLists(list2, 0, list2, aCoeff2); result = AddTransformLists(0, list2, aCoeff2, list2);
} }
} else { } else {
if (list2->mValue.GetUnit() == eCSSUnit_None) { if (list2->mValue.GetUnit() == eCSSUnit_None) {
result = AddTransformLists(list1, 0, list1, aCoeff1); result = AddTransformLists(0, list1, aCoeff1, list1);
} else { } else {
bool match = true; bool match = true;
@ -2109,9 +2109,9 @@ nsStyleAnimation::AddWeighted(nsCSSProperty aProperty,
} }
if (match) { if (match) {
result = AddTransformLists(list1, aCoeff1, list2, aCoeff2); result = AddTransformLists(aCoeff1, list1, aCoeff2, list2);
} else { } else {
result = AddDifferentTransformLists(list1, aCoeff1, list2, aCoeff2); result = AddDifferentTransformLists(aCoeff1, list1, aCoeff2, list2);
} }
} }
} }

View File

@ -27,8 +27,8 @@ import android.content.DialogInterface;
import android.content.OperationApplicationException; import android.content.OperationApplicationException;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.RemoteException;
import android.os.Build; import android.os.Build;
import android.os.RemoteException;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.BaseTypes; import android.provider.ContactsContract.CommonDataKinds.BaseTypes;
import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Email;
@ -921,8 +921,8 @@ public class ContactService implements GeckoEventListener {
} }
private boolean deleteContact(String rawContactId) { private boolean deleteContact(String rawContactId) {
ContentProviderOperation deleteOptions = ContentProviderOperation.newDelete(Data.CONTENT_URI) ContentProviderOperation deleteOptions = ContentProviderOperation.newDelete(RawContacts.CONTENT_URI)
.withSelection(Data.RAW_CONTACT_ID + "=?", .withSelection(RawContacts._ID + "=?",
new String[] {rawContactId}) new String[] {rawContactId})
.build(); .build();
@ -1482,7 +1482,9 @@ public class ContactService implements GeckoEventListener {
} }
private void getContactsCount(final String requestID) { private void getContactsCount(final String requestID) {
Integer numContacts = getAllRawContactIds().length; Cursor cursor = getAllRawContactIdsCursor();
Integer numContacts = Integer.valueOf(cursor.getCount());
cursor.close();
sendCallbackToJavascript("Android:Contacts:Count", requestID, new String[] {"count"}, sendCallbackToJavascript("Android:Contacts:Count", requestID, new String[] {"count"},
new Object[] {numContacts}); new Object[] {numContacts});
@ -1730,33 +1732,38 @@ public class ContactService implements GeckoEventListener {
} }
private long[] getAllRawContactIds() { private long[] getAllRawContactIds() {
// Only get contacts from the selected account Cursor cursor = getAllRawContactIdsCursor();
String selection = null;
String[] selectionArgs = null;
if (mAccountName != null) {
selection = RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?";
selectionArgs = new String[] {mAccountName, mAccountType};
}
// Get the ID's of all the contacts and use the number of contact ID's as // Put the ids into an array
// the total number of contacts long[] ids = new long[cursor.getCount()];
Cursor cursor = mContentResolver.query(Data.CONTENT_URI, int index = 0;
new String[] {Data.RAW_CONTACT_ID},
selection, selectionArgs, null);
List<Long> ids = new ArrayList<Long>();
// Filter out any duplicate IDs
cursor.moveToPosition(-1); cursor.moveToPosition(-1);
while(cursor.moveToNext()) { while(cursor.moveToNext()) {
Long id = Long.valueOf(cursor.getLong(cursor.getColumnIndex(Data.RAW_CONTACT_ID))); ids[index] = cursor.getLong(cursor.getColumnIndex(RawContacts._ID));
if (!ids.contains(id)) { index++;
ids.add(id);
}
} }
cursor.close(); cursor.close();
return convertLongListToArray(ids); return ids;
}
private Cursor getAllRawContactIdsCursor() {
// When a contact is deleted, it actually just sets the deleted field to 1 until the
// sync adapter actually deletes the contact later so ignore any contacts with the deleted
// flag set
String selection = RawContacts.DELETED + "=0";
String[] selectionArgs = null;
// Only get contacts from the selected account
if (mAccountName != null) {
selection += " AND " + RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?";
selectionArgs = new String[] {mAccountName, mAccountType};
}
// Get the ID's of all contacts and use the number of contact ID's as
// the total number of contacts
return mContentResolver.query(RawContacts.CONTENT_URI, new String[] {RawContacts._ID},
selection, selectionArgs, null);
} }
private static Long getRawContactIdFromContentProviderResults(ContentProviderResult[] results) throws NumberFormatException { private static Long getRawContactIdFromContentProviderResults(ContentProviderResult[] results) throws NumberFormatException {

View File

@ -307,6 +307,7 @@ public class GeckoAccessibility {
info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
info.addAction(AccessibilityNodeInfo.ACTION_CLICK); info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY); info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY); info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER | info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER |
@ -340,6 +341,10 @@ public class GeckoAccessibility {
GeckoAppShell. GeckoAppShell.
sendEventToGecko(GeckoEvent.createBroadcastEvent("Accessibility:ActivateObject", null)); sendEventToGecko(GeckoEvent.createBroadcastEvent("Accessibility:ActivateObject", null));
return true; return true;
} else if (action == AccessibilityNodeInfo.ACTION_LONG_CLICK && virtualViewId == VIRTUAL_CURSOR_POSITION) {
GeckoAppShell.
sendEventToGecko(GeckoEvent.createBroadcastEvent("Accessibility:LongPress", null));
return true;
} else if (action == AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY && } else if (action == AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY &&
virtualViewId == VIRTUAL_CURSOR_POSITION) { virtualViewId == VIRTUAL_CURSOR_POSITION) {
// XXX: Self brailling gives this action with a bogus argument instead of an actual click action; // XXX: Self brailling gives this action with a bogus argument instead of an actual click action;

View File

@ -171,6 +171,11 @@ NetAddrElement::NetAddrElement(const PRNetAddr *prNetAddr)
PRNetAddrToNetAddr(prNetAddr, &mAddress); PRNetAddrToNetAddr(prNetAddr, &mAddress);
} }
NetAddrElement::NetAddrElement(const NetAddrElement& netAddr)
{
mAddress = netAddr.mAddress;
}
NetAddrElement::~NetAddrElement() NetAddrElement::~NetAddrElement()
{ {
} }
@ -178,18 +183,9 @@ NetAddrElement::~NetAddrElement()
AddrInfo::AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, AddrInfo::AddrInfo(const char *host, const PRAddrInfo *prAddrInfo,
bool disableIPv4, const char *cname) bool disableIPv4, const char *cname)
{ {
size_t hostlen = strlen(host); MOZ_ASSERT(prAddrInfo, "Cannot construct AddrInfo with a null prAddrInfo pointer!");
mHostName = static_cast<char*>(moz_xmalloc(hostlen + 1));
memcpy(mHostName, host, hostlen + 1);
if (cname) {
size_t cnameLen = strlen(cname);
mCanonicalName = static_cast<char*>(moz_xmalloc(cnameLen + 1));
memcpy(mCanonicalName, cname, cnameLen + 1);
}
else {
mCanonicalName = nullptr;
}
Init(host, cname);
PRNetAddr tmpAddr; PRNetAddr tmpAddr;
void *iter = nullptr; void *iter = nullptr;
do { do {
@ -201,6 +197,11 @@ AddrInfo::AddrInfo(const char *host, const PRAddrInfo *prAddrInfo,
} while (iter); } while (iter);
} }
AddrInfo::AddrInfo(const char *host, const char *cname)
{
Init(host, cname);
}
AddrInfo::~AddrInfo() AddrInfo::~AddrInfo()
{ {
NetAddrElement *addrElement; NetAddrElement *addrElement;
@ -211,5 +212,31 @@ AddrInfo::~AddrInfo()
moz_free(mCanonicalName); moz_free(mCanonicalName);
} }
void
AddrInfo::Init(const char *host, const char *cname)
{
MOZ_ASSERT(host, "Cannot initialize AddrInfo with a null host pointer!");
size_t hostlen = strlen(host);
mHostName = static_cast<char*>(moz_xmalloc(hostlen + 1));
memcpy(mHostName, host, hostlen + 1);
if (cname) {
size_t cnameLen = strlen(cname);
mCanonicalName = static_cast<char*>(moz_xmalloc(cnameLen + 1));
memcpy(mCanonicalName, cname, cnameLen + 1);
}
else {
mCanonicalName = nullptr;
}
}
void
AddrInfo::AddAddress(NetAddrElement *address)
{
MOZ_ASSERT(address, "Cannot add the address to an uninitialized list");
mAddresses.insertBack(address);
}
} // namespace dns } // namespace dns
} // namespace mozilla } // namespace mozilla

View File

@ -114,6 +114,7 @@ union NetAddr {
class NetAddrElement : public LinkedListElement<NetAddrElement> { class NetAddrElement : public LinkedListElement<NetAddrElement> {
public: public:
NetAddrElement(const PRNetAddr *prNetAddr); NetAddrElement(const PRNetAddr *prNetAddr);
NetAddrElement(const NetAddrElement& netAddr);
~NetAddrElement(); ~NetAddrElement();
NetAddr mAddress; NetAddr mAddress;
@ -121,13 +122,23 @@ public:
class AddrInfo { class AddrInfo {
public: public:
// Creates an AddrInfo object. It calls the AddrInfo(const char*, const char*)
// to initialize the host and the cname.
AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, bool disableIPv4, AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, bool disableIPv4,
const char *cname); const char *cname);
// Creates a basic AddrInfo object (initialize only the host and the cname).
AddrInfo(const char *host, const char *cname);
~AddrInfo(); ~AddrInfo();
void AddAddress(NetAddrElement *address);
char *mHostName; char *mHostName;
char *mCanonicalName; char *mCanonicalName;
LinkedList<NetAddrElement> mAddresses; LinkedList<NetAddrElement> mAddresses;
private:
void Init(const char *host, const char *cname);
}; };
// Copies the contents of a PRNetAddr to a NetAddr. // Copies the contents of a PRNetAddr to a NetAddr.

View File

@ -564,22 +564,9 @@ nsHostResolver::ResolveHost(const char *host,
Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2, METHOD_HIT); Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2, METHOD_HIT);
// For entries that are in the grace period with a failed connect, // For entries that are in the grace period with a failed connect,
// or all cached negative entries, use the cache but start a new lookup in // or all cached negative entries, use the cache but start a new
// the background // lookup in the background
if ((((TimeStamp::NowLoRes() > he->rec->expiration) && ConditionallyRefreshRecord(he->rec, host);
he->rec->mBlacklistedItems.Length()) ||
he->rec->negative) && !he->rec->resolving) {
LOG(("Using %s cache entry for host [%s] but starting async renewal.",
he->rec->negative ? "negative" :"positive", host));
IssueLookup(he->rec);
if (!he->rec->negative) {
// negative entries are constantly being refreshed, only
// track positive grace period induced renewals
Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2,
METHOD_RENEWAL);
}
}
if (he->rec->negative) { if (he->rec->negative) {
Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2, Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2,
@ -619,35 +606,105 @@ nsHostResolver::ResolveHost(const char *host,
rv = NS_ERROR_OFFLINE; rv = NS_ERROR_OFFLINE;
} }
// otherwise, hit the resolver... // If this is an IPV4 or IPV6 specific request, check if there is
else { // an AF_UNSPEC entry we can use. Otherwise, hit the resolver...
// Add callback to the list of pending callbacks. else if (!he->rec->resolving) {
PR_APPEND_LINK(callback, &he->rec->callbacks); if (!(flags & RES_BYPASS_CACHE) &&
((af == PR_AF_INET) || (af == PR_AF_INET6))) {
// First, search for an entry with AF_UNSPEC
const nsHostKey unspecKey = { host, flags, PR_AF_UNSPEC };
nsHostDBEnt *unspecHe = static_cast<nsHostDBEnt *>
(PL_DHashTableOperate(&mDB, &unspecKey, PL_DHASH_LOOKUP));
NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(unspecHe) ||
(PL_DHASH_ENTRY_IS_BUSY(unspecHe) &&
unspecHe->rec),
"Valid host entries should contain a record");
if (PL_DHASH_ENTRY_IS_BUSY(unspecHe) &&
unspecHe->rec &&
unspecHe->rec->HasUsableResult(flags) &&
TimeStamp::NowLoRes() <= (he->rec->expiration +
TimeDuration::FromSeconds(mGracePeriod * 60))) {
LOG(("Specific DNS request (%s) for an unspecified "
"cached record",
(af == PR_AF_INET) ? "AF_INET" : "AF_INET6"));
if (!he->rec->resolving) { // Search for any valid address in the AF_UNSPEC entry
// in the cache (not blacklisted and from the right
// family).
NetAddrElement *addrIter =
unspecHe->rec->addr_info->mAddresses.getFirst();
he->rec->addr_info = nullptr;
while (addrIter) {
if ((af == addrIter->mAddress.inet.family) &&
!unspecHe->rec->Blacklisted(&addrIter->mAddress)) {
if (!he->rec->addr_info) {
he->rec->addr_info = new AddrInfo(
unspecHe->rec->addr_info->mHostName,
unspecHe->rec->addr_info->mCanonicalName);
}
he->rec->addr_info->AddAddress(
new NetAddrElement(*addrIter));
}
addrIter = addrIter->getNext();
}
if (he->rec->HasUsableResult(flags)) {
result = he->rec;
Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2,
METHOD_HIT);
ConditionallyRefreshRecord(he->rec, host);
}
// For AF_INET6, a new lookup means another AF_UNSPEC
// lookup. We have already iterated through the
// AF_UNSPEC addresses, so we mark this record as
// negative.
else if (af == PR_AF_INET6) {
result = he->rec;
he->rec->negative = true;
status = NS_ERROR_UNKNOWN_HOST;
Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2,
METHOD_NEGATIVE_HIT);
}
}
}
// If no valid address was found in the cache or this is an
// AF_UNSPEC request, then start a new lookup.
if (!result) {
LOG(("No valid address was found in the cache for the "
"requested IP family"));
// Add callback to the list of pending callbacks.
PR_APPEND_LINK(callback, &he->rec->callbacks);
he->rec->flags = flags; he->rec->flags = flags;
rv = IssueLookup(he->rec); IssueLookup(he->rec);
Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2, Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2,
METHOD_NETWORK_FIRST); METHOD_NETWORK_FIRST);
if (NS_FAILED(rv)) if (NS_FAILED(rv)) {
PR_REMOVE_AND_INIT_LINK(callback); PR_REMOVE_AND_INIT_LINK(callback);
else }
LOG(("DNS lookup for host [%s] blocking pending 'getaddrinfo' query.", host)); else {
LOG(("DNS lookup for host [%s] blocking pending "
"'getaddrinfo' query.", host));
}
} }
else if (he->rec->onQueue) { }
else {
// The record is being resolved. Append our callback.
PR_APPEND_LINK(callback, &he->rec->callbacks);
if (he->rec->onQueue) {
Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2, Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2,
METHOD_NETWORK_SHARED); METHOD_NETWORK_SHARED);
// Consider the case where we are on a pending queue of // Consider the case where we are on a pending queue of
// lower priority than the request is being made at. // lower priority than the request is being made at.
// In that case we should upgrade to the higher queue. // In that case we should upgrade to the higher queue.
if (IsHighPriority(flags) && !IsHighPriority(he->rec->flags)) { if (IsHighPriority(flags) &&
!IsHighPriority(he->rec->flags)) {
// Move from (low|med) to high. // Move from (low|med) to high.
MoveQueue(he->rec, mHighQ); MoveQueue(he->rec, mHighQ);
he->rec->flags = flags; he->rec->flags = flags;
ConditionallyCreateThread(he->rec); ConditionallyCreateThread(he->rec);
} else if (IsMediumPriority(flags) && IsLowPriority(he->rec->flags)) { } else if (IsMediumPriority(flags) &&
IsLowPriority(he->rec->flags)) {
// Move from low to med. // Move from low to med.
MoveQueue(he->rec, mMediumQ); MoveQueue(he->rec, mMediumQ);
he->rec->flags = flags; he->rec->flags = flags;
@ -770,6 +827,26 @@ nsHostResolver::IssueLookup(nsHostRecord *rec)
return rv; return rv;
} }
nsresult
nsHostResolver::ConditionallyRefreshRecord(nsHostRecord *rec, const char *host)
{
if ((((TimeStamp::NowLoRes() > rec->expiration) &&
rec->mBlacklistedItems.Length()) ||
rec->negative) && !rec->resolving) {
LOG(("Using %s cache entry for host [%s] but starting async renewal.",
rec->negative ? "negative" :"positive", host));
IssueLookup(rec);
if (!rec->negative) {
// negative entries are constantly being refreshed, only
// track positive grace period induced renewals
Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2,
METHOD_RENEWAL);
}
}
return NS_OK;
}
void void
nsHostResolver::DeQueue(PRCList &aQ, nsHostRecord **aResult) nsHostResolver::DeQueue(PRCList &aQ, nsHostRecord **aResult)
{ {

View File

@ -244,6 +244,12 @@ private:
void DeQueue(PRCList &aQ, nsHostRecord **aResult); void DeQueue(PRCList &aQ, nsHostRecord **aResult);
void ClearPendingQueue(PRCList *aPendingQueue); void ClearPendingQueue(PRCList *aPendingQueue);
nsresult ConditionallyCreateThread(nsHostRecord *rec); nsresult ConditionallyCreateThread(nsHostRecord *rec);
/**
* Starts a new lookup in the background for entries that are in the grace
* period with a failed connect or all cached entries are negative.
*/
nsresult ConditionallyRefreshRecord(nsHostRecord *rec, const char *host);
static void MoveQueue(nsHostRecord *aRec, PRCList &aDestQ); static void MoveQueue(nsHostRecord *aRec, PRCList &aDestQ);

View File

@ -145,7 +145,7 @@ function test_read_file() {
function do_test_read_dir(set_type, expected_type) { function do_test_read_dir(set_type, expected_type) {
dump("*** test_read_dir(" + set_type + ", " + expected_type + ")\n"); dump("*** test_read_dir(" + set_type + ", " + expected_type + ")\n");
var file = getFile("TmpD"); var file = do_get_tempdir();
var chan = new_file_channel(file); var chan = new_file_channel(file);
function on_read_complete(data) { function on_read_complete(data) {
@ -176,7 +176,7 @@ function test_upload_file() {
dump("*** test_upload_file\n"); dump("*** test_upload_file\n");
var file = do_get_file("../unit/data/test_readline6.txt"); // file to upload var file = do_get_file("../unit/data/test_readline6.txt"); // file to upload
var dest = getFile("TmpD"); // file upload destination var dest = do_get_tempdir(); // file upload destination
dest.append("junk.dat"); dest.append("junk.dat");
dest.createUnique(dest.NORMAL_FILE_TYPE, 0600); dest.createUnique(dest.NORMAL_FILE_TYPE, 0600);

View File

@ -24,17 +24,18 @@ dl.google.com: did not receive HSTS header
docs.google.com: did not receive HSTS header docs.google.com: did not receive HSTS header
drive.google.com: did not receive HSTS header drive.google.com: did not receive HSTS header
dropcam.com: did not receive HSTS header dropcam.com: did not receive HSTS header
emailprivacytester.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIStrictTransportSecurityService.processStsHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 123" data: no] emailprivacytester.com: did not receive HSTS header
encrypted.google.com: did not receive HSTS header encrypted.google.com: did not receive HSTS header
epoxate.com: max-age too low: 259200 epoxate.com: max-age too low: 259200
factor.cc: could not connect to host
fatzebra.com.au: did not receive HSTS header fatzebra.com.au: did not receive HSTS header
fj.simple.com: did not receive HSTS header fj.simple.com: did not receive HSTS header
gmail.com: did not receive HSTS header gmail.com: did not receive HSTS header
gocardless.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIStrictTransportSecurityService.processStsHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 123" data: no] gocardless.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-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no]
googlemail.com: did not receive HSTS header googlemail.com: did not receive HSTS header
googleplex.com: could not connect to host googleplex.com: could not connect to host
greplin.com: did not receive HSTS header greplin.com: did not receive HSTS header
grepular.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIStrictTransportSecurityService.processStsHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 123" data: no] grepular.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-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no]
groups.google.com: did not receive HSTS header groups.google.com: did not receive HSTS header
health.google.com: did not receive HSTS header health.google.com: did not receive HSTS header
history.google.com: did not receive HSTS header history.google.com: did not receive HSTS header
@ -86,7 +87,7 @@ www.dropcam.com: max-age too low: 2592000
www.elanex.biz: did not receive HSTS header www.elanex.biz: did not receive HSTS header
www.gmail.com: did not receive HSTS header www.gmail.com: did not receive HSTS header
www.googlemail.com: did not receive HSTS header www.googlemail.com: did not receive HSTS header
www.gov.uk: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIStrictTransportSecurityService.processStsHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 123" data: no] www.gov.uk: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no]
www.greplin.com: did not receive HSTS header www.greplin.com: did not receive HSTS header
www.jitsi.org: did not receive HSTS header www.jitsi.org: did not receive HSTS header
www.lastpass.com: did not receive HSTS header www.lastpass.com: did not receive HSTS header
@ -95,7 +96,7 @@ www.logentries.com: did not receive HSTS header
www.moneybookers.com: did not receive HSTS header www.moneybookers.com: did not receive HSTS header
www.neonisi.com: could not connect to host www.neonisi.com: could not connect to host
www.paycheckrecords.com: max-age too low: 86400 www.paycheckrecords.com: max-age too low: 86400
www.paypal.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIStrictTransportSecurityService.processStsHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 123" data: no] www.paypal.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-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no]
www.sandbox.mydigipass.com: could not connect to host www.sandbox.mydigipass.com: could not connect to host
www.surfeasy.com: did not receive HSTS header www.surfeasy.com: did not receive HSTS header
zoo24.de: did not receive HSTS header zoo24.de: did not receive HSTS header

View File

@ -4,11 +4,11 @@
/*****************************************************************************/ /*****************************************************************************/
/* This is an automatically generated file. If you're not */ /* This is an automatically generated file. If you're not */
/* nsStrictTransportSecurityService.cpp, you shouldn't be #including it. */ /* nsSiteSecurityService.cpp, you shouldn't be #including it. */
/*****************************************************************************/ /*****************************************************************************/
#include <stdint.h> #include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1386411284101000); const PRTime gPreloadListExpirationTime = INT64_C(1387620321046000);
class nsSTSPreload class nsSTSPreload
{ {
@ -75,9 +75,11 @@ static const nsSTSPreload kSTSPreloadList[] = {
{ "makeyourlaws.org", true }, { "makeyourlaws.org", true },
{ "manager.linode.com", false }, { "manager.linode.com", false },
{ "mattmccutchen.net", true }, { "mattmccutchen.net", true },
{ "mediacru.sh", true },
{ "mega.co.nz", false }, { "mega.co.nz", false },
{ "members.mayfirst.org", false }, { "members.mayfirst.org", false },
{ "members.nearlyfreespeech.net", false }, { "members.nearlyfreespeech.net", false },
{ "mudcrab.us", true },
{ "my.onlime.ch", false }, { "my.onlime.ch", false },
{ "mylookout.com", false }, { "mylookout.com", false },
{ "neg9.org", false }, { "neg9.org", false },

View File

@ -46,6 +46,36 @@ class TestSwitchRemoteFrame(MarionetteTestCase):
""") """)
self.assertFalse(main_process) self.assertFalse(main_process)
def test_remote_frame_revisit(self):
# test if we can revisit a remote frame (this takes a different codepath)
self.marionette.navigate(self.marionette.absolute_url("test.html"))
self.marionette.execute_script("SpecialPowers.addPermission('browser', true, document)")
self.marionette.execute_script("""
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
SpecialPowers.wrap(iframe).remote = true;
iframe.id = "remote_iframe";
iframe.style.height = "100px";
iframe.style.width = "100%%";
iframe.src = "%s";
document.body.appendChild(iframe);
""" % self.marionette.absolute_url("test.html"))
self.marionette.switch_to_frame("remote_iframe")
main_process = self.marionette.execute_script("""
return SpecialPowers.isMainProcess();
""")
self.assertFalse(main_process)
self.marionette.switch_to_frame()
main_process = self.marionette.execute_script("""
return SpecialPowers.isMainProcess();
""")
self.assertTrue(main_process)
self.marionette.switch_to_frame("remote_iframe")
main_process = self.marionette.execute_script("""
return SpecialPowers.isMainProcess();
""")
self.assertFalse(main_process)
def tearDown(self): def tearDown(self):
if self.oop_by_default is None: if self.oop_by_default is None:
self.marionette.execute_script(""" self.marionette.execute_script("""

View File

@ -10,6 +10,7 @@ marionette.jar:
content/marionette-sendkeys.js (marionette-sendkeys.js) content/marionette-sendkeys.js (marionette-sendkeys.js)
content/marionette-common.js (marionette-common.js) content/marionette-common.js (marionette-common.js)
content/marionette-simpletest.js (marionette-simpletest.js) content/marionette-simpletest.js (marionette-simpletest.js)
content/marionette-frame-manager.js (marionette-frame-manager.js)
content/EventUtils.js (EventUtils.js) content/EventUtils.js (EventUtils.js)
content/ChromeUtils.js (ChromeUtils.js) content/ChromeUtils.js (ChromeUtils.js)
#ifdef ENABLE_TESTS #ifdef ENABLE_TESTS

Some files were not shown because too many files have changed in this diff Show More