From b65d1620f89109f29f9747bbce9a10cb0a89bf5d Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Mon, 1 Dec 2014 19:24:00 +0100 Subject: [PATCH 01/24] Bug 1105126 - Change test_eme_stream_capture_blocked.html to check loadeddata instead of canplay. r=cpearce --- .../test/test_eme_stream_capture_blocked.html | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/dom/media/test/test_eme_stream_capture_blocked.html b/dom/media/test/test_eme_stream_capture_blocked.html index 13eb222ada7e..58682343ce44 100644 --- a/dom/media/test/test_eme_stream_capture_blocked.html +++ b/dom/media/test/test_eme_stream_capture_blocked.html @@ -28,10 +28,9 @@ function startTest(test, token) var v1 = SetupEME(test, case1token, { onSetKeysFail: setKeysFailed }); var context = new AudioContext(); var node = context.createMediaElementSource(v1); - v1.preload = "auto"; // Required due to "canplay" not firing for MSE unless we do this. v1.addEventListener("error", bail(case1token + " got error event")); - v1.addEventListener("canplay", function(ev) { - ok(false, TimeStamp(case1token) + " should never reach canplay, as setMediaKeys should fail"); + v1.addEventListener("loadeddata", function(ev) { + ok(false, TimeStamp(case1token) + " should never reach loadeddata, as setMediaKeys should fail"); }); manager.started(case1token); LoadTest(test, v1, case1token); @@ -40,10 +39,9 @@ function startTest(test, token) // Case 2. creating a MediaElementSource on a media element with a MediaKeys should fail. var case2token = token + "_case2"; var v2 = SetupEME(test, case2token); - v2.preload = "auto"; // Required due to "canplay" not firing for MSE unless we do this. v2.addEventListener("error", bail(case2token + " got error event")); - v2.addEventListener("canplay", function(ev) { - ok(true, case2token + " should reach canplay"); + v2.addEventListener("loadeddata", function(ev) { + ok(true, case2token + " should reach loadeddata"); var threw = false; try { var context = new AudioContext(); @@ -61,10 +59,9 @@ function startTest(test, token) // Case 3. capturing a media element with mozCaptureStream that has a MediaKeys should fail. var case3token = token + "_case3"; var v3 = SetupEME(test, case3token); - v3.preload = "auto"; // Required due to "canplay" not firing for MSE unless we do this. v3.addEventListener("error", bail(case3token + " got error event")); - v3.addEventListener("canplay", function(ev) { - ok(true, TimeStamp(case3token) + " should reach canplay"); + v3.addEventListener("loadeddata", function(ev) { + ok(true, TimeStamp(case3token) + " should reach loadeddata"); var threw = false; try { var stream = v3.mozCaptureStreamUntilEnded(); From 629560ff5fb68ed4340f68892e19d6eb5b25db21 Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Tue, 2 Dec 2014 20:33:24 +0900 Subject: [PATCH 02/24] Bug 1102632 - Stop triggering non-secure fallback for SSL_ERROR_UNSUPPORTED_VERSION. r=keeler --- security/manager/ssl/src/nsNSSIOLayer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index 3af7ae55b85b..0f9ba97defd0 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -1172,7 +1172,6 @@ uint32_t tlsIntoleranceTelemetryBucket(PRErrorCode err) case SSL_ERROR_NO_CYPHER_OVERLAP: return 7; case SSL_ERROR_BAD_SERVER: return 8; case SSL_ERROR_BAD_BLOCK_PADDING: return 9; - case SSL_ERROR_UNSUPPORTED_VERSION: return 10; case SSL_ERROR_PROTOCOL_VERSION_ALERT: return 11; case SSL_ERROR_RX_MALFORMED_FINISHED: return 12; case SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE: return 13; From 62d78cde2c1dbe3ecd87cb1540edf28457fbb670 Mon Sep 17 00:00:00 2001 From: Jan Horak Date: Tue, 2 Dec 2014 04:52:00 +0100 Subject: [PATCH 03/24] Bug 1097550 - "System dictionaries with underscore separator are ignored when trying to find dictionary". r=ehsan --- editor/composer/nsEditorSpellCheck.cpp | 34 +++++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/editor/composer/nsEditorSpellCheck.cpp b/editor/composer/nsEditorSpellCheck.cpp index 3190162f6468..467d0f61eb13 100644 --- a/editor/composer/nsEditorSpellCheck.cpp +++ b/editor/composer/nsEditorSpellCheck.cpp @@ -105,6 +105,23 @@ GetLoadContext(nsIEditor* aEditor) return loadContext.forget(); } +/** + * Helper function for converting underscore to dash in dictionary name, + * ie. en_CA to en-CA. This is required for some Linux distributions which + * use underscore as separator in system-wide installed dictionaries. + * We use it for nsStyleUtil::DashMatchCompare. + */ +static nsString +GetDictNameWithDash(const nsAString& aDictName) +{ + nsString dictNameWithDash(aDictName); + int32_t underScore = dictNameWithDash.FindChar('_'); + if (underScore != -1) { + dictNameWithDash.Replace(underScore, 1, '-'); + } + return dictNameWithDash; +} + /** * Fetches the dictionary stored in content prefs and maintains state during the * fetch, which is asynchronous. @@ -603,8 +620,8 @@ nsEditorSpellCheck::SetCurrentDictionary(const nsAString& aDictionary) } else { langCode.Assign(aDictionary); } - - if (mPreferredLang.IsEmpty() || !nsStyleUtil::DashMatchCompare(mPreferredLang, langCode, comparator)) { + if (mPreferredLang.IsEmpty() || + !nsStyleUtil::DashMatchCompare(GetDictNameWithDash(mPreferredLang), langCode, comparator)) { // When user sets dictionary manually, we store this value associated // with editor url. StoreCurrentDictionary(mEditor, aDictionary); @@ -750,12 +767,6 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher) // otherwise, get language from preferences nsAutoString preferedDict(Preferences::GetLocalizedString("spellchecker.dictionary")); - // Replace '_' with '-' in case the user has an underscore stored in their - // pref, see bug 992118 for how this could have happened. - int32_t underScore = preferedDict.FindChar('_'); - if (underScore != -1) { - preferedDict.Replace(underScore, 1, '-'); - } if (dictName.IsEmpty()) { dictName.Assign(preferedDict); } @@ -794,8 +805,8 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher) // try dictionary.spellchecker preference if it starts with langCode (and // if we haven't tried it already) - if (!preferedDict.IsEmpty() && !dictName.Equals(preferedDict) && - nsStyleUtil::DashMatchCompare(preferedDict, langCode, comparator)) { + if (!preferedDict.IsEmpty() && !dictName.Equals(preferedDict) && + nsStyleUtil::DashMatchCompare(GetDictNameWithDash(preferedDict), langCode, comparator)) { rv = SetCurrentDictionary(preferedDict); } @@ -823,8 +834,7 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher) // We have already tried it continue; } - - if (nsStyleUtil::DashMatchCompare(dictStr, langCode, comparator) && + if (nsStyleUtil::DashMatchCompare(GetDictNameWithDash(dictStr), langCode, comparator) && NS_SUCCEEDED(SetCurrentDictionary(dictStr))) { break; } From fd315ba8ffe740c331047de44ed777124d7aaca1 Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Mon, 1 Dec 2014 22:10:00 +0100 Subject: [PATCH 04/24] Bug 1106547 - Return EOS after drain is complete, rather than before. r=cpearce --- dom/media/fmp4/MP4Reader.cpp | 19 ++++++++++--------- dom/media/fmp4/MP4Reader.h | 2 -- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/dom/media/fmp4/MP4Reader.cpp b/dom/media/fmp4/MP4Reader.cpp index 8aa02c74ad82..71bb75ca5583 100644 --- a/dom/media/fmp4/MP4Reader.cpp +++ b/dom/media/fmp4/MP4Reader.cpp @@ -583,7 +583,6 @@ MP4Reader::Update(TrackType aTrack) bool needInput = false; bool needOutput = false; - bool eos = false; auto& decoder = GetDecoderData(aTrack); nsRefPtr output; { @@ -599,7 +598,6 @@ MP4Reader::Update(TrackType aTrack) output = decoder.mOutput[0]; decoder.mOutput.RemoveElementAt(0); } - eos = decoder.mEOS; } VLOG("Update(%s) ni=%d no=%d iex=%d or=%d fl=%d", TrackTypeToStr(aTrack), @@ -617,16 +615,15 @@ MP4Reader::Update(TrackType aTrack) { MonitorAutoLock lock(decoder.mMonitor); MOZ_ASSERT(!decoder.mEOS); - eos = decoder.mEOS = true; + decoder.mEOS = true; } + // DrainComplete takes care of reporting EOS upwards decoder.mDecoder->Drain(); } } if (needOutput) { if (output) { ReturnOutput(output, aTrack); - } else if (eos) { - ReturnEOS(aTrack); } } } @@ -730,9 +727,14 @@ void MP4Reader::DrainComplete(TrackType aTrack) { DecoderData& data = GetDecoderData(aTrack); - MonitorAutoLock mon(data.mMonitor); - data.mDrainComplete = true; - mon.NotifyAll(); + bool eos; + { + MonitorAutoLock mon(data.mMonitor); + eos = data.mEOS; + } + if (eos) { + ReturnEOS(aTrack); + } } void @@ -771,7 +773,6 @@ MP4Reader::Flush(TrackType aTrack) { MonitorAutoLock mon(data.mMonitor); data.mIsFlushing = true; - data.mDrainComplete = false; data.mEOS = false; } data.mDecoder->Flush(); diff --git a/dom/media/fmp4/MP4Reader.h b/dom/media/fmp4/MP4Reader.h index f1c4b6fac9b3..80bf2390eb9d 100644 --- a/dom/media/fmp4/MP4Reader.h +++ b/dom/media/fmp4/MP4Reader.h @@ -156,7 +156,6 @@ private: , mInputExhausted(false) , mError(false) , mIsFlushing(false) - , mDrainComplete(false) , mOutputRequested(false) , mUpdateScheduled(false) , mEOS(false) @@ -186,7 +185,6 @@ private: bool mInputExhausted; bool mError; bool mIsFlushing; - bool mDrainComplete; bool mOutputRequested; bool mUpdateScheduled; bool mEOS; From c2507c092109fb1c5268afa4e42c8f753ed79633 Mon Sep 17 00:00:00 2001 From: Dave Hunt Date: Tue, 2 Dec 2014 05:31:07 -0800 Subject: [PATCH 05/24] Bug 1105995 - [mozversion] Bump version to 1.1. r=wlachance --- testing/mozbase/mozversion/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/mozbase/mozversion/setup.py b/testing/mozbase/mozversion/setup.py index caa55b9fcc9b..2cfbc449e98b 100644 --- a/testing/mozbase/mozversion/setup.py +++ b/testing/mozbase/mozversion/setup.py @@ -4,7 +4,7 @@ from setuptools import setup -PACKAGE_VERSION = '1.0' +PACKAGE_VERSION = '1.1' dependencies = ['mozdevice >= 0.44', 'mozfile >= 1.0', From 003a5b8d578dd4697bfedc2bdd2a51357fe85eb2 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 20 Nov 2014 14:59:53 -0800 Subject: [PATCH 06/24] Bug 1021669 - Use protocol flags to whiteliste protocols not suspect to CSP (r=sstamm) --- dom/security/nsCSPService.cpp | 79 ++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/dom/security/nsCSPService.cpp b/dom/security/nsCSPService.cpp index 0683e78db0d0..1b1f8638a102 100644 --- a/dom/security/nsCSPService.cpp +++ b/dom/security/nsCSPService.cpp @@ -47,6 +47,56 @@ CSPService::~CSPService() NS_IMPL_ISUPPORTS(CSPService, nsIContentPolicy, nsIChannelEventSink) +// Helper function to identify protocols not subject to CSP. +bool +subjectToCSP(nsIURI* aURI) { + // The three protocols: data:, blob: and filesystem: share the same + // protocol flag (URI_IS_LOCAL_RESOURCE) with other protocols, like + // chrome:, resource:, moz-icon:, but those three protocols get + // special attention in CSP and are subject to CSP, hence we have + // to make sure those protocols are subject to CSP, see: + // http://www.w3.org/TR/CSP2/#source-list-guid-matching + bool match = false; + nsresult rv = aURI->SchemeIs("data", &match); + if (NS_SUCCEEDED(rv) && match) { + return true; + } + rv = aURI->SchemeIs("blob", &match); + if (NS_SUCCEEDED(rv) && match) { + return true; + } + rv = aURI->SchemeIs("filesystem", &match); + if (NS_SUCCEEDED(rv) && match) { + return true; + } + // finally we have to whitelist "about:" which does not fall in + // any of the two categories underneath but is not subject to CSP. + rv = aURI->SchemeIs("about", &match); + if (NS_SUCCEEDED(rv) && match) { + return false; + } + + // Other protocols are not subject to CSP and can be whitelisted: + // * URI_IS_LOCAL_RESOURCE + // e.g. chrome:, data:, blob:, resource:, moz-icon: + // * URI_INHERITS_SECURITY_CONTEXT + // e.g. javascript: + // + // Please note that it should be possible for websites to + // whitelist their own protocol handlers with respect to CSP, + // hence we use protocol flags to accomplish that. + rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE, &match); + if (NS_SUCCEEDED(rv) && match) { + return false; + } + rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT, &match); + if (NS_SUCCEEDED(rv) && match) { + return false; + } + // all other protocols are subject To CSP. + return true; +} + /* nsIContentPolicy implementation */ NS_IMETHODIMP CSPService::ShouldLoad(uint32_t aContentType, @@ -58,8 +108,9 @@ CSPService::ShouldLoad(uint32_t aContentType, nsIPrincipal *aRequestPrincipal, int16_t *aDecision) { - if (!aContentLocation) + if (!aContentLocation) { return NS_ERROR_FAILURE; + } #ifdef PR_LOGGING { @@ -73,26 +124,14 @@ CSPService::ShouldLoad(uint32_t aContentType, // default decision, CSP can revise it if there's a policy to enforce *aDecision = nsIContentPolicy::ACCEPT; - // No need to continue processing if CSP is disabled - if (!sCSPEnabled) + // No need to continue processing if CSP is disabled or if the protocol + // is *not* subject to CSP. + // Please note, the correct way to opt-out of CSP using a custom + // protocolHandler is to set one of the nsIProtocolHandler flags + // that are whitelistet in subjectToCSP() + if (!sCSPEnabled || !subjectToCSP(aContentLocation)) { return NS_OK; - - // shortcut for about: chrome: and resource: and javascript: uris since - // they're not subject to CSP content policy checks. - bool schemeMatch = false; - NS_ENSURE_SUCCESS(aContentLocation->SchemeIs("about", &schemeMatch), NS_OK); - if (schemeMatch) - return NS_OK; - NS_ENSURE_SUCCESS(aContentLocation->SchemeIs("chrome", &schemeMatch), NS_OK); - if (schemeMatch) - return NS_OK; - NS_ENSURE_SUCCESS(aContentLocation->SchemeIs("resource", &schemeMatch), NS_OK); - if (schemeMatch) - return NS_OK; - NS_ENSURE_SUCCESS(aContentLocation->SchemeIs("javascript", &schemeMatch), NS_OK); - if (schemeMatch) - return NS_OK; - + } // These content types are not subject to CSP content policy checks: // TYPE_CSP_REPORT -- csp can't block csp reports From c29b6d58c3fd6028ae20d5a9d328f33986f10096 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 2 Dec 2014 08:26:26 -0800 Subject: [PATCH 07/24] Bug 1096707 - SpiderMonkey: Use consistent operand order for round[sp][sd] and cmpps --- js/src/jit/shared/Assembler-x86-shared.h | 26 +++++++------- js/src/jit/shared/BaseAssembler-x86-shared.h | 34 +++++++++---------- .../jit/shared/CodeGenerator-x86-shared.cpp | 12 +++---- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/js/src/jit/shared/Assembler-x86-shared.h b/js/src/jit/shared/Assembler-x86-shared.h index c9939ee672f1..6821aa98be57 100644 --- a/js/src/jit/shared/Assembler-x86-shared.h +++ b/js/src/jit/shared/Assembler-x86-shared.h @@ -1675,36 +1675,36 @@ class AssemblerX86Shared : public AssemblerShared MOZ_CRASH("unexpected operand kind"); } } - void cmpps(const Operand &src, FloatRegister dest, uint8_t order) { + void cmpps(uint8_t order, const Operand &src, FloatRegister dest) { MOZ_ASSERT(HasSSE2()); switch (src.kind()) { case Operand::FPREG: - masm.cmpps_rr(src.fpu(), dest.code(), order); + masm.cmpps_rr(order, src.fpu(), dest.code()); break; case Operand::MEM_REG_DISP: - masm.cmpps_mr(src.disp(), src.base(), dest.code(), order); + masm.cmpps_mr(order, src.disp(), src.base(), dest.code()); break; case Operand::MEM_ADDRESS32: - masm.cmpps_mr(src.address(), dest.code(), order); + masm.cmpps_mr(order, src.address(), dest.code()); break; default: MOZ_CRASH("unexpected operand kind"); } } void cmpeqps(const Operand &src, FloatRegister dest) { - cmpps(src, dest, X86Assembler::ConditionCmp_EQ); + cmpps(X86Assembler::ConditionCmp_EQ, src, dest); } void cmpltps(const Operand &src, FloatRegister dest) { - cmpps(src, dest, X86Assembler::ConditionCmp_LT); + cmpps(X86Assembler::ConditionCmp_LT, src, dest); } void cmpleps(const Operand &src, FloatRegister dest) { - cmpps(src, dest, X86Assembler::ConditionCmp_LE); + cmpps(X86Assembler::ConditionCmp_LE, src, dest); } void cmpunordps(const Operand &src, FloatRegister dest) { - cmpps(src, dest, X86Assembler::ConditionCmp_UNORD); + cmpps(X86Assembler::ConditionCmp_UNORD, src, dest); } void cmpneqps(const Operand &src, FloatRegister dest) { - cmpps(src, dest, X86Assembler::ConditionCmp_NEQ); + cmpps(X86Assembler::ConditionCmp_NEQ, src, dest); } void rcpps(const Operand &src, FloatRegister dest) { MOZ_ASSERT(HasSSE2()); @@ -2173,13 +2173,13 @@ class AssemblerX86Shared : public AssemblerShared MOZ_ASSERT(HasSSE2()); masm.sqrtss_rr(src.code(), dest.code()); } - void roundsd(FloatRegister src, FloatRegister dest, X86Assembler::RoundingMode mode) { + void roundsd(X86Assembler::RoundingMode mode, FloatRegister src, FloatRegister dest) { MOZ_ASSERT(HasSSE41()); - masm.roundsd_rr(src.code(), dest.code(), mode); + masm.roundsd_rr(mode, src.code(), dest.code()); } - void roundss(FloatRegister src, FloatRegister dest, X86Assembler::RoundingMode mode) { + void roundss(X86Assembler::RoundingMode mode, FloatRegister src, FloatRegister dest) { MOZ_ASSERT(HasSSE41()); - masm.roundss_rr(src.code(), dest.code(), mode); + masm.roundss_rr(mode, src.code(), dest.code()); } unsigned insertpsMask(SimdLane sourceLane, SimdLane destLane, unsigned zeroMask = 0) { diff --git a/js/src/jit/shared/BaseAssembler-x86-shared.h b/js/src/jit/shared/BaseAssembler-x86-shared.h index 61a68b3fc690..e19eff340e8a 100644 --- a/js/src/jit/shared/BaseAssembler-x86-shared.h +++ b/js/src/jit/shared/BaseAssembler-x86-shared.h @@ -690,7 +690,7 @@ public: void addq_im(int imm, const void* addr) { - spew("addq %d, %p", imm, addr); + spew("addq $%d, %p", imm, addr); if (CAN_SIGN_EXTEND_8_32(imm)) { m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr); m_formatter.immediate8(imm); @@ -702,7 +702,7 @@ public: #endif void addl_im(int imm, const void* addr) { - spew("addl %d, %p", imm, addr); + spew("addl $%d, %p", imm, addr); if (CAN_SIGN_EXTEND_8_32(imm)) { m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr); m_formatter.immediate8(imm); @@ -2040,7 +2040,7 @@ public: void movb_i8m(int imm, const void* addr) { - spew("movb %d, %p", imm, addr); + spew("movb $%d, %p", imm, addr); m_formatter.oneByteOp_disp32(OP_GROUP11_EvIb, GROUP11_MOV, addr); m_formatter.immediate8(imm); } @@ -2056,7 +2056,7 @@ public: void movw_i16m(int imm, const void* addr) { - spew("movw %d, %p", imm, addr); + spew("movw $%d, %p", imm, addr); m_formatter.prefix(PRE_OPERAND_SIZE); m_formatter.oneByteOp_disp32(OP_GROUP11_EvIz, GROUP11_MOV, addr); m_formatter.immediate16(imm); @@ -2205,7 +2205,7 @@ public: } void movq_i32m(int imm, const void* addr) { - spew("movq %d, %p", imm, addr); + spew("movq $%d, %p", imm, addr); m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, addr); m_formatter.immediate32(imm); } @@ -2269,7 +2269,7 @@ public: void movl_i32m(int imm, const void* addr) { - spew("movl %d, %p", imm, addr); + spew("movl $%d, %p", imm, addr); m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr); m_formatter.immediate32(imm); } @@ -2691,24 +2691,24 @@ public: m_formatter.twoByteOp(OP2_PCMPGTD_VdqWdq, (RegisterID)dst, address); } - void cmpps_rr(XMMRegisterID src, XMMRegisterID dst, uint8_t order) + void cmpps_rr(uint8_t order, XMMRegisterID src, XMMRegisterID dst) { - spew("cmpps %s, %s, %u", nameFPReg(src), nameFPReg(dst), order); + spew("cmpps $%u, %s, %s", order, nameFPReg(src), nameFPReg(dst)); m_formatter.twoByteOp(OP2_CMPPS_VpsWps, (RegisterID)dst, (RegisterID)src); m_formatter.immediate8(order); } - void cmpps_mr(int offset, RegisterID base, XMMRegisterID dst, uint8_t order) + void cmpps_mr(uint8_t order, int offset, RegisterID base, XMMRegisterID dst) { - spew("cmpps %s0x%x(%s), %s, %u", - PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst), order); + spew("cmpps $%u, %s0x%x(%s), %s", + order, PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst)); m_formatter.twoByteOp(OP2_CMPPS_VpsWps, (RegisterID)dst, base, offset); m_formatter.immediate8(order); } - void cmpps_mr(const void* address, XMMRegisterID dst, uint8_t order) + void cmpps_mr(uint8_t order, const void* address, XMMRegisterID dst) { - spew("cmpps %p, %s, %u", address, nameFPReg(dst), order); + spew("cmpps $%u, %p, %s", order, address, nameFPReg(dst)); m_formatter.twoByteOp(OP2_CMPPS_VpsWps, (RegisterID)dst, address); m_formatter.immediate8(order); } @@ -3757,17 +3757,17 @@ public: m_formatter.twoByteOp(OP2_SQRTSS_VssWss, (RegisterID)dst, (RegisterID)src); } - void roundsd_rr(XMMRegisterID src, XMMRegisterID dst, RoundingMode mode) + void roundsd_rr(RoundingMode mode, XMMRegisterID src, XMMRegisterID dst) { - spew("roundsd %s, %s, %d", nameFPReg(src), nameFPReg(dst), (int)mode); + spew("roundsd $%d, %s, %s", (int)mode, nameFPReg(src), nameFPReg(dst)); m_formatter.prefix(PRE_SSE_66); m_formatter.threeByteOp(OP3_ROUNDSD_VsdWsd, ESCAPE_ROUNDSD, (RegisterID)dst, (RegisterID)src); m_formatter.immediate8(mode); } - void roundss_rr(XMMRegisterID src, XMMRegisterID dst, RoundingMode mode) + void roundss_rr(RoundingMode mode, XMMRegisterID src, XMMRegisterID dst) { - spew("roundss %s, %s, %d", nameFPReg(src), nameFPReg(dst), (int)mode); + spew("roundss $%d, %s, %s", (int)mode, nameFPReg(src), nameFPReg(dst)); m_formatter.prefix(PRE_SSE_66); m_formatter.threeByteOp(OP3_ROUNDSS_VsdWsd, ESCAPE_ROUNDSD, (RegisterID)dst, (RegisterID)src); m_formatter.immediate8(mode); // modes are the same for roundsd and roundss diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index 7fcd5a3444b2..2c22aaa31148 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -1688,7 +1688,7 @@ CodeGeneratorX86Shared::visitFloor(LFloor *lir) return false; // Round toward -Infinity. - masm.roundsd(input, scratch, X86Assembler::RoundDown); + masm.roundsd(X86Assembler::RoundDown, input, scratch); if (!bailoutCvttsd2si(scratch, output, lir->snapshot())) return false; @@ -1751,7 +1751,7 @@ CodeGeneratorX86Shared::visitFloorF(LFloorF *lir) return false; // Round toward -Infinity. - masm.roundss(input, scratch, X86Assembler::RoundDown); + masm.roundss(X86Assembler::RoundDown, input, scratch); if (!bailoutCvttss2si(scratch, output, lir->snapshot())) return false; @@ -1822,7 +1822,7 @@ CodeGeneratorX86Shared::visitCeil(LCeil *lir) // x <= -1 or x > -0 masm.bind(&lessThanMinusOne); // Round toward +Infinity. - masm.roundsd(input, scratch, X86Assembler::RoundUp); + masm.roundsd(X86Assembler::RoundUp, input, scratch); return bailoutCvttsd2si(scratch, output, lir->snapshot()); } @@ -1878,7 +1878,7 @@ CodeGeneratorX86Shared::visitCeilF(LCeilF *lir) // x <= -1 or x > -0 masm.bind(&lessThanMinusOne); // Round toward +Infinity. - masm.roundss(input, scratch, X86Assembler::RoundUp); + masm.roundss(X86Assembler::RoundUp, input, scratch); return bailoutCvttss2si(scratch, output, lir->snapshot()); } @@ -1958,7 +1958,7 @@ CodeGeneratorX86Shared::visitRound(LRound *lir) // Add 0.5 and round toward -Infinity. The result is stored in the temp // register (currently contains 0.5). masm.addsd(input, temp); - masm.roundsd(temp, scratch, X86Assembler::RoundDown); + masm.roundsd(X86Assembler::RoundDown, temp, scratch); // Truncate. if (!bailoutCvttsd2si(scratch, output, lir->snapshot())) @@ -2049,7 +2049,7 @@ CodeGeneratorX86Shared::visitRoundF(LRoundF *lir) // Add 0.5 and round toward -Infinity. The result is stored in the temp // register (currently contains 0.5). masm.addss(input, temp); - masm.roundss(temp, scratch, X86Assembler::RoundDown); + masm.roundss(X86Assembler::RoundDown, temp, scratch); // Truncate. if (!bailoutCvttss2si(scratch, output, lir->snapshot())) From 39d37c7d35593fb4a6abcd419a860d9f4cb97b24 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 2 Dec 2014 08:26:27 -0800 Subject: [PATCH 08/24] Bug 1096707 - SpiderMonkey: Use GvEv encodings for register-register instructions --- js/src/jit/shared/BaseAssembler-x86-shared.h | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/js/src/jit/shared/BaseAssembler-x86-shared.h b/js/src/jit/shared/BaseAssembler-x86-shared.h index e19eff340e8a..2e86ce4d849b 100644 --- a/js/src/jit/shared/BaseAssembler-x86-shared.h +++ b/js/src/jit/shared/BaseAssembler-x86-shared.h @@ -269,7 +269,7 @@ private: OP_GROUP1_EvIb = 0x83, OP_TEST_EbGb = 0x84, OP_TEST_EvGv = 0x85, - OP_XCHG_EvGv = 0x87, + OP_XCHG_GvEv = 0x87, OP_MOV_EbGv = 0x88, OP_MOV_EvGv = 0x89, OP_MOV_GvEb = 0x8A, @@ -594,7 +594,7 @@ public: void addl_rr(RegisterID src, RegisterID dst) { spew("addl %s, %s", nameIReg(4,src), nameIReg(4,dst)); - m_formatter.oneByteOp(OP_ADD_EvGv, src, dst); + m_formatter.oneByteOp(OP_ADD_GvEv, dst, src); } void addl_mr(int offset, RegisterID base, RegisterID dst) @@ -647,7 +647,7 @@ public: void addq_rr(RegisterID src, RegisterID dst) { spew("addq %s, %s", nameIReg(8,src), nameIReg(8,dst)); - m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst); + m_formatter.oneByteOp64(OP_ADD_GvEv, dst, src); } void addq_mr(int offset, RegisterID base, RegisterID dst) @@ -891,7 +891,7 @@ public: void andl_rr(RegisterID src, RegisterID dst) { spew("andl %s, %s", nameIReg(4,src), nameIReg(4,dst)); - m_formatter.oneByteOp(OP_AND_EvGv, src, dst); + m_formatter.oneByteOp(OP_AND_GvEv, dst, src); } void andl_mr(int offset, RegisterID base, RegisterID dst) @@ -937,7 +937,7 @@ public: void andq_rr(RegisterID src, RegisterID dst) { spew("andq %s, %s", nameIReg(8,src), nameIReg(8,dst)); - m_formatter.oneByteOp64(OP_AND_EvGv, src, dst); + m_formatter.oneByteOp64(OP_AND_GvEv, dst, src); } void andq_mr(int offset, RegisterID base, RegisterID dst) @@ -1052,7 +1052,7 @@ public: void orl_rr(RegisterID src, RegisterID dst) { spew("orl %s, %s", nameIReg(4,src), nameIReg(4,dst)); - m_formatter.oneByteOp(OP_OR_EvGv, src, dst); + m_formatter.oneByteOp(OP_OR_GvEv, dst, src); } void orl_mr(int offset, RegisterID base, RegisterID dst) @@ -1104,7 +1104,7 @@ public: void orq_rr(RegisterID src, RegisterID dst) { spew("orq %s, %s", nameIReg(8,src), nameIReg(8,dst)); - m_formatter.oneByteOp64(OP_OR_EvGv, src, dst); + m_formatter.oneByteOp64(OP_OR_GvEv, dst, src); } void orq_ir(int imm, RegisterID dst) @@ -1141,7 +1141,7 @@ public: void subl_rr(RegisterID src, RegisterID dst) { spew("subl %s, %s", nameIReg(4,src), nameIReg(4,dst)); - m_formatter.oneByteOp(OP_SUB_EvGv, src, dst); + m_formatter.oneByteOp(OP_SUB_GvEv, dst, src); } void subl_mr(int offset, RegisterID base, RegisterID dst) @@ -1187,7 +1187,7 @@ public: void subq_rr(RegisterID src, RegisterID dst) { spew("subq %s, %s", nameIReg(8,src), nameIReg(8,dst)); - m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst); + m_formatter.oneByteOp64(OP_SUB_GvEv, dst, src); } void subq_rm(RegisterID src, int offset, RegisterID base) @@ -1238,7 +1238,7 @@ public: void xorl_rr(RegisterID src, RegisterID dst) { spew("xorl %s, %s", nameIReg(4,src), nameIReg(4,dst)); - m_formatter.oneByteOp(OP_XOR_EvGv, src, dst); + m_formatter.oneByteOp(OP_XOR_GvEv, dst, src); } void xorl_mr(int offset, RegisterID base, RegisterID dst) @@ -1284,7 +1284,7 @@ public: void xorq_rr(RegisterID src, RegisterID dst) { spew("xorq %s, %s", nameIReg(8,src), nameIReg(8, dst)); - m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst); + m_formatter.oneByteOp64(OP_XOR_GvEv, dst, src); } void xorq_ir(int imm, RegisterID dst) @@ -1509,7 +1509,7 @@ public: void cmpl_rr(RegisterID src, RegisterID dst) { spew("cmpl %s, %s", nameIReg(4, src), nameIReg(4, dst)); - m_formatter.oneByteOp(OP_CMP_EvGv, src, dst); + m_formatter.oneByteOp(OP_CMP_GvEv, dst, src); } void cmpl_rm(RegisterID src, int offset, RegisterID base) @@ -1600,7 +1600,7 @@ public: void cmpq_rr(RegisterID src, RegisterID dst) { spew("cmpq %s, %s", nameIReg(8, src), nameIReg(8, dst)); - m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst); + m_formatter.oneByteOp64(OP_CMP_GvEv, dst, src); } void cmpq_rm(RegisterID src, int offset, RegisterID base) @@ -1701,7 +1701,7 @@ public: { spew("cmpw %s, %s", nameIReg(2, src), nameIReg(2, dst)); m_formatter.prefix(PRE_OPERAND_SIZE); - m_formatter.oneByteOp(OP_CMP_EvGv, src, dst); + m_formatter.oneByteOp(OP_CMP_GvEv, dst, src); } void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) @@ -1888,21 +1888,21 @@ public: void xchgl_rr(RegisterID src, RegisterID dst) { spew("xchgl %s, %s", nameIReg(4,src), nameIReg(4,dst)); - m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst); + m_formatter.oneByteOp(OP_XCHG_GvEv, dst, src); } #ifdef JS_CODEGEN_X64 void xchgq_rr(RegisterID src, RegisterID dst) { spew("xchgq %s, %s", nameIReg(8,src), nameIReg(8,dst)); - m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst); + m_formatter.oneByteOp64(OP_XCHG_GvEv, dst, src); } #endif void movl_rr(RegisterID src, RegisterID dst) { spew("movl %s, %s", nameIReg(4,src), nameIReg(4,dst)); - m_formatter.oneByteOp(OP_MOV_EvGv, src, dst); + m_formatter.oneByteOp(OP_MOV_GvEv, dst, src); } void movw_rm(RegisterID src, int offset, RegisterID base) @@ -2102,7 +2102,7 @@ public: void movq_rr(RegisterID src, RegisterID dst) { spew("movq %s, %s", nameIReg(8,src), nameIReg(8,dst)); - m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst); + m_formatter.oneByteOp64(OP_MOV_GvEv, dst, src); } void movq_rm(RegisterID src, int offset, RegisterID base) From f2394998f5f65e989f6b4034ce331cf107c410a5 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 2 Dec 2014 08:26:27 -0800 Subject: [PATCH 09/24] Bug 1096707 - SpiderMonkey: Use a consistent ordering for assembler function arguments --- js/src/jit/shared/BaseAssembler-x86-shared.h | 1086 +++++++++--------- 1 file changed, 543 insertions(+), 543 deletions(-) diff --git a/js/src/jit/shared/BaseAssembler-x86-shared.h b/js/src/jit/shared/BaseAssembler-x86-shared.h index 2e86ce4d849b..ebcaa73bb04a 100644 --- a/js/src/jit/shared/BaseAssembler-x86-shared.h +++ b/js/src/jit/shared/BaseAssembler-x86-shared.h @@ -554,13 +554,13 @@ public: void push_m(int offset, RegisterID base) { spew("push %s0x%x(%s)", PRETTY_PRINT_OFFSET(offset), nameIReg(base)); - m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset); + m_formatter.oneByteOp(OP_GROUP5_Ev, offset, base, GROUP5_OP_PUSH); } void pop_m(int offset, RegisterID base) { spew("pop %s0x%x(%s)", PRETTY_PRINT_OFFSET(offset), nameIReg(base)); - m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset); + m_formatter.oneByteOp(OP_GROUP1A_Ev, offset, base, GROUP1A_OP_POP); } void push_flags() @@ -582,10 +582,10 @@ public: { FIXME_INSN_PRINTING; if (CAN_SIGN_EXTEND_8_32(imm)) { - m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr); + m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_ADC); m_formatter.immediate8(imm); } else { - m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr); + m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_ADC); m_formatter.immediate32(imm); } } @@ -594,31 +594,31 @@ public: void addl_rr(RegisterID src, RegisterID dst) { spew("addl %s, %s", nameIReg(4,src), nameIReg(4,dst)); - m_formatter.oneByteOp(OP_ADD_GvEv, dst, src); + m_formatter.oneByteOp(OP_ADD_GvEv, src, dst); } void addl_mr(int offset, RegisterID base, RegisterID dst) { spew("addl %s0x%x(%s), %s", PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(4,dst)); - m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset); + m_formatter.oneByteOp(OP_ADD_GvEv, offset, base, dst); } void addl_rm(RegisterID src, int offset, RegisterID base) { spew("addl %s, %s0x%x(%s)", nameIReg(4,src), PRETTY_PRINT_OFFSET(offset), nameIReg(base)); - m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset); + m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, src); } void addl_ir(int imm, RegisterID dst) { spew("addl $0x%x, %s", imm, nameIReg(4,dst)); if (CAN_SIGN_EXTEND_8_32(imm)) { - m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst); + m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_ADD); m_formatter.immediate8(imm); } else { - m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst); + m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD); m_formatter.immediate32(imm); } } @@ -626,7 +626,7 @@ public: { // 32-bit immediate always, for patching. spew("addl $0x%x, %s", imm, nameIReg(4,dst)); - m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst); + m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD); m_formatter.immediate32(imm); } @@ -635,10 +635,10 @@ public: spew("addl $%d, %s0x%x(%s)", imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base)); if (CAN_SIGN_EXTEND_8_32(imm)) { - m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset); + m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_ADD); m_formatter.immediate8(imm); } else { - m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset); + m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_ADD); m_formatter.immediate32(imm); } } @@ -647,30 +647,30 @@ public: void addq_rr(RegisterID src, RegisterID dst) { spew("addq %s, %s", nameIReg(8,src), nameIReg(8,dst)); - m_formatter.oneByteOp64(OP_ADD_GvEv, dst, src); + m_formatter.oneByteOp64(OP_ADD_GvEv, src, dst); } void addq_mr(int offset, RegisterID base, RegisterID dst) { spew("addq %s0x%x(%s), %s", PRETTY_PRINT_OFFSET(offset), nameIReg(8,base), nameIReg(8,dst)); - m_formatter.oneByteOp64(OP_ADD_GvEv, dst, base, offset); + m_formatter.oneByteOp64(OP_ADD_GvEv, offset, base, dst); } void addq_mr(const void* addr, RegisterID dst) { spew("addq %p, %s", addr, nameIReg(8, dst)); - m_formatter.oneByteOp64(OP_ADD_GvEv, dst, addr); + m_formatter.oneByteOp64(OP_ADD_GvEv, addr, dst); } void addq_ir(int imm, RegisterID dst) { spew("addq $0x%x, %s", imm, nameIReg(8,dst)); if (CAN_SIGN_EXTEND_8_32(imm)) { - m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst); + m_formatter.oneByteOp64(OP_GROUP1_EvIb, dst, GROUP1_OP_ADD); m_formatter.immediate8(imm); } else { - m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst); + m_formatter.oneByteOp64(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD); m_formatter.immediate32(imm); } } @@ -680,10 +680,10 @@ public: spew("addq $0x%x, %s0x%x(%s)", imm, PRETTY_PRINT_OFFSET(offset), nameIReg(8,base)); if (CAN_SIGN_EXTEND_8_32(imm)) { - m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset); + m_formatter.oneByteOp64(OP_GROUP1_EvIb, offset, base, GROUP1_OP_ADD); m_formatter.immediate8(imm); } else { - m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset); + m_formatter.oneByteOp64(OP_GROUP1_EvIz, offset, base, GROUP1_OP_ADD); m_formatter.immediate32(imm); } } @@ -692,10 +692,10 @@ public: { spew("addq $%d, %p", imm, addr); if (CAN_SIGN_EXTEND_8_32(imm)) { - m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr); + m_formatter.oneByteOp64(OP_GROUP1_EvIb, addr, GROUP1_OP_ADD); m_formatter.immediate8(imm); } else { - m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr); + m_formatter.oneByteOp64(OP_GROUP1_EvIz, addr, GROUP1_OP_ADD); m_formatter.immediate32(imm); } } @@ -704,10 +704,10 @@ public: { spew("addl $%d, %p", imm, addr); if (CAN_SIGN_EXTEND_8_32(imm)) { - m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr); + m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_ADD); m_formatter.immediate8(imm); } else { - m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr); + m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_ADD); m_formatter.immediate32(imm); } } @@ -717,7 +717,7 @@ public: spew("lock xaddl %s, %s0x%x(%s)", nameIReg(1, srcdest), PRETTY_PRINT_OFFSET(offset), nameIReg(base)); m_formatter.oneByteOp(PRE_LOCK); - m_formatter.twoByteOp(OP2_XADD_EbGb, srcdest, base, offset); + m_formatter.twoByteOp(OP2_XADD_EbGb, offset, base, srcdest); } void lock_xaddb_rm(RegisterID srcdest, int offset, RegisterID base, RegisterID index, int scale) @@ -726,7 +726,7 @@ public: nameIReg(1, srcdest), PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameIReg(index), 1< Date: Mon, 1 Dec 2014 14:57:17 +0100 Subject: [PATCH 10/24] Bug 1093628 - IonMonkey MIPS: Fix scratch usage in store macro instructions. r=jandem --- js/src/jit/mips/MacroAssembler-mips.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/js/src/jit/mips/MacroAssembler-mips.cpp b/js/src/jit/mips/MacroAssembler-mips.cpp index d081e8b05059..bbed57fed9f7 100644 --- a/js/src/jit/mips/MacroAssembler-mips.cpp +++ b/js/src/jit/mips/MacroAssembler-mips.cpp @@ -2033,8 +2033,8 @@ MacroAssemblerMIPSCompat::store32(Register src, const Address &address) void MacroAssemblerMIPSCompat::store32(Imm32 src, const Address &address) { - move32(src, ScratchRegister); - storePtr(ScratchRegister, address); + move32(src, SecondScratchReg); + storePtr(SecondScratchReg, address); } void @@ -2053,8 +2053,8 @@ template void MacroAssemblerMIPSCompat::storePtr(ImmWord imm, T address) { - ma_li(ScratchRegister, Imm32(imm.value)); - ma_sw(ScratchRegister, address); + ma_li(SecondScratchReg, Imm32(imm.value)); + ma_sw(SecondScratchReg, address); } template void MacroAssemblerMIPSCompat::storePtr
(ImmWord imm, Address address); @@ -2074,8 +2074,8 @@ template void MacroAssemblerMIPSCompat::storePtr(ImmGCPtr imm, T address) { - ma_li(ScratchRegister, imm); - ma_sw(ScratchRegister, address); + ma_li(SecondScratchReg, imm); + ma_sw(SecondScratchReg, address); } template void MacroAssemblerMIPSCompat::storePtr
(ImmGCPtr imm, Address address); From 88fec34715389c7e5d7a0cdf237e64b6d4d79595 Mon Sep 17 00:00:00 2001 From: David Burns Date: Wed, 26 Nov 2014 00:33:53 +0000 Subject: [PATCH 11/24] Bug 940954: Allow marionette to restart the browser and create a new session This gives us the ability to restart a session from the client side, say for testing Firefox updates, and then carry on the test. To do this it is just self.marionette.restart() --HG-- extra : rebase_source : 95d0c6d4fcd30865ff7cbbf97de0e5ca09b3eaab --- .../client/marionette/geckoinstance.py | 41 +++++++++++++------ .../client/marionette/marionette.py | 15 +++---- .../tests/unit/test_profile_management.py | 8 +++- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/testing/marionette/client/marionette/geckoinstance.py b/testing/marionette/client/marionette/geckoinstance.py index e3447aab2fec..b29a8f54911d 100644 --- a/testing/marionette/client/marionette/geckoinstance.py +++ b/testing/marionette/client/marionette/geckoinstance.py @@ -30,12 +30,17 @@ class GeckoInstance(object): "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False} - def __init__(self, host, port, bin, profile, app_args=None, symbols_path=None, - gecko_log=None, prefs=None): + def __init__(self, host, port, bin, profile=None, app_args=None, symbols_path=None, + gecko_log=None, prefs=None, ): self.marionette_host = host self.marionette_port = port self.bin = bin - self.profile_path = profile + # Check if it is a Profile object or a path to profile + self.profile = None + if isinstance(profile, Profile): + self.profile = profile + else: + self.profile_path = profile self.prefs = prefs self.app_args = app_args or [] self.runner = None @@ -47,12 +52,14 @@ class GeckoInstance(object): profile_args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) - if not self.profile_path: - profile_args["restore"] = False - profile = Profile(**profile_args) - else: - profile_args["path_from"] = self.profile_path - profile = Profile.clone(**profile_args) + + if hasattr(self, "profile_path") and self.profile is None: + if not self.profile_path: + profile_args["restore"] = False + self.profile = Profile(**profile_args) + else: + profile_args["path_from"] = self.profile_path + self.profile = Profile.clone(**profile_args) process_args = { 'processOutputLine': [NullOutput()], @@ -101,20 +108,28 @@ class GeckoInstance(object): 'MOZ_CRASHREPORTER_NO_REPORT': '1', }) self.runner = Runner( binary=self.bin, - profile=profile, + profile=self.profile, cmdargs=['-no-remote', '-marionette'] + self.app_args, env=env, symbols_path=self.symbols_path, process_args=process_args) self.runner.start() - def close(self): + def close(self, restart=False): + if not restart: + self.profile.cleanup() + self.profile = None + if self.runner: self.runner.stop() self.runner.cleanup() - def restart(self, prefs=None): - self.close() + def restart(self, prefs=None, clean=True): + if clean: + self.profile.cleanup() + self.profile = None + + self.close(restart=True) if prefs: self.prefs = prefs else: diff --git a/testing/marionette/client/marionette/marionette.py b/testing/marionette/client/marionette/marionette.py index 010d83e9c148..26df978c3aa0 100644 --- a/testing/marionette/client/marionette/marionette.py +++ b/testing/marionette/client/marionette/marionette.py @@ -475,6 +475,7 @@ class Marionette(object): self.host = host self.port = self.local_port = port self.bin = bin + self.profile = profile self.instance = None self.session = None self.session_id = None @@ -512,7 +513,7 @@ class Marionette(object): KeyError): instance_class = geckoinstance.GeckoInstance self.instance = instance_class(host=self.host, port=self.port, - bin=self.bin, profile=profile, + bin=self.bin, profile=self.profile, app_args=app_args, symbols_path=symbols_path, gecko_log=gecko_log) self.instance.start() @@ -528,7 +529,7 @@ class Marionette(object): binary=emulator_binary, userdata=emulator_img, resolution=emulator_res, - profile=profile, + profile=self.profile, adb_path=adb_path, process_args=process_args) self.emulator = self.runner.device @@ -773,20 +774,20 @@ class Marionette(object): self.start_session() self._reset_timeouts() - def restart_with_clean_profile(self): + def restart(self, clean=False): """ This will terminate the currently running instance, and spawn a new instance - with a clean profile. + with the same profile and then reuse the session id when creating a session again. : param prefs: A dictionary whose keys are preference names. """ if not self.instance: - raise errors.MarionetteException("enforce_gecko_prefs can only be called " \ + raise errors.MarionetteException("restart can only be called " \ "on gecko instances launched by Marionette") self.delete_session() - self.instance.restart() + self.instance.restart(clean=clean) assert(self.wait_for_port()), "Timed out waiting for port!" - self.start_session() + self.start_session(session_id=self.session_id) self._reset_timeouts() def absolute_url(self, relative_url): diff --git a/testing/marionette/client/marionette/tests/unit/test_profile_management.py b/testing/marionette/client/marionette/tests/unit/test_profile_management.py index b1cbd46b8bb8..28b9477c2e97 100644 --- a/testing/marionette/client/marionette/tests/unit/test_profile_management.py +++ b/testing/marionette/client/marionette/tests/unit/test_profile_management.py @@ -27,6 +27,12 @@ class TestLog(MarionetteTestCase): self.assertFalse(bool_value) def test_clean_profile(self): - self.marionette.restart_with_clean_profile() + self.marionette.restart(clean=True) with self.assertRaisesRegexp(JavascriptException, "Error getting pref"): bool_value = self.marionette.execute_script("return SpecialPowers.getBoolPref('marionette.test.bool');") + + def test_can_restart_the_browser(self): + self.marionette.enforce_gecko_prefs({"marionette.test.restart": True}) + self.marionette.restart() + bool_value = self.marionette.execute_script("return SpecialPowers.getBoolPref('marionette.test.restart');") + self.assertTrue(bool_value) \ No newline at end of file From d81a78094b83b90415ff879a9947d5d0440c33d9 Mon Sep 17 00:00:00 2001 From: Robert Strong Date: Tue, 2 Dec 2014 13:47:37 -0500 Subject: [PATCH 12/24] Bug 1098112 - Auto-updates broken on Linux when /tmp is mounted noexec. r=bbondy --- toolkit/mozapps/update/nsUpdateService.js | 36 +++++++++++--------- toolkit/xre/nsUpdateDriver.cpp | 40 ++++++++++------------- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/toolkit/mozapps/update/nsUpdateService.js b/toolkit/mozapps/update/nsUpdateService.js index 5bbf0c9e0f2c..6e4a1ef25b02 100644 --- a/toolkit/mozapps/update/nsUpdateService.js +++ b/toolkit/mozapps/update/nsUpdateService.js @@ -1215,23 +1215,37 @@ function writeVersionFile(dir, version) { } /** - * Removes the MozUpdater folders that bgupdates/staged updates creates. + * Removes the MozUpdater directory that is created when replacing an install + * with a staged update and leftover MozUpdater-i folders in the tmp directory. */ function cleanUpMozUpdaterDirs() { + try { + // Remove the MozUpdater directory in the updates/0 directory. + var mozUpdaterDir = getUpdatesDir(); + mozUpdaterDir.append("MozUpdater"); + if (mozUpdaterDir.exists()) { + LOG("cleanUpMozUpdaterDirs - removing MozUpdater directory"); + mozUpdaterDir.remove(true); + } + } catch (e) { + LOG("cleanUpMozUpdaterDirs - Exception: " + e); + } + try { var tmpDir = Cc["@mozilla.org/file/directory_service;1"]. getService(Ci.nsIProperties). get("TmpD", Ci.nsIFile); - // We used to store MozUpdater-i folders directly inside the temp directory. - // We need to cleanup these directories if we detect that they still exist. + // We used to store MozUpdater-i directories in the temp directory. + // We need to remove these directories if we detect that they still exist. // To check if they still exist, we simply check for MozUpdater-1. var mozUpdaterDir1 = tmpDir.clone(); mozUpdaterDir1.append("MozUpdater-1"); - // Only try to delete the left over folders in "$Temp/MozUpdater-i/*" if + // Only try to delete the left over directories in "$Temp/MozUpdater-i/*" if // MozUpdater-1 exists. if (mozUpdaterDir1.exists()) { - LOG("cleanUpMozUpdaterDirs - Cleaning top level MozUpdater-i folders"); + LOG("cleanUpMozUpdaterDirs - Removing top level tmp MozUpdater-i " + + "directories"); let i = 0; let dirEntries = tmpDir.directoryEntries; while (dirEntries.hasMoreElements() && i < 10) { @@ -1247,15 +1261,6 @@ function cleanUpMozUpdaterDirs() { mozUpdaterDir1.remove(true); } } - - // If we reach here, we simply need to clean the MozUpdater folder. In our - // new way of storing these files, the unique subfolders are inside MozUpdater - var mozUpdaterDir = tmpDir.clone(); - mozUpdaterDir.append("MozUpdater"); - if (mozUpdaterDir.exists()) { - LOG("cleanUpMozUpdaterDirs - Cleaning MozUpdater folder"); - mozUpdaterDir.remove(true); - } } catch (e) { LOG("cleanUpMozUpdaterDirs - Exception: " + e); } @@ -2298,7 +2303,8 @@ UpdateService.prototype = { prompter.showUpdateError(update); } - // Now trash the MozUpdater folders which staged/bgupdates uses. + // Now trash the MozUpdater directory created when replacing an install with + // a staged update. cleanUpMozUpdaterDirs(); }, diff --git a/toolkit/xre/nsUpdateDriver.cpp b/toolkit/xre/nsUpdateDriver.cpp index 0e48e598ffcc..16f50ea99d61 100644 --- a/toolkit/xre/nsUpdateDriver.cpp +++ b/toolkit/xre/nsUpdateDriver.cpp @@ -417,43 +417,40 @@ CopyUpdaterIntoUpdateDir(nsIFile *greDir, nsIFile *appDir, nsIFile *updateDir, * staged. * * @param greDir the GRE dir - * @param updateDir the update root dir - * @param statusFile the update.status file + * @param updateDir the update dir where the mar file is located * @param appDir the app dir * @param appArgc the number of args to the application * @param appArgv the args to the application, used for restarting if needed */ static void -SwitchToUpdatedApp(nsIFile *greDir, nsIFile *updateDir, nsIFile *statusFile, +SwitchToUpdatedApp(nsIFile *greDir, nsIFile *updateDir, nsIFile *appDir, int appArgc, char **appArgv) { nsresult rv; // Steps: - // - copy updater into temp dir + // - copy updater into updates/0/MozUpdater/bgupdate/ dir // - run updater with the correct arguments - nsCOMPtr tmpDir; - GetSpecialSystemDirectory(OS_TemporaryDirectory, - getter_AddRefs(tmpDir)); - if (!tmpDir) { - LOG(("failed getting a temp dir\n")); + nsCOMPtr mozUpdaterDir; + rv = updateDir->Clone(getter_AddRefs(mozUpdaterDir)); + if (NS_FAILED(rv)) { + LOG(("failed cloning update dir\n")); return; } - // Try to create our own new temp directory in case there is already an - // updater binary in the OS temporary location which we cannot write to. - // Note that we don't check for errors here, as if this directory can't - // be created, the following CopyUpdaterIntoUpdateDir call will fail. - // We create the unique directory inside a subfolder of MozUpdater instead - // of directly in the temp directory so we can efficiently delete everything - // after updates. - tmpDir->Append(NS_LITERAL_STRING("MozUpdater")); - tmpDir->Append(NS_LITERAL_STRING("bgupdate")); - tmpDir->CreateUnique(nsIFile::DIRECTORY_TYPE, 0755); + // Create a new directory named MozUpdater in the updates/0 directory to copy + // the updater files to that will be used to replace the installation with the + // staged application that has been updated. Note that we don't check for + // directory creation errors since the call to CopyUpdaterIntoUpdateDir will + // fail if the creation of the directory fails. A unique directory is created + // in MozUpdater in case a previous attempt locked the directory or files. + mozUpdaterDir->Append(NS_LITERAL_STRING("MozUpdater")); + mozUpdaterDir->Append(NS_LITERAL_STRING("bgupdate")); + mozUpdaterDir->CreateUnique(nsIFile::DIRECTORY_TYPE, 0755); nsCOMPtr updater; - if (!CopyUpdaterIntoUpdateDir(greDir, appDir, tmpDir, updater)) { + if (!CopyUpdaterIntoUpdateDir(greDir, appDir, mozUpdaterDir, updater)) { LOG(("failed copying updater\n")); return; } @@ -1012,8 +1009,7 @@ ProcessUpdates(nsIFile *greDir, nsIFile *appDir, nsIFile *updRootDir, case eAppliedService: // An update was staged and needs to be switched so the updated application // is used. - SwitchToUpdatedApp(greDir, updatesDir, statusFile, - appDir, argc, argv); + SwitchToUpdatedApp(greDir, updatesDir, appDir, argc, argv); break; case eNoUpdateAction: // We don't need to do any special processing here, we'll just continue to From 8de369539eb81f3ab96e4410095c1f043e8b094b Mon Sep 17 00:00:00 2001 From: Hannes Verschore Date: Tue, 2 Dec 2014 17:43:25 -0800 Subject: [PATCH 13/24] Bug 1105727 - IonMonkey: Don't abort compiling when inlining array join fails, r=nbp --- js/src/jit/MCallOptimize.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 9e7787b45af8..62723531e007 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -550,14 +550,14 @@ IonBuilder::InliningStatus IonBuilder::inlineArrayJoin(CallInfo &callInfo) { if (callInfo.argc() != 1 || callInfo.constructing()) - return InliningStatus_Error; + return InliningStatus_NotInlined; if (getInlineReturnType() != MIRType_String) - return InliningStatus_Error; + return InliningStatus_NotInlined; if (callInfo.thisArg()->type() != MIRType_Object) - return InliningStatus_Error; + return InliningStatus_NotInlined; if (callInfo.getArg(0)->type() != MIRType_String) - return InliningStatus_Error; + return InliningStatus_NotInlined; callInfo.setImplicitlyUsedUnchecked(); From 4a745facf7872eb2b8eb319b5179ec0db4cff993 Mon Sep 17 00:00:00 2001 From: Andrew Halberstadt Date: Tue, 2 Dec 2014 14:40:14 -0800 Subject: [PATCH 14/24] Bug 1104941 - Bump marionette-client to 0.8.5, r=AutomatedTester --HG-- extra : rebase_source : f6435707a5808e9119cca7bbe3ad5a8d40585b0f --- testing/marionette/client/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/marionette/client/setup.py b/testing/marionette/client/setup.py index 9c678b3c62d7..6c9635dc76b0 100644 --- a/testing/marionette/client/setup.py +++ b/testing/marionette/client/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup, find_packages import sys -version = '0.8.4' +version = '0.8.5' # dependencies with open('requirements.txt') as f: From 09a19cc46cebccb1f170702ae7f32cb955a6b021 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Tue, 2 Dec 2014 14:28:19 +0100 Subject: [PATCH 15/24] Bug 1104008 - Make sure the D3D11 swapchain's textures are cleared before resizing. r=Bas. --- gfx/layers/composite/TextureHost.h | 7 ++++--- gfx/layers/d3d11/CompositorD3D11.cpp | 10 +++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index cf1fc47508ee..37ee46613aa7 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -86,13 +86,15 @@ public: * * This class is used on the compositor side. */ -class TextureSource +class TextureSource: public RefCounted { public: - NS_INLINE_DECL_REFCOUNTING(TextureSource) + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(TextureSource) TextureSource(); + virtual ~TextureSource(); + /** * Should be overridden in order to deallocate the data that is associated * with the rendering backend, such as GL textures. @@ -159,7 +161,6 @@ public: int NumCompositableRefs() const { return mCompositableCount; } protected: - virtual ~TextureSource(); RefPtr mNextSibling; int mCompositableCount; diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 2be4be291ba0..334a54f64124 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -938,7 +938,15 @@ CompositorD3D11::VerifyBufferSize() return; } - mDefaultRT = nullptr; + if (mDefaultRT) { + // Make sure the texture, which belongs to the swapchain, is destroyed + // before resizing the swapchain. + if (mCurrentRT == mDefaultRT) { + mCurrentRT = nullptr; + } + MOZ_ASSERT(mDefaultRT->hasOneRef()); + mDefaultRT = nullptr; + } if (IsRunningInWindowsMetro()) { hr = mSwapChain->ResizeBuffers(2, mSize.width, mSize.height, From 76435865a2be4b575aa6a7477972e47bd2634c97 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 25 Nov 2014 17:20:33 -0500 Subject: [PATCH 16/24] Bug 1105015. Make the UnboundnessFixer more readable. r=milan --HG-- extra : rebase_source : f584762adbf2afbbdccc563f2a198ac069ef0106 --- gfx/2d/DrawTargetCG.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/gfx/2d/DrawTargetCG.cpp b/gfx/2d/DrawTargetCG.cpp index 6510a8fb8e08..20dfaf705460 100644 --- a/gfx/2d/DrawTargetCG.cpp +++ b/gfx/2d/DrawTargetCG.cpp @@ -266,9 +266,9 @@ class UnboundnessFixer { CGRect mClipBounds; CGLayerRef mLayer; - CGContextRef mCg; + CGContextRef mLayerCg; public: - UnboundnessFixer() : mCg(nullptr) {} + UnboundnessFixer() : mLayerCg(nullptr) {} CGContextRef Check(CGContextRef baseCg, CompositionOp blend, const Rect* maskBounds = nullptr) { @@ -287,14 +287,14 @@ class UnboundnessFixer //XXX: The size here is in default user space units, of the layer relative to the graphics context. // is the clip bounds still correct if, for example, we have a scale applied to the context? mLayer = CGLayerCreateWithContext(baseCg, mClipBounds.size, nullptr); - mCg = CGLayerGetContext(mLayer); + mLayerCg = CGLayerGetContext(mLayer); // CGContext's default to have the origin at the bottom left // so flip it to the top left and adjust for the origin // of the layer - CGContextTranslateCTM(mCg, -mClipBounds.origin.x, mClipBounds.origin.y + mClipBounds.size.height); - CGContextScaleCTM(mCg, 1, -1); + CGContextTranslateCTM(mLayerCg, -mClipBounds.origin.x, mClipBounds.origin.y + mClipBounds.size.height); + CGContextScaleCTM(mLayerCg, 1, -1); - return mCg; + return mLayerCg; } else { return baseCg; } @@ -302,12 +302,13 @@ class UnboundnessFixer void Fix(CGContextRef baseCg) { - if (mCg) { + if (mLayerCg) { + // we pushed a layer so draw it to baseCg CGContextTranslateCTM(baseCg, 0, mClipBounds.size.height); CGContextScaleCTM(baseCg, 1, -1); mClipBounds.origin.y *= -1; CGContextDrawLayerAtPoint(baseCg, mClipBounds.origin, mLayer); - CGContextRelease(mCg); + CGContextRelease(mLayerCg); } } }; From 5b4a6569a522a484dad8d580f4d9f33649856ffa Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Wed, 26 Nov 2014 17:57:20 -0500 Subject: [PATCH 17/24] Bug 1049138. Add more crashing to PadDrawTargetOutFromRegion. r=BenWa try: -b do -p all -u all -t none Hopefully, this will give us a better idea of what the problem is. --HG-- extra : rebase_source : 4f048b2501bb13edc4e257aa561bce87ea3137fd --- gfx/layers/client/TiledContentClient.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 97bddf1c7340..9e65dff8ac11 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -987,6 +987,22 @@ void PadDrawTargetOutFromRegion(RefPtr drawTarget, nsIntRegion ®i return x; } + static void ensure_memcpy(uint8_t *dst, uint8_t *src, size_t n, uint8_t *bitmap, int stride, int height) + { + if (src + n > bitmap + stride*height) { + MOZ_CRASH("long src memcpy"); + } + if (src < bitmap) { + MOZ_CRASH("short src memcpy"); + } + if (dst + n > bitmap + stride*height) { + MOZ_CRASH("long dst mempcy"); + } + if (dst < bitmap) { + MOZ_CRASH("short dst mempcy"); + } + } + static void visitor(void *closure, VisitSide side, int x1, int y1, int x2, int y2) { LockedBits *lb = static_cast(closure); uint8_t *bitmap = lb->data; @@ -999,12 +1015,14 @@ void PadDrawTargetOutFromRegion(RefPtr drawTarget, nsIntRegion ®i if (y1 > 0) { x1 = clamp(x1, 0, width - 1); x2 = clamp(x2, 0, width - 1); + ensure_memcpy(&bitmap[x1*bpp + (y1-1) * stride], &bitmap[x1*bpp + y1 * stride], (x2 - x1) * bpp, bitmap, stride, height); memcpy(&bitmap[x1*bpp + (y1-1) * stride], &bitmap[x1*bpp + y1 * stride], (x2 - x1) * bpp); } } else if (side == VisitSide::BOTTOM) { if (y1 < height) { x1 = clamp(x1, 0, width - 1); x2 = clamp(x2, 0, width - 1); + ensure_memcpy(&bitmap[x1*bpp + y1 * stride], &bitmap[x1*bpp + (y1-1) * stride], (x2 - x1) * bpp, bitmap, stride, height); memcpy(&bitmap[x1*bpp + y1 * stride], &bitmap[x1*bpp + (y1-1) * stride], (x2 - x1) * bpp); } } else if (side == VisitSide::LEFT) { From c3a9dd35edc7fa36500cf4ba6f726d0c2f7d3765 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 2 Dec 2014 17:46:32 -0800 Subject: [PATCH 18/24] Bug 1094097. Fix building ANGLE without D3D11. r=jrmuizel --HG-- extra : rebase_source : 0a1bfad2cdd76ddf26565d664f3b0e1c5a208cba --- gfx/angle/src/commit.h | 4 ++-- gfx/angle/src/common/NativeWindow.h | 4 ++++ gfx/angle/src/common/win32/NativeWindow.cpp | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gfx/angle/src/commit.h b/gfx/angle/src/commit.h index 8a951412c034..d221ae7291ed 100644 --- a/gfx/angle/src/commit.h +++ b/gfx/angle/src/commit.h @@ -1,3 +1,3 @@ -#define ANGLE_COMMIT_HASH "f0cacb827771" +#define ANGLE_COMMIT_HASH "0fb6a60df77b" #define ANGLE_COMMIT_HASH_SIZE 12 -#define ANGLE_COMMIT_DATE "2014-10-28 23:00:12 -0400" +#define ANGLE_COMMIT_DATE "2014-11-28 13:56:37 -0500" diff --git a/gfx/angle/src/common/NativeWindow.h b/gfx/angle/src/common/NativeWindow.h index c5062789fd63..c0920a33d311 100644 --- a/gfx/angle/src/common/NativeWindow.h +++ b/gfx/angle/src/common/NativeWindow.h @@ -16,12 +16,14 @@ #include "common/debug.h" #include "common/platform.h" +#ifdef ANGLE_ENABLE_D3D11 // DXGISwapChain and DXGIFactory are typedef'd to specific required // types. The HWND NativeWindow implementation requires IDXGISwapChain // and IDXGIFactory and the Windows Store NativeWindow // implementation requires IDXGISwapChain1 and IDXGIFactory2. typedef IDXGISwapChain DXGISwapChain; typedef IDXGIFactory DXGIFactory; +#endif namespace rx { @@ -37,9 +39,11 @@ class NativeWindow inline bool getClientRect(LPRECT rect) { return GetClientRect(mWindow, rect) == TRUE; } inline bool isIconic() { return IsIconic(mWindow) == TRUE; } +#ifdef ANGLE_ENABLE_D3D11 HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, DXGI_FORMAT format, UINT width, UINT height, DXGISwapChain** swapChain); +#endif inline EGLNativeWindowType getNativeWindow() const { return mWindow; } diff --git a/gfx/angle/src/common/win32/NativeWindow.cpp b/gfx/angle/src/common/win32/NativeWindow.cpp index 403f9bc3e68a..07e80d97cece 100644 --- a/gfx/angle/src/common/win32/NativeWindow.cpp +++ b/gfx/angle/src/common/win32/NativeWindow.cpp @@ -20,6 +20,7 @@ NativeWindow::NativeWindow(EGLNativeWindowType window) : mWindow(window) { } +#ifdef ANGLE_ENABLE_D3D11 HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain** swapChain) @@ -48,4 +49,5 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory return factory->CreateSwapChain(device, &swapChainDesc, swapChain); } -}; \ No newline at end of file +#endif +}; From 49545109bb6aabfa5d55a02e82bc53e71d29d9e9 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Mon, 1 Dec 2014 06:07:25 -0800 Subject: [PATCH 19/24] Bug 1102858 - Fix tracing of debugger objects' private pointers for compacting GC r=terrence --- js/src/gc/RootMarking.cpp | 2 +- js/src/jsgc.cpp | 2 +- js/src/vm/Debugger.cpp | 58 ++++++++++++++++++--------------------- js/src/vm/Debugger.h | 28 +++++++++++-------- 4 files changed, 44 insertions(+), 46 deletions(-) diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 61a123d6ecc0..f1db475739a9 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -454,7 +454,7 @@ js::gc::GCRuntime::markRuntime(JSTracer *trc, if (!c->zone()->isCollecting()) c->markCrossCompartmentWrappers(trc); } - Debugger::markCrossCompartmentDebuggerObjectReferents(trc); + Debugger::markAllCrossCompartmentEdges(trc); } AutoGCRooter::traceAll(trc); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 28d39562ebf5..2f16ea2856a0 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -2662,7 +2662,7 @@ GCRuntime::updatePointersToRelocatedCells() // Mark roots to update them. markRuntime(&trc, MarkRuntime); Debugger::markAll(&trc); - Debugger::markCrossCompartmentDebuggerObjectReferents(&trc); + Debugger::markAllCrossCompartmentEdges(&trc); for (GCCompartmentsIter c(rt); !c.done(); c.next()) { WeakMapBase::markAll(c, &trc); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 9a62ec31faba..67383307af2a 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -93,6 +93,11 @@ enum { JSSLOT_DEBUGSOURCE_COUNT }; +void DebuggerObject_trace(JSTracer *trc, JSObject *obj); +void DebuggerEnv_trace(JSTracer *trc, JSObject *obj); +void DebuggerScript_trace(JSTracer *trc, JSObject *obj); +void DebuggerSource_trace(JSTracer *trc, JSObject *obj); + /*** Utils ***************************************************************************************/ @@ -2073,17 +2078,12 @@ Debugger::setObservesAllExecution(JSContext *cx, IsObserving observing) /*** Debugger JSObjects **************************************************************************/ void -Debugger::markKeysInCompartment(JSTracer *trc) +Debugger::markCrossCompartmentEdges(JSTracer *trc) { - /* - * WeakMap::Range is deliberately private, to discourage C++ code from - * enumerating WeakMap keys. However in this case we need access, so we - * make a base-class reference. Range is public in HashMap. - */ - objects.markKeys(trc); - environments.markKeys(trc); - scripts.markKeys(trc); - sources.markKeys(trc); + objects.markCrossCompartmentEdges(trc); + environments.markCrossCompartmentEdges(trc); + scripts.markCrossCompartmentEdges(trc); + sources.markCrossCompartmentEdges(trc); } /* @@ -2091,35 +2091,30 @@ Debugger::markKeysInCompartment(JSTracer *trc) * discovered that the WeakMap was live; that is, some object containing the * WeakMap was marked during mark phase. * - * However, during compartment GC, we have to do something about - * cross-compartment WeakMaps in non-GC'd compartments. If their keys and values - * might need to be marked, we have to do it manually. + * However, during zone GC, we have to do something about cross-compartment + * edges in non-GC'd compartments. Since the source may be live, we + * conservatively assume it is and mark the edge. * - * Each Debugger object keeps found cross-compartment WeakMaps: objects, scripts, - * script source objects, and environments. They have the nice property that all - * their values are in the same compartment as the Debugger object, so we only - * need to mark the keys. We must simply mark all keys that are in a compartment - * being GC'd. + * Each Debugger object keeps four cross-compartment WeakMaps: objects, scripts, + * script source objects, and environments. They have the property that all + * their values are in the same compartment as the Debugger object, but we have + * to mark the keys and the private pointer in the wrapper object. * - * We must scan all Debugger objects regardless of whether they *currently* - * have any debuggees in a compartment being GC'd, because the WeakMap - * entries persist even when debuggees are removed. + * We must scan all Debugger objects regardless of whether they *currently* have + * any debuggees in a compartment being GC'd, because the WeakMap entries + * persist even when debuggees are removed. * * This happens during the initial mark phase, not iterative marking, because * all the edges being reported here are strong references. */ /* static */ void -Debugger::markCrossCompartmentDebuggerObjectReferents(JSTracer *trc) +Debugger::markAllCrossCompartmentEdges(JSTracer *trc) { JSRuntime *rt = trc->runtime(); - /* - * Mark all objects in comp that are referents of Debugger.Objects in other - * compartments. - */ for (Debugger *dbg = rt->debuggerList.getFirst(); dbg; dbg = dbg->getNext()) { if (!dbg->object->zone()->isCollecting()) - dbg->markKeysInCompartment(trc); + dbg->markCrossCompartmentEdges(trc); } } @@ -2213,7 +2208,6 @@ Debugger::markAll(JSTracer *trc) GlobalObjectSet &debuggees = dbg->debuggees; for (GlobalObjectSet::Enum e(debuggees); !e.empty(); e.popFront()) { GlobalObject *global = e.front(); - MarkObjectUnbarriered(trc, &global, "Global Object"); if (global != e.front()) e.rekeyFront(global); @@ -3814,7 +3808,7 @@ GetScriptReferent(JSObject *obj) return static_cast(obj->as().getPrivate()); } -static void +void DebuggerScript_trace(JSTracer *trc, JSObject *obj) { /* This comes from a private pointer, so no barrier needed. */ @@ -4765,7 +4759,7 @@ GetSourceReferent(JSObject *obj) return static_cast(obj->as().getPrivate()); } -static void +void DebuggerSource_trace(JSTracer *trc, JSObject *obj) { /* @@ -5845,7 +5839,7 @@ static const JSFunctionSpec DebuggerFrame_methods[] = { /*** Debugger.Object *****************************************************************************/ -static void +void DebuggerObject_trace(JSTracer *trc, JSObject *obj) { /* @@ -6753,7 +6747,7 @@ static const JSFunctionSpec DebuggerObject_methods[] = { /*** Debugger.Environment ************************************************************************/ -static void +void DebuggerEnv_trace(JSTracer *trc, JSObject *obj) { /* diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index 04ef22ce4305..7748fa0b8241 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -36,10 +36,9 @@ class Breakpoint; class DebuggerMemory; /* - * A weakmap that supports the keys being in different compartments to the - * values, although all values must be in the same compartment. - * - * The Key and Value classes must support the compartment() method. + * A weakmap from GC thing keys to JSObject values that supports the keys being + * in different compartments to the values. All values must be in the same + * compartment. * * The purpose of this is to allow the garbage collector to easily find edges * from debugee object compartments to debugger compartments when calculating @@ -55,10 +54,13 @@ class DebuggerMemory; * debugger compartments. If it is false, we assert that such entries are never * created. */ -template -class DebuggerWeakMap : private WeakMap > +template +class DebuggerWeakMap : private WeakMap, RelocatablePtrObject> { private: + typedef PreBarriered Key; + typedef RelocatablePtrObject Value; + typedef HashMap, @@ -112,8 +114,10 @@ class DebuggerWeakMap : private WeakMap > } public: - void markKeys(JSTracer *tracer) { + template + void markCrossCompartmentEdges(JSTracer *tracer) { for (Enum e(*static_cast(this)); !e.empty(); e.popFront()) { + traceValueEdges(tracer, e.front().value()); Key key = e.front().key(); gc::Mark(tracer, &key, "Debugger WeakMap key"); if (key != e.front().key()) @@ -282,15 +286,15 @@ class Debugger : private mozilla::LinkedListElement FrameMap frames; /* An ephemeral map from JSScript* to Debugger.Script instances. */ - typedef DebuggerWeakMap ScriptWeakMap; + typedef DebuggerWeakMap ScriptWeakMap; ScriptWeakMap scripts; /* The map from debuggee source script objects to their Debugger.Source instances. */ - typedef DebuggerWeakMap SourceWeakMap; + typedef DebuggerWeakMap SourceWeakMap; SourceWeakMap sources; /* The map from debuggee objects to their Debugger.Object instances. */ - typedef DebuggerWeakMap ObjectWeakMap; + typedef DebuggerWeakMap ObjectWeakMap; ObjectWeakMap objects; /* The map from debuggee Envs to Debugger.Environment instances. */ @@ -356,7 +360,7 @@ class Debugger : private mozilla::LinkedListElement static void traceObject(JSTracer *trc, JSObject *obj); void trace(JSTracer *trc); static void finalize(FreeOp *fop, JSObject *obj); - void markKeysInCompartment(JSTracer *tracer); + void markCrossCompartmentEdges(JSTracer *tracer); static const Class jsclass; @@ -506,7 +510,7 @@ class Debugger : private mozilla::LinkedListElement * Debugger objects that are definitely live but not yet marked, it marks * them and returns true. If not, it returns false. */ - static void markCrossCompartmentDebuggerObjectReferents(JSTracer *tracer); + static void markAllCrossCompartmentEdges(JSTracer *tracer); static bool markAllIteratively(GCMarker *trc); static void markAll(JSTracer *trc); static void sweepAll(FreeOp *fop); From be4331ca4b3363adf0197fcf879f9ce05747fc57 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Tue, 2 Dec 2014 18:02:45 -0800 Subject: [PATCH 20/24] Bug 650161 - Fix a bug than meant we relocated fewer arenas than we should have r=terrence --- js/src/jsgc.cpp | 21 ++++++--------------- js/src/jsgc.h | 1 - 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 2f16ea2856a0..cc29f566874e 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -2082,20 +2082,6 @@ size_t ArenaHeader::countUsedCells() return Arena::thingsPerArena(getThingSize()) - countFreeCells(); } -/* - * Iterate throught the list and count the number of cells used. - * - * We may be able to precalculate this while sweeping and store the result - * somewhere. - */ -size_t ArenaList::countUsedCells() -{ - size_t count = 0; - for (ArenaHeader *arena = head_; arena; arena = arena->next) - count += arena->countUsedCells(); - return count; -} - ArenaHeader * ArenaList::removeRemainingArenas(ArenaHeader **arenap, const AutoLockGC &lock) { @@ -2153,7 +2139,12 @@ ArenaList::pickArenasToRelocate(JSRuntime *runtime) ArenaHeader **arenap = cursorp_; // Next arena to consider size_t previousFreeCells = 0; // Count of free cells before - size_t followingUsedCells = countUsedCells(); // Count of used cells after + + // Count of used cells after arenap. + size_t followingUsedCells = 0; + for (ArenaHeader *arena = *arenap; arena; arena = arena->next) + followingUsedCells += arena->countUsedCells(); + mozilla::DebugOnly lastFreeCells(0); size_t cellsPerArena = Arena::thingsPerArena((*arenap)->getThingSize()); diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 8e8661ab5f8e..05f58ca33962 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -503,7 +503,6 @@ class ArenaList { } #ifdef JSGC_COMPACTING - size_t countUsedCells(); ArenaHeader *removeRemainingArenas(ArenaHeader **arenap, const AutoLockGC &lock); ArenaHeader *pickArenasToRelocate(JSRuntime *runtime); ArenaHeader *relocateArenas(ArenaHeader *toRelocate, ArenaHeader *relocated); From 87d521274ec1c0a26bf51bca6445dcc6d3f995b9 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Mon, 1 Dec 2014 16:21:37 -0800 Subject: [PATCH 21/24] Bug 1099252 - Blocklist ATI graphics driver version 8.832.0.0. r=Bas --- widget/windows/GfxInfo.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/widget/windows/GfxInfo.cpp b/widget/windows/GfxInfo.cpp index ee215fe2f0d7..fb122e27a257 100644 --- a/widget/windows/GfxInfo.cpp +++ b/widget/windows/GfxInfo.cpp @@ -857,6 +857,12 @@ GfxInfo::GetGfxDriverInfo() GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_LESS_THAN, V(8,62,0,0), "9.6" ); + // Bug 1099252 + APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_WINDOWS_7, + (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices, + GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, + DRIVER_EQUAL, V(8,832,0,0)); + /* * Bug 783517 - crashes in AMD driver on Windows 8 */ From b341a046f7f9500510c447b6d542e9f3f7ee031e Mon Sep 17 00:00:00 2001 From: Matthew Gregan Date: Tue, 2 Dec 2014 14:00:45 +1300 Subject: [PATCH 22/24] Bug 1106657 - Move MOZ_PDM_VPX definition to moz.build. r=bholley --- dom/media/webm/WebMReader.cpp | 3 +-- dom/media/webm/moz.build | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dom/media/webm/WebMReader.cpp b/dom/media/webm/WebMReader.cpp index ef2a0f869657..eafa1272d7c1 100644 --- a/dom/media/webm/WebMReader.cpp +++ b/dom/media/webm/WebMReader.cpp @@ -26,9 +26,8 @@ #include "OggReader.h" // IntelWebMVideoDecoder uses the WMF backend, which is Windows Vista+ only. -#if defined(MOZ_FMP4) && defined(MOZ_WMF) +#if defined(MOZ_PDM_VPX) #include "IntelWebMVideoDecoder.h" -#define MOZ_PDM_VPX 1 #endif // Un-comment to enable logging of seek bisections. diff --git a/dom/media/webm/moz.build b/dom/media/webm/moz.build index 7d0c586ccd8c..159752721c26 100644 --- a/dom/media/webm/moz.build +++ b/dom/media/webm/moz.build @@ -19,7 +19,8 @@ UNIFIED_SOURCES += [ 'WebMReader.cpp', ] -if CONFIG['MOZ_FMP4']: +if CONFIG['MOZ_FMP4'] and CONFIG['MOZ_WMF']: + DEFINES['MOZ_PDM_VPX'] = True UNIFIED_SOURCES += ['IntelWebMVideoDecoder.cpp'] if CONFIG['MOZ_WEBM_ENCODER']: From 4eaf476a529c98ad993b74441fcef636b0281c4b Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Tue, 2 Dec 2014 18:40:15 -0800 Subject: [PATCH 23/24] Back out 1b87e7511983 (bug 940954) on suspicion of causing b2g desktop Mac sqlite troubles CLOSED TREE --- .../client/marionette/geckoinstance.py | 41 ++++++------------- .../client/marionette/marionette.py | 15 ++++--- .../tests/unit/test_profile_management.py | 8 +--- 3 files changed, 21 insertions(+), 43 deletions(-) diff --git a/testing/marionette/client/marionette/geckoinstance.py b/testing/marionette/client/marionette/geckoinstance.py index b29a8f54911d..e3447aab2fec 100644 --- a/testing/marionette/client/marionette/geckoinstance.py +++ b/testing/marionette/client/marionette/geckoinstance.py @@ -30,17 +30,12 @@ class GeckoInstance(object): "browser.tabs.remote.autostart.1": False, "browser.tabs.remote.autostart.2": False} - def __init__(self, host, port, bin, profile=None, app_args=None, symbols_path=None, - gecko_log=None, prefs=None, ): + def __init__(self, host, port, bin, profile, app_args=None, symbols_path=None, + gecko_log=None, prefs=None): self.marionette_host = host self.marionette_port = port self.bin = bin - # Check if it is a Profile object or a path to profile - self.profile = None - if isinstance(profile, Profile): - self.profile = profile - else: - self.profile_path = profile + self.profile_path = profile self.prefs = prefs self.app_args = app_args or [] self.runner = None @@ -52,14 +47,12 @@ class GeckoInstance(object): profile_args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port if self.prefs: profile_args["preferences"].update(self.prefs) - - if hasattr(self, "profile_path") and self.profile is None: - if not self.profile_path: - profile_args["restore"] = False - self.profile = Profile(**profile_args) - else: - profile_args["path_from"] = self.profile_path - self.profile = Profile.clone(**profile_args) + if not self.profile_path: + profile_args["restore"] = False + profile = Profile(**profile_args) + else: + profile_args["path_from"] = self.profile_path + profile = Profile.clone(**profile_args) process_args = { 'processOutputLine': [NullOutput()], @@ -108,28 +101,20 @@ class GeckoInstance(object): 'MOZ_CRASHREPORTER_NO_REPORT': '1', }) self.runner = Runner( binary=self.bin, - profile=self.profile, + profile=profile, cmdargs=['-no-remote', '-marionette'] + self.app_args, env=env, symbols_path=self.symbols_path, process_args=process_args) self.runner.start() - def close(self, restart=False): - if not restart: - self.profile.cleanup() - self.profile = None - + def close(self): if self.runner: self.runner.stop() self.runner.cleanup() - def restart(self, prefs=None, clean=True): - if clean: - self.profile.cleanup() - self.profile = None - - self.close(restart=True) + def restart(self, prefs=None): + self.close() if prefs: self.prefs = prefs else: diff --git a/testing/marionette/client/marionette/marionette.py b/testing/marionette/client/marionette/marionette.py index 26df978c3aa0..010d83e9c148 100644 --- a/testing/marionette/client/marionette/marionette.py +++ b/testing/marionette/client/marionette/marionette.py @@ -475,7 +475,6 @@ class Marionette(object): self.host = host self.port = self.local_port = port self.bin = bin - self.profile = profile self.instance = None self.session = None self.session_id = None @@ -513,7 +512,7 @@ class Marionette(object): KeyError): instance_class = geckoinstance.GeckoInstance self.instance = instance_class(host=self.host, port=self.port, - bin=self.bin, profile=self.profile, + bin=self.bin, profile=profile, app_args=app_args, symbols_path=symbols_path, gecko_log=gecko_log) self.instance.start() @@ -529,7 +528,7 @@ class Marionette(object): binary=emulator_binary, userdata=emulator_img, resolution=emulator_res, - profile=self.profile, + profile=profile, adb_path=adb_path, process_args=process_args) self.emulator = self.runner.device @@ -774,20 +773,20 @@ class Marionette(object): self.start_session() self._reset_timeouts() - def restart(self, clean=False): + def restart_with_clean_profile(self): """ This will terminate the currently running instance, and spawn a new instance - with the same profile and then reuse the session id when creating a session again. + with a clean profile. : param prefs: A dictionary whose keys are preference names. """ if not self.instance: - raise errors.MarionetteException("restart can only be called " \ + raise errors.MarionetteException("enforce_gecko_prefs can only be called " \ "on gecko instances launched by Marionette") self.delete_session() - self.instance.restart(clean=clean) + self.instance.restart() assert(self.wait_for_port()), "Timed out waiting for port!" - self.start_session(session_id=self.session_id) + self.start_session() self._reset_timeouts() def absolute_url(self, relative_url): diff --git a/testing/marionette/client/marionette/tests/unit/test_profile_management.py b/testing/marionette/client/marionette/tests/unit/test_profile_management.py index 28b9477c2e97..b1cbd46b8bb8 100644 --- a/testing/marionette/client/marionette/tests/unit/test_profile_management.py +++ b/testing/marionette/client/marionette/tests/unit/test_profile_management.py @@ -27,12 +27,6 @@ class TestLog(MarionetteTestCase): self.assertFalse(bool_value) def test_clean_profile(self): - self.marionette.restart(clean=True) + self.marionette.restart_with_clean_profile() with self.assertRaisesRegexp(JavascriptException, "Error getting pref"): bool_value = self.marionette.execute_script("return SpecialPowers.getBoolPref('marionette.test.bool');") - - def test_can_restart_the_browser(self): - self.marionette.enforce_gecko_prefs({"marionette.test.restart": True}) - self.marionette.restart() - bool_value = self.marionette.execute_script("return SpecialPowers.getBoolPref('marionette.test.restart');") - self.assertTrue(bool_value) \ No newline at end of file From 18b2531efe9fa64064ab78379b2f74c5138a9bac Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Tue, 2 Dec 2014 20:29:29 -0800 Subject: [PATCH 24/24] Bug 1106665 - Fix text-align:justify for vertical writing modes. r=smontagu --- layout/generic/nsTextFrame.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index e44405cd7e52..2aac1c38a0d1 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -3382,13 +3382,16 @@ PropertyProvider::SetupJustificationSpacing(bool aPostReflow) return; } + // Remember that textrun measurements are in the run's orientation, + // so its advance "width" is actually a height in vertical writing modes, + // corresponding to the inline-direction of the frame. gfxFloat naturalWidth = mTextRun->GetAdvanceWidth(mStart.GetSkippedOffset(), GetSkippedDistance(mStart, realEnd), this); if (mFrame->GetStateBits() & TEXT_HYPHEN_BREAK) { naturalWidth += GetHyphenWidth(); } - mJustificationSpacing = mFrame->GetSize().width - naturalWidth; + mJustificationSpacing = mFrame->ISize() - naturalWidth; if (mJustificationSpacing <= 0) { // No space available return;